#include "zplaywavesound.h"
void CALLBACK waveOutProc(
HWAVEOUT hwo,
UINT uMsg,
DWORD dwInstance,
DWORD dwParam1,
DWORD dwParam2
)
{
if(uMsg == WOM_DONE)
{
LPWAVEHDR pwh = (LPWAVEHDR)dwParam1;
// set as empty
((char *)(pwh->lpData))[ZPlayWaveSound::ZPLAYWAVESOUND_BUF_LEN] = 0;
}
return;
}
ZPlayWaveSound::ZPlayWaveSound()
{
m_hwo = NULL;
m_iIndexOfBuf = 0;
m_iIndexOfBlank = 0;
}
ZPlayWaveSound::~ZPlayWaveSound()
{
close();
}
bool ZPlayWaveSound::init()
{
WAVEFORMATEX wfx;
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 1;
wfx.nSamplesPerSec = 8000;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = wfx.wBitsPerSample / 8 * wfx.nChannels;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
wfx.cbSize = 0;
int iRetOpen = waveOutOpen(&m_hwo, WAVE_MAPPER, &wfx,
(DWORD)waveOutProc, 0, CALLBACK_FUNCTION);
if (iRetOpen != MMSYSERR_NOERROR)
{
return false;
}
for (int i = 0; i < ZPLAYWAVESOUND_BUF_NUM; i++)
{
memset(m_pcBuf[i], 0, ZPLAYWAVESOUND_BUF_LEN + 2);
memset(&m_pwh[i], 0, sizeof(WAVEHDR));
m_pwh[i].lpData = m_pcBuf[i];
m_pwh[i].dwBufferLength = ZPLAYWAVESOUND_BUF_LEN;
waveOutPrepareHeader(m_hwo, &m_pwh[i], sizeof(WAVEHDR));
}
return true;
}
int ZPlayWaveSound::writeBuf(char *pcBuf, int iLen)
{
int iLenToWrite = iLen;
while (iLenToWrite >= ZPLAYWAVESOUND_BUF_LEN - m_iIndexOfBlank)
{
// full
if (m_pcBuf[m_iIndexOfBuf][ZPLAYWAVESOUND_BUF_LEN] != 0)
{
return (iLen - iLenToWrite);
}
WAVEHDR *pwhCurrent = &(m_pwh[m_iIndexOfBuf]);
memcpy(m_pcBuf[m_iIndexOfBuf] + m_iIndexOfBlank,
pcBuf + (iLen - iLenToWrite),
ZPLAYWAVESOUND_BUF_LEN - m_iIndexOfBlank);
pwhCurrent->lpData = m_pcBuf[m_iIndexOfBuf];
pwhCurrent->lpData[ZPLAYWAVESOUND_BUF_LEN] = 1; // set as full
waveOutWrite(m_hwo, pwhCurrent, sizeof(WAVEHDR));
iLenToWrite -= (ZPLAYWAVESOUND_BUF_LEN - m_iIndexOfBlank);
m_iIndexOfBlank = 0;
m_iIndexOfBuf = (m_iIndexOfBuf + 1) % ZPLAYWAVESOUND_BUF_NUM;
}
if (iLenToWrite > 0)
{
// full
if (m_pcBuf[m_iIndexOfBuf][ZPLAYWAVESOUND_BUF_LEN] != 0)
{
return (iLen - iLenToWrite);
}
memcpy(m_pcBuf[m_iIndexOfBuf] + m_iIndexOfBlank,
pcBuf + (iLen - iLenToWrite),
iLenToWrite);
m_iIndexOfBlank = (m_iIndexOfBlank + iLenToWrite) %
ZPLAYWAVESOUND_BUF_LEN;
}
return iLen;
}
void ZPlayWaveSound::close()
{
for (int i = 0; i < ZPLAYWAVESOUND_BUF_NUM; i++)
{
waveOutUnprepareHeader(m_hwo, &m_pwh[i], sizeof(WAVEHDR));
}
waveOutClose(m_hwo);
}
- 1
- 2
- 3
- 4
- 5
- 6
前往页