简体   繁体   中英

Integrating Libsndfile with xaudio2

I'm trying to integrate libsndfile with xaudio2. There isn't much I could find on the internet so I'll ask it here.

I successfuly integrated libsndfile with OpenAL preatty easly but i'm strugling with xaudio2.

It generates pops and crackling. I'm sure its because I'm not giving the correct format xaudio expects... but I can't seem to figure out what values should be sent to xaudio2.

Here is how i'm loading the sound file...

SF_INFO info;
    SNDFILE* file =
        sf_open(
            filename.c_str(),
            SFM_READ,
            &info);

    std::vector<uint16_t> wav;
    std::array<int16_t, READ_BLOCK_SIZE> read_buf;

    sf_count_t read_size = 0;

    while ((read_size =
        sf_read_short(
            file,
            read_buf.data(),
            read_buf.size())) != 0)
        wav.insert(
            wav.end(),
            read_buf.begin(),
            read_buf.begin() + read_size);

So wav vector gets populated with uhsorts while xaudio expects a BYTE array....not sure if this is also an issue.

info Gets populated with the sound file information as you know.

this is how I'm filling the xaudio buffer.

waveFormat = {};
waveFormat.wFormatTag = WAVE_FORMAT_PCM;
waveFormat.nChannels = info.channels;
waveFormat.nSamplesPerSec = info.samplerate;
waveFormat.wBitsPerSample = 8;
waveFormat.nBlockAlign = 
        waveFormat.nChannels * 
        waveFormat.wBitsPerSample / 8;
waveFormat.nAvgBytesPerSec =
    waveFormat.nSamplesPerSec * 
    waveFormat.nBlockAlign;
waveFormat.cbSize = sizeof(WAVEFORMATEX);


buffer = { 0 };
buffer.AudioBytes = (UINT32)(wav.size() * sizeof(uint16_t));
buffer.Flags = XAUDIO2_END_OF_STREAM;
buffer.LoopBegin = 0;
buffer.LoopCount = 0;
buffer.LoopLength = 0;
buffer.pAudioData = (BYTE*)wav.data();
buffer.pContext = nullptr;
buffer.PlayBegin = 0;
buffer.PlayLength = (UINT32)wav.size();

I'm not sure if AudioBytes is correct either.... As you might already know I'm clueless about what to feed into xaudio2.

How can I fill the xaudio buffer with the correct values given from libsndfile?

Thanks.

So, the problem was indeed the format....

So I changed the method to read the audio file from shorts to floats and changed the format from WAVE_FORMAT_PCM to WAVE_FORMAT_IEEE_FLOAT. Also gave it a bits per sample of 32 bits.

And convert the float array to a byte array with reinterpret_cast.... Hope the following code will help others to load file audio files to Xaudio2 buffers with the LibSndFile.

Cheers.

std::vector<float> wav;
    std::array<float, READ_BLOCK_SIZE> read_buf;
    while ((read_size =
        sf_read_float(
            file,
            read_buf.data(),
            read_buf.size())) != 0)
        wav.insert(
            wav.end(),
            read_buf.begin(),
            read_buf.begin() + read_size);
    waveFormat = {};
    waveFormat.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
    waveFormat.nChannels = info.channels;
    waveFormat.nSamplesPerSec = info.samplerate;
    waveFormat.wBitsPerSample = 32;
    waveFormat.nBlockAlign = 
        (waveFormat.nChannels * 
        waveFormat.wBitsPerSample) / 8;
    waveFormat.nAvgBytesPerSec =
        waveFormat.nSamplesPerSec * 
        waveFormat.nBlockAlign;
    waveFormat.cbSize = 0;// sizeof(waveFormat);

    buffer = { 0 };
    buffer.AudioBytes =
        (UINT32)(wav.size() * sizeof(float));
    buffer.Flags = XAUDIO2_END_OF_STREAM;
    buffer.pAudioData = 
        (BYTE*)new BYTE[
            wav.size() * sizeof(float)];
    std::memcpy(
        (void*)buffer.pAudioData, 
        reinterpret_cast<BYTE*>(wav.data()),
        wav.size() * sizeof(float));
    buffer.pContext = nullptr;
    buffer.PlayLength = (UINT32)info.frames;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM