将 Libsndfile 与 xaudio2 集成

问题描述

我正在尝试将 libsndfile 与 xaudio2 集成。我在互联网上找不到太多,所以我会在这里问。

我成功地将 libsndfile 与 OpenAL preatty 轻松集成,但我正在努力使用 xaudio2

它会产生爆裂声和噼啪声。我确定是因为我没有给出 xaudio 期望的正确格式......但我似乎无法弄清楚应该将哪些值发送到 xaudio2

这是我加载声音文件的方式...

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);

所以 wav 向量被 uhsorts 填充,而 xaudio 需要一个 BYTE 数组......不确定这是否也是一个问题。

info 填充您所知道的声音文件信息。

这就是我填充 xaudio 缓冲区的方式。

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();

我也不确定 AudioBytes 是否正确......正如您可能已经知道的那样,我对 xaudio2内容一无所知。

如何使用 libsndfile 提供的正确值填充 xaudio 缓冲区?

谢谢。

解决方法

所以,问题确实是格式......

所以我改变了读取音频文件的方法,从shorts到float,并将格式从WAVE_FORMAT_PCM改为WAVE_FORMAT_IEEE_FLOAT。 还给它一个 32 位的样本。

并使用 reinterpret_cast 将浮点数组转换为字节数组.... 希望以下代码能帮助其他人使用 LibSndFile 将文件音频文件加载到 Xaudio2 缓冲区。

干杯。

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;