www.pudn.com > audioTest.rar > WaveIn.h
// WaveIn.h: interface for the CWaveIn class. //CWaveIn is the base class for recording (record, pause, continue, stop) and making a new CWave from the recording. In future development, //we will add a virtual function to allow some work on new buffers during recording. ////////////////////////////////////////////////////////////////////// #if !defined(AFX_WAVEIN_H__7CA0A7A7_58D6_486F_95B4_3C3B8B842333__INCLUDED_) #define AFX_WAVEIN_H__7CA0A7A7_58D6_486F_95B4_3C3B8B842333__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 //////////////////////////////////// #include "Wave.h" #include "WaveDevice.h" #includeusing namespace std; //#include "TestAudioDlg.h" /////////////////////////////////// void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance, DWORD dwParam1,DWORD dwParam2); //////////////////////////////////////////////////// #ifdef WAVE_IN_BUFFER_SIZE #undef WAVE_IN_BUFFER_SIZE #endif #define WAVE_IN_BUFFER_SIZE 4096 #define NUMWAVEINHDR 4 //录音时buffer的个数 ////////////////////////////////////////////////////// #define WM_MSG_1 (WM_USER + 100) //发送消息参数的结构 typedef struct wimm_data { int *data_buffer; DWORD len; DWORD deviceNo; }wimm_data; class CWaveIn :public CWnd { //回调函数,当buffer满时的系统消息调用这个函数处理buffer //I got some samples code for recording and playing wave buffers, //but they almost all had memory leaks. They also all use messages, threads or events. //So, as it was not as easy as I expected for my own use, I decide to make my own classes, //using the callback method. //The first problem was for playing buffers: there were noises and interruptions, //so I tried to use double buffering, //and finally triple buffering (NUMWAVEOUTHDR parameter). //So I prepare 3 WAVEHDR structure from a class member buffer (see AddNewHeader() and Play() ) //and the callback function takes care of adding a new one //(function of the index to be prepared) and un-prepare the completed one. friend void CALLBACK waveInProc(HWAVEIN hwi,UINT uMsg,DWORD dwInstance, DWORD dwParam1,DWORD dwParam2); public: void regist(LPVOID wnd); CString GetError() const; DWORD GetPosition(); bool IsRecording();// Return true if current instance is recording. CWave MakeWave();// Build a wave from instance buffer and MS Windows wave format. bool Close(); bool Continue(); bool Open(); bool Pause(); //As recommended in MSDN, for playing or recording, //make a waveXUnprepareHeader, and then free the waveheader.lpData buffer. bool Record(UINT nTaille = /*4096*/1024); // Start recording. Return true if no problem occur. bool Stop(); void SetDevice(const CWaveDevice &aDevice); void SetWaveFormat(WAVEFORMATEX tagFormat); CWaveIn(); CWaveIn(WAVEFORMATEX tagFormat,const CWaveDevice &aDevice); virtual ~CWaveIn(); private: bool AddNewBuffer(WAVEHDR *pWaveHdr); //自己添加的缓存数据处理函数 void BufferDill(WAVEHDR *pWaveHdr,DWORD deviceNo); bool AddNewHeader(HWAVEIN hwi); void FreeListOfBuffer(); DWORD GetNumSamples(); void FreeListOfHeader(); void InitListOfHeader(); bool IsError(MMRESULT nResult); //Another bug arose as I worked on recording: //I could not reset the device. //As waveOutReset sends a MM_WOM_DONE message to the callback function, //the AddNewHeader don't have to be execute. //I introduced the ResetRequired() function to test if the reset has been requested. bool ResetRequired(CWaveIn *pWaveIn); private: bool m_bResetRequired; HWAVEIN m_hWaveIn; //Recording is almost the same process as playing, but you have to store recorded buffers. //So I use a PtrList (see AddNewBuffer()). CPtrList m_listOfBuffer; UINT m_nError; int m_nIndexWaveHdr; UINT m_nBufferSize; WAVEHDR m_tagWaveHdr[NUMWAVEINHDR]; CWave m_wave; CWaveDevice m_waveDevice; CWinThread* m_wnd; }; #endif // !defined(AFX_WAVEIN_H__7CA0A7A7_58D6_486F_95B4_3C3B8B842333__INCLUDED_)