我来自 .net 背景,对 C++ 开发相当陌生。
我有一个这样的缓冲区:
short* pBuffer = &pGraph->m_pDataBuf[0];
如何从声卡播放此缓冲区?
注意:这个缓冲区是循环填充的,在每个循环中,我都想播放缓冲区。
我的研究表明这个命令解决了我的问题,但是通过执行这个命令,不会播放任何声音......
::PlaySound((LPCSTR)pBuffer, NULL, SND_MEMORY | SND_ASYNC | SND_NODEFAULT);
另一种解决方案是:
void PlaySoundBuffer()
{
static HWAVEOUT hwo;
CEMGDoc *pDoc = GetDocument();
CEMGGraph *pGraph = &pDoc->m_aGraphs[m_nCurGraph];
if (pGraph->m_nFlag & G_EMPTY)
return;
m_bInPlayingEMGMode = true;
int nHelperBufSize = (pGraph->m_nBufSize - pGraph->m_nEMGFirstVisibleIndex) * 2;
pGraph->m_pHelperDataBuf = new short[nHelperBufSize];
short *pHelperBuf = pGraph->m_pHelperDataBuf;
short *pBuffer = &pGraph->m_pDataBuf[0];
// This Coe. calibrate sounds that wave plays with the one that line-in plays
for (int i = 0; i < nHelperBufSize; i++, i++)
pHelperBuf[i] = pHelperBuf[i + 1] = short(pBuffer[i >> 1] * 1.75f);
WAVEFORMATEX wfx;
wfx.wFormatTag = WAVE_FORMAT_PCM;
wfx.nChannels = 2;
wfx.nSamplesPerSec = m_nSampleRate;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign = wfx.nChannels * wfx.wBitsPerSample / 8;
wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign;
wfx.cbSize = 0;
WICatchError(waveOutOpen(&hwo, _Master_Audio_ID, &wfx, 0, 0, CALLBACK_NULL));
WAVEHDR hdr;
hdr.lpData = (char *)pHelperBuf;
hdr.dwBufferLength = nHelperBufSize * sizeof(short);
hdr.dwLoops = 1;
hdr.dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP;
WICatchError(waveOutPrepareHeader(hwo, &hdr, sizeof(WAVEHDR)));
WICatchError(waveOutWrite(hwo, &hdr, sizeof(WAVEHDR)));
while (!(hdr.dwFlags & WHDR_DONE))
{
//wait while buffer played...
}
WICatchError(waveOutReset(hwo));
WICatchError(waveOutUnprepareHeader(hwo, &hdr, sizeof(WAVEHDR)));
WICatchError(waveOutClose(hwo));
delete[] pHelperBuf;
}
但是还不会播放任何声音...