⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wavebox.cpp

📁 UHF RFID Reader Program
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// WaveBox.cpp: implementation of the CWave class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "WaveBox.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CWaveBox::CWaveBox()
{ 
    // init wave(s) counter
    wload   = 0;

    // thread suspended < used for resuming thread at first play >
    run     = 0;

    // create suspended player thread
    thread  = CreateThread(  NULL,
                             0,
                             (LPTHREAD_START_ROUTINE)PlayThread,
                             (LPVOID)this,
                             CREATE_SUSPENDED,
                             NULL                                   );
    

    // alloc mem for interface(s)
    for( unsigned int i = 0; i < SUPPORT_INTERFACES; i++ )
    {
        I[i].wblock     = allocateBlocks( BLOCK_SIZE, BLOCK_COUNT );
        I[i].wfreeblock = BLOCK_COUNT;
        I[i].wcurrblock = 0;
        I[i].state      = INT_FREE;
        I[i].wpos       = 0;
    }
    
    // init msg
    for( unsigned int i = 0; i < SUPPORT_WAVES; i++ )    W[i].WMSG = WMSG_WAIT;

    // init cs
    InitializeCriticalSection( &cs );
}


CWaveBox::~CWaveBox()
{
	unsigned long exit = 0;

	if( run ) // thread resumed
	{
		// set thread close message
		EnterCriticalSection( &cs );
		TMSG = TMSG_CLOSE;
		LeaveCriticalSection( &cs );
		
		do // wait for soft close
		{ 
			GetExitCodeThread( thread, &exit ); 
			Sleep( 10 );

		}while( exit != THREAD_EXIT );
	
	}else // thread suspended	
	{
		// hard close 
		GetExitCodeThread( thread, &exit ); 
		TerminateThread( thread, exit );
	}
	
	
	// release wave(s)
	for( unsigned int i = 0; i < wload; i++ )
		free( W[i].data );

	// release interface(s)
	for( unsigned int i = 0; i < SUPPORT_INTERFACES; i++ )
		freeBlocks( I[i].wblock ); 

	// del cs
	DeleteCriticalSection( &cs );
}



WAVEHDR* CWaveBox::allocateBlocks(int size, int count)
{
    unsigned char* buffer;
    int i;
    WAVEHDR* blocks;
    DWORD totalBufferSize = (size + sizeof(WAVEHDR)) * count;
    
    //  allocate memory for the entire set in one go
    if((buffer = ( UCHAR*) HeapAlloc( GetProcessHeap(), 
									  HEAP_ZERO_MEMORY, 
									  totalBufferSize )) == NULL)	return NULL;
    
    // and set up the pointers to each bit
    blocks = (WAVEHDR*)buffer;
    buffer += sizeof(WAVEHDR) * count;
    for(i = 0; i < count; i++) 
	{
        blocks[i].dwBufferLength = size;
        blocks[i].lpData = (CHAR *)buffer;
        buffer += size;
    }
    
    return blocks;
}


void CWaveBox::freeBlocks(WAVEHDR* blockArray)
{
    // and this is why allocateBlocks works the way it does
    HeapFree(GetProcessHeap(), 0, blockArray);
}


