//----------------------------------------------------------------- // driff.cpp: // RIFF 構造データの再生/表示(AVI/WAVE + MP3) // AVI: codec の使用(divx,xvid etc. に対応) // MP3: ACM->PCM // Last Update: <2005/06/04 11:43:31 A.Murakami> //----------------------------------------------------------------- #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); } // mmr 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;ibiClrUsed*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; //DrawDibBegin(dg_DDib,hdc,-1,-1,dibh,-1,-1,0); // 連続再生 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;//(int)(ds.y*iscale) + 5; pR.bottom = wr.bottom;//(int)(ds.y*iscale) + 100; 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; } // DIB描画用 LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)a; int bsz = lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD); LPBYTE start = (LPBYTE)a + bsz; // DIB描画 DrawDibDraw(dg_DDib, // DrawDIB のハンドル hdc, // デバイスコンテキスト 0,0, // 転送先の先頭座標 pR.right, // 転送先の幅(int)(iscale*ds.x) pR.bottom-105, // 転送先の高さ lpbi, // BITMAPINFOHEADER構造体 (LPVOID)start, // 転送元画像データ 0,0, // 転送元の先頭画素 dggd.ds.x,dggd.ds.y, // 転送画素の行と列数 DDF_BUFFER //DDF_SAME_HDC //| DDF_SAME_DRAW // 描画用フラグ ); // 表示待ち 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); // set sec if(dr.WaveEof()) { dr.WaveSeek(0); Sleep(1000); // 小休止 } dr.DrawWave(hdc,&pR); } // FPS 表示 //static char t_str[256]; //wsprintf(t_str,"%s [%s%s]",dg_fname,getfps(),getwif()); //SetWindowText(hWnd,t_str); // 再描画 InvalidateRect(hWnd,&rdr,FALSE); InvalidateRect(dggd.edHwnd,NULL,FALSE); EndPaint(hWnd,&ps); } //DrawDibClose(dg_DDib); 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); } //----------------------------------------------------------------- // // Class of DRIFF // AVI draw graphic and playing wave(PCM) sound // //----------------------------------------------------------------- DRIFF::DRIFF() { file = NULL; type = 0; memset(&movie,0,sizeof(movie)); memset(&wave,0,sizeof(wave)); wave.buf = NULL; wave.fft = NULL; WaveOutInit(); WaveInInit(); // find an MP3 codec 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")){ // RIFF チャンクの読み込み 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); // WAVE else if(type == DRIFF_AVI) ret=AviOpen(filename); // AVI } else ret = FALSE; if(ret==FALSE) sprintf(buf,"RIFF:形式が異なります."); } else if(check_suffix(filename,"mp3")){ // [RIFF] 以外 ret = MP3Open(filename); if(ret==FALSE) sprintf(buf,"MP3:形式が異なります."); } else { ret = FALSE; sprintf(buf,"未対応"); } if(ret==FALSE) { type = 0; set_info(""); Close(); //MessageBox(NULL,buf,"入力ファイル",MB_OK); 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; } //----------------------------------------------------------------- // // AVI 画像関数 // //----------------------------------------------------------------- int DRIFF::AviOpen(char *filename) { WAVEFORMATEX cpf; //-------------------------------------------------- // VFW 関数(Video for Windows)でAVIファイルを開く //-------------------------------------------------- AVIFileInit(); if(AVIFileOpen(&movie.file,filename,OF_READ|OF_SHARE_DENY_NONE,NULL)){ MessageBox(NULL,"AVIファイルエラー","入力ファイル",MB_OK); return FALSE; } // VIDEO & AUDIO ストリームを開く AVIFileGetStream(movie.file,&movie.ps_movie,streamtypeVIDEO,0); AVIFileGetStream(movie.file,&movie.ps_audio,streamtypeAUDIO,0); AVIFileInfo(movie.file,&movie.info,sizeof(AVIFILEINFO)); // VIDEO ストリームを開く(2) if(movie.ps_movie) { cat_info("**VIDEO\r\n"); // read format 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); // frame open 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; } // AUDIO ストリームを開く(2) 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); //-------------------------------------------------- // wave format compression setup. //-------------------------------------------------- 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); //-------------------------------------------------- // compress start //-------------------------------------------------- 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() { //-------------------------------------------------- // get format size //-------------------------------------------------- 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); //-------------------------------------------------- // read format //-------------------------------------------------- LPBITMAPINFOHEADER s,d; s = movie.lpSrcFmt; d = movie.lpDecFmt; // set source format AVIStreamInfo(movie.ps_movie,&movie.si,sizeof(AVISTREAMINFO)); // set decode format 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; // alloc buffer 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); // suggested buffer size if(movie.si.dwSuggestedBufferSize) if(movie.si.dwSuggestedBufferSize < (unsigned)movie.lLength) movie.lLength = (LONG)movie.si.dwSuggestedBufferSize; //-------------------------------------------------- // open the decompressor //-------------------------------------------------- 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){ // cannot find codec 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); //-------------------------------------------------- // get palette(if used) //-------------------------------------------------- //ICDecompressGetPalette(hic,s,d); //-------------------------------------------------- // start decompressing //-------------------------------------------------- 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; } //----------------------------------------------------------------- // // WAVE 関数 // //----------------------------------------------------------------- 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; } // read header. if(head[i].ckID == mmioFOURCC('f','m','t',' ')){ // [fmt ] 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')) { // [data] 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) // Default Buffer(4KB) size = (1024 / f.nBlockAlign) * f.nBlockAlign; return size; } int DRIFF::WaveSeek(double sec) { if(!wave.init_flag) return FALSE; if(acm.flag) { // ACM のseek は、先頭以外サポート外 if(sec!=0) return FALSE; else { AcmBufferClear(); fseek(file,0,SEEK_SET); } } else { // RIFF data if(type == DRIFF_WAVE) { fseek(file,WavePos(sec)+wave.start_pos,SEEK_SET); } else { // AVI AUDIO 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){ // read err. 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; } //----------------------------------------------------------------- // WaveOut //----------------------------------------------------------------- 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(); // 境界バイトが1秒に合わないもの if(bufsize % format->nBlockAlign != 0) return FALSE; // PCM フォーマット以外 if(format->wFormatTag != WAVE_FORMAT_PCM) return FALSE; // wave 出力の開始 mmr = waveOutOpen(&waveio.FHWaveOut,WAVE_MAPPER,format,0,0,CALLBACK_NULL); if(mmr) return FALSE; waveio.out_count = count; waveio.FOWaveHdr = new WAVEHDR*[count]; // set wave volume waveOutGetVolume(waveio.FHWaveOut,&waveio.volume); waveOutSetVolume(waveio.FHWaveOut,MAKELONG(0x3000,0x3000)); // prepare header for(int i=0;ilpData = (char*)HeapAlloc(GetProcessHeap(),0,bufsize); waveio.FOWaveHdr[i]->dwBufferLength = 0; mmr = waveOutPrepareHeader(waveio.FHWaveOut,waveio.FOWaveHdr[i], sizeof(WAVEHDR)); if(mmr) return FALSE; // WHDR_DONE を付けるため、ダミーデータの出力 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);//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; // set volume waveOutSetVolume(waveio.FHWaveOut,waveio.volume); // clean up waveOutReset(waveio.FHWaveOut); for(int i=0;ilpData); 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; } //----------------------------------------------------------------- // WaveIn //----------------------------------------------------------------- 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; //-------------------------------------------------- // WAVE データの設定 //-------------------------------------------------- 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; //-------------------------------------------------- // WAVE 入力開始 //-------------------------------------------------- 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;ilpData = (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;ilpData); } 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; } //----------------------------------------------------------------- // ACM sound //----------------------------------------------------------------- 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) { // 残りバッファ0 + eof 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; } //----------------------------------------------------------------- // MP3 出力関数 //----------------------------------------------------------------- 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; //-------------------------------------------------- // define MP3 input format //-------------------------------------------------- acm.format_src = (LPMPEGLAYER3WAVEFORMAT)malloc(maxFormatSize); memset(acm.format_src,0,maxFormatSize); MPEGLAYER3WAVEFORMAT* fmp3 = acm.format_src; if(!MP3Info(filename,fmp3)) return FALSE; //-------------------------------------------------- // define desired output format //-------------------------------------------------- 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; //-------------------------------------------------- // decoder check //-------------------------------------------------- mmr = acmFormatSuggest(NULL,(WAVEFORMATEX*)fmp3, fwav,sizeof(WAVEFORMATEX), ACM_FORMATSUGGESTF_WFORMATTAG); if(!err_check(mmr)) return FALSE; //-------------------------------------------------- // ACM出力開始 //-------------------------------------------------- acm.acm = NULL; mmr = acmStreamOpen(&acm.acm, // open an ACM conversion stream NULL, // querying all ACM drivers (LPWAVEFORMATEX)fmp3, // converting from MP3 fwav, // to WAV NULL, // with no filter 0, // or async callbacks 0, // (and no data for the callback) 0 // and no flags ); 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; //-------------------------------------------------- // WAVE 音源初期化 //-------------------------------------------------- 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; // for reading MPEG Audio Frame Header int FSize,pHead; // Filesize and header position int impegVer,iLayer; // MPEG ver and layer int mp3Freq; // Frequency int padBit; // Padding bit int iFramesize,n_Frames; // Frame size and number int n_Channel; // Channels long int FreqTab[4][4]={ 11025,12000,8000,0, // MPEG 2.5 0,0,0,0, // Reserved 22050,24000,16000,0, // MPEG II 44100,48000,32000,0, // MPEG I }; static char channelmode[4][20] = { // Channel "Stereo","Joint Stereo","Dual Channel","Single Channel" }; int BitRate; // bitrate int BRateTab1[3][16] = { // MPEG I - Layer III,II,I 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] = { // MPEG II - Layer III, II ,I 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] = { // Samples Per Frame 576,1152,384, // MPEG 2.5 0,0,0, // Reserved 576,1152,384, // MPEG 2 1152,1152,384, // MPEG 1 }; //-------------------------------------------------- char idtag[5]; int ch_flag=0,fpos=0; static int id3tag; //-------------------------------------------------- // set initial mp3 header values //-------------------------------------------------- mp3fmt->wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES; mp3fmt->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3; mp3fmt->wfx.nChannels = 2; mp3fmt->wfx.nAvgBytesPerSec = 128 * (1000/8); // 64,96,112,128,160kbps mp3fmt->wfx.wBitsPerSample = 0; // MUST BE ZERO mp3fmt->wfx.nBlockAlign = 1; // MUST BE ONE mp3fmt->wfx.nSamplesPerSec = 44100; // 44.1kHz mp3fmt->fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF; mp3fmt->nBlockSize = 144 * 128 * 1000 / 44100 + 0; mp3fmt->nFramesPerBlock = 1; // MUST BE ONE mp3fmt->nCodecDelay = 0x571; // voodoo value #2 mp3fmt->wID = MPEGLAYER3_ID_MPEG; //-------------------------------------------------- // Get file size //-------------------------------------------------- if(file==NULL) { MessageBox(NULL,"file == NULL",0,0); return FALSE; } fseek(file,0,SEEK_END); FSize = ftell(file); fseek(file,0,SEEK_SET); //-------------------------------------------------- // Version and Layer check MPEG 1/2, Layer I,II,III //-------------------------------------------------- // check ID3 tag 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); // seek first frame 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; } //-------------------------------------------------- // position of first frame header //-------------------------------------------------- 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); //-------------------------------------------------- // Info. of 2nd byte //-------------------------------------------------- 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); // CRC if(tolower(((curch%16)%4)%2)==1) sprintf(stmp,"CRCs : No\r\n"); else sprintf(stmp,"CRCs : Yes\r\n"); strcat(sbuf,stmp); //-------------------------------------------------- // Info. of 3rd byte [bitrate, frequency etc.] //-------------------------------------------------- curch = fgetc(file); // bitrate info switch(impegVer){ case MPEG1: // MPEG I BitRate = BRateTab1[iLayer-1][tolower(curch/16)]; break; case MPEG2: // MPEG II BitRate = BRateTab2[iLayer-1][tolower(curch/16)]; break; case MPEG25: // MPEG 2.5 BitRate = BRateTab2[iLayer-1][tolower(curch/16)]; break; } sprintf(stmp,"Bitrate(kbps) : %d\r\n",BitRate); strcat(sbuf,stmp); // frequency info mp3Freq = FreqTab[impegVer][tolower((curch%16)/4)]; sprintf(stmp,"Frequency(Hz) : %d\r\n",mp3Freq); strcat(sbuf,stmp); // padding bit 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); // private bit 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); //-------------------------------------------------- // Info. of 4th byte [channel, copyright etc.] //-------------------------------------------------- curch = fgetc(file); //channel mode n_Channel = (tolower((curch/16)/4)==3)?1:2; sprintf(stmp,"Channel : %s\r\n",channelmode[tolower((curch/16)/4)]); strcat(sbuf,stmp); // copyright bit 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); // original bit 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); // emphasis 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); //-------------------------------------------------- // Calculating Frame size and Length //-------------------------------------------------- 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); // song length... 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); // set file pointer fseek(file,pHead,SEEK_SET); //-------------------------------------------------- // set format values //-------------------------------------------------- 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; // display mp3 information cat_info(sbuf); //MessageBox(NULL,sbuf,"MP3情報",0); return TRUE; } //----------------------------------------------------------------- // WAVE 波形表示 //----------------------------------------------------------------- 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) { // normal wave dwx = wave.dgw_size/(dggd.wave_bit/8); if(dggd.wave_bit == 8) dwy = 1<<9; else dwy = 1<<17; } else {// for FFT draw int fftn = FFT(); //Hz 表示に[max:15000Hz=>15000/(wave_hlz/2)*(4096/2)] dwx = (1024/2)*15000/(dggd.wave_hlz/2)/4;//dwx = FFT()/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;ileft+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) { // normal wave 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){ // draw sound wave for(i=0;i= 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=1){ for(j=0;ji){ if(i