#include "driff.h"
DRIFF dr;
CDG_Global dggd;
HDRAWDIB dg_DDib;
void TRACE(char *fmt,...)
{
char szBuff[BUFSIZ];
va_list ap;
va_start(ap,fmt);
vsprintf(szBuff,fmt,ap);
#ifdef _MSC_VER
OutputDebugString(szBuff);
#else
fprintf(stderr,szBuff);
#endif
va_end(ap);
}
int err_check(MMRESULT mmr)
{
switch(mmr) {
case MMSYSERR_NOERROR: return TRUE;
case MMSYSERR_INVALPARAM:
MessageBox(NULL,"Invalid parameters passed to acmStreamOpen",0,0);
return FALSE;
case ACMERR_NOTPOSSIBLE:
MessageBox(NULL,"No ACM filter found capable of decoding MP3",0,0);
return FALSE;
default:
MessageBox(NULL,"Some error opening ACM decoding stream!",0,0);
return FALSE;
}
return TRUE;
}
BOOL CALLBACK acmDrvFind(HACMDRIVERID hadid,DWORD dwInst,DWORD fdwSupport)
{
if(fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) {
MMRESULT mmr;
ACMDRIVERDETAILS details;
HACMDRIVER driver;
UINT i;
details.cbStruct = sizeof(ACMDRIVERDETAILS);
mmr = acmDriverDetails(hadid,&details,0);
mmr = acmDriverOpen(&driver,hadid,0);
for(i=0;i<details.cFormatTags;i++) {
ACMFORMATTAGDETAILS fmtDetails;
ZeroMemory(&fmtDetails,sizeof(fmtDetails));
fmtDetails.cbStruct = sizeof(ACMFORMATTAGDETAILS);
fmtDetails.dwFormatTagIndex = i;
mmr = acmFormatTagDetails(driver,&fmtDetails,
ACM_FORMATTAGDETAILSF_INDEX);
if(fmtDetails.dwFormatTag == WAVE_FORMAT_MPEGLAYER3){
TRACE("Found an MP3-capable ACM codec: %s\n",
details.szLongName);
dggd.g_mp3Drivers++;
}
}
mmr = acmDriverClose(driver,0);
}
return TRUE;
}
void err_avi(int err)
{
switch(err){
case AVIERR_OK: return;
case AVIERR_BUFFERTOOSMALL:
TRACE("cbBuffer パラメータに、データの1 つのサンプルよりも"
"小さいバッファサイズが指定されています。\n");
break;
case AVIERR_MEMORY:
TRACE("メモリが不足しているため、読み取り操作を完了"
"できませんでした。\n");
break;
case AVIERR_FILEREAD:
TRACE("ファイルの読み取り中にディスクエラーが発生しました。\n");
break;
}
}
int check_suffix(char* filename,char* ext)
{
static char buf[256]="";
int i=strlen(filename);
buf[0] = '\0';
while(1){ if(filename[i--] == '.') break; }
if(i<=0) return FALSE;
strncpy(buf,filename+i+2,strlen(filename)-i-1);
if(!strcmp(buf,ext)) return TRUE;
return FALSE;
}
void set_win(HWND mwh,HWND edwh)
{
dggd.AppHwnd = mwh;
dggd.edHwnd = edwh;
}
void set_info(char* sbuf)
{
SetWindowText(dggd.edHwnd,sbuf);
}
void cat_info(char* sbuf)
{
int tlen;
static char wbuf[BUFSIZ];
wbuf[0] = '\0';
tlen = GetWindowText(dggd.edHwnd,wbuf,BUFSIZ);
strcat(wbuf+tlen,sbuf);
SetWindowText(dggd.edHwnd,wbuf);
}
char* getfps()
{
static DWORD last = 0;
static DWORD frames = 0;
static char buf[256] = "";
DWORD current = timeGetTime();
frames++;
if(500 <= current - last) {
double dt = (double)(current - last) / 1000.0f;
double fps = (double)frames / dt;
last = current;
frames = 0;
sprintf(buf,"%.02f fps",fps);
}
return buf;
}
char* getwif()
{
static char buf[256];
buf[0] = '\0';
switch(dggd.dg_type){
case DRIFF_AVI:
if(!dggd.avi_audio) break;
wsprintf(buf,": WAVE %dHz %dbit",dggd.wave_hlz,dggd.wave_bit);
break;
default:
wsprintf(buf,": WAVE %dHz %dbit",dggd.wave_hlz,dggd.wave_bit);
break;
}
return buf;
}
int dg_fileopen(HWND hWnd)
{
DWORD old_type = dggd.dg_type;
static char filename[MAX_PATH];
dggd.dg_type = 0;
filename[0] = '\0';
OPENFILENAME file;
memset(&file,0,sizeof(OPENFILENAME));
file.lStructSize = sizeof(OPENFILENAME);
file.hwndOwner = hWnd;
file.lpstrFilter =
"AVI ファイル(*.avi)\0*.avi\0"
"WAVE ファイル(*.wav)\0*.wav\0"
"MP3 ファイル(*.mp3)\0*.mp3\0"
"全てのファイル(*.*)\0*.*\0\0";
file.lpstrFile = filename;
file.lpstrFileTitle = "読み込み";
file.nMaxFile = sizeof(filename);
file.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
file.lpstrDefExt = "avi";
file.lpstrTitle = "開く";
if(!GetOpenFileName(&file)){
dggd.dg_type = old_type;
if(old_type) dg_draw(hWnd);
return FALSE;
}
dg_close();
if(!dr.Open(filename)) {
dggd.dg_type = old_type;
if(old_type) dg_draw(hWnd);
return FALSE;
}
dggd.ds = *dr.AviGetSize();
dggd.waittime = 1/dr.AviGetFps();
dggd.dg_type = dr.GetType();
strcpy(dggd.dg_fname,filename);
static char t_str[256];
wsprintf(t_str,"%s %s",dggd.dg_fname,getwif());
SetWindowText(hWnd,t_str);
dg_draw(hWnd);
return TRUE;
}
void dg_close()
{
dggd.dg_type = 0;
WaitForSingleObject(dggd.dg_hthr,1000);
dr.Close();
InvalidateRect(dggd.AppHwnd,NULL,TRUE);
PostMessage(dggd.AppHwnd,WM_PAINT,(unsigned int)NULL,(long int)NULL);
}
void dg_isave(HWND hWnd)
{
if(dggd.dg_type != DRIFF_AVI) return;
static char filename[MAX_PATH];
dggd.dg_type = 0;
filename[0] = '\0';
OPENFILENAME file;
memset(&file,0,sizeof(OPENFILENAME));
file.lStructSize = sizeof(OPENFILENAME);
file.hwndOwner = hWnd;
file.lpstrFilter =
"BMP ファイル(*.bmp)\0*.bmp\0"
"全てのファイル(*.*)\0*.*\0\0";
file.lpstrFile = filename;
file.lpstrFileTitle = "画像保存";
file.nMaxFile = sizeof(filename);
file.Flags = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;
file.lpstrDefExt = "bmp";
file.lpstrTitle = "保存";
GetOpenFileName(&file);
LPVOID a;
if(!dr.AviRead2(&a)){
MessageBox(NULL,"画像読込み失敗",0,0);
return;
}
SaveBMP(filename,(LPBYTE)a);
dggd.dg_type = DRIFF_AVI;
dg_draw(hWnd);
}
UINT SaveBMP(char* filename,LPBYTE lpBuf)
{
HANDLE hdlBmp;
BITMAPFILEHEADER bfhBmp;
LPBITMAPINFOHEADER bih = (LPBITMAPINFOHEADER)lpBuf;
LONG offset = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
LONG cpsize = bih->biClrUsed*sizeof(RGBQUAD);
UINT bCnt = bih->biBitCount,bPln = bih->biPlanes;
DWORD dwdPixelsSize,wSize;
dwdPixelsSize = BMPLL(bih)*bih->biHeight;
hdlBmp = CreateFile(filename,GENERIC_WRITE,0,NULL,OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,NULL);
if(hdlBmp==INVALID_HANDLE_VALUE){
MessageBox(NULL,"書込みに失敗しました",NULL,MB_OK);
return FALSE;
}
bfhBmp.bfType = 'M'*256+'B';
bfhBmp.bfSize = offset + cpsize + dwdPixelsSize;
bfhBmp.bfReserved1 = 0;
bfhBmp.bfReserved2 = 0;
bfhBmp.bfOffBits = offset + cpsize;
dwdPixelsSize += sizeof(BITMAPINFOHEADER) + cpsize;
WriteFile(hdlBmp,&bfhBmp,sizeof(BITMAPFILEHEADER),&wSize,NULL);
WriteFile(hdlBmp,lpBuf,sizeof(BYTE)*dwdPixelsSize,&wSize,NULL);
CloseHandle(hdlBmp);
return TRUE;
}
void set_wavedraw(int dgw)
{
dggd.dgw_type = dgw;
}
ULONG __stdcall DG_thread(void* p_arg)
{
HWND hWnd = *(HWND*)p_arg;
HDC hdc; PAINTSTRUCT ps;
RECT rdr,wr,wer,pR;
while(dggd.dg_type){
hdc = BeginPaint(dggd.AppHwnd,&ps);
if(dggd.dg_type == DRIFF_WIN) break;
SetRect(&pR,0,
(dggd.ds.y)?dggd.ds.y+5:0,
dggd.ds.x,(dggd.ds.y)?(dggd.ds.y+100):100);
GetClientRect(hWnd,&wr);
GetWindowRect(dggd.edHwnd,&wer);
pR.right = wr.right-(wer.right-wer.left);
SetRect(&rdr,0,0,pR.right,wr.bottom);
if(dggd.dg_type == DRIFF_AVI) {
LPVOID a;
double iscale =
(dggd.ds.x>pR.right)? pR.right/(double)dggd.ds.x : 1.0;
pR.top = wr.bottom-100;
pR.bottom = wr.bottom;
if(pR.top < 0) pR.top = 0;
if(pR.bottom > wr.bottom) pR.bottom = wr.bottom;
if(dggd.avi_audio){
int wait = 2;
if(dr.AviGetFps() < 10) wait = 1;
if(dr.AviGetFps() > 60) wait = 30;
if(dr.AviGetCount() % wait == 0){
dr.WavePlay(wait*dggd.waittime,TRUE);
dr.DrawWave(hdc,&pR);
if(dr.WaveEof()) dr.WaveSeek(0);
}
}
if(!dr.AviRead(&a)){
dr.Seek(0);
Sleep(1000);
continue;
}
LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)a;
int bsz = lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD);
LPBYTE start = (LPBYTE)a + bsz;
DrawDibDraw(dg_DDib,
hdc,
0,0,
pR.right,
pR.bottom-105,
lpbi,
(LPVOID)start,
0,0,
dggd.ds.x,dggd.ds.y,
DDF_BUFFER
);
if(dggd.avi_audio==FALSE) Sleep((int)(1000.*dggd.waittime/2));
} else if(dggd.dg_type == DRIFF_WAVE || dggd.dg_type == DRIFF_MP3) {
dr.WavePlay(0.1,TRUE);
if(dr.WaveEof()) {
dr.WaveSeek(0);
Sleep(1000);
}
dr.DrawWave(hdc,&pR);
}
InvalidateRect(hWnd,&rdr,FALSE);
InvalidateRect(dggd.edHwnd,NULL,FALSE);
EndPaint(hWnd,&ps);
}
return 0;
}
void dg_draw(HWND hWnd)
{
if(!dggd.dg_type || dggd.dg_type == DRIFF_WIN) return;
DWORD tid;
dggd.dg_hthr = CreateThread(NULL,0,DG_thread,&hWnd,0,&tid);
SetThreadPriority(dggd.dg_hthr,THREAD_PRIORITY_ABOVE_NORMAL);
InvalidateRect(hWnd,NULL,TRUE);
PostMessage(hWnd,WM_PAINT,0,0);
}
void dg_wavein(HWND hWnd)
{
if(dggd.dg_type == DRIFF_WIN) return;
dg_close();
if(!dr.WaveInOpen()){
MessageBox(NULL,"初期化失敗","WAVE IN",MB_OK);
}
dggd.dg_type = DRIFF_WIN;
dggd.ds.x = 0; dggd.ds.y = 0;
static char t_str[256];
wsprintf(t_str,"WAVE 音声入力%s",getwif());
SetWindowText(hWnd,t_str);
InvalidateRect(hWnd,NULL,TRUE);
PostMessage(hWnd,WM_PAINT,0,0);
}
void dg_windraw(HWND hWnd)
{
if(dggd.dg_type != DRIFF_WIN) return;
if(!dr.WaveInPlay()) return;
RECT wr,wer,rdr,pR;
SetRect(&pR,0,0,0,100);
GetClientRect(hWnd,&wr);
GetWindowRect(dggd.edHwnd,&wer);
pR.right = wr.right-(wer.right-wer.left);
SetRect(&rdr,0,0,pR.right,wr.bottom);
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd,&ps);
dr.DrawWave(hdc,&pR);
EndPaint(hWnd,&ps);
InvalidateRect(hWnd,&rdr,FALSE);
PostMessage(dggd.edHwnd,WM_PAINT,0,0);
}
DRIFF::DRIFF()
{
file = NULL;
type = 0;
memset(&movie,0,sizeof(movie));
memset(&wave,0,sizeof(wave));
wave.buf = NULL;
wave.fft = NULL;
WaveOutInit();
WaveInInit();
acmDriverEnum(acmDrvFind,0,0);
if(dggd.g_mp3Drivers == 0){
MessageBox(NULL,"No MP3 decoders found!",0,0);
}
}
DRIFF::~DRIFF()
{
Close();
}
int DRIFF::Open(char *filename)
{
file = fopen(filename,"rb");
if(file == NULL) return FALSE;
int ret;
char buf[256];
sprintf(buf,"FILE: %s\r\n",filename);
set_info(buf);
if(check_suffix(filename,"avi") || check_suffix(filename,"wav")){
fread(&head[0],1,sizeof(DRIFF_HEAD),file);
if(head[0].ckID == mmioFOURCC('R','I','F','F')) {
fread(&type,1,sizeof(DWORD),file);
if(type == DRIFF_WAVE) ret=WaveOpen(filename);
else if(type == DRIFF_AVI) ret=AviOpen(filename);
} else ret = FALSE;
if(ret==FALSE) sprintf(buf,"RIFF:形式が異なります.");
} else if(check_suffix(filename,"mp3")){
ret = MP3Open(filename);
if(ret==FALSE) sprintf(buf,"MP3:形式が異なります.");
} else {
ret = FALSE; sprintf(buf,"未対応");
}
if(ret==FALSE) {
type = 0; set_info(""); Close();
return FALSE;
}
return TRUE;
}
int DRIFF::Close()
{
if(file != NULL) { fclose(file); file = NULL; }
if(movie.init_flag) { AviClose(); movie.init_flag = FALSE; }
if(wave.init_flag) { WaveClose(); wave.init_flag = FALSE; }
if(wave.in_flag) { WaveInClose(); wave.in_flag = FALSE; }
type = 0;
memset(&movie,0,sizeof(movie));
memset(&wave,0,sizeof(wave));
return TRUE;
}
int DRIFF::Seek(double sec)
{
AviSeek(sec);
WaveSeek(sec);
return TRUE;
}
int DRIFF::GetType()
{
return type;
}
int DRIFF::AviOpen(char *filename)
{
WAVEFORMATEX cpf;
AVIFileInit();
if(AVIFileOpen(&movie.file,filename,OF_READ|OF_SHARE_DENY_NONE,NULL)){
MessageBox(NULL,"AVIファイルエラー","入力ファイル",MB_OK);
return FALSE;
}
AVIFileGetStream(movie.file,&movie.ps_movie,streamtypeVIDEO,0);
AVIFileGetStream(movie.file,&movie.ps_audio,streamtypeAUDIO,0);
AVIFileInfo(movie.file,&movie.info,sizeof(AVIFILEINFO));
if(movie.ps_movie) {
cat_info("**VIDEO\r\n");
AVIStreamFormatSize(movie.ps_movie,0,&movie.FmtLeng);
if(movie.lpSrcFmt) GlobalFree(movie.lpSrcFmt);
if(dggd.dibh) GlobalFree(dggd.dibh);
movie.lpSrcFmt = (LPBITMAPINFOHEADER)GlobalAlloc(GPTR,movie.FmtLeng);
dggd.dibh = (LPBITMAPINFOHEADER)GlobalAlloc(GPTR,movie.FmtLeng);
AVIStreamReadFormat(movie.ps_movie,0,movie.lpSrcFmt,&movie.FmtLeng);
memcpy(dggd.dibh,movie.lpSrcFmt,movie.FmtLeng);
movie.movie_frame = AVIStreamGetFrameOpen(movie.ps_movie,NULL);
if(movie.movie_frame == NULL){
if(!(movie.codec=codecOpen())){
MessageBox(NULL,"AVI未対応","入力ファイル",MB_OK);
AviClose();
return FALSE;
}
}
static char buf[256];
sprintf(buf," size: %dx%d[%dbit]\r\n",movie.info.dwWidth,
movie.info.dwHeight,movie.lpSrcFmt->biBitCount);
cat_info(buf);
sprintf(buf," FPS: %.1lf\r\n",AviGetFps());
cat_info(buf);
} else { AviClose(); return FALSE; }
if(movie.ps_audio) {
LONG len;
AVIStreamReadFormat(movie.ps_audio,0,NULL,&len);
wave.format_src = (WAVEFORMATEX *)malloc(len);
AVIStreamReadFormat(movie.ps_audio,0,wave.format_src,&len);
AVICOMPRESSOPTIONS opt;
WAVEFORMATEX* f = wave.format_src;
cpf = *wave.format_src;
if(f->wFormatTag != WAVE_FORMAT_PCM){
f->wFormatTag = WAVE_FORMAT_PCM;
f->wBitsPerSample = f->wBitsPerSample<12?8:16;
f->nBlockAlign = f->nChannels*f->wBitsPerSample/8;
f->nAvgBytesPerSec = f->nSamplesPerSec*f->nBlockAlign;
f->cbSize = 0;
}
memset(&opt,0,sizeof(opt));
opt.fccType = streamtypeAUDIO;
opt.lpFormat = f;
opt.cbFormat = sizeof(WAVEFORMATEX)-sizeof(WORD);
if(AVIMakeCompressedStream(
&movie.ps_autmp,movie.ps_audio,&opt,NULL) == AVIERR_OK){
if(!WaveInit(*f)){
MessageBox(NULL,"AVI音声初期化エラー","AVI",MB_OK);
AviClose();
return FALSE;
}
LONG hr,size=1024,rb,rc;
BYTE buffer[1024];
hr = AVIStreamRead(movie.ps_autmp,0,1,buffer,size,&rb,&rc);
if(!hr && rb){
dggd.avi_audio = TRUE;
dggd.wave_hlz = f->nSamplesPerSec;
dggd.wave_bit = f->wBitsPerSample;
dggd.wave_chn = f->nChannels;
wave.current_samples = 0;
} else {
err_avi(hr);
dggd.avi_audio = FALSE;
movie.ps_audio = NULL;
movie.ps_autmp = NULL;
}
} else {
dggd.avi_audio = FALSE;
movie.ps_audio = NULL;
movie.ps_autmp = NULL;
}
} else dggd.avi_audio = FALSE;
type = DRIFF_AVI;
movie.init_flag = TRUE;
if(dggd.avi_audio) WaveInfo("**WAVE AUDIO",cpf);
Seek(0);
return TRUE;
}
int DRIFF::codecOpen()
{
AVIStreamFormatSize(movie.ps_movie,0,&movie.FmtLeng);
if(movie.lpDecFmt) GlobalFree(movie.lpDecFmt);
if(dggd.dibh) GlobalFree(dggd.dibh);
movie.lpDecFmt = (LPBITMAPINFOHEADER)GlobalAlloc(GPTR,movie.FmtLeng);
dggd.dibh = (LPBITMAPINFOHEADER)GlobalAlloc(GPTR,movie.FmtLeng);
LPBITMAPINFOHEADER s,d;
s = movie.lpSrcFmt; d = movie.lpDecFmt;
AVIStreamInfo(movie.ps_movie,&movie.si,sizeof(AVISTREAMINFO));
memcpy(dggd.dibh,s,movie.FmtLeng);
memcpy(d,s,movie.FmtLeng);
d->biBitCount = 24;
d->biCompression = BI_RGB;
d->biSize = movie.FmtLeng;
d->biSizeImage = BMPLL(d)*d->biHeight;
movie.lLength = BMPLL(s)*s->biHeight;
if(movie.lpSrc) GlobalFree(movie.lpSrc);
if(movie.lpDec) GlobalFree(movie.lpDec);
movie.lpSrc = (LPBYTE)GlobalAlloc(GPTR,movie.lLength);
movie.lpDec = (LPBYTE)GlobalAlloc(GPTR,d->biSizeImage+movie.FmtLeng);
if(movie.lpSrc == NULL || movie.lpDec == NULL) return FALSE;
memcpy(movie.lpDec,d,movie.FmtLeng);
if(movie.si.dwSuggestedBufferSize)
if(movie.si.dwSuggestedBufferSize < (unsigned)movie.lLength)
movie.lLength = (LONG)movie.si.dwSuggestedBufferSize;
ICINFO icinfo;
static char buf[256];
movie.hicd = ICDecompressOpen(ICTYPE_VIDEO,movie.si.fccHandler,s,d);
ICGetInfo(movie.hicd,&icinfo,sizeof(icinfo));
if(!movie.hicd){
wsprintf(buf,"%S[%S]: cannot decode image.",
icinfo.szName,icinfo.szDescription);
MessageBox(NULL,buf,"codec open",0);
return FALSE;
}
wsprintf(buf," codec info: %S\r\n (%S)\r\n",
icinfo.szName,icinfo.szDescription);
cat_info(buf);
if(ICDecompressBegin(movie.hicd,movie.lpSrcFmt,movie.lpDecFmt))
return FALSE;
return TRUE;
}
int DRIFF::AviClose()
{
if(movie.ps_autmp) {
AVIStreamRelease(movie.ps_autmp); movie.ps_autmp = NULL;
}
if(movie.ps_audio) {
AVIStreamRelease(movie.ps_audio); movie.ps_audio = NULL;
}
if(movie.ps_movie) {
AVIStreamRelease(movie.ps_movie); movie.ps_movie = NULL;
}
if(movie.file) {
AVIFileRelease(movie.file); movie.file = NULL;
}
if(movie.movie_frame) {
AVIStreamGetFrameClose(movie.movie_frame); movie.movie_frame = NULL;
}
if(movie.codec){
if(movie.lpSrc) { GlobalFree(movie.lpSrc); movie.lpSrc = NULL; }
if(movie.lpDec) { GlobalFree(movie.lpDec); movie.lpDec = NULL; }
if(movie.lpSrcFmt) {
GlobalFree(movie.lpSrcFmt); movie.lpSrcFmt = NULL;
}
if(movie.lpDecFmt) {
GlobalFree(movie.lpDecFmt); movie.lpDecFmt = NULL;
}
ICDecompressEnd(movie.hicd);
ICClose(movie.hicd);
movie.codec = FALSE;
}
AVIFileExit();
return TRUE;
}
int DRIFF::AviSeek(double sec)
{
if(type != DRIFF_AVI) return FALSE;
double fps = AviGetFps();
if(sec == 0) movie.current_samples = -1;
else movie.current_samples = (int)(fps * sec);
movie.eof = FALSE;
return TRUE;
}
int DRIFF::AviRead(void **data)
{
if(type != DRIFF_AVI || movie.eof) return FALSE;
int ret;
if(movie.current_samples < 0){
ret = AviGetFrame(0,data);
movie.current_samples = 0;
} else {
ret = AviGetFrame(movie.current_samples,data);
double fps=AviGetFps();
if(fps>100) movie.current_samples+=5;
else if(fps>60) movie.current_samples+=3;
else movie.current_samples+=1;
}
if(ret==FALSE) movie.eof = TRUE;
return ret;
}
int DRIFF::AviRead2(void **data)
{
if(type != DRIFF_AVI || movie.eof) return FALSE;
if(movie.current_samples < 0){
return AviGetFrame(0,data);
} else {
return AviGetFrame(movie.current_samples,data);
}
}
POINT* DRIFF::AviGetSize()
{
static POINT dsize;
if(type == DRIFF_AVI) {
dsize.x = movie.info.dwWidth; dsize.y = movie.info.dwHeight;
} else {
dsize.x = 0; dsize.y = 0;
}
return &dsize;
}
int DRIFF::AviGetCount()
{
return movie.current_samples;
}
int DRIFF::AviGetFrame(int frame,void **data)
{
if(type != DRIFF_AVI) return FALSE;
if(movie.codec==FALSE){
*data = AVIStreamGetFrame(movie.movie_frame,frame);
} else {
if(!AVIStreamRead(movie.ps_movie,frame,1,movie.lpSrc,movie.lLength,
NULL,NULL)){
LPBYTE dst = movie.lpDec + movie.lpDecFmt->biSize;
ICDecompress(movie.hicd,0,movie.lpSrcFmt,movie.lpSrc,
movie.lpDecFmt,dst);
*data = movie.lpDec;
} else return FALSE;
}
if(*data == NULL) return FALSE;
return TRUE;
}
double DRIFF::AviGetFps()
{
if(type != DRIFF_AVI) return 1;
return (double)movie.info.dwRate / movie.info.dwScale;
}
int DRIFF::AviEof()
{
return movie.eof;
}
void DRIFF::WaveInfo(char* title,WAVEFORMATEX f)
{
static char stmp[BUFSIZ],sbuf[BUFSIZ];
sprintf(sbuf,"%s\r\n",title);
sprintf(stmp," wFormatTag: %d\r\n",f.wFormatTag);
strcat(sbuf,stmp);
sprintf(stmp," nChannels: %d\r\n",f.nChannels);
strcat(sbuf,stmp);
sprintf(stmp," nSamplesPerSec: %d\r\n",f.nSamplesPerSec);
strcat(sbuf,stmp);
sprintf(stmp," nAvgBytesPerSec: %d\r\n",f.nAvgBytesPerSec);
strcat(sbuf,stmp);
sprintf(stmp," nBlockAlign: %d\r\n",f.nBlockAlign);
strcat(sbuf,stmp);
sprintf(stmp," wBitsPerSample: %d\r\n",f.wBitsPerSample);
strcat(sbuf,stmp);
sprintf(stmp," cbSize: %d\r\n",f.cbSize);
strcat(sbuf,stmp);
cat_info(sbuf);
}
int DRIFF::WaveOpen(char* filename)
{
int i=0;
acm.flag = FALSE;
while(i<(int)(sizeof(head)/sizeof(head[0]))) {
i++;
fread(&head[i],1,sizeof(DRIFF_HEAD),file);
if(feof(file)) { Close(); return FALSE; }
if(head[i].ckID == mmioFOURCC('f','m','t',' ')){
wave.format_src = (WAVEFORMATEX *)malloc(head[i].ckSize);
fread(wave.format_src,1,head[i].ckSize,file);
wave.format_src->wFormatTag = WAVE_FORMAT_PCM;
if(!WaveInit(*wave.format_src)) {
type = 0;
MessageBox(NULL,"WAVE format 未対応","WAVE FILE",MB_OK);
return FALSE;
}
dggd.wave_hlz = wave.format_src->nSamplesPerSec;
dggd.wave_bit = wave.format_src->wBitsPerSample;
dggd.wave_chn = wave.format_src->nChannels;
} else if(head[i].ckID == mmioFOURCC('d','a','t','a')) {
wave.start_pos = ftell(file);
type = DRIFF_WAVE;
WaveInfo("**WAVE FILE",*wave.format_src);
return TRUE;
} else {
fseek(file,head[i].ckSize,SEEK_CUR);
}
if(head[i].ckSize % 2 != 0) {
fseek(file,1,SEEK_CUR);
}
}
type = 0;
MessageBox(NULL,"WAVE未対応","WAVE FILE",MB_OK);
return FALSE;
}
int DRIFF::WaveClose()
{
if(wave.format_src) { delete wave.format_src; wave.format_src = NULL; }
if(acm.format_src) { delete acm.format_src; acm.format_src = NULL; }
if(acm.flag) { AcmClose(); acm.flag = FALSE; }
WaveOutClose();
return TRUE;
}
int DRIFF::WaveInit(WAVEFORMATEX f)
{
if(wave.init_flag) WaveClose();
if(f.wFormatTag != WAVE_FORMAT_PCM) {
if(!AcmOpen(f)) return FALSE;
} else wave.format = f;
if(type != DRIFF_MP3)
wave.block_size = WaveBlockSize(f);
wave.buf = new char[wave.block_size];
wave.fft = new float[wave.block_size];
if(!WaveOutOpen(&f,wave.block_size,2)) {
return FALSE;
}
wave.init_flag = TRUE;
return TRUE;
}
int DRIFF::WaveBlockSize(WAVEFORMATEX f)
{
int size = (f.nChannels*f.nSamplesPerSec*f.wBitsPerSample/8/
f.nBlockAlign) * f.nBlockAlign;
if(size == 0)
size = (1024 / f.nBlockAlign) * f.nBlockAlign;
return size;
}
int DRIFF::WaveSeek(double sec)
{
if(!wave.init_flag) return FALSE;
if(acm.flag) {
if(sec!=0) return FALSE;
else {
AcmBufferClear();
fseek(file,0,SEEK_SET);
}
} else {
if(type == DRIFF_WAVE) {
fseek(file,WavePos(sec)+wave.start_pos,SEEK_SET);
} else {
wave.current_samples = WavePos(sec) / wave.format.nBlockAlign;
}
}
wave.eof = FALSE;
return TRUE;
}
int DRIFF::WavePos(double sec)
{
if(!wave.init_flag) return 0;
int samples = (int)(wave.block_size*sec)/wave.format.nBlockAlign;
return samples*wave.format.nBlockAlign;
}
int DRIFF::WavePlay(void *buffer,int size,int wait=FALSE)
{
if(!wave.init_flag || size > wave.block_size) return FALSE;
WaveOutPlay(buffer,size,wait);
return TRUE;
}
int DRIFF::WavePlay(double sec,int wait=FALSE)
{
if(!wave.init_flag) return FALSE;
int size = WavePos(sec);
if(wave.eof || size > wave.block_size) return FALSE;
size = WaveRead(wave.buf,size);
WavePlay(wave.buf,size,wait);
return TRUE;
}
int DRIFF::WaveEof()
{
if(!wave.init_flag) return TRUE;
return wave.eof;
}
int DRIFF::WaveRead(void *buf,int size)
{
void *buffer = buf;
if(!wave.init_flag) return 0;
if(!acm.flag) return WaveRead2(buf,size);
return AcmRead(buf,size);
}
int DRIFF::WaveRead2(void *buffer,int size)
{
if(!wave.init_flag || wave.eof) return 0;
LONG read_byte=0;
if(type == DRIFF_WAVE || type == DRIFF_MP3) {
read_byte = fread(buffer,1,size,file);
wave.dgw_size = read_byte;
} else if(type == DRIFF_AVI) {
LONG hr,read_count;
hr = AVIStreamRead(movie.ps_autmp,
wave.current_samples,
size / wave.format.nBlockAlign,
buffer,
size,
&read_byte,
&read_count
);
if(hr){
err_avi(hr);
TRACE("wave: current_sample = %d\n",wave.current_samples);
TRACE("wave: nBlockAlign = %d\n",wave.format.nBlockAlign);
TRACE("wave: size = %d\n",size);
wave.current_samples += size / wave.format.nBlockAlign;
return 0;
}
wave.dgw_size = read_byte;
wave.current_samples += read_count;
}
if(read_byte != size) wave.eof = TRUE;
return read_byte;
}
int DRIFF::WaveOutInit()
{
waveio.FHWaveOut = NULL;
waveio.out_count = 0;
waveio.out_current = 0;
return TRUE;
}
int DRIFF::WaveOutOpen(WAVEFORMATEX *format,int bufsize,int count=2)
{
MMRESULT mmr;
if(waveio.FHWaveOut != NULL) WaveOutClose();
if(bufsize % format->nBlockAlign != 0) return FALSE;
if(format->wFormatTag != WAVE_FORMAT_PCM) return FALSE;
mmr = waveOutOpen(&waveio.FHWaveOut,WAVE_MAPPER,format,0,0,CALLBACK_NULL);
if(mmr) return FALSE;
waveio.out_count = count;
waveio.FOWaveHdr = new WAVEHDR*[count];
waveOutGetVolume(waveio.FHWaveOut,&waveio.volume);
waveOutSetVolume(waveio.FHWaveOut,MAKELONG(0x3000,0x3000));
for(int i=0;i<count;i++) {
waveio.FOWaveHdr[i] = (WAVEHDR*)HeapAlloc(
GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEHDR));
waveio.FOWaveHdr[i]->lpData =
(char*)HeapAlloc(GetProcessHeap(),0,bufsize);
waveio.FOWaveHdr[i]->dwBufferLength = 0;
mmr = waveOutPrepareHeader(waveio.FHWaveOut,waveio.FOWaveHdr[i],
sizeof(WAVEHDR));
if(mmr) return FALSE;
mmr = waveOutWrite(waveio.FHWaveOut,waveio.FOWaveHdr[i],
sizeof(WAVEHDR));
if(mmr) return FALSE;
}
return TRUE;
}
int DRIFF::WaveOutPlay(void *buffer,int size,int wait=FALSE)
{
if(waveio.FHWaveOut == NULL) return FALSE;
while(!(waveio.FOWaveHdr[waveio.out_current]->dwFlags & WHDR_DONE)) {
if(wait) Sleep(1);
else break;
}
memcpy(waveio.FOWaveHdr[waveio.out_current]->lpData,buffer,size);
waveio.FOWaveHdr[waveio.out_current]->dwBufferLength = size;
if(waveOutWrite(waveio.FHWaveOut,waveio.FOWaveHdr[waveio.out_current],
sizeof(WAVEHDR)))
return FALSE;
waveio.out_current = (waveio.out_current + 1) % waveio.out_count;
return TRUE;
}
int DRIFF::WaveOutClose()
{
if(waveio.FHWaveOut == NULL) return FALSE;
waveOutSetVolume(waveio.FHWaveOut,waveio.volume);
waveOutReset(waveio.FHWaveOut);
for(int i=0;i<waveio.out_count;i++) {
waveOutUnprepareHeader(waveio.FHWaveOut,
waveio.FOWaveHdr[i],sizeof(WAVEHDR));
HeapFree(GetProcessHeap(),0,waveio.FOWaveHdr[i]->lpData);
HeapFree(GetProcessHeap(),0,waveio.FOWaveHdr[i]);
}
delete []waveio.FOWaveHdr;
waveOutClose(waveio.FHWaveOut);
waveio.FHWaveOut = NULL;
if(wave.buf){ delete []wave.buf; wave.buf = NULL; }
if(wave.fft){ delete []wave.fft; wave.fft = NULL; }
return TRUE;
}
int DRIFF::WaveInInit()
{
wave.in_flag = FALSE;
waveio.FHWaveIn = NULL;
waveio.in_count = 0;
waveio.in_current = 0;
return TRUE;
}
int DRIFF::WaveInOpen()
{
ULONG FBlockSize,SRATE = 44100;
MMRESULT mmr;
WAVEFORMATEX FWaveFmt;
FWaveFmt.wFormatTag = WAVE_FORMAT_PCM;
FWaveFmt.nChannels = 1;
FWaveFmt.nSamplesPerSec = SRATE;
FWaveFmt.wBitsPerSample = 16;
FWaveFmt.nBlockAlign = 1*16/8;
FWaveFmt.nAvgBytesPerSec = SRATE*2;
FWaveFmt.cbSize = 0;
FBlockSize = 1024*2;
wave.dgw_size = FBlockSize;
waveio.in_count = 2;
waveio.in_current = 0;
dggd.wave_hlz = SRATE;
dggd.wave_bit = 16;
mmr = waveInOpen(&waveio.FHWaveIn,WAVE_MAPPER,&FWaveFmt,(DWORD)dggd.AppHwnd,
0,CALLBACK_WINDOW);
if(mmr) return FALSE;
waveio.FIWaveHdr = new WAVEHDR*[waveio.in_count];
for(int i=0;i<waveio.in_count;i++){
waveio.FIWaveHdr[i] = (WAVEHDR*)HeapAlloc(
GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(WAVEHDR));
waveio.FIWaveHdr[i]->lpData = (char*)HeapAlloc(
GetProcessHeap(),0,FBlockSize);
waveio.FIWaveHdr[i]->dwBufferLength = FBlockSize;
waveio.FIWaveHdr[i]->dwLoops = 1000;
waveio.FIWaveHdr[i]->dwBytesRecorded = 0;
waveio.FIWaveHdr[i]->dwUser = 0;
waveio.FIWaveHdr[i]->dwFlags = 0;
waveio.FIWaveHdr[i]->lpNext = NULL;
waveio.FIWaveHdr[i]->reserved = 0;
mmr = waveInPrepareHeader(waveio.FHWaveIn,waveio.FIWaveHdr[i],
sizeof(WAVEHDR));
if(mmr){ WaveInClose(); return FALSE; }
mmr = waveInAddBuffer(waveio.FHWaveIn,waveio.FIWaveHdr[i],
sizeof(WAVEHDR));
if(mmr){ WaveInClose(); return FALSE; }
}
waveInStart(waveio.FHWaveIn);
if(wave.buf) delete []wave.buf;
if(wave.fft) delete []wave.fft;
wave.buf = new char[FBlockSize];
wave.fft = new float[FBlockSize];
if(wave.buf == NULL || wave.fft == NULL){
WaveInClose(); return FALSE;
}
type = DRIFF_WIN;
set_info("**WAVE IN");
WaveInfo("",FWaveFmt);
wave.in_flag = TRUE;
return TRUE;
}
int DRIFF::WaveInPlay()
{
if(wave.in_flag == FALSE) return FALSE;
memcpy(wave.buf,waveio.FIWaveHdr[waveio.in_current]->lpData,wave.dgw_size);
waveInPrepareHeader(waveio.FHWaveIn,waveio.FIWaveHdr[waveio.in_current],
sizeof(WAVEHDR));
waveInAddBuffer(waveio.FHWaveIn,waveio.FIWaveHdr[waveio.in_current],
sizeof(WAVEHDR));
waveio.in_current = (waveio.in_current + 1) % waveio.in_count;
return TRUE;
}
int DRIFF::WaveInClose()
{
if(waveio.FHWaveIn == NULL) return FALSE;
waveInStop(waveio.FHWaveIn);
waveInReset(waveio.FHWaveIn);
for(int i=0;i<waveio.in_count;i++){
waveInUnprepareHeader(waveio.FHWaveIn,waveio.FIWaveHdr[i],
sizeof(WAVEHDR));
HeapFree(GetProcessHeap(),0,waveio.FIWaveHdr[i]->lpData);
}
delete []waveio.FIWaveHdr;
waveInClose(waveio.FHWaveIn);
waveio.FHWaveIn = NULL;
if(wave.buf) { delete []wave.buf; wave.buf = NULL; }
if(wave.fft) { delete []wave.fft; wave.fft = NULL; }
wave.in_flag = FALSE;
return TRUE;
}
int DRIFF::AcmOpen(WAVEFORMATEX f)
{
MMRESULT mmr;
memset(&wave.format,0,sizeof(WAVEFORMATEX));
wave.format.wFormatTag = WAVE_FORMAT_PCM;
mmr = acmFormatSuggest(NULL,wave.format_src,&wave.format,
sizeof(WAVEFORMATEX),ACM_FORMATSUGGESTF_WFORMATTAG);
if(mmr) return FALSE;
mmr = acmStreamOpen(&acm.acm,NULL,wave.format_src,&wave.format,
NULL,0,0,ACM_STREAMOPENF_NONREALTIME);
if(mmr) return FALSE;
acm.read_size = WaveBlockSize(*wave.format_src);
mmr = acmStreamSize(acm.acm,acm.read_size,&acm.buf_size,
ACM_STREAMSIZEF_SOURCE);
if(mmr) return FALSE;
acm.flag = TRUE;
acm.buf = new char[acm.buf_size];
acm.buf_read = new char[acm.read_size];
AcmBufferClear();
return true;
}
int DRIFF::AcmBufferClear()
{
acm.buf_p = acm.buf;
acm.buf_left = 0;
acm.buf_read_p = acm.buf_read;
return TRUE;
}
int DRIFF::AcmRead(void *buf,int size)
{
char *buffer=(char*)buf;
int s,s2=size;
while(size) {
if(acm.buf_left == 0) {
if(wave.eof) { return s2 - size; }
int left = acm.buf_read_p - acm.buf_read;
s = WaveRead2(acm.buf_read_p,acm.read_size-left);
AcmConvert(acm.buf_read,s+left,acm.buf,wave.block_size);
}
s = min(size,acm.buf_left);
memcpy(buffer,acm.buf_p,s);
size -= s; buffer += s;
acm.buf_p += s; acm.buf_left -= s;
}
wave.dgw_size = s2-size;
return s2 - size;
}
int DRIFF::AcmConvert(void *src,int src_size,void *dest,int dest_size)
{
memset(&acm.ach,0,sizeof(acm.ach));
acm.ach.cbStruct = sizeof(acm.ach);
acm.ach.pbSrc = (unsigned char*)src;
acm.ach.cbSrcLength = src_size;
acm.ach.pbDst = (unsigned char*)dest;
acm.ach.cbDstLength = dest_size;
acmStreamPrepareHeader(acm.acm,&acm.ach,0);
acmStreamConvert(acm.acm,&acm.ach,ACM_STREAMCONVERTF_BLOCKALIGN);
acmStreamUnprepareHeader(acm.acm,&acm.ach,0);
if((int)acm.ach.cbSrcLengthUsed == src_size) {
acm.buf_read_p = acm.buf_read;
} else {
LONG len = src_size - acm.ach.cbSrcLengthUsed;
acm.buf_read_p = &acm.buf_read[len];
memmove(acm.buf_read,&acm.buf_read[acm.ach.cbSrcLengthUsed],len);
}
acm.buf_left = acm.ach.cbDstLengthUsed;
acm.buf_p = acm.buf;
return TRUE;
}
int DRIFF::AcmClose()
{
if(acm.buf) { delete []acm.buf; acm.buf = NULL; }
if(acm.buf_read) { delete []acm.buf_read; acm.buf_read = NULL; }
acmStreamClose(acm.acm,0);
acm.flag = FALSE;
return TRUE;
}
int DRIFF::MP3Open(char* filename)
{
MMRESULT mmr;
DWORD maxFormatSize = sizeof(MPEGLAYER3WAVEFORMAT);
mmr = acmMetrics(NULL,ACM_METRIC_MAX_SIZE_FORMAT,&maxFormatSize);
if(maxFormatSize == 0) return FALSE;
acm.format_src = (LPMPEGLAYER3WAVEFORMAT)malloc(maxFormatSize);
memset(acm.format_src,0,maxFormatSize);
MPEGLAYER3WAVEFORMAT* fmp3 = acm.format_src;
if(!MP3Info(filename,fmp3)) return FALSE;
wave.format_src = (LPWAVEFORMATEX)malloc(maxFormatSize);
WAVEFORMATEX* fwav = wave.format_src;
memset(fwav,0,maxFormatSize);
memcpy(fwav,fmp3,maxFormatSize);
fwav->wFormatTag = WAVE_FORMAT_PCM;
fwav->wBitsPerSample = fmp3->wfx.wBitsPerSample<12?8:16;
fwav->nBlockAlign = fmp3->wfx.nChannels*fwav->wBitsPerSample/8;
fwav->nAvgBytesPerSec = fmp3->wfx.nSamplesPerSec * fwav->nBlockAlign;
fwav->cbSize = 0;
acm.read_size = fmp3->nBlockSize;
mmr = acmFormatSuggest(NULL,(WAVEFORMATEX*)fmp3,
fwav,sizeof(WAVEFORMATEX),
ACM_FORMATSUGGESTF_WFORMATTAG);
if(!err_check(mmr)) return FALSE;
acm.acm = NULL;
mmr = acmStreamOpen(&acm.acm,
NULL,
(LPWAVEFORMATEX)fmp3,
fwav,
NULL,
0,
0,
0
);
if(!err_check(mmr)) return FALSE;
mmr = acmStreamSize(acm.acm,acm.read_size,&acm.buf_size,
ACM_STREAMSIZEF_SOURCE);
if(!err_check(mmr)) return FALSE;
wave.block_size = acm.buf_size;
if(!WaveInit(*fwav)) {
MessageBox(NULL,"WAVE未対応","MP3",MB_OK);
return FALSE;
}
type = DRIFF_MP3;
acm.flag = TRUE;
dggd.wave_hlz = fwav->nSamplesPerSec;
dggd.wave_bit = fwav->wBitsPerSample;
dggd.wave_chn = fwav->nChannels;
acm.buf_read = new char[acm.read_size];
acm.buf = new char[acm.buf_size];
AcmBufferClear();
return TRUE;
}
int DRIFF::MP3Info(char* filename,MPEGLAYER3WAVEFORMAT* mp3fmt)
{
static char sbuf[BUFSIZ],stmp[BUFSIZ];
fpos_t pFile;
int curch;
int FSize,pHead;
int impegVer,iLayer;
int mp3Freq;
int padBit;
int iFramesize,n_Frames;
int n_Channel;
long int FreqTab[4][4]={
11025,12000,8000,0,
0,0,0,0,
22050,24000,16000,0,
44100,48000,32000,0,
};
static char channelmode[4][20] = {
"Stereo","Joint Stereo","Dual Channel","Single Channel"
};
int BitRate;
int BRateTab1[3][16] = {
0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,0,
0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384,0,
0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448,0,
};
int BRateTab2[3][16] = {
0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0,
0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160,0,
0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256,0,
};
int SmpsPerFrame[4][3] = {
576,1152,384,
0,0,0,
576,1152,384,
1152,1152,384,
};
char idtag[5];
int ch_flag=0,fpos=0;
static int id3tag;
mp3fmt->wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES;
mp3fmt->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
mp3fmt->wfx.nChannels = 2;
mp3fmt->wfx.nAvgBytesPerSec = 128 * (1000/8);
mp3fmt->wfx.wBitsPerSample = 0;
mp3fmt->wfx.nBlockAlign = 1;
mp3fmt->wfx.nSamplesPerSec = 44100;
mp3fmt->fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF;
mp3fmt->nBlockSize = 144 * 128 * 1000 / 44100 + 0;
mp3fmt->nFramesPerBlock = 1;
mp3fmt->nCodecDelay = 0x571;
mp3fmt->wID = MPEGLAYER3_ID_MPEG;
if(file==NULL) {
MessageBox(NULL,"file == NULL",0,0);
return FALSE;
}
fseek(file,0,SEEK_END); FSize = ftell(file); fseek(file,0,SEEK_SET);
memset(idtag,0,sizeof(idtag));
fread(idtag,1,3,file);
if(!strcmp(idtag,"ID3")) id3tag = 1;
else {
id3tag = 0;
fseek(file,0,SEEK_SET);
}
TRACE("id3tag = %d\n",id3tag);
while(!ch_flag) {
curch = fgetc(file);
if(curch == EOF) break;
if(curch == 0xff) {
curch = fgetc(file);
fgetpos(file,(fpos_t*)&fpos);
fpos-=2;
if(((curch&0xe0)>>5) == 7) {
impegVer = ((curch&0x18)>>3);
iLayer = ((curch&0x03)>>1);
if(impegVer == NOT_MPEG || iLayer == NOT_LAYER) ;
else {
ch_flag = 1;
TRACE("id3tag = %d, fpos = %d\n",id3tag,fpos);
if(id3tag == 1 && fpos < 0xff) ch_flag = 0;
}
}
}
}
if(ch_flag == 0){
MessageBox(NULL,"cannot find first frame.",0,0);
return FALSE;
}
sprintf(sbuf,"** MP3\r\n");
fgetpos(file,&pFile);
pFile -= 2; pHead = (int)pFile;
sprintf(stmp,"First frame found at byte : %d [byte]\r\n\r\n",pHead);
TRACE("First frame found at byte : %d [byte]\r\n\r\n",pHead);
strcat(sbuf,stmp);
switch(impegVer){
case MPEG1: sprintf(stmp,"[ MPEG-1"); break;
case MPEG2: sprintf(stmp,"[ MPEG-2"); break;
case MPEG25: sprintf(stmp,"[ MPEG-2.5"); break;
}
strcat(sbuf,stmp);
switch(iLayer){
case MPEG_LAYER1: sprintf(stmp," Layer I ]\r\n"); break;
case MPEG_LAYER2: sprintf(stmp," Layer II ]\r\n"); break;
case MPEG_LAYER3: sprintf(stmp," Layer III ]\r\n"); break;
default: sprintf(stmp," ]\r\n"); break;
}
strcat(sbuf,stmp);
if(tolower(((curch%16)%4)%2)==1)
sprintf(stmp,"CRCs : No\r\n");
else
sprintf(stmp,"CRCs : Yes\r\n");
strcat(sbuf,stmp);
curch = fgetc(file);
switch(impegVer){
case MPEG1:
BitRate = BRateTab1[iLayer-1][tolower(curch/16)]; break;
case MPEG2:
BitRate = BRateTab2[iLayer-1][tolower(curch/16)]; break;
case MPEG25:
BitRate = BRateTab2[iLayer-1][tolower(curch/16)]; break;
}
sprintf(stmp,"Bitrate(kbps) : %d\r\n",BitRate);
strcat(sbuf,stmp);
mp3Freq = FreqTab[impegVer][tolower((curch%16)/4)];
sprintf(stmp,"Frequency(Hz) : %d\r\n",mp3Freq);
strcat(sbuf,stmp);
padBit = tolower(((curch%16)%4)/2);
sprintf(stmp,"Padding : ");
strcat(sbuf,stmp);
if(padBit==0) sprintf(stmp,"No\r\n");
else sprintf(stmp,"Yes\r\n");
strcat(sbuf,stmp);
sprintf(stmp,"Private : ");
strcat(sbuf,stmp);
if(tolower(((curch%16)%4)%2)==0) sprintf(stmp,"No\r\n");
else sprintf(stmp,"Yes\r\n");
strcat(sbuf,stmp);
curch = fgetc(file);
n_Channel = (tolower((curch/16)/4)==3)?1:2;
sprintf(stmp,"Channel : %s\r\n",channelmode[tolower((curch/16)/4)]);
strcat(sbuf,stmp);
sprintf(stmp,"Copyrighted : ");
strcat(sbuf,stmp);
if(tolower(((curch%16)/4)/2)==1) sprintf(stmp,"Yes\r\n");
else sprintf(stmp,"No\r\n");
strcat(sbuf,stmp);
sprintf(stmp,"Original : ");
strcat(sbuf,stmp);
if(tolower(((curch%16)/4)%2)==1) sprintf(stmp,"Yes\r\n");
else sprintf(stmp,"No\r\n");
strcat(sbuf,stmp);
sprintf(stmp,"Emphasis : ");
strcat(sbuf,stmp);
switch(tolower((curch%16)%4)){
case 0: sprintf(stmp,"None\r\n"); break;
case 1: sprintf(stmp,"50/15 ms\r\n"); break;
case 3: sprintf(stmp,"CCITT J.17\r\n"); break;
}
strcat(sbuf,stmp);
int smps = SmpsPerFrame[impegVer][iLayer-1];
iFramesize = (smps/8*BitRate*1000) / mp3Freq + padBit;
n_Frames = (FSize-pHead)/iFramesize;
sprintf(stmp,"Framesize : %d\r\n",iFramesize);
strcat(sbuf,stmp);
sprintf(stmp,"Frame Num : %d\r\n",n_Frames);
strcat(sbuf,stmp);
double temp,msec;
int Allsec,min,sec;
temp = (double)(n_Frames * smps) / (double)mp3Freq;
Allsec = (n_Frames * smps) / mp3Freq;
min = Allsec/60;
sec = Allsec%60;
msec = (temp - Allsec)*1000;
if(msec > 500) sec += 1;
sprintf(stmp,"Length : (%d:%d)\r\n",min,sec);
strcat(sbuf,stmp);
fseek(file,pHead,SEEK_SET);
mp3fmt->wfx.nChannels = n_Channel;
mp3fmt->wfx.nAvgBytesPerSec = BitRate;
mp3fmt->wfx.nSamplesPerSec = mp3Freq;
mp3fmt->nBlockSize = iFramesize;
if(padBit) mp3fmt->fdwFlags = MPEGLAYER3_FLAG_PADDING_ON;
else mp3fmt->fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF;
cat_info(sbuf);
return TRUE;
}
BOOL DRIFF::DrawWave(HDC hDC,RECT *pR)
{
SaveDC(hDC);
HPEN *bgp,*wvp;
int i,wx,wy,dwx,dwy;
wx = pR->right - pR->left;
wy = pR->bottom - pR->top;
if(dggd.dgw_type == DGW_NORMAL) {
dwx = wave.dgw_size/(dggd.wave_bit/8);
if(dggd.wave_bit == 8) dwy = 1<<9;
else dwy = 1<<17;
} else {
int fftn = FFT();
dwx = (1024/2)*15000/(dggd.wave_hlz/2)/4;
if(dggd.wave_bit == 8) dwy = 50;
else dwy = 10000;
}
bgp = (HPEN*)CreatePen(PS_SOLID,1,RGB(0,0,0));
SelectObject(hDC,bgp);
for(i=0;i<wx;i++){
MoveToEx(hDC,pR->left+i,pR->top,NULL);
LineTo(hDC,pR->left+i,pR->bottom);
}
SetMapMode(hDC,MM_ANISOTROPIC);
SetWindowExtEx(hDC,dwx,dwy,NULL);
SetViewportExtEx(hDC,wx,-wy,NULL);
if(dggd.dgw_type == DGW_NORMAL) {
SetViewportOrgEx(hDC,0,pR->top+wy/2,NULL);
MoveToEx(hDC,0,0,NULL);
} else {
SetViewportOrgEx(hDC,0,pR->top+wy-1,NULL);
}
wvp = (HPEN*)CreatePen(PS_SOLID,1,RGB(255,230,50));
SelectObject(hDC,wvp);
int dstep = dwx/wx;
int istep = (dggd.wave_bit/8);
double mean = 0.0;
if(dstep < 2) dstep = 2;
if(dggd.dgw_type == DGW_NORMAL){
for(i=0;i<dwx;i+=istep) {
if(i%dstep == 0){
mean /= (double)dstep;
if(mean < dwy) LineTo(hDC,i,(int)mean);
else LineTo(hDC,i,dwy);
mean = 0.0;
} else {
if(dggd.wave_bit==8) mean += wave.buf[i];
else mean += (short)(wave.buf[i]+(wave.buf[i+1]<<8));
}
}
} else {
for(i=0;i<dwx;i++) {
if(i%dstep == 0){
mean /= (double)dstep;
MoveToEx(hDC,i,0,NULL);
if(mean < dwy) LineTo(hDC,i,(int)mean);
else LineTo(hDC,i,dwy);
} else mean += wave.fft[i];
}
}
RestoreDC(hDC,-1);
return TRUE;
}
int DRIFF::FFT()
{
if(wave.dgw_size <= 0) return 0;
int i,j,k,k1,num,nhalf,phi,phi0;
int m,N,NN,istep;
double s,sc,c,a0,b0,tmp;
static int rot[1024];
static complex f[1024];
for(i=0;i<=10;i++){
N = (int)pow(2,i); m = i;
if(N >= wave.dgw_size) break;
}
if(m<=10){ if(dggd.wave_bit==16){ m-=1; N = N/2; } }
else { m = 10; N = 1024; }
NN = (dggd.wave_bit==8)?N:N*2;
istep = (dggd.wave_bit==8)?1:2;
for(i=0;i<NN;i+=istep){
if(dggd.wave_bit==8){
f[i].re = wave.buf[i];
f[i].im = 0.0;
} else {
f[i/2].re = (short)(wave.buf[i]+(wave.buf[i+1]<<8));
f[i/2].im = 0.0;
}
}
nhalf=N/2; num=N/2; sc=FFT_TWOPI/(double)N;
while(num>=1){
for(j=0;j<N;j+=(2*num)){
phi=rot[j]/2; phi0=phi+nhalf;
c=cos(sc*(double)phi); s=sin(sc*(double)(phi));
for(k=j;k<j+num;k++){
k1 = k+num;
a0 = f[k1].re*c-f[k1].im*s;
b0 = f[k1].re*s+f[k1].im*c;
f[k1].re = f[k].re-a0; f[k1].im = f[k].im-b0;
f[k].re = f[k].re+a0; f[k].im = f[k].im+b0;
rot[k] = phi; rot[k1] = phi0;
}
}
num/=2;
}
for(i=0;i<N-1;i++){
if((j=rot[i])>i){
if(i<N && j<N){
tmp=f[i].re; f[i].re=f[j].re; f[j].re=tmp;
tmp=f[i].im; f[i].im=f[j].im; f[j].im=tmp;
}
}
}
for(i=0;i<N;i++){
wave.fft[i] = (float)(PW(f[i].re,f[i].im)/(N/2));
}
return 1024/2;
}