dirent, stat

이번에 dirent 와 stat 을 이용하여 작업을 하면서 알게된 내용들을 간단하게 정리했다.

dirent

dirent 는 디렉토리 정보를 담는 구조체이다.
dirent 와 scandir() 을 사용하면 디렉토리에 어떤 파일들이 있는지 간략하게 알 수 있는 속성과 파일 리스트 포인터를 이용할 수 있다.

struct dirent
{
#ifndef __USE_FILE_OFFSET64
    __ino_t d_ino;
    __off_t d_off;
#else
    __ino64_t d_ino;
    __off64_t d_off;
#endif
    unsigned short int d_reclen;
    unsigned char d_type;
    char d_name[256];		/* We must not include limits.h! */
};

구조체 내용 중, d_type 으로 파일의 속성을 파악할 수 있는데, 종류는 다음과 같다.

#ifdef __USE_BSD
/* File types for `d_type'.  */
enum
  {
    DT_UNKNOWN = 0,
# define DT_UNKNOWN	DT_UNKNOWN
    DT_FIFO = 1,
# define DT_FIFO	DT_FIFO
    DT_CHR = 2,
# define DT_CHR		DT_CHR
    DT_DIR = 4,
# define DT_DIR		DT_DIR
    DT_BLK = 6,
# define DT_BLK		DT_BLK
    DT_REG = 8,
# define DT_REG		DT_REG
    DT_LNK = 10,
# define DT_LNK		DT_LNK
    DT_SOCK = 12,
# define DT_SOCK	DT_SOCK
    DT_WHT = 14
# define DT_WHT		DT_WHT
  };

/* Convert between stat structure types and directory types.  */
# define IFTODT(mode)	(((mode) & 0170000) >> 12)
# define DTTOIF(dirtype)	((dirtype) << 12)
#endif

 

stat

stat 은 파일 속성을 가져오는 함수이며, 구조체이다. stat 을 호출하면, 입력한 파일에 대한 속성들이 struct stat 구조체에 입력된다.

struct stat {
   dev_t     st_dev;     /* ID of device containing file */
   ino_t     st_ino;     /* inode number */
   mode_t    st_mode;    /* protection */
   nlink_t   st_nlink;   /* number of hard links */
   uid_t     st_uid;     /* user ID of owner */
   gid_t     st_gid;     /* group ID of owner */
   dev_t     st_rdev;    /* device ID (if special file) */
   off_t     st_size;    /* total size, in bytes */
   blksize_t st_blksize; /* blocksize for filesystem I/O */
   blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
   time_t    st_atime;   /* time of last access */
   time_t    st_mtime;   /* time of last modification */
   time_t    st_ctime;   /* time of last status change */
};

 

Eaxmple

아래는 stat 과 scandir 을 이용한 예제 프로그램이다.
현재 디렉토리 내에 있는 모든 파일들을 최근 수정한 순서대로 검색하며 각각의 파일명과 사이즈(Byte)를 표시한다.
만약, 디렉토리 안에 있는 파일들의 용량의 10M가 넘어가면, 그 이후부터는 파일을 삭제한다.

즉, 디렉토리에 있는 파일들의 용량이 10M가 넘어가면 오래된 파일부터 삭제하는 것이다.

그리고 파일을 검색하는 도중 파일명에 .wav(wav 파일)이 들어있으면 “Found wav file” 을 표시한다.

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#define TARGET_DIR "."
#define LIMIT_SIZE 10485760 // 10M

int file_select( const struct dirent *d );
int cmp_time(const struct dirent **e1, const struct dirent **e2);


