Before you can start recording, you have to set up the sound card for a few things, such as mono or stereo, sample
rate, bits per sample, etc. The WAVEFORMATEX structure holds all these items. This structure needs to be initialized before
you can open the sound card. Here's a snippet that initializes WAVEFORMATEX:
// Initialize WAVEFORMATEX members: m_WFXInSettings->wFormatTag=WAVE_FORMAT_PCM; m_WFXInSettings->nChannels=1;
m_WFXInSettings->wBitsPerSample=16; m_WFXInSettings->nSamplesPerSec=11025; m_WFXInSettings->nBlockAlign=m_WFXInSettings->nChannels
*(m_WFXInSettings->wBitsPerSample/8); m_WFXInSettings->nAvgBytesPerSec=m_WFXInSettings->nSamplesPerSec*(m_WFXInSettings->nBlockAlign);
m_WFXInSettings->cbSize=0;
WAVEHDR structure defines a block of memory for waveform-audio input data. It holds a pointer to the data array used,
the length of the data array, bytes used, among other things. Create and initialize an object of this structure after
you do the WAVEFORMATEX structure. Here's a snippet that initializes WAVEHDR :
// allocate input data buffers: m_pInputBuffer[i]=NULL; if( (m_pInputBuffer[i]=new WAVEHDR[sizeof(WAVEHDR)] )==NULL)
{MessageBox("MEMORY ERROR","INPUTBUFFER",MB_OK);} m_pInputBuffer->dwBufferLength=4096;
m_pInputBuffer->dwFlags=0; m_pInputBuffer->dwUser=NULL; m_pInputBuffer->dwBytesRecorded=NULL; if
( ( m_pInputBuffer->lpData=newchar [ m_InBufferSize ] ) == NULL ) MessageBox("MEMORY ERROR","DATA BUFFERS",MB_OK);
After the structures are ceated, use the waveInOpen command to initialize the sound card. In this command you also specify
what callback function or event the sound card notifies when it's done. Among other things, the waveInOpen command needs
a device ID, (use WAVEMAPPER to use the default sound card), a pointer to the WAVEFORMATEX object, a pointer to the call
back function or event, a flag indicating whether a callback function or event is being used. Here's a snippet openning
the sound card:
// Open sound card for input: m_ErrorCode = waveInOpen( m_hwvin, // handle for opened device
WAVE_MAPPER, // default audio input device m_WFXInSettings, // address of WAVEFORMAT structure
(DWORD) &WaveInCallback, //address of callback function (DWORD) this, // app who owns callback
CALLBACK_FUNCTION // call back type ); // Check for error in waveInOpen: if (m_ErrorCode !=
0) { MessageBox("OPEN FAILED","waveInOpen",MB_OK); }
Once the sound card is open, prepare the data buffers using the waveInPrepareHeader command, passing it the handle to
the sound card returned from the waveInOpen command, a pointer to the WAVEHDR object and the size of the WAVEHDR object.
Then assign the buffer to the sound card with the command waveInAddBuffer, passing it the handle to the sound card returned
from the waveInOpen command, a pointer to the WAVEHDR object and the size of the WAVEHDR object. Here's a snippet preparing
& adding the buffer :
// prepare headers: if ( ( m_ErrorCode=waveInPrepareHeader ( *m_hwvin,m_pInputBuffer, sizeof *m_pInputBuffer ) ) !=NULL
) MessageBox("Prep hdr error","PREP HDRS",MB_OK); // add buffers: if ( ( m_ErrorCode=waveInAddBuffer
( *m_hwvin,m_pInputBuffer, sizeof *m_pInputBuffer ) ) != NULL ) MessageBox("Add buffer error","ADD BUFFERS",MB_OK);
Don't forget to add your call back function oer event. These snippets used a callback function the set an event that the app
is waiting for. Here it is:
// ***** GLOBAL callback function for sound card: void CALLBACK WaveInCallback(HWAVEIN m_hwvin,UINT uMsg, CApp* pCApp,
DWORD dwParam1, DWORD dwParam2) { if (uMsg==MM_WIM_DATA) // message from Sound card m_Event.SetEvent();
// signal waiting thread to continue }
Here's a snippet of the InRead function that's waiting on the sound card to set the call back event :
CSingleLock SyncOb(&m_Event); // Create Sync Object // wait for mmsystem to fill new buffer SyncOb.Lock( 5000);
// wait for sound card to set event // read data out of WAVEHDR data array SyncOb.Unlock(); // reset event
All's that left is to start thesound card recording, using waveInOpenStart, passing the sound card handle. Here's a snippet
starting the sound card :
// start input capture to buffer: if ( ( m_ErrorCode=waveInStart ( *m_hwvin ) ) != NULL ) MessageBox("Sound card
error" , "SND CARD START" , MB_OK) ;
|