본문 바로가기

공부/컴퓨터

Mp3 정보 긁기 - C 및 C++로 구현.

반응형
시작 일시 : 2004년 1월 10일.
완료 일시 : 2004년 1월 16일. 새벽.

// 별로 좋은것도 아니지만 저의 허락 없이 사용하는것을 금지합니다.
// 허락을 받고 사용하였어도, 어떠한 문제도 책임 지지 않습니다.


사용법
실제 만들어지고 사용되는 클래스는  GetMp3Info.cpp 화일이다.
하지만 mp3 정보를 저장하는 구조체는 mp3struct.h 화일이다.

그리고 GetMp3Info 클래스에서 static getMp3Info(char* filename, s_mp3InfoTag &info); 를 사용한다.
char* filename : 경로를 포함한 화일명.
s_mp3Info &info : s_mp3Info는 정보를 저장할 구조체이고, 그 구조체의 info를 만들어 주소 값을 넘겨준다.

아래는 직접 사용한 예이다.



#include <stdio.h>
#include "mp3struct.h"


int main()
{
        int returnValue=0;
        s_mp3InfoTag info;
        
        char * filename = "c:\a.mp3";

        if ( returnValue = Mp3Info::getInfo(filename,&info) ) {

                printf("Filename : %s
"
,filename);
                printf("MPEG Version : %s
"
,info.version);
                printf("Layer : %d Layer
"
,info.layer);
                printf("Crc : %d
"
,info.crc);
                printf("BitRate : %d
"
,info.bitRate);
                printf("Frequency : %d
"
,info.rateFrequency);
                printf("isPadding : %d
"
,info.padding);
                printf("Mode : %s
"
,info.mode);
                printf("isCopyRight : %d
"
,info.copyright);
                printf("isOriginal : %d
"
,info.original);
                printf("Emphasis : %s
"
,info.emphasis);
                printf("Frame Size : %d byte
"
,info.framesize);
                printf("Play Time : %d sec
"
,info.time);


                printf("Title : %s
"
,info.title);
                printf("Artist : %s
"
,info.artist);
                printf("Album : %s
"
,info.album);
                printf("Year : %s
"
,info.year);
                printf("Comment : %s
"
,info.comment);
                printf("Genre : %s
"
,info.genre);

        }

        return 0;

}












개발일지 :

2004년 1월 16일
이전에 미구현 되었었던 플레이 시간을 구하는것을 하였다.
mp3는 각 프레임의 크기가 달랐다.

난 처음에 각 프레임의 크기(사이즈) 가 같다고 생각했으나.
mp3 화일을 HEX EDIT로 열어서 확인해 본 결과
0xFFE0 으로 매치되는 것들은 일정한 간격을 이루고 있지 않는것이 있었다.
그래서 각 프레임의 크기를 일일이 구해서, 건너뛰고,
그 프레임의 카운터를 세어, 샘플링 / frame을 이용하여 플레이 시간을 구했다.

식은 다음과 같다.


// Get Play Time
//  vbr 일경우 다음과 같이 계산된다.
// info->time = ((float)1152/info->rateFrequency) * framecount;
// 단 샘플 프리퀀시가 32000 보다 작을때에는 나누는 값이 달라진다.
if ( info->rateFrequency >= 32000 )
        info->time = ((float)1152/info->rateFrequency) * framecount;
else
        info->time = ((float)576/info->rateFrequency) * framecount;


근데 내가 본 자료에 의하면 vbr 일때 이렇게 계산된다고 하였고
아래에 있는 PHP MP3 정보 긁기에 의하면 Xing 이라는 문자가 헤더의 특정 위치에 있을때
VBR 이라고 설정했는데. 그렇지 않은 mp3 화일도 정확한 시간이 구해 졌다.

아마도 VBR이 아닌것은 bitrate가 같으므로.. 프레임사이즈도 같지 않을까?
그래서 그냥 일일이 프레임을 하나씩 집고 가는것이 아니라.
그냥 바로 계산이 가능한것 같다.

샘플 프리퀀시가 달라짐에 따라 계산을 다르게 하라는 것은 아래 게시물중
"샘플당 프레임수 구하기 ( http://ggaman.com/zboard/view.php?id=Work&no=93 )" 라는 게시물을 참고 하기 바란다.



2004년 1월 15일
콜 스택 뷰라는것을 이용해서 메모리 관련 문제를 해결했다.
콜 스택 뷰는 디버그 모드시 alt + 6 키를 눌러서 창을 띄울수 있고,
커널에서 메인 다시 함수로 넘어 갈때, 그 스택을 볼수 있다.

내가 실수한 점은 맨 마지막에 strncpy를 할때 허용된 양 보다 많은 양을
복사하여서 kernel 쪽으로 돌아가야하는 스택 부분이 삭제 되어 버린데서 비롯된것이다.
그래서 main 함수가 끝나고 나서 맨 마지막 부분에서 억세스 바이얼레이션이 생긴것이다.

프레임 사이즈까지는 계산하는 법으로 계산을 했는데.
아직 플레이 시간을 구현하지 못했다.


2004년 1월 14일
직접 실행 시킨 후 main()  문에서 맨 마지막 return 시키는데 문제가 있다.
리턴 시에 스택이 깨지는 문제가 있다고 한다. 확인해 볼 사항이다.


반응형