Voice Recording/Playing back using simple classes






4.62/5 (35 votes)
Apr 17, 2005
1 min read

485288

12252
This article introduces some useful classes that wrap the WAVE APIs.
Introduction
Most of us are familiar with at least one multimedia recording software. Windows has one of the simplest ones: Sound Recorder. In this article I want to introduce some simple but useful classes for recording/playing back of voice that wrap the WAVE APIs.
WAVE APIs
Here is the list of all the Wave APIs that I have used:
Recording
waveInOpen |
Open the Wave device for recording. |
waveInPrepareHeader |
Prepare the Wave header for recording. |
waveInAddBuffer |
Add buffer |
waveInStart |
Start recording. Recorded data will be saved in a specified buffer. |
waveInUnprepareHeader |
After finishing the record process, should un-prepare Wave header. |
waveInClose |
Close the recording device. |
Playing
waveOutOpen |
Open the Wave device for playing. |
waveOutPrepareHeader |
Prepare the Wave header for playing. |
waveOutWrite |
Play the buffer. |
waveOutUnprepareHeader |
Un-prepare the Wave header. |
waveOutClose |
Close the playing device. |
As you can see, working with these APIs are straightforward but if you want to skip them and simply do a copy/paste code in your project, my classes are for you.
Here is the definition of the classes:
class CVoiceBase { public: CString m_result; MMRESULT res; enum { SPS_8K=8000, SPS_11K=11025, SPS_22K=22050, SPS_44K=44100 }; enum { CH_MONO=1, CH_STEREO=2 }; char* buffer; WAVEHDR WaveHeader; WAVEFORMATEX PCMfmt; void SetFormat(DWORD nSamplesPerSec, WORD wBitsPerSample,WORD nChannels); BOOL CopyBuffer(LPVOID lpBuffer, DWORD ntime); CString GetLastError(); void GetMMResult(MMRESULT res); void DestroyBuffer(); BOOL PrepareBuffer(DWORD ntime); CVoiceBase(); virtual ~CVoiceBase(); }; class CVoiceRecording : public CVoiceBase { public: void RecordFinished(); BOOL IsOpen(); BOOL Close(); BOOL Open(); BOOL Record(); HWAVEIN hWaveIn; CVoiceRecording(); virtual ~CVoiceRecording(); }; class CVoicePlaying : public CVoiceBase { public: void PlayFinished(); BOOL IsOpen(); BOOL Close(); BOOL Open(); BOOL Play(); HWAVEOUT hWaveOut; CVoicePlaying(); virtual ~CVoicePlaying(); };
Also, for notifying of events, such as finishing recording/playing, I have used two callback functions:
BOOL CALLBACK VoiceWaveInProc(HWAVEIN hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 ); BOOL CALLBACK VoiceWaveOutProc(HWAVEOUT hwi, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 );
Example
Just declare two variables of type CVoiceRecording
and CVoicePlaying
. Use SetFormat
, PrepareBuffer
, Open
and Record
or Play
member functions to work with them:
CVoiceRecording m_Record; CVoicePlaying m_Play; m_Record.PrepareBuffer(10); //prepare buffer for recording 10 seconds. m_Record.Open(); m_Play.PrepareBuffer(10); //prepare buffer for playing of 10 seconds of data m_Play.Open(); if (m_Record.IsOpen()) { m_Record.Record(); } //after finishing the record scenario, //play the buffer, first copy recorded buffer to m_Play buffer m_Play.CopyBuffer(m_Record.buffer, 10); if (m_Play.IsOpen()) { m_Play.Play(); }
Enjoy!