int main(int argc, char** argv)
{
    struct dirent **namelist;
    struct stat tmp_stat;
    unsigned long total_size;
    char* pszFilename;
    int iCnt;
    int i;
    int iRet;
    char* pRet;

    iCnt = scandir(TARGET_DIR, &namelist, file_select, cmp_time);
    if(iCnt < 0)
    {
        printf("Could not scanning.. err:%d, msg:%s\n", errno, strerror(errno));
        return 0;
    }

    total_size = 0;
    printf("Scan files:%d\n", iCnt);
    for(i = 0; i < iCnt; i++)
    {
        asprintf(&pszFilename, "%s/%s", TARGET_DIR, namelist[i]->d_name);
        stat(pszFilename, &tmp_stat);
        printf("filename: %s, size:%ld\n", pszFilename, tmp_stat.st_size);
        pRet = strstr(namelist[i]->d_name, ".wav");
        if(pRet != NULL)
        {
            printf("Found wav file!\n");
        }

        total_size += tmp_stat.st_size;
        if(total_size > LIMIT_SIZE)
        {
            total_size -= tmp_stat.st_size;
            
            printf("Delete limit overed files... name: %s\n", pszFilename);
            iRet = remove(pszFilename);
            if(iRet == -1)
            {
                printf("Err! Could not delete file. name:%s, err:%d, msg:%s\n", pszFilename, errno, strerror(errno));
            }
        }
        
        free(pszFilename);
        free(namelist[i]);
    }
    
    free(namelist);
    
    printf("totalSize %lu\n", total_size);
    
    return 0;
}

/**
 * 
 */
int file_select(const struct dirent *entry)
{
    if(entry->d_type == DT_DIR)
    {
        return 0;
    }

    return 1;
}

/**
 *
 */
int cmp_time(const struct dirent **e1, const struct dirent **e2)
{
    int iRet;
    struct stat sb1;
    struct stat sb2;
    char* filename_e1;
    char* filename_e2;
    
    asprintf(&filename_e1, "%s/%s", TARGET_DIR, (*e1)->d_name);
    asprintf(&filename_e2, "%s/%s", TARGET_DIR, (*e2)->d_name);
        
    iRet = stat(filename_e1, &sb1);
    if(iRet == -1)
    {
        printf("Error occured! name:%s, err:%d, msg:%s\n", filename_e1, errno, strerror(errno));

        free(filename_e1);
        free(filename_e2);
        return -1;
    }
    
    iRet = stat(filename_e2, &sb2);
    if(iRet == -1)
    {
        printf("Error occured! Err:%d, Msg:%s\n", errno, strerror(errno));

        free(filename_e1);
        free(filename_e2);
        return -1;
    }
    
    free(filename_e1);
    free(filename_e2);
    
    return sb1.st_mtime < sb2.st_mtime;
}

What’s different between GET/POST?

출처 : http://blog.outsider.ne.kr/312

 

———————————————————————————————————————————–

다들 아시다시피 GET과 POST는 HTTP프로토콜을 이용해서 서버에 무언가를 전달할 때 사용하는 방식입니다. 웹개발자라면 당연히 알고 있어야 하는 사항이고 이걸 모르면 웹개발자체를 할 수가 없습니다. 상당히 기초적인 부분이긴 한데 잘 모르시는 분들도 있고 해서 미루고 미루던 포스팅을 이제야 합니다. ㅎㅎ GET과 POST 얘기를 하니까 예전 생각이 납니다. 예전이라고 해봤자 불과 2년밖에 되지 않았군요. 졸업을 앞두고 어떤 회사에 면접을 봤었는데 거기 이사님이 저에게 GET과 POST의 차이점이 뭐냐고 물었었는데 전 그땐 그게 무슨말인지도 몰랐죠. 떨어진 이유가 아마 그거이지 싶네요.. ㅎㅎㅎ(지금 생각하면 창피하군요)

어쨌든 처음 웹개발을 하게 되면 한번쯤은 생각하게 되는 문제 입니다. GET과 POST는 머가 다를까…. 하는…. 저도 처음엔 이게 상당히 궁금했습니다. 흔히 얘기하는 GET과 POST의 차이는 다음과 같습니다.(배울때 당시 이해하던 수준정도로만 적습니다.)

  • GET은 주소줄에 값이 ?뒤에 쌍으로 이어붙고 POST는 숨겨져서(body안에) 보내진다.
  • GET은 URL에 이어붙기 때문에 길이제한이 있어서 많은양의 데이터는 보내기 어렵고 POST는 많은 양의 보내기에도 적합하다.(역시 용량제한은 있지만)
  • 즉 http://url/bbslist.html?id=5&pagenum=2 같이 하는 것이 GET방식이고 form을 이용해서 submit을 하는 형태가 POST입니다.

