This article introduces the method of obtaining audio streams using the examples. The specific steps are as follows:
1. First, you need to include the following reference object
#include <> #include "" #pragma comment(lib, "")
2. 7 functions are required to obtain audio
1. waveInGetNumDevs: Returns the number of waveform sound input devices ready in the system
UINT waveInGetNumDevs(VOID);
2. waveInGetDevCaps: Check the characteristics of the specified waveform input device
MMRESULT waveInGetDevCaps( UINT_PTR uDeviceID, LPWAVEINCAPS pwic, UINT cbwic ); //uDeviceID The audio input device identifier, which can also be a handle to an open audio input device.// I personally believe that if multiple devices were obtained in the previous step, each device can be identified with an index.// //pwic A pointer to the WAVEINCAPS structure, containing the audio characteristics of the device.// //Cbwic WAVEINCAPS structure size, just use sizeof.// //The result of the execution of the MMRESULT function// MMSYSERR_NOERROR indicates successful execution// MMSYSERR_BADDEVICEID Index goes beyond the bounds// MMSYSERR_NODRIVER No ready device// MMSYSERR_NOMEM cannot allocate or lock memory
Introducing the meaning of WAVEINCAPS structure:
typedef struct { WORD wMid; //Driver ID defined by audio equipment manufacturer WORD wPid; //Product identification of audio input device MMVERSION vDriverVersion; //Driver version number TCHAR szPname[MAXPNAMELEN];//Manufacturer name DWORD dwFormats; //Supported formats, see MSDN WORD wChannels; // Supported number of channels WORD wReserved1; //Reserve parameters} WAVEINCAPS;
3. waveInOpen: Open the specified audio input device and record it
MMRESULT waveInOpen( LPHWAVEIN phwi, //Receive the pointer of the HWAVEIN structure identified by the open audio input device UINT_PTR uDeviceID, //Specify a device ID that needs to be turned on. You can use WAVE_MAPPER to select a device that records in the specified recording format LPWAVEFORMATEX pwfx, // A required format for recording the WAVEFORMATEX structure pointer DWORD_PTR dwCallback, //Point to a callback function, event handle, window handle, thread identifier to handle recording events. DWORD_PTR dwCallbackInstance, // Parameters passed to the callback mechanism DWORD fdwOpen //Open the device method ID, specify the type of callback. See CSDN);
Introducing the meaning of WAVEFORMATEX structure:
typedef struct { WORD wFormatTag; //Format of waveform sound, mono dual channel uses WAVE_FORMAT_PCM. When included in the WAVEFORMATEXTENSIBLE structure, use WAVE_FORMAT_EXTENSIBLE. WORD nChannels; //Number of channels DWORD nSamplesPerSec; //Sampling rate.WFormatTag is WAVE_FORMAT_PCM, there are 8.0kHz, 11.025kHz, 22.05kHz, and 44.1kHz. DWORD nAvgBytesPerSec; //Number of sampled bytes per second. Calculated by nSamplesPerSec * nChannels * wBitsPerSample / 8 WORD nBlockAlign; //The number of bytes per sample. Calculated by nChannels * wBitsPerSample / 8 WORD wBitsPerSample; //The number of sample bits.wFormatTag is WAVE_FORMAT_PCM, it is 8 or 16 WORD cbSize; //WFormatTag is WAVE_FORMAT_PCM, this parameter is ignored} WAVEFORMATEX;
Introduce the dwCallback callback function format:
void CALLBACK waveInProc( HWAVEIN hwi, //The device handle of this function is called back UINT uMsg, //Waveform sound input information, marking off (WIM_CLOSE), buffer full (WIM_DATA), on (WIM_OPEN). DWORD_PTR dwInstance, //The data specified by the user in waveInOpen DWORD_PTR dwParam1, //(LPWAVEHDR)dwParam1, the buffer specified by the user DWORD_PTR dwParam2 );
4. waveInPrepareHeader: Prepare a buffer for the audio input device
MMRESULT waveInPrepareHeader( HWAVEIN hwi, //Audio input device handle LPWAVEHDR pwh,//Pointer to WAVEHDR structure identifying the prepared buffer UINT cbwh //The size of the WAVEHDR structure is used, just use sizeof);
Introducing the WAVEHDR structure:
typedef struct wavehdr_tag { LPSTR lpData; //Point to the buffer of waveform format DWORD dwBufferLength; //Buffer size DWORD dwBytesRecorded; //How much data is currently stored DWORD_PTR dwUser; //User Data DWORD dwFlags; //Information provided for the buffer, use WHDR_PREPARED in the waveInPrepareHeader function DWORD dwLoops; //Use when output, identify the number of playbacks struct wavehdr_tag * lpNext;//reserved DWORD_PTR reserved; //reserved } WAVEHDR, *LPWAVEHDR;
5. waveInAddBuffer: Send the buffer to the device. If the buffer is full, it will not work. (The parameters are the same as above)
MMRESULT waveInAddBuffer( HWAVEIN hwi, LPWAVEHDR pwh, UINT cbwh );
6. waveInStart: Start recording
MMRESULT waveInStart( HWAVEIN hwi // Device handle);
7. waveInClose: Turn off the device
MRESULT waveInClose( HWAVEIN hwi // Device handle);
3. The complete example code is as follows:
//document#include <> #include <> #include "" #pragma comment(lib, "") void PlayMusi(); void WaveInitFormat(LPWAVEFORMATEX m_WaveFormat, WORD nCh,DWORD nSampleRate,WORD BitsPerSample); DWORD CALLBACK MicCallback(HWAVEIN hwavein, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2); void RecordWave(); void main() { //PlayMusi(); RecordWave(); while(1); } void RecordWave() { int count = waveInGetNumDevs();//1 printf("\nNumber of audio inputs: %d\n",count); WAVEINCAPS waveIncaps; MMRESULT mmResult = waveInGetDevCaps(0,&waveIncaps,sizeof(WAVEINCAPS));//2 printf("\nAudio input device: %s\n",); if(MMSYSERR_NOERROR==mmResult) { HWAVEIN phwi; WAVEFORMATEX pwfx; WaveInitFormat(&pwfx,1,8000,8); printf("\nRequest to turn on the audio input device"); printf("\nSampling parameters: Mono 8kHz 8bit\n"); mmResult=waveInOpen(&phwi,WAVE_MAPPER,&pwfx,(DWORD)(MicCallback),NULL,CALLBACK_FUNCTION);//3 if(MMSYSERR_NOERROR==mmResult) { WAVEHDR pwh1; char buffer1[10240]; =buffer1; =10240; =1; =0; mmResult=waveInPrepareHeader(phwi,&pwh1,sizeof(WAVEHDR));//4 printf("\nPrepare buffer 1"); WAVEHDR pwh2; char buffer2[10240]; =buffer2; =10240; =2; =0; mmResult=waveInPrepareHeader(phwi,&pwh2,sizeof(WAVEHDR));//4 printf("\nPrepare buffer 2\n"); if(MMSYSERR_NOERROR==mmResult) { mmResult=waveInAddBuffer(phwi,&pwh1,sizeof(WAVEHDR));//5 printf("\nAdd buffer 1 to audio input device"); mmResult=waveInAddBuffer(phwi,&pwh2,sizeof(WAVEHDR));//5 printf("\nAdd buffer 2 to audio input device\n"); if(MMSYSERR_NOERROR==mmResult) { mmResult=waveInStart(phwi);//6 printf("\nRequest to start recording\n"); } } } } } DWORD CALLBACK MicCallback(HWAVEIN hwavein, UINT uMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2) { switch(uMsg) { case WIM_OPEN: printf("\nThe device is turned on...\n"); break; case WIM_DATA: printf("\nBuffer %d is full...\n",((LPWAVEHDR)dwParam1)->dwUser); waveInAddBuffer (hwavein, (LPWAVEHDR)dwParam1, sizeof (WAVEHDR)) ; break; case WIM_CLOSE: printf("\nThe device has been turned off...\n"); break; default: break; } return 0; } void WaveInitFormat(LPWAVEFORMATEX m_WaveFormat, WORD nCh,DWORD nSampleRate,WORD BitsPerSample) { m_WaveFormat->wFormatTag = WAVE_FORMAT_PCM; m_WaveFormat->nChannels = nCh; m_WaveFormat->nSamplesPerSec = nSampleRate; m_WaveFormat->nAvgBytesPerSec = nSampleRate * nCh * BitsPerSample/8; m_WaveFormat->nBlockAlign = m_WaveFormat->nChannels * BitsPerSample/8; m_WaveFormat->wBitsPerSample = BitsPerSample; m_WaveFormat->cbSize = 0; } void PlayMusi() { int error = mciSendString("open C:\\Users\\Angel\\Desktop\\How much love can I do again.mp3 alias myDivece", NULL, 0, NULL); if (error == 0) { mciSendString("play myDivece", NULL, 0, NULL); //Play } }