从 C 代码中获取 ALSA 峰值

Posted

技术标签:

【中文标题】从 C 代码中获取 ALSA 峰值【英文标题】:Get ALSA peak value from C code 【发布时间】:2013-09-04 04:36:11 【问题描述】:

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

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

【问题讨论】:

完全不清楚你想获得哪个信号的瞬时音量;输入(麦克风)或输出(正在播放什么)?两个都?我猜是后者,但@TheCodeArtist 似乎猜是前者。基本上,这个问题令人困惑。 我很抱歉造成混乱。我已经更新了我的问题,我指的是仅检测扬声器/播放输出。就像标准的峰值/分贝计一样。 @unwind 是的,我的印象是错误的。不过,似乎没有一种直接的方法可以完成操作所需的操作。 This answer 是我能想到的一个绝望的解决方法...... 【参考方案1】:

ALSA 没有当前的音频峰值。

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

【讨论】:

这允许程序只分析自己播放的音频。在系统的播放设备上实际播放的音频还包括其他程序同时播放的流。【参考方案2】:

使用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;

然而,我仍然怀疑这是一个很好的解决方案。

【讨论】:

以上是关于从 C 代码中获取 ALSA 峰值的主要内容,如果未能解决你的问题,请参考以下文章

从 C 代码中以 dB 为单位设置 ALSA 主音量

如何使用 C# 使用 ALSA 在 Linux 中获取和设置音量?

如何编写 C 应用程序代码来测试 linux 音频驱动程序

从 ALSA Raspberry Pi 获取音频幅度

我从 wav 文件中获取峰值频率。但是对于录制的 2 个频道 wav,它不起作用

C#获取话筒主峰值(实时音频输出分贝量)