我用waveOut API写了一个播放声音的代码。播放声音没有问题,但是如果想在声音播放过程中和声音播放结束后关闭设备就会出问题。具体表现为waveOutReset()和waveOutClose()函数执行的过程中死机。
下面是我的源代码,请大侠多多指教。
class CWaveOut
{
public:
CWaveOut();
virtual ~CWaveOut();public:
long m_nBufferLen;
WORD m_nFormatTag;
WORD m_nBlockAlign;
DWORD m_nAvgBytesPerSec;
WORD m_nChannels;
WORD m_nBitsPerSample;
DWORD m_nSamplesPerSec; DWORD m_ThreadID; UINT m_nDeviceID;
UINT m_nNumOfDev; CString m_strPath;
BOOL m_bPause;
void SetOutputDevice( const CString str);
void GetFileInfo();
void GetDeviceInfo();
void Open();
void Play();
void Close();
void Pause();};#include "stdafx.h"
#include "WaveOut.h"
#include "mmsystem.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
FILE *Outfp = NULL;
BYTE *pBufferOut[2];
long nBuffer = 0;
long nBufferLenOut;
long nBufferNoOut = 0;
int i = 0;WAVEFORMATEX waveformatOut;
WAVEHDR wavehdrOut[2];
MMRESULT OutResult;
HWAVEOUT hwo;void AddBuffer()
{
int nSize;
memset( pBufferOut[nBufferNoOut], 0, nBufferLenOut );
nSize = fread( pBufferOut[nBufferNoOut], sizeof(char), nBufferLenOut, Outfp ); wavehdrOut[nBufferNoOut].lpData = (char *)pBufferOut[ nBufferNoOut ];
wavehdrOut[nBufferNoOut].dwBufferLength = nSize;
wavehdrOut[nBufferNoOut].dwFlags = 0; waveOutPrepareHeader( hwo, &wavehdrOut[nBufferNoOut], sizeof(WAVEHDR) ); nBuffer++;
}void CALLBACK WaveOutProc( HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, WORD dwParam2 )
{ int end = feof(Outfp);
switch( uMsg )
{
case WOM_DONE:
nBuffer--; OutResult = waveOutUnprepareHeader( hwo, &wavehdrOut[nBufferNoOut], sizeof(WAVEHDR) );
if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Unprepare wave header error!");
return;
}
nBufferNoOut++;
nBufferNoOut = nBufferNoOut % 2;
if( !end )
{
i++;
TRACE( "turn: %d\tEnd: %d\n", i, end ) ;
AddBuffer();
waveOutWrite( hwo, &wavehdrOut[nBufferNoOut], sizeof(WAVEHDR) );
}
else
{
fclose(Outfp); nBufferNoOut = 0;
nBuffer = 0;
i = 0; OutResult = waveOutReset( hwo );
hwo = NULL;
if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Close wave device error!");
return;
}
}
break; case WOM_CLOSE:
TRACE( "wavefile closed!\n" );
break; default:
break;
}
}
CWaveOut::CWaveOut()
{
m_nDeviceID = 0;
m_bPause = FALSE;
m_ThreadID = ::GetCurrentThreadId();
}CWaveOut::~CWaveOut()
{}void CWaveOut::OnMM_WOM_DONE( UINT wParam, long lParam)
{
}void CWaveOut::GetFileInfo()
{
char ctmp; if( Outfp )
fclose( Outfp );
Outfp = fopen( (LPCTSTR)m_strPath, "rb" );
if( !Outfp )
{
AfxMessageBox("Can't open specified file!");
return;
}
else
{
fseek( Outfp, 0, SEEK_SET );
for( int i = 0; i < 22; i++ )
fread( &ctmp, sizeof(char), 1, Outfp ); fread( &m_nChannels, sizeof(WORD), 1, Outfp );
fread( &m_nSamplesPerSec, sizeof(DWORD), 1, Outfp );
fread( &m_nAvgBytesPerSec, sizeof( DWORD), 1, Outfp );
fread( &m_nBlockAlign, sizeof(WORD), 1, Outfp );
fread( &m_nBitsPerSample, sizeof(WORD), 1, Outfp ); for( i = 0; i < 8; i++ )
fread( &ctmp, sizeof(char), 1, Outfp );
}
}void CWaveOut::GetDeviceInfo()
{
m_nNumOfDev = waveOutGetNumDevs( );
if( m_nNumOfDev == 0 )
{
AfxMessageBox( "No device is avaliable!" );
return;
}
}void CWaveOut::SetOutputDevice(const CString str)
{
WAVEOUTCAPS woc;
int i = 0; CString *pStr = new CString [m_nNumOfDev]; for( i = 0; i < m_nNumOfDev; i++ )
{
waveOutGetDevCaps( i, &woc, sizeof(WAVEOUTCAPS) );
pStr[i] = woc.szPname;
} i = 0;
while( pStr[i] != str && i < m_nNumOfDev ) i++;
if( i >= m_nNumOfDev )
{
AfxMessageBox( "The inputed device name is wrong!" );
return;
}
else
m_nDeviceID = i;
}void CWaveOut::Open()
{
m_nBufferLen = (long)( m_nAvgBytesPerSec * 5 );
nBufferLenOut = m_nBufferLen;
GetDeviceInfo(); waveformatOut.wFormatTag = WAVE_FORMAT_PCM;
waveformatOut.nAvgBytesPerSec = m_nAvgBytesPerSec;
waveformatOut.nBlockAlign = m_nBlockAlign;
waveformatOut.nChannels = m_nChannels;
waveformatOut.nSamplesPerSec = m_nSamplesPerSec;
waveformatOut.wBitsPerSample = m_nBitsPerSample;
waveformatOut.cbSize = sizeof(waveformatOut); pBufferOut[0] = new BYTE [ nBufferLenOut ];
pBufferOut[1] = new BYTE [ nBufferLenOut ]; OutResult = waveOutOpen( &hwo,
m_nDeviceID,
&waveformatOut,
(DWORD)WaveOutProc,
NULL,
CALLBACK_FUNCTION
);
if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Audio device open error!");
return;
}
if( !pBufferOut )
{
AfxMessageBox( "Fail to alloc memery!" );
return;
}
}void CWaveOut::Play()
{
AddBuffer();
OutResult = waveOutWrite( hwo, &wavehdrOut[nBufferNoOut], sizeof(WAVEHDR) );
if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Audio device play error!");
return;
}
}void CWaveOut::Close()
{
if( hwo )
{
if( !feof( Outfp ) )
{
OutResult = waveOutReset( hwo );
if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Audio device reset error!");
return;
}
waveOutUnprepareHeader( hwo, &wavehdrOut[nBufferNoOut], sizeof(WAVEHDR) );
delete pBufferOut[ nBufferNoOut ];
}
nBuffer = 0;
i = 0;
OutResult = waveOutClose( hwo ); if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Audio device stop error!");
return;
} nBufferNoOut = 0;
fclose( Outfp );
}
}
void CWaveOut::Pause()
{
if( !m_bPause )
{
waveOutPause( hwo );
m_bPause = TRUE;
}
else
{
waveOutRestart( hwo );
m_bPause = FALSE;
}
}
下面是我的源代码,请大侠多多指教。
class CWaveOut
{
public:
CWaveOut();
virtual ~CWaveOut();public:
long m_nBufferLen;
WORD m_nFormatTag;
WORD m_nBlockAlign;
DWORD m_nAvgBytesPerSec;
WORD m_nChannels;
WORD m_nBitsPerSample;
DWORD m_nSamplesPerSec; DWORD m_ThreadID; UINT m_nDeviceID;
UINT m_nNumOfDev; CString m_strPath;
BOOL m_bPause;
void SetOutputDevice( const CString str);
void GetFileInfo();
void GetDeviceInfo();
void Open();
void Play();
void Close();
void Pause();};#include "stdafx.h"
#include "WaveOut.h"
#include "mmsystem.h"#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
FILE *Outfp = NULL;
BYTE *pBufferOut[2];
long nBuffer = 0;
long nBufferLenOut;
long nBufferNoOut = 0;
int i = 0;WAVEFORMATEX waveformatOut;
WAVEHDR wavehdrOut[2];
MMRESULT OutResult;
HWAVEOUT hwo;void AddBuffer()
{
int nSize;
memset( pBufferOut[nBufferNoOut], 0, nBufferLenOut );
nSize = fread( pBufferOut[nBufferNoOut], sizeof(char), nBufferLenOut, Outfp ); wavehdrOut[nBufferNoOut].lpData = (char *)pBufferOut[ nBufferNoOut ];
wavehdrOut[nBufferNoOut].dwBufferLength = nSize;
wavehdrOut[nBufferNoOut].dwFlags = 0; waveOutPrepareHeader( hwo, &wavehdrOut[nBufferNoOut], sizeof(WAVEHDR) ); nBuffer++;
}void CALLBACK WaveOutProc( HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, WORD dwParam2 )
{ int end = feof(Outfp);
switch( uMsg )
{
case WOM_DONE:
nBuffer--; OutResult = waveOutUnprepareHeader( hwo, &wavehdrOut[nBufferNoOut], sizeof(WAVEHDR) );
if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Unprepare wave header error!");
return;
}
nBufferNoOut++;
nBufferNoOut = nBufferNoOut % 2;
if( !end )
{
i++;
TRACE( "turn: %d\tEnd: %d\n", i, end ) ;
AddBuffer();
waveOutWrite( hwo, &wavehdrOut[nBufferNoOut], sizeof(WAVEHDR) );
}
else
{
fclose(Outfp); nBufferNoOut = 0;
nBuffer = 0;
i = 0; OutResult = waveOutReset( hwo );
hwo = NULL;
if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Close wave device error!");
return;
}
}
break; case WOM_CLOSE:
TRACE( "wavefile closed!\n" );
break; default:
break;
}
}
CWaveOut::CWaveOut()
{
m_nDeviceID = 0;
m_bPause = FALSE;
m_ThreadID = ::GetCurrentThreadId();
}CWaveOut::~CWaveOut()
{}void CWaveOut::OnMM_WOM_DONE( UINT wParam, long lParam)
{
}void CWaveOut::GetFileInfo()
{
char ctmp; if( Outfp )
fclose( Outfp );
Outfp = fopen( (LPCTSTR)m_strPath, "rb" );
if( !Outfp )
{
AfxMessageBox("Can't open specified file!");
return;
}
else
{
fseek( Outfp, 0, SEEK_SET );
for( int i = 0; i < 22; i++ )
fread( &ctmp, sizeof(char), 1, Outfp ); fread( &m_nChannels, sizeof(WORD), 1, Outfp );
fread( &m_nSamplesPerSec, sizeof(DWORD), 1, Outfp );
fread( &m_nAvgBytesPerSec, sizeof( DWORD), 1, Outfp );
fread( &m_nBlockAlign, sizeof(WORD), 1, Outfp );
fread( &m_nBitsPerSample, sizeof(WORD), 1, Outfp ); for( i = 0; i < 8; i++ )
fread( &ctmp, sizeof(char), 1, Outfp );
}
}void CWaveOut::GetDeviceInfo()
{
m_nNumOfDev = waveOutGetNumDevs( );
if( m_nNumOfDev == 0 )
{
AfxMessageBox( "No device is avaliable!" );
return;
}
}void CWaveOut::SetOutputDevice(const CString str)
{
WAVEOUTCAPS woc;
int i = 0; CString *pStr = new CString [m_nNumOfDev]; for( i = 0; i < m_nNumOfDev; i++ )
{
waveOutGetDevCaps( i, &woc, sizeof(WAVEOUTCAPS) );
pStr[i] = woc.szPname;
} i = 0;
while( pStr[i] != str && i < m_nNumOfDev ) i++;
if( i >= m_nNumOfDev )
{
AfxMessageBox( "The inputed device name is wrong!" );
return;
}
else
m_nDeviceID = i;
}void CWaveOut::Open()
{
m_nBufferLen = (long)( m_nAvgBytesPerSec * 5 );
nBufferLenOut = m_nBufferLen;
GetDeviceInfo(); waveformatOut.wFormatTag = WAVE_FORMAT_PCM;
waveformatOut.nAvgBytesPerSec = m_nAvgBytesPerSec;
waveformatOut.nBlockAlign = m_nBlockAlign;
waveformatOut.nChannels = m_nChannels;
waveformatOut.nSamplesPerSec = m_nSamplesPerSec;
waveformatOut.wBitsPerSample = m_nBitsPerSample;
waveformatOut.cbSize = sizeof(waveformatOut); pBufferOut[0] = new BYTE [ nBufferLenOut ];
pBufferOut[1] = new BYTE [ nBufferLenOut ]; OutResult = waveOutOpen( &hwo,
m_nDeviceID,
&waveformatOut,
(DWORD)WaveOutProc,
NULL,
CALLBACK_FUNCTION
);
if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Audio device open error!");
return;
}
if( !pBufferOut )
{
AfxMessageBox( "Fail to alloc memery!" );
return;
}
}void CWaveOut::Play()
{
AddBuffer();
OutResult = waveOutWrite( hwo, &wavehdrOut[nBufferNoOut], sizeof(WAVEHDR) );
if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Audio device play error!");
return;
}
}void CWaveOut::Close()
{
if( hwo )
{
if( !feof( Outfp ) )
{
OutResult = waveOutReset( hwo );
if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Audio device reset error!");
return;
}
waveOutUnprepareHeader( hwo, &wavehdrOut[nBufferNoOut], sizeof(WAVEHDR) );
delete pBufferOut[ nBufferNoOut ];
}
nBuffer = 0;
i = 0;
OutResult = waveOutClose( hwo ); if( OutResult != MMSYSERR_NOERROR )
{
AfxMessageBox("Audio device stop error!");
return;
} nBufferNoOut = 0;
fclose( Outfp );
}
}
void CWaveOut::Pause()
{
if( !m_bPause )
{
waveOutPause( hwo );
m_bPause = TRUE;
}
else
{
waveOutRestart( hwo );
m_bPause = FALSE;
}
}
解决方案 »
- 怎么不让一些类出现在类视图中?
- 着急修改下(有源码)80分给会的人,20分给顶的。。
- 急急急!!CPropertySheet做向导,向导页中用radio button做选择,选择不同的页,怎么做?
- 求助:帮忙下载PUDN上的资料,谢谢!!!
- 有谁用过udt.sdk.4.1开发包吗?有熟悉的一起研究下,碰到些问题不明白。
- from 子句语法错误,在线等......
- 问问个位高手,哪种边缘检测算法精度比较高。
- 请教如何使用West Wind HTML Help Builder
- 改变ActiveX控件父窗体!
- 如何获得某个资源在exe文件中的地址????
- 哪位高手会GetUserNameEx函数的用法啊?请教,我急啊!
- 对话框控件焦点,消息发送问题
{
...m_bStart = TRUE;
}void CWaveOut::Close()
{
m_bStart = FALSE;
...
}
void CALLBACK WaveOutProc( HWAVEOUT hwo, UINT uMsg, DWORD dwInstance, DWORD dwParam1, WORD dwParam2 )
{
// waveOutOpen() 中第五个参数传入
CWaveOut *pThis = (CWaveOut*) dwInstance; int end = feof(Outfp);
switch( uMsg )
{
case WOM_DONE:
if (!pThis->m_bStart) break;
...
}