처음 배울때 배운건 이정도뿐이었던 것 같습니다. 위 내용은 맞는말이긴 하지만 이로썬 해결안되는 문제가 있습니다. 그건 언제 GET을 쓰고 언제 POST를 써야 하는가에 대한 문제였습니다. 이건 신입일때 꽤 오랫동안 생각하고 있었던 문제이기도 하는데 딱히 가르쳐 주는 곳은 없었습니다. 지금와서 보면 책에 이에 대해 나와있는 책들이 상당히 많이 있습니다만 웹표준에서도 그러하듯이 현업의 개발에서는 “원래의 목적에 맞게 기술을 사용하고 있는가?”에 대해서는 크게 관심이 없고 “어떤 기술이든 기능을 구현할 수 있는가?”에만 관심을 가지는 것이 전반적으로 깔려있기 때문에 이런 부분에 대해서 관심을 가지는 개발자는 빈도수로 봤을때 그리 많지 않은 듯 합니다. 어쨌든 쉽게 말하면 클라이언트에서 서버로 데이터를 전송하려면 GET 아니면 POST밖에 없습니다.(사실 HTTP에는 PUT, DELETE등등 몇가지 더 있지만 그건 이글의 범주에서 벗어나서 언급하지 않습니다. 사실은 잘 몰라서 ㅡ..ㅡ HTTP 1.1 스펙 참조)

id 를 넘겨서 게시판의 리스트를 가져온다고 하면 당연히 GET을 쓸 것이고 글을 작성한다고 하면 POST를 작성하는 것이 일반적입니다. 전달해야 될 양이 많을 경우에는 고민없이 POST를 쓰게 되지만 양이 많지 않은 경우에는 GET도 되고 POST도 되기 때문에 고민이 시작됩니다. GET을 써야하나 POST를 써야하나. GET을 쓰면 URL이 깔끔해 지는 효과도 있기 때문에 작은 양을 여러개 전달해야 할 경우에는 POST를 써야하는가 하는 고민을 하게됩니다.(상당히 명백한 차이인듯 하면서 실제로 개발하다보면 고민하게 되는 경우가 좀 있더군요. 저만 그런지 모르겠지만…)


Image by dbking via Flickr

여기서 위의 언급한 차이점 외에 GET과 POST의 중요한 개념이 있습니다.

GET은 가져오는 것이고 POST는 수행하는 것입니다.

이 개념만 잘 생각하고 있으면 상황에 따라서 어느정도 선택을 할 수 있습니다.(물론 그래도 좀 고민되는 예외상황들은 있게 마련이죠.) 좀 자세히 설명하면 GET은 Select적인 성향을 가지고 있습니다. GET은 서버에서 어떤 데이터를 가져와서 보여준다거나 하는 용도이지 서버의 값이나 상태등을 바꾸지 않습니다. 게시판의 리스트라던지 글보기 기능 같은 것이 이에 해당하죠.(방문자의 로그를 남긴다거나 글읽은 횟수를 올려준다거나 하는건 예외입니다.) 반면에 POST는 서버의 값이나 상태를 바꾸기 위해서 사용합니다. 글쓰기를 하면 글의 내용이 디비에 저장이 되고 수정을 하면 디비값이 수정이 되죠. 이럴 경우에 POST를 사용합니다.

이 얘기를 하면 어느곳에서곤 반드시 예시로 나오는 것이 Google의 Accelerator 사건입니다.(대표적으로 예를 들게 이거밖에 없나봅니다. 항상 거론되는걸 보면…) Accelerator라는 것은 그이름대로 웹서핑의 속도를 향상시킬 목적으로 구글이 발표한 것이었습니다. 어떤 웹사이트에 갔을때 페이지에 있는 URL등을 Accelerator가 미리 모두 클릭해봐서 사용자가 해당 URL로 이동하기 전에 이미지등의 미리 받아놓을 수 있는 것들을 받아놓는 역할을 해서 웹서핑의 체감속도를 높여주는 것이 목적이었습니다. 캐시때문에 한번 방문한 사이트는 더 빨리 뜨는 것을 이용한 것이죠.