int CWaveBox::Load( TCHAR *file )
{
    if( wload == SUPPORT_WAVES )
        return -1;

    HANDLE hFile;

    // open file
    if((hFile = CreateFile( file,
                            GENERIC_READ,
                            FILE_SHARE_READ,
                            NULL,
                            OPEN_EXISTING,
                            0,
                            NULL )) == INVALID_HANDLE_VALUE)    return -1;

    
    // read wave header
    char            header[HEADER_SIZE];
    unsigned long   rbytes  = 0;
    
    if( !ReadFile(hFile, header, sizeof(header), &rbytes, NULL) )
    { CloseHandle(hFile);   return -1; }

    if( !rbytes || rbytes < sizeof(header) )
    { CloseHandle(hFile);   return -1; }

    /// check if this is a wave file
    if( strncmp( header, WAVE_FILE_MARK, strlen( WAVE_FILE_MARK )) )
    { CloseHandle(hFile);   return -1; }

    if( strncmp( header + OFFSET_HEAD_MARK, WAVE_HEAD_MARK, strlen( WAVE_HEAD_MARK )) )
    { CloseHandle(hFile);   return -1; }

    /// check if wave is uncompressed PCM format
    if (    ((*(DWORD*)(header + OFFSET_WAVE_PCM1)) != WAVE_PCM_16 )
         || ((*(WORD *)(header + OFFSET_WAVE_PCM2)) != WAVE_PCM_1  ))
    {CloseHandle(hFile);     return -1; }

    /// check for 'data' mark
    if( !strncmp( header + OFFSET_DATA_MARK, WAVE_DATA_MARK, strlen( WAVE_DATA_MARK )) )
        W[wload].size = *((DWORD*)(header + OFFSET_DATA_SIZE ));                /* size of data */  
    else
    {   /// if data block size cant be read
        /// try to predict data block without extra info
        /// this is unusualy case
        W[wload].size  = *((DWORD*)(header + OFFSET_FILE_LEFT ));  
        W[wload].size -=  ( HEADER_SIZE - EOF_EXTRA_INFO );             /* size of data */ 
    }

    // fill WAVEFORMATEX from wave header
    W[wload].wfx.nSamplesPerSec  = *((DWORD*)(header + OFFSET_SAMPLESPERSEC )); /* sample rate */
    W[wload].wfx.wBitsPerSample  = *((WORD *)(header + OFFSET_BITSPERSAMPLE )); /* sample size */
    W[wload].wfx.nChannels       = *((WORD *)(header + OFFSET_CHANNELS      )); /* channels    */
    W[wload].wfx.cbSize          = 0;                                           /* size of _extra_ info */
    W[wload].wfx.wFormatTag      = WAVE_FORMAT_PCM;
    W[wload].wfx.nBlockAlign     = *((WORD *)(header + OFFSET_BLOCKALIGN    ));
    W[wload].wfx.nAvgBytesPerSec = *((DWORD*)(header + OFFSET_AVGBYTESPERSEC));

    // get mem for wave data block
    if((W[wload].data = ( char *) calloc( W[wload].size, sizeof( char ))) == NULL)
    { CloseHandle(hFile); return -1; }
 
    char            buffer[READ_BLOCK];
    
    unsigned long   size         = W[wload].size; 
    unsigned long   read_block   = 0;
                    rbytes       = 0;
                      
    do  /// copy uncompressed PCM wave data block
    {
        if( ( size -= rbytes ) >= READ_BLOCK )  read_block = READ_BLOCK;
        else
        if( size && size < READ_BLOCK )         read_block = size;
        else                                    break;

        if( !ReadFile(hFile, buffer, read_block, &rbytes, NULL) )
            break;
        if( rbytes == 0 )
            break;
        if( rbytes < sizeof(buffer) ) 
            memset(buffer + rbytes, 0, sizeof(buffer) - rbytes);
        
        memcpy( &W[wload].data[W[wload].size - size], buffer, rbytes );         

    }while( 1 );    

    // close file handle
    CloseHandle(hFile);
    
    // return current wave count
    return ++wload;
}


int CWaveBox::Play( unsigned int wave )
{
    // check wave id
    if( wave < 0 || wave >= wload )
        return -1;
    
    // set play message
    EnterCriticalSection(&cs);
    W[wave].WMSG = WMSG_START;
    LeaveCriticalSection(&cs);

    // resume thread < at first play >
    if( !run ){ run = 1; TMSG = TMSG_ALIVE; ResumeThread( thread ); }
    
    return 1;
}


int CWaveBox::AddInterface( HWAVEOUT	*dev, 
					     WAVEFORMATEX	*wfx, 
						 volatile int	*wfreeblock )
{
	// check for free device
	if( !waveOutGetNumDevs() )
		return -1;
    
    // try to open the default wave device. WAVE_MAPPER is
    // a constant defined in mmsystem.h, it always points to the
    // default wave device on the system (some people have 2 or
    // more sound cards).

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -