📄 soundbuffer.cpp
字号:
//----------------------------------------------------------------------------------------------
// 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 + -