gstreamer 从缓冲区读取分贝

Posted

技术标签:

【中文标题】gstreamer 从缓冲区读取分贝【英文标题】:gstreamer read decibel from buffer 【发布时间】:2015-09-26 00:12:28 【问题描述】:

我正在尝试获取传入音频样本的 dB 级别。在每个视频帧上,我都会更新 dB 级别并绘制一个代表 0 - 100% 值的条形(0% 是任意值,例如 -20.0dB,100% 是 0dB。)

gdouble sum, rms;
sum = 0.0;
guint16 *data_16 = (guint16 *)amap.data;
for (gint i = 0; i < amap.size; i = i + 2)

    gdouble sample = ((guint16)data_16[i]) / 32768.0;
    sum += (sample * sample);

rms = sqrt(sum / (amap.size / 2));
dB = 10 * log10(rms);

这是从here 标记为答案的代码示例改编为 C 的。我想知道这个非常简单的方程式中缺少什么。

已回答:夹克关于丢失标志的代码是正确的,所以一切最终都是肯定的。代码10 * log(rms) 也不正确。它应该是20 * log(rms),因为我正在将幅度转换为分贝(作为输出功率的度量)。

【问题讨论】:

因为我是个白痴,所以我忘了描述到底是什么问题。从这个等式返回的 dB 值始终介于 +1 到 +5 之间,即使对于非常安静的音频也是如此。 代码看起来是正确的,所以问题很微妙。由于 dB 是正数,这意味着 rms 大于 1。可能总和太大,这将暗示转换为 gdouble 你不能使用关卡元素或者至少是其中的数学吗? 我可以请我从流中读取代码 【参考方案1】:

关卡元素最适合这项任务(正如@ensonic 已经提到的),它旨在满足您的需求..

所以基本上你添加到名为“级别”的管道元素中,然后启用消息触发。

Level 元素然后发出包含 RMS Peak 和 Decay 值的消息。 RMS 正是您所需要的。

您可以设置连接到此类消息事件的回调函数:

audio_level = gst_element_factory_make ("level", "audiolevel");
g_object_set(audio_level, "message", TRUE, NULL);
...
g_signal_connect (bus, "message::element", G_CALLBACK (callback_function), this);

bus 变量的类型是 GstBus.. 我希望你知道如何使用 buses

然后在回调函数中检查元素名称并获取 RMS 描述 here

还有一个带有 pow() 函数的标准化算法可以转换为 0.0 -> 1.0 之间的值,您可以使用它来转换为 % ,如您在问题中所述。

【讨论】:

感谢最后一点。我有一个漂亮的小条被渲染出来,它可以粗略地了解 dB 级别是多少。

以上是关于gstreamer 从缓冲区读取分贝的主要内容,如果未能解决你的问题,请参考以下文章

如何从 gstreamer 中的源请求更多缓冲区?

将输出从 rs_get_frame_data() 传递到 GStreamer

使用 (Python) Gstreamer 解码音频(到 PCM 数据)

有人可以解释这段代码如何使用 Accelerate Framework 将音量转换为分贝吗?

从 tun 设备读取()而不删除从操作系统缓冲区读取的数据

libevent:从缓冲区读取所有字节