【问题标题】:Fixing Real Time Audio with PortAudio in Windows 10在 Windows 10 中使用 PortAudio 修复实时音频
【发布时间】:2021-04-04 08:16:59
【问题描述】:

几年前我创建了一个应用程序,它允许我通过将 6 通道或 8 通道(即 5.1)缩混为 7.1 作为矩阵立体声编码来处理音频,为此我使用了 portaudio 库,效果很好,这是一个示例用于缩混 7.1 信号的开放流函数和回调

 Pa_OpenStream(&Flujo, &inputParameters, &outParameters, SAMPLE_RATE, 1, paClipOff, ptrFunction, NULL);

注意使用的 framesPerBuffer 值只有一 (1) 个,这是我的回调函数

int downmixed8channels(const void *input, void *output, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo * info, PaStreamCallbackFlags state, void * userData)
{
    (void)userData;
    (void)info;
    (void)state;
    (void)framesBuffer;

    float *ptrInput = (float*)input;
    float *ptrOutput = (float*)ouput;

    /*This is a struct to identify samples*/

    AudioSamples->L = ptrInput[0];
    AudioSamples->R = ptrInput[1];
    AudioSamples->C = ptrInput[2];
    AudioSamples->LFE = ptrInput[3];
    AudioSamples->RL = ptrInput[4];
    AudioSamples->RR = ptrInput[5];
    AudioSamples->SL = ptrInput[6];
    AudioSamples->SR = ptrInput[7];

    Encoder->8channels(AudioSamples->L,
        AudioSamples->R,
        AudioSamples->C,
        AudioSamples->LFE,
        MuestrasdeAudio->SL,
        MuestrasdeAudio->SR,
        MuestrasdeAudio->RL,
        MuestrasdeAudio->RR,);


    ptrOutput[0] = Encoder->gtLT();
    ptrOutput[1] = Encoder->gtRT();


    return paContinue;
}

如您所见,输出和输入缓冲区中的索引设置的顺序对应于离散通道 在输出的情况下,0 = 左声道,1 = 右声道。这曾经运行良好,直到进入 Windows 10 2004,因为我将我的系统更新到这个新版本,我的音频故障并且我得到了类似的工件

这些是从窗口的音频设备面板下的通道测试窗口的声音中捕获的。通过图像很清楚我的程序正在丢帧,所以第一次尝试解决这个问题是使用一个比一个更大的缓冲区来保存样本处理它们然后发送,原因我在第一次没有使用大于一个的缓冲区大小地方是程序会掉帧。

但在实现 a 之前,我做了一个概念验证,根本不包括音频处理,即从输入到输出的简单数据传递,因为我将输出 channelCount 参数设置为 8,就像输入一样,产生了一些结果就这么简单。

    for (int i = 0; i < FramesPerBuffer /*1000*/; i++)
    {
        ptrOutput[i] = ptrOutput[i];
    }

但程序仍在丢弃样本。

接下来我使用了两个回调,一个用于写入缓冲区,另一个用于读取缓冲区并将其发送到输出

    (void)info;
    (void)userData;
    (void)state;
    (void)output;
    
    float* ptrInput = (float*)input;

    for (int i = 0; i < FRAME_SIZE; i++)
    {
        buffer_input[i] = ptrInput[i];
    }

    return paContinue;

回调到存储。

    (void)info;
    (void)userData;
    (void)state;
    (void)output;

    float* ptrOutput = (float*)output;

    for (int i = 0; i < FRAME_SIZE; i++)
    {
        AudioSamples->L = (buffer_input[i] );
        AudioSamples->R = (buffer_input[i++]);
        AudioSamples->C = (buffer_input[i++] );
        AudioSamples->LFE = (buffer_input[i++]);
        AudioSamples->SL = (buffer_input[i++] );
        AudioSamples->SR = (buffer_input[i++]);

        Encoder->Encoder(AudioSamples->L, AudioSamples->R, AudioSamples->C, AudioSamples->LFE, 
        AudioSamples->SL, AudioSamples->SR);

        bufferTransformed[w] = (Encoder->getLT() );
        bufferTransformed[w++] = (Encoder->getRT() );
    }

    w = 0;

    for (int i = 0; i < FRAME_REDUCED; i++)
    {
        ptrOutput[i] = buffer_Transformed[i];
    }

return paContinue;

处理回调

处理回调使用每个缓冲区减少的帧数,因为 2 通道小于 8,因为在 portaudio 中,帧似乎由每个音频通道的样本组成。

这也没用,既然第一个问题,是如何同步两个回调?,毕竟,有什么建议或建议,可以给我解决这个问题,

注意:两个设备的采样率必须相同,我在程序中实现了逻辑来防止这种情况,位深度也相同,我使用的是 paFloat32, .portaudio 是 audacity 修改后的用途,因为我想使用他们的 WASAPI 实现 环回

提前非常感谢!

【问题讨论】:

    标签: c++ windows audio real-time portaudio


    【解决方案1】:

    归根结底,我不必以任何方式更改我的回调函数,解决它的方法是将输入和输出参数的参数“.suggestedLatency”更改或增加到 1.0,甚至设备defaultLowOutputLatency 或 defaultHighOutputLatency 值会导致很多故障,我对其进行测试,直到 1.0 成为 de sweepspot,更高的值并没有改善。

    TL;DR 增加了建议的延迟,直到故障消失。

    【讨论】:

      猜你喜欢
      • 2021-01-21
      • 2019-07-30
      • 1970-01-01
      • 2012-12-16
      • 2012-09-18
      • 2017-11-22
      • 2023-01-09
      • 2016-06-27
      • 2014-04-29
      相关资源
      最近更新 更多