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

📄 soundbuffer.cpp

📁 C人工智能游戏开发的一些实例源代码 C Game development in artificial intelligence source code of some examples
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//----------------------------------------------------------------------------------------------
// Sequential Prediction Demo: The positioning pattern
// 
// Author:  Fri Mommersteeg
// Date:    10-09-2001
// File:    SoundBuffer.h
//----------------------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------
// Include files
//----------------------------------------------------------------------------------------------

#include "StdAfx.h"
#include "SoundBuffer.h"

//----------------------------------------------------------------------------------------------
// CSoundBuffer(): constructor
//----------------------------------------------------------------------------------------------

CSoundBuffer::CSoundBuffer()
{
	lpDS = NULL;
	lpDSB = NULL;
}

//----------------------------------------------------------------------------------------------
// ~CSoundBuffer(): destructor
//----------------------------------------------------------------------------------------------

CSoundBuffer::~CSoundBuffer()
{
	Release();
}

//----------------------------------------------------------------------------------------------
// CSoundBuffer(): creates a new soundbuffer according the specified requirements
//----------------------------------------------------------------------------------------------

void CSoundBuffer::Create(LPDS lpds, DWORD dwBufferSize, DWORD dwFrequency, WORD nChannels, WORD wBitsPerSample, DWORD dwFlags )
{
	lpDS = lpds;

	DSBD dsbd;
	WAVEFORMATEX wfx;

	// set up wave format
	wfx.wFormatTag = WAVE_FORMAT_PCM;
	wfx.nChannels = nChannels;
	wfx.nSamplesPerSec = dwFrequency;
	wfx.wBitsPerSample = wBitsPerSample;
	wfx.nBlockAlign = nChannels * wBitsPerSample / 8;
	wfx.nAvgBytesPerSec = dwFrequency * wfx.nBlockAlign;
	wfx.cbSize = 0;

	// set up sound buffer description
	ZeroMemory(&dsbd, sizeof(dsbd));
	dsbd.dwSize = sizeof(dsbd);
	dsbd.dwFlags = dwFlags | DSBCAPS_STATIC;
	dsbd.dwBufferBytes = dwBufferSize;
	dsbd.lpwfxFormat = &wfx;

	// create sound buffer
	lpDS->CreateSoundBuffer(&dsbd, &lpDSB, NULL);

	// fill sound buffer with silence
	Silence();
}

//----------------------------------------------------------------------------------------------
// CSoundBuffer(): creates a new soundbuffer using the specified wave file
//----------------------------------------------------------------------------------------------

void CSoundBuffer::CreateWave(LPDS lpds, LPSTR strWave, DWORD dwFlags)
{
	lpDS = lpds;

	DSBD	dsbd;
	LPVOID	lpvAudio;
	DWORD	dwBytes;
	UINT	cbBytesRead;

	// open file for input
    WaveOpenFile( strWave, &hmmio, &pwfx, &mmckinfoParent );

	// prepare file for input
    WaveStartDataRead( &hmmio, &mmckinfo, &mmckinfoParent );

	// set up buffer description
	ZeroMemory(&dsbd, sizeof(dsbd));
	dsbd.dwSize = sizeof(dsbd);
	dsbd.dwFlags = dwFlags | DSBCAPS_STATIC;
	dsbd.dwBufferBytes = mmckinfo.cksize;
	dsbd.lpwfxFormat = pwfx;

	// create sound buffer
	lpDS->CreateSoundBuffer(&dsbd, &lpDSB, NULL);

	// read wave data into buffer
	lpDSB->Lock(0, 0, &lpvAudio, &dwBytes, NULL, NULL, DSBLOCK_ENTIREBUFFER);
	WaveReadFile( hmmio, dwBytes, (BYTE *)lpvAudio, &mmckinfo, &cbBytesRead );
	lpDSB->Unlock( lpvAudio, dwBytes, NULL, 0);

	// close file
	WaveCloseReadFile( &hmmio, &pwfx );
}

//----------------------------------------------------------------------------------------------
// CreateCopy(): creates a reference copy of the sound buffer
//----------------------------------------------------------------------------------------------

void CSoundBuffer::CreateCopy(LPDS lpds, LPDSB lpDSB)
{
	lpDS = lpds;
	lpDSB = lpDSB;
}

//----------------------------------------------------------------------------------------------
// CreateDuplicate(): creates a duplicate of the sound buffer
//----------------------------------------------------------------------------------------------

void CSoundBuffer::CreateDuplicate(LPDS lpds, LPDSB lpDSB)
{
	lpDS = lpds;
	lpDS->DuplicateSoundBuffer(lpDSB, &this->lpDSB);
}

//----------------------------------------------------------------------------------------------
// Release(): releases the sound buffer
//----------------------------------------------------------------------------------------------

void CSoundBuffer::Release()
{
	if ( lpDSB != NULL )
	{
		lpDSB->Release();
		lpDSB = NULL;
	}
	lpDS = NULL;
}

//----------------------------------------------------------------------------------------------
// ReleaseCopy(): releases a copy of the sound buffer
//----------------------------------------------------------------------------------------------

void CSoundBuffer::ReleaseCopy()
{
	lpDSB = NULL;
	lpDS = NULL;
}

