2008년 1월 21일 월요일

멜론 파일(DCF)를 MP3로 만들자.. #3

오랜만에 다시 시작한다.
3번째 시간... 멜론 파일(DCF)를 MP3로 만드는데 필요한 것들을 프로그램으로 구현한다.

오늘은 DCF 파일에서 음악에 대한 정보를 추출하는 방법에 대해서 알아보자.
DCF 파일을 메모장으로 열면 다음과 같다.

2 : Rights-Issuer:http://mobile.melon.com/utility/dcfd.jsp
3 : Content-Name:?덇? ?щ뒗 洹몄쭛
4 : Content-Description:1764198 11
5 : Content-Vendor:melon.com
6 : Icon-URI:http://icon.digicaps.com/icon.asp
7 : eTarget:MIN,"SSeID-1/6715B86BE79D2FAA0617"
8 : eCEK:SSKEY-1;cidType=MIN;dMethod=AES128CBC-RFC2630;eValue="4603F2D6713F6DD8E3F13536469706E3A087BA1DC7F847A18FE1E8F539BB2ACE"
9 : Usage-Control:Time-Not-After/20080204235959Z+09,Allowable-Services/00000000;cidType=MIN;eAuthCode="SSeAuth-1/F7FD18EFD6A894E12893"
10 : Meta-Container:KS_C_5601-1992;MENU="mp3";Title="니가 사는 그집 - 박진영";Copyright="widerthan";Length="00:03:47";Codec type="mp3";


앞에 붙은 숫자는 라인번호이다. 중요한 정보는 10번째 줄에 있는데 이부분을 추출하는 프로그램을 만들어 보겠다.
왜 다른건 놔두고 10번째 줄만 추출하는가? 그리고 추출해서 어디에 쓰는가? 라는 질문을 가질수도 있다. 그에 따른 대답은 10번째 줄은 음악의 길이 제목 가수명 등의 정보를 가지고 있고, 그 정보를 이용하여 녹음에 활용 할 수가 있다. 그리고 녹음이 끝난후에 변환된 MP3파일에 ID3태그를 채우는데도 활용이 된다.

정보를 추출하는 과정은

1. 파일을 연다.
2. 10번째의 정보를 읽는다.
3. 필드별로 정보를 가져온다.

이과정을 거치면 된다. 그럼 만들어진 프로그램을 보자
먼저 파일 정보에 대한 구조체는 어떻게 생겼는지 생각해보자.
지금부터 나오는 프로그램 소스 코드에 대한 태클을 사양해줬으면 좋겠다. 이 글을 보는 사람 중에는 나보다 내공이 더 높은 사람도 많을 것이다. 프로그램이 비효율적다. 어처구니 없다. 이런식의 태클은 그냥 생각만 해달라. 내 프로그램을 보고 아이디어를 얻어서 더 좋은 프로그램을 만든다면 그걸로 만족한다.


typedef struct _dcf{
 char Title[100];  //제목
 int  Length;   //음악 길이(초)
 int  SampleRate;  //샘플링 레이트
 char Genre[30];  //장르
 char Album[100];  //앨범
 char Artist[100]; //가수
 int  TrackNum;  //트랙번호
} dcf;



프로그램에 사용될 구조체이다. 이 구조체는 음악에 대한 정보를 담고 있다. 근데... DCF 파일에 있던 BitRate에 대한 정보는 없다. 왜 없을까... BitRate는 MP3에서 사용되는 정보인데, 음악파일(Wav)을 어느정도로 압축할 것인지 결정하는 정보이다. 나는 일단 Wav 로 저장할 것이 때문에 BitRate 정보는 사용하지 않는다.

다음은 DCF 파일에서 정보를 가져오는 함수를 만들어 보자

int getDCFFileInfo(char* FileName, dcf* data)
{
 int i, j, k;
 char* ci, *cj;
 FILE *fp;
 char dummyData[14][500];
 char dummyData2[14][500];

 fp=fopen(FileName,"r");
 if(fp == NULL)return -1;
 for(i=0;i<10;i++)
  fgets(dummyData[0],500,fp);
 fclose(fp);

 j=1; k=0;

 for(i=0;i<strlen(dummyData[0]);i++)
 {
  if(dummyData[0][i] == ';')
  {
   i++;
   k=i;
   j++;
  }
  dummyData[j][i-k]=dummyData[0][i];
 }

 for(i=2;i < 14;i++)
 {
  memset(dummyData2[i], 0, sizeof(char) * 500);
  ci=strstr(dummyData[i], "=\"");
  for(cj = ci+2; (*cj) != '\"'; cj++)
  {
   dummyData2[i][cj - ci -2] = *cj;
  }
 }

 strcpy(data->Title, dummyData2[3]);
 strcpy(data->Genre, dummyData2[10]);
 strcpy(data->Album, dummyData2[11]);
 strcpy(data->Artist, dummyData2[12]);
 data->TrackNum = atoi(dummyData2[13]);
 data->SampleRate = atoi(dummyData2[8]);


 return 0;
 
}



생각보다 프로그램이 길어졌다. 짧게도 만들수 있겠지만 내가 무지한 관계로 프로그램이 좀 길어졌다. 그냥 그렇구나 이해해졌으면 좋겠다.

이 함수는 DCF의 10번째 줄을 파싱해서 스트링 배열에 넣은다음 데이터형에 맞게 변환하여 구조체에 저장하는 함수이다.

여기 까지가 DCF 파일에서 정보를 추출하는 방법이다.
하지만 이 함수를 그대로 가져다 쓰기에는 문제가 좀 있다. 그 이유는 문자셋 때문인데 윈도우즈 프로그래밍을 할 때는 문자셋에 유의해서 프로그램을 작성해야 한다.

예를 들어 char를 TCHAR 로 쓴다던지 strcpy를 lstrcpy로 쓴다던지 하는것인데 이부분에 대해서는 자세히 설명하지 않을것이고, 이에 대한 자세한 정보는 다른 서적을 참고하기 바란다.

다음 글에서는 Wav 파일 녹음에 대해서 알아보겠다.

댓글 4개:

  1. 대단하십니다! 프로그램은 만드셨나요? ㅋㅋ

    답글삭제
  2. 대단하시네



    난 머리가 아프네^^;;

    답글삭제
  3. 한번 만들어봤는데



    재생은 되기 힘들듯..ㅋㅋ

    답글삭제
  4. 아무리 그래도 힘들듯...하네요

    바꾸긴 바꿔도 재생될지가...

    답글삭제