구글러들은 위에서 언급한 GET과 POST의 개념을 확실히 이해하고 이를 당연하다고 생각하는 사람들이었을 테니 이것이 문제가 될꺼라고는 전혀 생각지 못한듯 합니다. 하지만 현실은 그렇지 않죠. 실제 많은 개발자들은 GET과 POST를 용도구분없이 혼용해서 사용했고 Delete같은 곳에도 GET방식을 편의대로 이용한 것입니다. Accelerator는 이것을 구분하지 못하니 URL만 보였다 싶으면 냅다 클릭을 해댄 것이고 사용자가 클립한 것이 아닌 Bot이 직접 URL로 접근해버리자 해당 데이터들은 Delete를 수행해버려서 메일이나 게시글이 마구 지워지는 사태가 발생하였습니다. 좋은 의도였는데 상당히 안좋은 결과가 되었죠. 우리가 모두 이걸 지켰다면 훨씬 좋은 웹 환경이 됐을 텐데요.

그리고 가져오는 곳에 GET을 사용해야 하는 이유가 하나 더 있습니다. 얼마전에도 관련해서 포스팅한 적이 있지만 웹의 핵심이라고 할 수 있는 Link문제입니다. 기본적으로 웹에서 모든 리소스는 Link할 수 있는 URL을 가지고 있어야 합니다.(퍼머링크(permalink)1퍼 머링크라면 더 좋겠지만 꼭 퍼머링크가 아니라고 하더라도) 그래야 Link를 할 수 있으니까요. 쉽게 말하면 어떤 페이지를 보고 있을때 다른 사람한테 그 주소를 주기 위해서 주소창의 URL을 복사해서 줄 수 있어야 한다는 것입니다. POST를 할 결우에는 값이 내부적으로 전달되기 때문에 URL만 전달할 수 없죠. 글을 저장하는 경우에는 URL을 제공할 필요가 없기 때문에 POST를 해도 상관이 없는 것이고요.

다른 것들에서도 그렇듯이 GET과 POST도 그냥 만들어진 것이 아니기 때문에 스펙에 정의된 용도대로 사용한다면 위에 언급한대로 부가적으로 얻을 수 있는 이익이 많이 있고 전체 웹을 생각해도 올바르다고 생각합니다.

  1. 는 인터넷에서 특정 페이지의 고유한 URL 주소를 뜻한다. 이 주소는 어떤 상황에도 관계없이 항상 동일한 내용을 가지는 페이지로 링크된다는 의미에서, 고유(permanent)한 주소라는 뜻의 permanent link를 줄여 만든 말이다. 한국어로 고유링크, 고유주소 등으로 부르기도 한다. – Wikipedia 발췌 – [Back]

 

How to apply to work permit in Denmark.(Positive List)

이번에 덴마크에서 취업비자를 신청한 후기를 작성한다.

덴마크에서 취업비자를 신청하기 위한 방법/케이스는 여러가지가 있는데… 나는 Positive List 로 신청을 했다.
나머지 방법은 다음의 링크를 참고 바란다.
이 글은 Positive List 신청에 한해서만 적은 글이다.

 

덴마크 취업비자 얻는 방법

https://www.nyidanmark.dk/en-us/coming_to_dk/work/work.htm

 

Positive List 신청시 필요한 항목은 다음과 같다.

신청비용 : 약 3300 Kr
신청일로부터 30일 이내의 계약서(즉, 회사의 Offer 가 필요하다)
AR1 서류
여권
여권 사본(겉표지를 포함한 모든 부분을 하나하나 복사-다들 워홀신청할때 한번씩을 해 봤을듯..)
기타 증명 서류(영문 혹은 덴마크어로 작성되어야 함)

 

조건(Condition)

Positive List 에 해당하는 비자를 신청하기 위해서는 미리 회사측의 Offer 가 있어야 한다.
즉, 직장없이 비자를 신청할 수 는 없다는 것…
그리고 당연한 말이겠지만… 취업비자를 신청할 때 제출한 계약서에 나와있는 Job Description 의 내용이 Positive List 에 있어야 한다.
IT/교육/의료 등등의 리스트가 올라와있다.
https://www.nyidanmark.dk/en-us/coming_to_dk/work/positivelist/positive_list_overview.htm

 

기간(Duration)

