/*http://sdr-reu.wikispaces.com/file/view/SoundIn.cFile to read sound from sound card and record it to a file in PCM format.*/#include#include #include #include #pragma comment(lib, "winmm.lib")#define IN_BUFFERS_NUMBER 4 //开辟三个数据缓冲区#define REC_STATUS_STARTING_RECORD 1#define REC_STATUS_RECORDING 2#define REC_STATUS_ALL_DONE -2 //录音完成#define REC_STATUS_FINISHING -1 //即将完成#define REC_STATUS_FAIL -3#define SIZE_OF_WAVEHDR 32 //wave头大小//函数void FreeBuffers(WAVEHDR * buffers);DWORD WINAPI waveInProc(LPVOID threadControls);typedef struct soundInDataAndControls{ WAVEHDR buffers[IN_BUFFERS_NUMBER]; //开辟三个数据缓冲区 int recordingStatus; //录音状态 HWAVEIN inWaveDevice; int buffers_left; //可用内存数目}SoundThreadInfo;WAVEFORMATEX sampleFormat; //全局变量char * outfilename;HMMIO m_hFile;MMCKINFO m_MMCKInfoData;MMCKINFO m_MMCKInfoParent;MMCKINFO m_MMCKInfoChild;int main(){ MMRESULT errorResult = 0 ; SoundThreadInfo soundIn; HANDLE inWaveThreadHandle; //线程 int x = 0; //计数器 soundIn.recordingStatus = 0; //设置录音状态 soundIn.buffers_left = IN_BUFFERS_NUMBER; //设置预期缓冲数量 outfilename = ".\\1.wav"; inWaveThreadHandle = CreateThread(0 ,0,(LPTHREAD_START_ROUTINE)waveInProc,/*参数*/ &soundIn, 0, &errorResult); //创建线程 if(!inWaveThreadHandle) { printf("Can't create sound in thread! -- %08X\n",GetLastError()); return 0; } CloseHandle(inWaveThreadHandle); //关闭线程 for (x = 0; x > 3); sampleFormat.nAvgBytesPerSec = sampleFormat.nSamplesPerSec * sampleFormat.nBlockAlign; if(!CreateWaveFile()) { return getchar(); } //分配 memory sound in buffers. for(x = 0; x < IN_BUFFERS_NUMBER; x++) //this loop is not need after testing { //can be replaced with hard coded buffer allocation //clear waveheaders ZeroMemory(&soundIn.buffers[x],SIZE_OF_WAVEHDR); soundIn.buffers[x].dwBufferLength = sampleFormat.nAvgBytesPerSec << 2; //内存大小估计一块 soundIn.buffers[x].dwFlags = 0; soundIn.buffers[x].lpData = (char *) VirtualAlloc(NULL, soundIn.buffers[0].dwBufferLength, MEM_COMMIT, PAGE_READWRITE); //申请内存 if(soundIn.buffers[x].lpData == NULL) { printf("Sound In Buffer number %d failed to get allocate memory.\n",x); for(--x;x;x--) // start 1 down, and while x!=0 x-- { VirtualFree(soundIn.buffers[x].lpData, 0, MEM_RELEASE); //释放内存 } return 0; } else { printf(" %d Buffer Application sucsess\n",x); } } //open wave device errorResult = waveInOpen(&soundIn.inWaveDevice, WAVE_MAPPER, &sampleFormat, (DWORD)errorResult, 0, CALLBACK_THREAD); if(errorResult != MMSYSERR_NOERROR) { FreeBuffers(soundIn.buffers); return getchar(); } // buffers and queue them for(x=0;x dwBytesRecorded); //collect data if(inFORMATION->recordingStatus != 0) //recording not began or stopped只有0 ,-1 -2 三个值 { if(inFORMATION->recordingStatus == REC_STATUS_ALL_DONE) { printf("Possible error recieving WIM_DATA during condition ALL_DONE\n"); break; //time for thread to end } outputlenth = mmioWrite(m_hFile, ((WAVEHDR *) msg.lParam)->lpData,((WAVEHDR *)msg.lParam)->dwBytesRecorded); if(outputlenth == ((WAVEHDR *)msg.lParam)->dwBytesRecorded) { printf("sucsess save data_dwBytesRecorded %d\n",outputlenth); printf("sucsess save data_dwBufferLength %d\n",((WAVEHDR *)msg.lParam)->dwBufferLength); } //was this that last block the user wanted. if(inFORMATION->recordingStatus == REC_STATUS_FINISHING) { //the buffers are each sent back, but not requeue if(--inFORMATION->buffers_left == 0) { inFORMATION->recordingStatus = REC_STATUS_ALL_DONE; } printf("Buffer finished.\n"); continue; } } //if stopped it only requeue s the buffer and continues. //requeue buffer if(!waveInAddBuffer(inFORMATION->inWaveDevice, (WAVEHDR *) msg.lParam, SIZE_OF_WAVEHDR)) { if(!waveInAddBuffer(inFORMATION->inWaveDevice, (WAVEHDR *) msg.lParam, SIZE_OF_WAVEHDR)) { printf("Buffer requeue error.\n"); if(--inFORMATION->buffers_left < 2) { FreeBuffers(inFORMATION->buffers); printf("in requeue error device."); errorResult = waveInClose(inFORMATION->inWaveDevice); if(errorResult) { printf("Can't Close Wave Device!\n"); getchar(); } return 0; inFORMATION->recordingStatus = REC_STATUS_FINISHING; //finishing means takes the queued blocks and no more //in thoery the next block (the last one) that was queue //previously mmioAscend(m_hFile, &m_MMCKInfoChild, 0); mmioAscend(m_hFile, &m_MMCKInfoParent, 0); return -1; } } } } } return 1;}