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);
m_Record.Open();
m_Play.PrepareBuffer(10);
m_Play.Open();
if (m_Record.IsOpen())
{
m_Record.Record();
}
m_Play.CopyBuffer(m_Record.buffer, 10);
if (m_Play.IsOpen())
{
m_Play.Play();
}
Enjoy!