계약서에 특별히 계약 만료 일자가 표기되어 있지 않으면 비자 기간은 4년으로 해준단다. 그리고 연장또한 가능하다고 한다.
https://www.nyidanmark.dk/en-us/coming_to_dk/work/positivelist/positive-list.htm

 

임금(Salary)

취업비자 관련해서 코펜하겐 International Centre 에서 상담을 받았는데, 이 부분을 따로 이야기해주었다.
임금이 일정 금액 이상이 되어야 한다는 것이다. 그 금액이 얼마인지를 물어봤는데, 직업과 경력에 따라서 다르기 때문에 얼마인지 정확하게 알려줄 수 가 없단다.(자기도 모른단다.)
덴마크 노동조합에서 그 액수를 결정하기때문에 자세한 부분은 노동조합에 확인해봐야 한단다.
우리나라처럼 최저 임금액이 남녀노소를 구분없이 똑같이 매겨지는 것이 아니라서 조금 놀랬다.
아래쪽에 유럽 평균 임금을 링크 찾아서 걸어놨다.

 

유럽 평균 임금

http://en.wikipedia.org/wiki/List_of_European_countries_by_average_wage
덴마크의 경우.. 환산하면 약 4 293 638.81 원이 나온다. 평균 임금이 한달에 약 430만원.(2012년 기준)
많아 보인다.. 하지만 덴마크는 세금이 쎄기로 이름 높은 나라! 과연 세금을 제하고도 월급이 많이 남을까??

 

계약서(Contract)

계약서에는 정확한 Job Description 과 월급 부분이 명세되어 있어야한다.(당연하겠지만..)

 

AR1

이 부분이 조금 헷갈렸었다. 취업비자 신청을 위해 어느 문서를 작성해야하는가…
AR2 문서는 Extension 에 관련된 문서이고, AR1 은 새로 신청과 관련된 문서이다.
워홀도.. 나름 취업비자이니 AR2를 작성해야 하지 않을까? 공식적인 답변은 AR1 이었다.
AR1 문서를 작성하면 알겠지만, 신청자가 작성하는 부분이 있고, 회사측에서 작성하는 부분이 있다.
내용을 꼼꼼히 읽어보고 또박또박 기입하면 된다.

 

Case ID 만들기/수수료 지불하기

모든 준비가 끝났으면 이제 Case ID 를 생성해야 한다.
Case ID 란, 접수하는 서류에 부여하는 ID 넘버라고 생각하면 되는데, 이 Case ID 를 생성하고, 생성한 ID 에 수수료를 입금해야지만 업무를 진행하는 방식이다.
중요한 점은 서류를 접수하기 전에 수수료를 납부 해야만하며, 접수 현장에서 납부하는 것은 안된다고 문서에 명시적으로 적혀있다는 것이다.
따라서, 미리미리 돈을 내도록 하자.
즉 수수료 납부된 Case ID 가 없다면 접수조차 않된다.
인터넷 뱅킹/신용카드 등등으로 납부가 가능하다.
Case ID 관련 링크 https://www.nyidanmark.dk/en-us/coming_to_dk/fee/fee.htm

 

신청하기

위의 모든 내용물들이 준비되었다면 조심조심 챙겨들고 아래로 향하자.
예전에 덴마크 도착해서 생체등록 하던 곳으로 가면 된다. 필자는 화요일 9시정도에 갔었는데 10분정도 기다렸었다. 가급적 빨리가면 더 좋을 듯.

https://www.google.com/maps/place/Njalsgade+72+%EC%BD%94%ED%8E%9C%ED%95%98%EA%B2%90+%EB%8C%80%ED%95%99%EA%B5%90+2300+K%C3%B8benhavn,+%EB%8D%B4%EB%A7%88%ED%81%AC/@55.663501,12.5862144,17z/data=!4m2!3m1!1s0x465253416187d475:0x6db2f6c2fc1e39a6

 

결과 기다리기

업무 처리까지 30일 정도 걸린다고 한다.
직장동료들에게 말하니 접수했다고 하는 영수증 같은 문서 잘 챙겨놓고 30일 이후부터는 일주일에 한번씩은 전화를 걸어 처리 상황을 물어보란다.
그래야 일처리가 된다고.. -_-;;;

 

