Xaudio2 поп-звук при смене буфера или зацикливания

У меня есть простая программа, которая воспроизводит синусоидальную волну.
В конце буфера я получаю хлопающий звук.
Если я пытаюсь зациклить, я получаю хлопающий звук между каждым циклом.
Если Я чередую буферы и получаю хлопающий звук.

struct win32_audio_buffer
{
    XAUDIO2_BUFFER XAudioBuffer = {};
    int16 *Memory;
};

struct win32_audio_setteings
{
    int32 SampleRate = 44100;
    int32 ToneHz = 200;
    int32 Channels = 2;
    int32 LoopTime = 10;
    int32 TotalSamples = SampleRate * LoopTime;
};

win32_audio_setteings AudioSetteings;
win32_audio_buffer MainAudioBuffer;
win32_audio_buffer SecondaryAudioBuffer;
IXAudio2SourceVoice* pSourceVoice;

internal void Win32InitXaudio2()
{
    WAVEFORMATEX WaveFormat = {};
    WaveFormat.wFormatTag = WAVE_FORMAT_PCM;
    WaveFormat.nChannels = AudioSetteings.Channels;
    WaveFormat.nSamplesPerSec = AudioSetteings.SampleRate;
    WaveFormat.wBitsPerSample = 16;
    WaveFormat.nBlockAlign = (WaveFormat.nChannels * WaveFormat.wBitsPerSample) / 8;
    WaveFormat.nAvgBytesPerSec = WaveFormat.nSamplesPerSec * WaveFormat.nBlockAlign;
    WaveFormat.cbSize = 0;
    
    IXAudio2* pXAudio2;
    IXAudio2MasteringVoice* pMasterVoice;
    
    XAudio2Create(&pXAudio2);
    pXAudio2->CreateMasteringVoice(&pMasterVoice);
    
    pXAudio2->CreateSourceVoice(&pSourceVoice, &WaveFormat);
}
//DOC: AudioBytes - Size of the audio data
//DOC: pAudioData - The buffer start loaction (Needs to be type cast into BYTE pointer)
internal void Win32CreateAudioBuffer(win32_audio_buffer *AudioBuffer)
{
    int32 Size = (int16)sizeof(int16) * AudioSetteings.Channels * AudioSetteings.SampleRate * AudioSetteings.LoopTime;
    
    AudioBuffer->Memory = (int16 *)VirtualAlloc(0, Size, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
    
    AudioBuffer->XAudioBuffer.AudioBytes = Size;   
    AudioBuffer->XAudioBuffer.pAudioData = (BYTE *) AudioBuffer->Memory;  
    //AudioBuffer->XAudioBuffer.Flags = XAUDIO2_END_OF_STREAM;
    AudioBuffer->XAudioBuffer.PlayBegin = 0;
    AudioBuffer->XAudioBuffer.PlayLength = AudioSetteings.TotalSamples;
    //AudioBuffer->XAudioBuffer.LoopCount = 10;
    
}

internal void Win32Playback(win32_audio_buffer *AudioBuffer)
{
    for (int32 Index = 0, Sample = 0; Sample < AudioSetteings.TotalSamples; Sample++)
    {
        real32 Sine = sinf(Sample * 2.0f * Pi32 / AudioSetteings.ToneHz);
        int16 value = (int16)(4000 * Sine);
        AudioBuffer->Memory[Index++] = value;
        AudioBuffer->Memory[Index++] = value;
    }
    pSourceVoice->SubmitSourceBuffer(&AudioBuffer->XAudioBuffer);
}

Win32InitXaudio2();
Win32CreateAudioBuffer(&MainAudioBuffer);
//Win32CreateAudioBuffer(&SecondaryAudioBuffer);
Win32Playback(&MainAudioBuffer);
//Win32Playback(&SecondaryAudioBuffer);
pSourceVoice->Start(0);

Я разместил здесь соответствующий код, и он просто воспроизводит один синусоидальный буфер.
Я пробовал использовать альтернативные буферы, а также начинать и заканчивать при переходе через нуль.


person Rxzlion    schedule 13.07.2020    source источник


Ответы (1)


У меня была аналогичная проблема.

Может кому поможет.

Проблема в том, чтобы выделить для звука больше памяти, чем необходимо.

Итак, я попробовал что-то вроде этого и нашел проблему (это не решение, я просто показываю, как я нашел проблему! Возможно, если это не поможет в вашем случае, проблема в другом месте)

// XAUDIO2_BUFFER m_xaudio2Buffer...
m_xaudio2Buffer.pAudioData = source->m_data;
m_xaudio2Buffer.AudioBytes = source->m_dataSize - 100; // -100 and `pop` sound is gone
m_xaudio2Buffer.Flags = XAUDIO2_END_OF_STREAM;
person Тёма Басов    schedule 05.11.2020