本人应用场景:播放采集设备输出的PCM音频,参考了两种网上实现方法,接口做了些调整,因为播放的音频属性经常需要改变,在播放初始化函数Start传入WAVEFORMATEX参数,这样支持的播放音频种类多,经测试,均能正常播放,使用方法:
CViWavePlay* m_pWavPlay;
m_pWavPlay = new CViWavePlay;
m_pWavPlay->Start(PWAVEFORMATEX(pbFormat));
m_pWavPlay->PlayAudio((char*)pPData->m_pData,pPData->m_nData);
m_pWavPlay->Stop();
Start函数参数WAVEFORMATEX设置方法:
参见头文件的定义:
typedef struct tWAVEFORMATEX
{
WORD wFormatTag; /* format type */// 波形声音的格式,本人此处设置为 WAVE_FORMAT_PCM
WORD nChannels; /* number of channels (i.e. mono, stereo...) *///音频文件的通道数量,单声道为1,立体声为2.
DWORD nSamplesPerSec; /* sample rate *///样本采样率,对于 WAVE_FORMAT_PCM通常为8.0 kHz, 11.025 kHz, 22.05 kHz和44.1 kHz
DWORD nAvgBytesPerSec; /* for buffer estimation */
WORD nBlockAlign; /* block size of data */
WORD wBitsPerSample; /* Number of bits per sample of mono data *//每个样本的BIT数目,一般为16
WORD cbSize; /* The count in bytes of the size of// 额外信息的大小,以字节为单位,添加在WAVEFORMATEX的结尾。如果不需要额外的信息,此值必为0
extra information (after cbSize) */
} WAVEFORMATEX;
典型设置示例:
WAVEFORMATEX _wfx;
_wfx.nSamplesPerSec = 44100; /* sample rate */
_wfx.wBitsPerSample = 16; /* sample size */
_wfx.nChannels = 2; /* channels */
_wfx.cbSize = 0; /* size of _extra_ info */
_wfx.wFormatTag = WAVE_FORMAT_PCM;
_wfx.nBlockAlign = (_wfx.wBitsPerSample * _wfx.nChannels) >> 3;
_wfx.nAvgBytesPerSec = _wfx.nBlockAlign * _wfx.nSamplesPerSec;
m_pWavPlay->Start(&_wfx);
实现方法一的头文件:
M_Critical_Section 是自用封装好的线程锁,可用afxmt.h中的CCriticalSection来代替
#ifndef _WAVEPLAY_4FR567H6_H_
#define _WAVEPLAY_4FR567H6_H_
#include <mmsystem.h>
#include "mthread.h"
//音频播放
class CViWavePlay
{
public:
CViWavePlay();
~CViWavePlay();
public:
BOOL Start(PWAVEFORMATEX pWaveformat);
BOOL PlayAudio(char* buf,unsigned int nSize);
void Stop();
public:
UINT GetDeviceNum();
WAVEOUTCAPS* GetDeviceCap();
private:
static DWORD WINAPI ThreadProc(LPVOID lpParameter);
inline int GetBufferNum();
inline void AddBuffer();
inline void SubBuffer();
BOOL Open(PWAVEFORMATEX pWaveformat);
void Close();
BOOL StartThread();
void StopThread();
private:
WAVEOUTCAPS m_waveCaps;
BOOL m_bDevOpen;
BOOL m_bThread;
HWAVEOUT m_hWave;
HANDLE m_hThread;
DWORD m_ThreadID;
WAVEFORMATEX m_Waveformat;
M_Critical_Section m_Lock;
int m_BufferQueue;
};
#endi