从C代码获取ALSA峰值

时间:2013-09-04 04:36:12

标签: c linux api audio alsa

我正在尝试使用ALSA和C检索当前的音频峰值。我希望将此值设置为介于0.0和1.0(或者可能为0到100)之间的标量。在Windows上,我使用IAudioMeterInformation,这允许我构建一个非常基本的VU表。

编辑:我指的是仅检测扬声器输出,而不是麦克风。

3 个答案:

答案 0 :(得分:1)

ALSA没有当前音频峰值。

在您编写或阅读时,循环遍历样本以获得最大值。

答案 1 :(得分:0)

使用snd_pcm_readi似乎有效,请参阅以下示例:

static float GetLevel (void)
{
    float result = 0.0f;
    snd_pcm_t* waveform;

    // Open and initialize a waveform
    if (snd_pcm_open (&waveform, "default",
        SND_PCM_STREAM_CAPTURE, 0) != 0)
        return 0;

    // Set the hardware parameters
    if (!snd_pcm_set_params (waveform, SND_PCM_FORMAT_S16_LE,
        SND_PCM_ACCESS_RW_INTERLEAVED, 2, 48000, 1, 0))
    {
        // Read current samples
        short buffer[256];
        if (snd_pcm_readi (waveform, buffer, 128) == 128)
        {
            // Compute the maximum peak value
            for (int i = 0; i < 256; ++i)
            {
                // Substitute better algorithm here if needed
                float s = buffer[i] / 32768.0f;
                if (s < 0) s *= -1;
                if (result < s) result = s;
            }
        }
    }

    snd_pcm_close (waveform);
    return result;
}
然而,我仍然持怀疑态度,这是一个很好的解决方案。

答案 2 :(得分:-1)

AFAIK有 NO 方式查询ALSA中的当前音频峰值。


但是如果你真的需要这个,那么实现它的一种方法如下。

  1. 设置虚拟环回设备
    - 创建新的虚拟捕捉设备,只需播放真实播放设备的输出。

  2. 记录简短的样本
    - 从环回设备中捕获几毫秒的瞬时音频样本。

  3. 分析样本的统计数据
    - 计算样本中瞬时音频的峰值音量。

  4. Step1 涉及到   - building and inserting the snd-aloop Linux kernel module
      - setting up the .asoundrc configuration file
    here 可以对整个过程进行详细说明。

    如上所示覆盖default设备后,第2步&amp; 3 只需使用arecordsox的组合即可实现,如下所示:

    $ arecord -Ddefault -d1 -twav -r48000 > rec.wav; \
    sox -V -t wav -r48000 rec.wav -n stat 2>&1 | \
    grep "Maximum amplitude" | awk '{print $3}'
    

    上面的代码片段 - 记录默认输入设备1秒钟 - 使用sox进行分析 - 解析其输出以获得最大振幅。

    要使用C代码计算PCM-wav文件中音频样本的最大幅度,您可以研究source-code of sox。此外,还可以使用C代码段来here here