WindowsAPIによる録音と再生
41698 ワード
レコーディング
1、初期化
2、録音のパラメータを設定する
3、レコーディング開始
4、コールバック処理は、データをファイルに書き込んだ後、バッファをクリアし、録音装置に再追加する必要があることに注意する.
5、録音を止める
再生
1、ここで初期化するとき、dwUserという変数を1つのデータが再生されたかどうかのマークにします.getAudioDevices()、setWaveFormat()の2つの関数は、録音中の処理と似ています.
2、放送開始
3、コールバック処理
プロジェクトのダウンロード先:https://download.csdn.net/download/zeroling96/11939315
1、初期化
memset(&hWaveIn, 0, sizeof(HWAVEIN));
memset(&waveForm, 0, sizeof(WAVEFORMATEX));
if (getAudioDevices()) //
{
//
setWaveFormat(&waveForm, 2, 44100, 16);
//
for (int i = 0; i < 2; ++i)
{
whdr[i].lpData = (CHAR*)malloc(bufLength);
memset(whdr[i].lpData, 0, bufLength);
whdr[i].dwBufferLength = bufLength; //
whdr[i].dwBytesRecorded = 0; // ,
whdr[i].dwUser = 0; //
whdr[i].dwFlags = 0; //
whdr[i].dwLoops = 0; //
whdr[i].lpNext = NULL; //
whdr[i].reserved = 0; //
}
}
bool InputSound::getAudioDevices()
{
//
int count = 0;
count = waveInGetNumDevs();
if (count == 0)
{
printf(" ,
");
return false;
}
printf(" :%d
", count);
//
WAVEINCAPS waveIncaps;
MMRESULT mmResult = waveInGetDevCaps(0, &waveIncaps, sizeof(WAVEINCAPS));
if (mmResult != MMSYSERR_NOERROR)
{
printf("
");
return false;
}
//printf(" :%s
", waveIncaps.szPname);
std::cout << " :" << waveIncaps.szPname << std::endl;
return true;
}
2、録音のパラメータを設定する
void InputSound::setWaveFormat(LPWAVEFORMATEX waveformat, WORD nCh, DWORD nSampleRate, WORD BitsPerSample)
{
waveformat->wFormatTag = WAVE_FORMAT_PCM;
waveformat->nChannels = nCh; //
waveformat->nSamplesPerSec = nSampleRate; //
waveformat->nAvgBytesPerSec = nSampleRate * nCh * BitsPerSample / 8; //
waveformat->nBlockAlign = nCh * BitsPerSample / 8; //
waveformat->wBitsPerSample = BitsPerSample; //
waveformat->cbSize = 0;
}
3、レコーディング開始
void InputSound::startRecording()
{
try
{
MMRESULT mmResult = waveInOpen(&hWaveIn, WAVE_MAPPER, &waveForm, (DWORD)waveInProc, (DWORD)this, CALLBACK_FUNCTION);
if (mmResult != MMSYSERR_NOERROR)
{
printf("
");
return;
}
waveInPrepareHeader(hWaveIn, &whdr[0], sizeof(WAVEHDR)); //
waveInPrepareHeader(hWaveIn, &whdr[1], sizeof(WAVEHDR));
//
waveInAddBuffer(hWaveIn, &whdr[0], sizeof(WAVEHDR)); //
waveInAddBuffer(hWaveIn, &whdr[1], sizeof(WAVEHDR));
//
waveInStart(hWaveIn);
isStop = FALSE;
printf("
");
}
catch (...)
{
printf("
");
}
return;
}
4、コールバック処理は、データをファイルに書き込んだ後、バッファをクリアし、録音装置に再追加する必要があることに注意する.
DWORD CALLBACK InputSound::waveInProc(HWAVEIN hwavein, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
InputSound* inputSound = (InputSound*)dwInstance;
char buf[bufLength] = {0};
switch (uMsg)
{
case WIM_OPEN: //
printf("
");
break;
case WIM_DATA: //
memcpy(&buf, ((LPWAVEHDR)dwParam1)->lpData, bufLength); //
FILE *pf;
fopen_s(&pf, "./RecordSounds.pcm", "ab+");
if (strlen(buf))
{
//
fwrite(buf, 1, ((LPWAVEHDR)dwParam1)->dwBufferLength, pf);
}
if (inputSound->isStop != TRUE)
{
//
memset(((LPWAVEHDR)dwParam1)->lpData, 0, bufLength);
((LPWAVEHDR)dwParam1)->dwBytesRecorded = 0;
waveInAddBuffer(hwavein, (PWAVEHDR)dwParam1, sizeof(WAVEHDR)); //
}
fclose(pf);
break;
case WIM_CLOSE: //
printf("
");
break;
default:
break;
}
return 0;
}
5、録音を止める
void InputSound::stopRocording()
{
try
{
isStop = TRUE;
//
waveInStop(hWaveIn);
waveInReset(hWaveIn);
//
waveInUnprepareHeader(hWaveIn, &whdr[0], sizeof(WAVEHDR));
waveInUnprepareHeader(hWaveIn, &whdr[1], sizeof(WAVEHDR));
printf("
");
//
waveInClose(hWaveIn);
}
catch (...)
{
printf("
");
}
return;
}
再生
1、ここで初期化するとき、dwUserという変数を1つのデータが再生されたかどうかのマークにします.getAudioDevices()、setWaveFormat()の2つの関数は、録音中の処理と似ています.
if (getAudioDevices())
{
//
setWaveFormat(&waveForm, 2, 44100, 16);
for (int i = 0; i < 2; ++i)
{
whdr[i].lpData = (CHAR*)malloc(bufLength);
memset(whdr[i].lpData, 0, bufLength);
whdr[i].dwBufferLength = bufLength; //
whdr[i].dwBytesRecorded = 0; // ,
whdr[i].dwUser = 0; // ,0 ,1
whdr[i].dwFlags = 0; //
whdr[i].dwLoops = 0; //
whdr[i].lpNext = NULL; //
whdr[i].reserved = 0; //
}
}
2、放送開始
void OutputSound::startPlaying()
{
try
{
MMRESULT mmResult = waveOutOpen(&hWaveOut, WAVE_MAPPER, &waveForm, (DWORD)waveOutProc, (DWORD)this, CALLBACK_FUNCTION);
if (mmResult != MMSYSERR_NOERROR)
{
printf("
");
return;
}
FILE *pf;
fopen_s(&pf, "./RecordSounds.pcm", "rb");
while (true)
{
for (int i = 0; i < 2; ++i)
{
if (whdr[i].dwUser != 1) // ,
{
char buf[bufLength] = { 0 };
//whdr[i].dwBufferLength = fread(&buf, sizeof(char), bufLength, pf);
fread(&buf, bufLength, 1, pf);
memcpy(whdr[i].lpData, &buf, bufLength);
whdr[i].dwUser = 1;
waveOutPrepareHeader(hWaveOut, &whdr[i], sizeof(WAVEHDR));//
waveOutWrite(hWaveOut, &whdr[i], sizeof(WAVEHDR)); //
}
}
if (feof(pf))
{
printf("
");
Sleep(1000);
waveOutClose(hWaveOut);
break;
}
}
fclose(pf);
}
catch (...)
{
printf("
");
}
return;
}
3、コールバック処理
DWORD CALLBACK OutputSound::waveOutProc(HWAVEOUT hwaveOut, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
{
LPWAVEHDR phdr = (LPWAVEHDR)dwParam1;
switch (uMsg)
{
case WOM_OPEN:
printf("
");
break;
case WOM_DONE:
// ,
phdr->dwUser = 0;
break;
case WOM_CLOSE:
printf("
");
break;
default:
break;
}
return 0;
}
プロジェクトのダウンロード先:https://download.csdn.net/download/zeroling96/11939315