1

我来自 .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;
}

但是还不会播放任何声音...

4

0 回答 0