후기

아무튼… 필자는 현재 결과를 기다리고 있는 중이다.
이제.. 기다리면 답이 오겠지. 🙂

 

Sample rate / Bit rate

Sample rate(샘플 레이트)와 Bit rate(비트 레이트)

출처 : http://ospace.tistory.com/101?srchid=BR1http%3A%2F%2Fospace.tistory.com%2F101

 

———————————————————————————————————————-

작성자: 박재성(ospace114@empal.컴)
작성일: 2008.4.21

* 편의상 평어를 사용했습니다.
* 퍼갈때는 출처를 밝히는 센스 부탁해요.

아래 내용은 나름대로 여러 분에게 도움이 되고자 정리하였습니다. 그림까지 있으면 더 좋을텐데 시간 관계상 글로만 작성했습니다.

인터넷 상에서 샘플레이트와 비트레이트의 정의는 간혹 있다. 샘플레이트는 이해가 쉽지만, 비트레이트는 쉽게 와닫지않는다. 즉 알송달송하다. 비트레이트와 오디오 포멧에서 어떤 관계를 가지고 있는지 알 수 없다.

이에 대해서 실제 데이터 량인 파일 크기를 가지고 두 rate(레이트)간에 비료를 해두었다. 그리고 글의 내용은 오디오에 대해서 어느정도 지식을 가지고  있는 분들을 대상으로 작성하였다.
초보자분 들은 다른 곳에서 기본적인 용어와 지식을 찾아보길 바란다.

위의 단어는 오디오 다루면서 매우 많이 접하는 단어이다. 일단 간단하게 정리를 해보자.
먼저 sample(샘플)을 먼저 알아 보자.

샘플은 말그대로 샘플이다. 아날로그의 연속된 데이터를 디지털로 표현하기에는 한계가 있다. 아날로그의 연속된 값은 무한 대로 쪼갤 수 있기 때문이다. 그렇기에 그중에 대표적인 특정 값(샘플)을 추출해서 사용하게 된다. 다수의 샘플들 집합으로 소리를 표현할 수 있다.

Sample rate (샘플레이트)

이는 샘플의 빈도 수이다. 좀더 직접적으로 말하면, 1초당 추출되는 샘플 개수이다. 오디오에서 44.1KHz(44100Hz), 22KHz(22050Hz)를 말한다. 괄호안에 값은 좀더 정확하게 표현한 값이다.
예를 들어 44.1KHz는 1초동안에 사만사천백(44100)개로 등분해서 샘플을 추출한다. 값이 커질 수록 더욱더 세밀하게 등분해서 정확한 오디오 데이터를 추출할 수 있다. 그러나 너무 큰 값은 추출되는 데이터 크기를 너무 크게 만들어서 처리하기 힘들다. 보통 44.1KHz가 CD음질로 많이 사용되므로 이이상 추출하는 것의 특수한 경우를 제외하고 의미가 없다.

Bit rate (비트레이트)

초당 전송되는 데이터 양이다. 직접적으로 표현하면 1초당 전송되는 비트 수이다. 간혹 혼돈되는 내용이 평균 데이터 전송량(Avarage Byte Rate)이다. 즉 실제 갖고 있는 데이터 량으로 같은 포멧의 원본(PCM) 데이터 량과 틀리다. Bit rate가 나올 수 있는 것은 오디오 압축 기술이 나오면서 가능하게 되었다.
보통 192Kbps, 128Kbps, 56Kbps 등을 사용한다. 128Kbps정도면 음질은 CD음질정도 되면 192Kbps정도면 최상이다. 그 이상이 되면 용량이 들어날뿐 보통 음질을 잘 구분하지 못한다.

실제 간단한 예를 보면사 둘간의 상관관계를 살표보자.
아래는 샘플 파일 정보이다.

파일명: stop.mp3

재생시간: 4분 59초 (299초)
비트레이트: 56Kbps (CBR)
채널수: 2 ch
비트: 16 bit
샘플레이트:22050 Hz
크기: 2,094,939byte

파일명: stop.pcm
크기: 26,394,624 byte

MP3 파일 크기 계산

