PCMデータをwaveファイルにの保存(VC++) mmio関数群を利用して、録音したデータやプログラムで作った音声データをwaveファイルに保存する手順についてのメモです。mmio関数群を利用する為に、winmm.libをリンクして、mmsystem.hをインクルードする必要があります。データをwaveファイルに保存するために、下記の処理が必要です。 1.WAVEFORMATEX構造体を設定します。音声データを準備します。 2.ファイルオープン。WINMMAPI HMMIO WINAPI mmioOpen(LPSTR pszFileName, LPMMIOINFO pmmioinfo, DWORD fdwOpen)というAPI関数を呼び出して、保存先のwaveファイルを開きます。 3.各情報チャンクの書き込み。WINMMAPI FOURCC WINAPI mmioStringToFOURCC(LPCSTR sz, UINT uFlags)関数を使って、各情報を「チャンク」に保存します。下記の三つのチャンクに必要な情報を保存しなければいけません。RIFFチャンクで、WAV形式のデータファイルであることを設定します。フォーマットチャンクは、音声制御情報(WAVEFORMATEX)を保存します。データチャンクは、音声データの塊りを保存します。例:Dドライブに「file1.wav」というファイルに長さの10秒の音階の「ラ=440Hz」を保存します。 WAVEFORMATEX wf; wf.nChannels = 1; wf.wFormatTag = WAVE_FORMAT_PCM; wf.wBitsPerSample = 8; wf.nBlockAlign = wf.nChannels * wf.wBitsPerSample / 8; wf.nSamplesPerSec = 32000; wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign; DWORD dwRecordSecond = 10; LPSTR lpData = (LPSTR)HeapAlloc(GetProcessHeap(), 0, wf.nAvgBytesPerSec * dwRecordSecond); if (lpData) { double pi_2_f_deltaT_left = 8.0 * atan(1.0) * 440.0 / 32000.0; for (int i = 0; i < (int)(wf.nAvgBytesPerSec * dwRecordSecond); i ++) { double dblY1 = 127 * sin(pi_2_f_deltaT_left * i); BYTE byt = (BYTE)dblY1; byt += (BYTE)127; lpData[i] = byt; } DWORD dwSize = wf.nAvgBytesPerSec * dwRecordSecond; HMMIO hmmio; MMCKINFO mmckRif; MMCKINFO mmckDat; MMCKINFO mmckFmt; hmmio = mmioOpen(TEXT("d:\\file1.wav"), NULL, MMIO_CREATE | MMIO_WRITE); mmckRif.fccType = mmioStringToFOURCC(TEXT("WAVE"), 0); mmioCreateChunk(hmmio, &mmckRif, MMIO_CREATERIFF); mmckFmt.ckid = mmioStringToFOURCC(TEXT("fmt "), 0); mmioCreateChunk(hmmio, &mmckFmt, 0); mmioWrite(hmmio, (char *)&wf, sizeof(WAVEFORMATEX)); mmioAscend(hmmio, &mmckFmt, 0); mmckDat.ckid = mmioStringToFOURCC(TEXT("data"), 0); mmioCreateChunk(hmmio, &mmckDat, 0); mmioWrite(hmmio, (char *)lpData, dwSize); mmioAscend(hmmio, &mmckDat, 0); mmioAscend(hmmio, &mmckRif, 0); mmioClose(hmmio, 0); HeapFree(GetProcessHeap(), 0, lpData); } |