Trying to write functions that record and play sound through WinAPI

半城伤御伤魂 提交于 2019-12-08 05:31:48

问题


I'm trying to create 2 functions in C :

  • One that record the microphone for X seconds
  • One that gets a recording, and play it to the user

This is what I wrote :

#include <iostream>
#include <Windows.h>
using namespace std;

#pragma comment(lib, "winmm.lib")

WAVEHDR StartRecord(int seconds)
{
const int NUMPTS = 44100 * seconds;
int sampleRate = 44100;
short int *waveIn = new short int[NUMPTS];

HWAVEIN hWaveIn;
WAVEHDR WaveInHdr;
MMRESULT result;

WAVEFORMATEX pFormat;
pFormat.wFormatTag = WAVE_FORMAT_PCM;
pFormat.nChannels = 1;
pFormat.nSamplesPerSec = sampleRate;
pFormat.nAvgBytesPerSec = 2 * sampleRate;
pFormat.nBlockAlign = 2;
pFormat.wBitsPerSample = 16;
pFormat.cbSize = 0;

result = waveInOpen(&hWaveIn, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT);

if(result)
{
    char fault[256];
    waveInGetErrorTextA(result, fault, 256);
    MessageBoxA(NULL, fault, "Failed to open waveform input device.", MB_OK | MB_ICONEXCLAMATION);
}

WaveInHdr.lpData = (LPSTR)waveIn;
WaveInHdr.dwBufferLength = 2 * NUMPTS;
WaveInHdr.dwBytesRecorded = 0;
WaveInHdr.dwUser = 0;
WaveInHdr.dwFlags = 0;
WaveInHdr.dwLoops = 0;
waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

result = waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
if(result)
{
    MessageBoxA(NULL, "Failed to read block from device", NULL, MB_OK | MB_ICONEXCLAMATION);
}

result = waveInStart(hWaveIn);
if(result)
{
    MessageBoxA(NULL, "Failed to start recording", NULL, MB_OK | MB_ICONEXCLAMATION);
}

cout << "Recording..." << endl;
Sleep(seconds * 1000); //Sleep while recording

return WaveInHdr;

}

void PlayRecord(WAVEHDR WaveInHdr, int seconds)
{
WAVEFORMATEX pFormat;
pFormat.wFormatTag = WAVE_FORMAT_PCM;
pFormat.nChannels = 1;
pFormat.nSamplesPerSec = 44100;
pFormat.nAvgBytesPerSec = 2 * 44100;
pFormat.nBlockAlign = 2;
pFormat.wBitsPerSample = 16;
pFormat.cbSize = 0;

HWAVEOUT hWaveOut;

if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT))
{
    MessageBoxA(NULL, "Failed to replay", NULL, MB_OK | MB_ICONEXCLAMATION );
}

waveOutWrite(hWaveOut, &WaveInHdr, sizeof(WaveInHdr)); // Playing the data
Sleep(seconds * 1000); //Sleep for as long as there was recorded
 }

int main()
{
PlayRecord(StartRecord(3), 3);
return 0;
}

Whats wrong with the code? Why doesnt it work ? I cant seem to hear anything...

Also, is there an option to record the microphone, instead of X seconds, to record it for example untill there is no input from the microphone (for example - start recording it, I'm saying a word into the microphone, and when theres a silence for a second or two it stops recording or something?)

Thanks!


回答1:


Re: recording until there is no input from the microphone. Yes, prepare several buffers and call waveInAddBuffer with each of them before you WaveInStart. WaveIn will continuously and sequentially fill the buffers and return them to you as they are filled. You will need to use one of the notifications provided by WaveIn to know when a buffer has been filled. Examine the buffer data to decide when to stop. If you want to keep going then give each filled buffer back to WaveIn and it will keep filling them as long as you want.



来源:https://stackoverflow.com/questions/21741194/trying-to-write-functions-that-record-and-play-sound-through-winapi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!