//----------------------------------------------------------------------------------------------
// Play(): plays the soundbuffer
//----------------------------------------------------------------------------------------------

void CSoundBuffer::Play(BOOL bLooping)
{
	HRESULT hr = lpDSB->Play(0, 0, bLooping ? DSBPLAY_LOOPING : 0);

	if ( FAILED( hr ) )
	{
		if ( hr == DSERR_BUFFERLOST )
		{
			// restore buffer and resume
			lpDSB->Restore();
			lpDSB->Play(0, 0, bLooping ? DSBPLAY_LOOPING : 0);
		}
	}
}

//----------------------------------------------------------------------------------------------
// Stop(): stops a playing sound buffer
//----------------------------------------------------------------------------------------------

void CSoundBuffer::Stop()
{
	lpDSB->Stop();
}

//----------------------------------------------------------------------------------------------
// Silence(): fills a sound buffer with silence
//----------------------------------------------------------------------------------------------

void CSoundBuffer::Silence()
{
    WAVEFORMATEX    wfx;
    DWORD           dwSizeWritten;
    PBYTE			pb;
    DWORD			cb;

    lpDSB->GetFormat( &wfx, sizeof( WAVEFORMATEX ), &dwSizeWritten );

    lpDSB->Lock( 0, 0, (LPVOID *)&pb, &cb, NULL, NULL, DSBLOCK_ENTIREBUFFER );
    FillMemory( pb, cb, ( wfx.wBitsPerSample == 8 ) ? 128 : 0 );
    lpDSB->Unlock( pb, cb, NULL, 0 );
}

//----------------------------------------------------------------------------------------------
// WaveOpenFile(): This function will open a wave input file and prepare it for reading, so the 
// data can be easily read with WaveReadFile. Returns 0 if successful, the error code if not.
//
//      pszFileName - Input filename to load.
//      phmmioIn    - Pointer to handle which will be used for further mmio routines.
//      ppwfxInfo   - Ptr to ptr to WaveFormatEx structure with all info about the file.
//----------------------------------------------------------------------------------------------

int CSoundBuffer::WaveOpenFile(
    TCHAR*pszFileName,                              // (IN)
    HMMIO *phmmioIn,                                // (OUT)
    WAVEFORMATEX **ppwfxInfo,                       // (OUT)
    MMCKINFO *pckInRIFF                             // (OUT)
            )
{
    HMMIO           hmmioIn;
    MMCKINFO        ckIn;           // chunk info. for general use.
    PCMWAVEFORMAT   pcmWaveFormat;  // Temp PCM structure to load in.
    WORD            cbExtraAlloc;   // Extra bytes for waveformatex
    int             nError;         // Return value.


    // Initialization...
    *ppwfxInfo = NULL;
    nError = 0;
    hmmioIn = NULL;

    if ((hmmioIn = mmioOpen(pszFileName, NULL, MMIO_ALLOCBUF | MMIO_READ)) == NULL)
        {
        nError = ER_CANNOTOPEN;
        goto ERROR_READING_WAVE;
        }

    if ((nError = (int)mmioDescend(hmmioIn, pckInRIFF, NULL, 0)) != 0)
        {
        goto ERROR_READING_WAVE;
        }


    if ((pckInRIFF->ckid != FOURCC_RIFF) || (pckInRIFF->fccType != mmioFOURCC('W', 'A', 'V', 'E')))
        {
        nError = ER_NOTWAVEFILE;
        goto ERROR_READING_WAVE;
        }

    /* Search the input file for for the 'fmt ' chunk.     */
    ckIn.ckid = mmioFOURCC('f', 'm', 't', ' ');
    if ((nError = (int)mmioDescend(hmmioIn, &ckIn, pckInRIFF, MMIO_FINDCHUNK)) != 0)
        {
        goto ERROR_READING_WAVE;
        }

    /* Expect the 'fmt' chunk to be at least as large as <PCMWAVEFORMAT>;
    * if there are extra parameters at the end, we'll ignore them */

    if (ckIn.cksize < (long) sizeof(PCMWAVEFORMAT))
        {
        nError = ER_NOTWAVEFILE;
        goto ERROR_READING_WAVE;
        }

    /* Read the 'fmt ' chunk into <pcmWaveFormat>.*/
    if (mmioRead(hmmioIn, (HPSTR) &pcmWaveFormat, (long) sizeof(pcmWaveFormat)) != (long) sizeof(pcmWaveFormat))
        {
        nError = ER_CANNOTREAD;
        goto ERROR_READING_WAVE;
        }


    // Ok, allocate the waveformatex, but if its not pcm
    // format, read the next word, and thats how many extra
    // bytes to allocate.
    if (pcmWaveFormat.wf.wFormatTag == WAVE_FORMAT_PCM)
        cbExtraAlloc = 0;

    else
        {
        // Read in length of extra bytes.
        if (mmioRead(hmmioIn, (LPTSTR) &cbExtraAlloc,
            (long) sizeof(cbExtraAlloc)) != (long) sizeof(cbExtraAlloc))
            {
            nError = ER_CANNOTREAD;
            goto ERROR_READING_WAVE;
            }

⌨️ 快捷键说明

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