먼저 MP3 파일 크기를 계산해 보자. 이때 필요한 값이 재생시간과 비트레이트이다.

파일크기 = 재생시간 * 비트레이트 / 8

8를 나눠준 이유는 비트에서 바이트로 변환하기 위한 것이다.

299 * 56000 / 8 = 2,093,000 (byte)

실제 값과 약간의 오차가 있는 이는 재생 시간이 1초 이하의 시간을 고려하지 않았고, MP3의 테그와 헤더 정보를 고려하지 않았기 때문이다. 비트 레이트는 실제로 처리되는 데이터 크기이므로 실제 재생시간과 곱함으로서 실제 데이터 크기를 알아낼 수 있다.

PCM 데이터 처리량

원래 초당 데이터 량이 다음과 같이 처리된다고 알고 있을 것이다.

초당 데이터 량 = 샘플레이트 * 채널 수 * 비트

그러므로,

22050 * 2 * 16 = 705,600 (bit)

즉, 약 705Kbps가 된다. 바로 이 값이 실제 PCM에서 처리되는 데이터 량이다. 그러나 MP3로 되면서 705Kbps값이 56Kbps 값으로 약 12배 차이가 난다.

PCM 파일 크기 계산

PCM 파일 계산에서는 비트 레이트가 없다. PCM 자체에 모든 데이터를 저장하고 있기 때문이다. 즉 앞에서 구한 PCM 데이터 처리량을 이용해서 구하면 된다.

PCM 파일 크기 = PCM 데이터 처리량 * 재생시간 / 8

8로 나눈이유는 비트를 바이트로 변경하기 위해서이다.

705,000 * 299 / 8 = 26,349,375 (byte)

실제 크기인 26,394,624와 약간의 차이가 있다. 이는 위의 계산시 1초 이하의 시간을 고려하지 않았기 때문이다.

마무리

즉 다시 말하면 PCM 파일에서 bit rate는 pcm 데이터 처리량과 같다. 이를 계산 식으로 변경하면,

비트 레이트 = 샘플 레이트 * 채널 수 * 비트

그러나 MP3인 경우는 위 식이 맞지 않는다.

실제 파일 크기를 보아도 10배 이상의 차이가 발생한다. 이 차이가 MP3와 PCM의 비트레이트 차이와 비슷하다. 그리고 MP3 자체 음질도 나쁘지 않기에 MP3 파일을 사용하게 된다.

위의 MP3 샘플은 음질을 많이 저하시켰기 때문에 음악 감상용으로 적합하지 않지만, 온라인상에서 간단히 재생하는 목적이라면 적합한 포멧이다. 즉 적절히 원하는 용도로 음질을 조절해서 사용할 수 있으면 그만큼 처리되는 데이터 량을 조절할 수 있게 된다.

주의할 것은 bit rate를 CBR(Constant Bit Rate)만 다루었다. 실제는 다음과 같은 것이 추가로 있다.

  • VBR(Variable Bit Rate):  가변 전송율
  • ABR(Average Bit Rate): 평균 전송율
  • SBC(Smart Bit Rate): 스마트 전송율

위의 용어 정의는 다른 사이트를 검색해보면 쉽게 찾을 수 있다. 위의 전송율 방식에 따라서 실제 파일 길이도 차이가 발생하므로 앞에서 계산한 식이 절대적이라고 말할 수 없다.

위의 내용은 MP3를 다루었지만 OGG나 다른 포멧에서도 동일하게 적용된다.
이상으로 마치겠다.

덧글

우리가 알고 있는 WAV가 PCM으로 착각할 수 있는데, 동일 하지 않는다. WAV는 PCM외에 다른 인코딩 방식도 지원하고 있다. 즉 WAV가 PCM를 저장할 수 있는 포멧이다. 자체가 PCM이 아니다.
PCM는 순수 데이터만 저장하고 있다. 그렇기에 PCM파일을 불러오는 경우 샘플 레이트, 채널 수, 비트 수를 직접 입력해야한다. 즉, 헤더 정보가 없다.

추가로 PCM 파일을 재생할 수 있는 프로그램은 Cool Edit를 사용하면 된다.

출처:
인터넷에서 기본적인 용어 정의
내 두뇌~~