CWaveRecorder代码

/*
 *	模块: Pingbu's Windows Wave Recorder
 *	版本: 1.0.110613
 *	作者: pingbu@iflytek.com
 *
 *	版权: 您可以任意使用和分发本模块,但作任何修改将导致不得再冠以本模块的名称,
 *	      否则将视为对作者的侵权。
 */

#pragma once

#include <assert.h>
#include <tchar.h>
#include <windows.h>
#include <mmsystem.h>

#ifdef _WIN32_WCE
	#pragma comment(lib, "coredll")
#else
	#pragma comment(lib, "winmm")
#endif

#define WM_MY_MESSAGE_CLOSEPCM (WM_USER + 1)

#define REC_BUF_COUNT	4
#define REC_BUF_SIZE	8192

struct IWaveRecordListener
{
	virtual void InWaveRecordData(int nID, const void* pData, int cbSize) = 0;
};

class CWaveRecorder
{
public:
    HWND m_hWnd;

private:
#ifdef _DEBUG
	DWORD m_dwThreadID;
#endif

	IWaveRecordListener* m_pListener;
	int m_nID;
	HWAVEIN m_hWaveIn;
	WAVEHDR m_tWaveHdr[REC_BUF_COUNT];
	char m_pBuffer[REC_BUF_COUNT][REC_BUF_SIZE];
	int m_nBusyBuf;

	static LRESULT CALLBACK __WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
	{
		if (uMsg == MM_WIM_DATA)
		{
			CWaveRecorder* pThis = (CWaveRecorder*)GetWindowLong(hWnd, GWL_USERDATA);
			if (pThis->m_nBusyBuf)
			{
				--pThis->m_nBusyBuf;
			}
			else
			{
				LPWAVEHDR lpwvhdr = (LPWAVEHDR)lParam;
				pThis->m_pListener->InWaveRecordData(pThis->m_nID, lpwvhdr->lpData, lpwvhdr->dwBytesRecorded);
				waveInAddBuffer(pThis->m_hWaveIn, lpwvhdr, sizeof(WAVEHDR));
			}
			return 0;
        } else if(uMsg == WM_MY_MESSAGE_CLOSEPCM){
            CWaveRecorder* pThis = (CWaveRecorder*)GetWindowLong(hWnd, GWL_USERDATA);
            pThis->Close();
            return 0;
        }

		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}

public:
	CWaveRecorder(IWaveRecordListener* pListener, HMODULE hModule = NULL, int nID = 0)
	{
#ifdef _DEBUG
		m_dwThreadID = GetCurrentThreadId();
#endif

		assert(pListener);
		m_pListener = pListener;
		m_nID = nID;

		WNDCLASS wc;
		ZeroMemory(&wc, sizeof(wc));
		wc.lpszClassName = _T("WaveRecorder");
		wc.hInstance = hModule ? hModule : GetModuleHandle(NULL);
		wc.lpfnWndProc = __WndProc;
		RegisterClass(&wc);
		TCHAR szWndName[32] = {0};
		_stprintf(szWndName, TEXT("%d"), nID);

		m_hWnd = CreateWindow(wc.lpszClassName, szWndName, WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL, wc.hInstance, NULL);
		assert(m_hWnd);
		SetWindowLong(m_hWnd, GWL_USERDATA, (LONG)this);

		m_hWaveIn = NULL;
	}

	~CWaveRecorder()
	{
		assert(GetCurrentThreadId() == m_dwThreadID);
		assert(!m_hWaveIn);
		DestroyWindow(m_hWnd);
	}

	bool Open(LPWAVEFORMATEX pwfx)
	{
		assert(GetCurrentThreadId() == m_dwThreadID);
		assert(!m_hWaveIn);

		int i = waveInOpen(&m_hWaveIn, WAVE_MAPPER, pwfx, (DWORD)m_hWnd, (DWORD)this, CALLBACK_WINDOW);
		//waveInOpen(&m_hWaveIn, 1, pwfx, (DWORD)m_hWnd, (DWORD)this, CALLBACK_WINDOW);
		if (!m_hWaveIn)
			return false;

		ZeroMemory(m_tWaveHdr, sizeof(m_tWaveHdr));
		for (int i = 0; i < REC_BUF_COUNT; ++i)
		{
			m_tWaveHdr[i].lpData = m_pBuffer[i];
			m_tWaveHdr[i].dwBufferLength = REC_BUF_SIZE;
			m_tWaveHdr[i].dwBytesRecorded = 0;
			m_tWaveHdr[i].dwUser = 0;
			m_tWaveHdr[i].dwFlags = 0;
			m_tWaveHdr[i].dwLoops = 1;
			m_tWaveHdr[i].lpNext = NULL;
			m_tWaveHdr[i].reserved = 0;
			waveInPrepareHeader(m_hWaveIn, m_tWaveHdr + i, sizeof(WAVEHDR));
			waveInAddBuffer(m_hWaveIn, m_tWaveHdr + i, sizeof(WAVEHDR));
		}

		m_nBusyBuf = 0;
		waveInStart(m_hWaveIn);
		return true;
	}

	bool OpenPCM(DWORD nSamplesPerSec, WORD nChannels = 1, WORD wBitsPerSample = 16)
	{
		WAVEFORMATEX wfx;
		wfx.wFormatTag = WAVE_FORMAT_PCM;
		wfx.cbSize = 0;
		wfx.nSamplesPerSec = nSamplesPerSec;
		wfx.nChannels = nChannels;
		wfx.wBitsPerSample = wBitsPerSample;
		wfx.nBlockAlign = (wBitsPerSample + 7) / 8 * nChannels;
		wfx.nAvgBytesPerSec = wfx.nBlockAlign * nSamplesPerSec;
		return Open(&wfx);
	}

	void Close()
	{
		assert(GetCurrentThreadId() == m_dwThreadID);

		if (m_hWaveIn)
		{
			m_nBusyBuf = REC_BUF_COUNT;

			waveInReset(m_hWaveIn);
		

			while (m_nBusyBuf)
			{
				MSG msg;
				GetMessage(&msg, m_hWnd, MM_WIM_DATA, MM_WIM_DATA);
				DispatchMessage(&msg);
			}

			for (int i = 0; i < REC_BUF_COUNT; ++i)
				waveInUnprepareHeader(m_hWaveIn, m_tWaveHdr + i, sizeof(WAVEHDR));
			
			waveInClose(m_hWaveIn);
			m_hWaveIn = NULL;
		}
	}
};

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值