📄 wavebox.cpp
字号:
if(waveOutOpen( dev,
WAVE_MAPPER,
wfx,
(DWORD)waveOutProc,
(DWORD)wfreeblock,
CALLBACK_FUNCTION ) != MMSYSERR_NOERROR ) return -1;
return 1;
}
int CWaveBox::RemoveInterface( HWAVEOUT dev )
{
// try to close given wave device / interface.
if( waveOutClose( dev ) != MMSYSERR_NOERROR ) return -1;
return 1;
}
static void CALLBACK waveOutProc( HWAVEOUT hWaveOut,
UINT uMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2 )
{
// pointer to free block counter
int* freeBlockCounter = (int*)dwInstance;
// ignore calls that occur due to openining and closing the device.
if(uMsg != WOM_DONE)
return;
// increase free block counter
EnterCriticalSection(&cs);
(*freeBlockCounter)++;
LeaveCriticalSection(&cs);
}
#include "RFIDRadioManager.h"
static unsigned int __stdcall PlayThread( LPVOID lp )
{
/// get the class instance
CWaveBox *wb = ( CWaveBox *)lp;
/// pooling variables < most frequently used / checked >
register WMsg wmsg = WMSG_WAIT;
register TMsg tmsg = TMSG_ALIVE;
register unsigned int i = 0;
/// thread life cycle
while( tmsg )
{
/// check for 'play' msg
for( i = 0; i < wb->wload; i++ )
{
/// read msg
EnterCriticalSection( &cs );
wmsg = wb->W[i].WMSG;
LeaveCriticalSection( &cs );
/// wave to play?
if( wmsg == WMSG_START ) break;
}
/// playable wave
if( wmsg == WMSG_START )
/// link with first free interface
for( unsigned int j = 0; j < SUPPORT_INTERFACES; j++ )
/// check for free interface
if( wb->I[j].state == INT_FREE )
/// attach wave to interface
if( wb->AddInterface( &wb->I[j].dev,
&wb->W[i].wfx,
&wb->I[j].wfreeblock ) )
{
/// get wave pointer
wb->I[j].wave = &wb->W[i];
/// mark interface as used
wb->I[j].state = INT_USED;
/// free wave
EnterCriticalSection( &cs );
wb->W[i].WMSG = WMSG_WAIT;
LeaveCriticalSection( &cs );
/// leave loop
break;
}
/////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////
///
/// < main playing loop >
///
/// search for the first marked interface and play attached wave
///
for( unsigned int k = 0; k < SUPPORT_INTERFACES; k++ )
{
/// nothing to do with free interface
if( wb->I[k].state == INT_FREE ) continue;
EnterCriticalSection( &cs );
int free = wb->I[k].wfreeblock;
LeaveCriticalSection( &cs );
/// nothing to do with full queued interface
if( free < BP_TURN ) continue;
WAVEHDR *current = NULL;
/// how much blocks per turn will be queued
for( unsigned int m = 0; m < BP_TURN; m++ )
{
/// set current block pointer
current = &wb->I[k].wblock[wb->I[k].wcurrblock];
// first make sure the header we're going to use is unprepared
if( current->dwFlags & WHDR_PREPARED )
waveOutUnprepareHeader( wb->I[k].dev,
current,
sizeof(WAVEHDR) );
/// how much data is left at this interface to play
unsigned long left = wb->I[k].wave->size - wb->I[k].wpos;
unsigned long chunk = 0;
if( left >= BLOCK_SIZE )
chunk = BLOCK_SIZE;
else
if( left && left < BLOCK_SIZE )
chunk = left;
else
{
////////////////////
/// nothing left ///
////////////////////////////////////////////////////////////////////////
///
/// < clean job, close waveOutProc threads >
///
/// all buffers are queued to the interface
///
/// get free block count
EnterCriticalSection( &cs );
int free = wb->I[k].wfreeblock;
LeaveCriticalSection( &cs );
if( free == BLOCK_COUNT ) /// are all blocks played!?
{
/// unprepare any blocks that are still prepared
for( int i = 0; i < wb->I[k].wfreeblock; i++)
if( wb->I[k].wblock[i].dwFlags & WHDR_PREPARED )
waveOutUnprepareHeader( wb->I[k].dev,
&wb->I[k].wblock[i],
sizeof(WAVEHDR) );
/// close interface
if( wb->RemoveInterface( wb->I[k].dev ) )
{
/// free interface
wb->I[k].wcurrblock = 0;
wb->I[k].state = INT_FREE;
wb->I[k].wpos = 0;
wb->I[k].wave = NULL;
}
}
/// step out
break;
}
/// prepare current wave data block header
memcpy( current->lpData, &wb->I[k].wave->data[wb->I[k].wpos], chunk );
current->dwBufferLength = chunk; // sizeof block
wb->I[k].wpos += chunk; // update position
/// prepare for playback
waveOutPrepareHeader( wb->I[k].dev, current, sizeof(WAVEHDR) );
/// push to the queue
waveOutWrite(wb->I[k].dev, current, sizeof(WAVEHDR));
/// decrease free block counter
EnterCriticalSection( &cs );
wb->I[k].wfreeblock--;
LeaveCriticalSection( &cs );
/// point to the next block
wb->I[k].wcurrblock++;
wb->I[k].wcurrblock %= BLOCK_COUNT;
}/// block(s)
}/// interface(s)
/// wait 10 ms < save CPU time >
Sleep( 300 );
/// check for thread message
EnterCriticalSection( &cs );
tmsg = wb->TMSG;
LeaveCriticalSection( &cs );
}/// thread
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///
/// force to close interfaces which are still playing
///
for( i = 0; i < SUPPORT_INTERFACES; i++ )
if( wb->I[i].state == INT_USED )
if( waveOutReset( wb->I[i].dev ) == MMSYSERR_NOERROR )
wb->RemoveInterface( wb->I[i].dev );
return THREAD_EXIT; /// return exit code < destructor >
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -