5

waveOutWrite()を使用してスムーズなオーディオ再生を実現しようとすると問題が発生します。私のデータには、カメラから取得した多くのadpcmdataボックが含まれています。各adpcmブロックをデコードした後、waveOutWrite()を使用して再生します。最初のブロックは正常に再生されますが(少なくとも聞こえます)、これらのブロック間にギャップが存在する次のブロックで再生すると問題が発生します。waveOutWrite()を使用した後にsleep()を呼び出そうとしましたが、問題があります。この場合、私がどのようにスムーズになるかを誰かに教えてもらえますか?オーディオの再生方法に問題はありますか?

for (i = 0, i < MaxBlockData, i++)  


        BYTE * pcmBuff = new BYTE[length*8];
        memset(pcmBuff, 0, length*8);
        G726 g726;

        int pcmDataSize = 0;
        g726.SetRate(g726.Rate32kBits);
        g726.SetLaw(g726.PCM16);
        pcmDataSize = g726.Decode(pcmBuff, adpcmData[i], 0, length*8); /decode adcmData PCM 16

        if(pcmDataSize > 0)
        {
            int sampleRate = 8000;
            CHAR* waveIn = new CHAR[pcmDataSize];

            HWAVEIN hWaveIn;
            WAVEHDR WaveInHdr;
            MMRESULT result;
            HWAVEOUT hWaveOut;

            WAVEFORMATEX pFormat;
            pFormat.wFormatTag = WAVE_FORMAT_PCM;
            pFormat.nChannels = 1;
            pFormat.nSamplesPerSec = sampleRate;
            pFormat.nAvgBytesPerSec = 2 * sampleRate;
            pFormat.nBlockAlign = 2;
            pFormat.wBitsPerSample = 16;
            pFormat.cbSize = 0;

            result = waveInOpen(&hWaveIn, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT);

            if(result != MMSYSERR_NOERROR)
            {
                char fault[256];
                waveInGetErrorTextA(result, fault, 256);
                MessageBoxA(NULL, fault, "Failed to open waveform input device.", MB_OK | MB_ICONEXCLAMATION);
                return;
            }

            WaveInHdr.lpData = (LPSTR)waveIn;
            WaveInHdr.dwBufferLength = pcmDataSize;
            WaveInHdr.dwBytesRecorded = 0;
            WaveInHdr.dwUser = 0;
            WaveInHdr.dwFlags = 0;
            WaveInHdr.dwLoops = 0;

            waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
            memcpy(WaveInHdr.lpData, pcmBuff, pcmDataSize);

            if(waveOutOpen(&hWaveOut, WAVE_MAPPER, &pFormat, 0, 0, WAVE_FORMAT_DIRECT))
            {
                MessageBoxA(NULL, "Failed to replay", NULL, MB_OK | MB_ICONEXCLAMATION );
            }

            waveOutWrite(hWaveOut, &WaveInHdr, sizeof(WaveInHdr)); 
            Sleep((pcmDataSize/sampleRate ) * 1000); //Sleep for as long as there was recorded

            waveOutUnprepareHeader(hWaveOut, &WaveInHdr, sizeof(WAVEHDR));
            waveInUnprepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));
            waveInClose(hWaveIn);
            waveOutClose(hWaveOut);


            WaveInHdr.lpData = NULL;
            delete []waveIn;
        }
    }

私の質問を読んでくれてありがとう。

4

2 に答える 2

2

私はこのようには働きません。
最初のサンプルを再生するときは、次のサンプルの時間はスリープできません。代わりに、ダブルまたはマルチバッファリングとコールバックメカニズムを使用する必要があります。
全体的なプロトコルは次のとおりです
。1)カメラなどから最初のブロックを取得し
ます。2)カメラなどから2番目のブロックを取得します
。3)最初のブロックを書き込み、次に2番目のブロックを待機せずに書き込みます。
次に、コールバックからのシグナルを待機するループを作成し、シグナルを受信すると、次にキャプチャされたブロックを書き込みます。

于 2012-08-08T10:15:58.833 に答える
0

waveOut *ファミリを使用してオーディオをスムーズに再生するには、デバイスを開き、バッファを割り当て、再生するデータのバックログを保持しながらデバイスにバッファを送信し続けます。コードSleep内で、新しいデータの準備とデバイスへの書き込みに取り組むと同時に、再生されたバッファーをチェックする必要があります(WHDR_DONEドライバーがバッファーを使用しなくなり、アプリケーションがバッファーを受信することを示すフラグが設定されます) 。

于 2012-06-01T17:44:12.140 に答える