#include #include"wavefile.h" #pragma comment(lib,"winmm") // エラー表示 void ErrMsg(PCTSTR text,PCTSTR caption) { MessageBox(NULL,text,caption,MB_OK); } // マルチメディア関数のエラーを表示 MMRESULT MMErrMsg(MMRESULT result,PCTSTR caption) { #ifdef _DEBUG if(result!=MMSYSERR_NOERROR) { TCHAR text[256]; mciGetErrorString(result,text,sizeof(text)/sizeof(text[0])); MessageBox(NULL,text,caption,MB_OK); } #endif return result; } // PCM形式のWAVEファイルを読み込む // PCTSTR filename ファイルの名前を指すポインタ // WAVEFORMATEX *pwfe データを格納するWAVEFORMATEX構造体を指すポインタ // WAVEHDR *pwhdr データを格納するWAVEHDR構造体を指すポインタ // 戻り値 true(成功) or false(失敗) bool LoadWaveFile(PCTSTR filename,WAVEFORMATEX *pwfe,WAVEHDR *pwhdr) { HANDLE fh=CreateFile(filename,GENERIC_READ,0,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if(fh==INVALID_HANDLE_VALUE) { ErrMsg(filename,TEXT("ファイルを開けません")); return false; } DWORD file_size=GetFileSize(fh,NULL); BYTE *pMem=(BYTE*)malloc(file_size); DWORD read_size; ReadFile(fh,pMem,file_size,&read_size,NULL); CloseHandle(fh); char str[4]; memcpy(str,pMem+8,4); if(strncmp(str,"WAVE",4)) { free(pMem); ErrMsg(filename,TEXT("WAVEファイルを指定して下さい")); return false; } DWORD wfe_size=*(DWORD*)(pMem+16); memset(pwfe,0,sizeof(WAVEFORMATEX)); memcpy(pwfe,pMem+20,wfe_size); // フォーマット情報をコピー if(pwfe->wFormatTag != WAVE_FORMAT_PCM) { free(pMem); ErrMsg(filename,TEXT("PCM形式のWAVEファイルを指定して下さい")); return false; } memcpy(str,pMem+20+wfe_size,4); DWORD offset; // 先頭から波形データのバイト数までのオフセット if(strncmp(str,"fact",4)==0) // factチャンクが有る { DWORD fact_size=*(DWORD*)(pMem+24+wfe_size); offset=28+wfe_size+fact_size; } else if(strncmp(str,"data",4)==0) // dataチャンク(factチャンクが無い) { offset=24+wfe_size; } else { free(pMem); ErrMsg(filename,TEXT("非対応のWAVEファイルです")); return false; } // 波形データをコピー DWORD data_size=*(DWORD*)(pMem+offset); BYTE *pWave=(BYTE*)malloc(data_size); memcpy(pWave,pMem+offset+4,data_size); free(pMem); memset(pwhdr,0,sizeof(WAVEHDR)); pwhdr->lpData=(LPSTR)pWave; pwhdr->dwBufferLength=data_size; pwhdr->dwFlags=WHDR_BEGINLOOP | WHDR_ENDLOOP; pwhdr->dwLoops=1; pwhdr->dwUser=STOP; return true; } // WAVEファイルの終了処理 // HWAVEOUT hwo ウェーブフォームオーディオ出力デバイスのハンドル // WAVEHDR *pwhdr クリーンアップするデータブロックを識別するWAVEHDR構造体を指すポインタ void CloseWaveFile(HWAVEOUT hwo,WAVEHDR *pwhdr) { if(pwhdr->dwUser!=STOP) { pwhdr->dwUser=STOP; DEBUG_MM(waveOutReset(hwo),TEXT("reset")); DEBUG_MM(waveOutUnprepareHeader(hwo,pwhdr,sizeof(WAVEHDR)),TEXT("unprepare")); DEBUG_MM(waveOutClose(hwo),TEXT("close")); } if(pwhdr->lpData) { free(pwhdr->lpData); pwhdr->lpData=NULL; } }