【问题标题】:Controlling audio volume in real time实时控制音量
【发布时间】:2013-03-24 11:19:57
【问题描述】:

我目前正在结合使用libsndfilePortAudio V19 从文件中读取音频数据并进行播放。 (请注意,我是在运行 Raspbian 的 Raspberry Pi 上执行此操作的。)我遇到的问题是我需要为以这种方式播放的每个音频样本实时动态控制播放音量。我尝试使用系统调用通过 alsamixer 来操纵全局播放音量,这在我的用例中是一个可以接受的解决方案,但是延迟太高而无法工作。

我正在寻找的是两件事之一:

  • 一个可以处理实时修改音频音量的库,可以通过对 libsndfile 检索到的原始音频数据进行操作,或者通过设置具有最小延迟(亚毫秒)的全局播放音量。该库必须是免费的(免费)并可在 Raspbian 上使用;许可不是问题。

  • 需要对 libsndfile 检索到的音频数据应用数学变换,以修改数据的音量级别,最好是目标音量在 [0.0f, 1.0f] 范围内, 0.0f 是静音,1.0f 是文件中的原始卷。

我试图到处寻找有关此主题的有用(免费)材料,但未能找到任何有用的东西。非常感谢任何帮助!

【问题讨论】:

    标签: c raspberry-pi audio-processing portaudio libsndfile


    【解决方案1】:

    您可以通过对每个样本应用乘数来控制 PCM 音频流的幅度。您可以在将每个缓冲区(样本集)传递给 PortAudio 之前执行此操作。很简单:

    float buffer[SAMPLES_PER_BUFFER];
    const float volumeMultiplier = 0.2f;
    for(int i = 0; i < SAMPLES_PER_BUFFER; ++i)
    {
       buffer[i] *= volumeMultiplier;
    }
    

    但是,诀窍在于如何计算乘数。通常,在将整体信号电平减半 volumeMultiplier = 0.5f 之前,您不会注意到信号电平有太大变化。正如您可能知道的那样,人耳感知的音量变化不是线性的,而是对数的。以下链接可能有助于解释这个概念:

    使用此信息可能会更改上面的代码:

    float buffer[SAMPLES_PER_BUFFER];
    //volume in dB 0db = unity gain, no attenuation, full amplitude signal
    //           -20db = 10x attenuation, significantly more quiet
    float volumeLevelDb = -6.f; //cut amplitude in half; same as 0.5 above
    const float VOLUME_REFERENCE = 1.f;
    const float volumeMultiplier = (VOLUME_REFERENCE * pow(10, (volumeLevelDb / 20.f);
    for(int i = 0; i < SAMPLES_PER_BUFFER; ++i)
    {
       buffer[i] *= volumeMultiplier;
    }
    

    出于您的目的,这可能并不重要,但如果您要将 volumeLevelDb 或 volumeMultiplier 的值附加到滑块小部件等用户界面,则差异会很明显。

    您可以将此算法应用于任何数据类型。

    【讨论】:

    • 对不起,我正在尝试学习PortAudio,我猜我们在回调函数中这样做,如果要调整音量我只需将一个值传递给缓冲区我该如何调整频率?从 doc/src/tutorials 中的示例来看,在我看来,我们也将频率传递给缓冲区,如果是这样,那么它如何知道哪个是哪个(频率或音量)?
    • @platinoob_ 我必须知道你在看哪个例子。我的示例操作 PCM 流的各个样本。幅度值不是简单地传递给函数。操纵流的频率也是如此。这在很大程度上取决于您的用例。你应该考虑用你的代码发布你自己的问题。
    • 我对 PortAudio 输出提出了一般性问题,实际上是我在此评论中的问题,但更通用,链接:stackoverflow.com/q/65806332/12690890
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多