从 C 代码中以 dB 为单位设置 ALSA 主音量
Posted
技术标签:
【中文标题】从 C 代码中以 dB 为单位设置 ALSA 主音量【英文标题】:Set ALSA master volume in dB from C code 【发布时间】:2013-10-29 15:20:57 【问题描述】:我似乎无法在我的机器上以 dB 为单位设置音量。
我在 VirtualBox 中运行 Ubuntu 13.04 系统(用于开发)。
我按照这些说明前往set the volume as scalar 和control the mute state,一切正常。
但是当我尝试用这个函数将它设置为 dB 时
snd_mixer_selem_set_playback_dB_all(elem, volume, 0)
或使用该功能
snd_mixer_selem_set_playback_dB(elem, chn, volume, 0)
它总是失败,错误代码 -22(无效参数)
在您问之前:我已经尝试了多种音量级别来设置(从 -20000 到 20000),并且我还将最后一个参数更改为三个定义的值 [-1, 0, 1]
这是我现在测试的完整代码:
#include <alsa/asoundlib.h>
#include <stdbool.h>
#include <stdlib.h>
void SetAlsaMasterVolume(long volume)
long min, max;
snd_mixer_t *handle;
snd_mixer_selem_id_t *sid;
const char *card = "default";
const char *selem_name = "Master";
int x, mute_state;
long i;
snd_mixer_open(&handle, 0);
snd_mixer_attach(handle, card);
snd_mixer_selem_register(handle, NULL, NULL);
snd_mixer_load(handle);
snd_mixer_selem_id_alloca(&sid);
snd_mixer_selem_id_set_index(sid, 0);
snd_mixer_selem_id_set_name(sid, selem_name);
snd_mixer_elem_t* elem = snd_mixer_find_selem(handle, sid);
//snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
//snd_mixer_selem_set_playback_volume_all(elem, volume * max / 100);
snd_mixer_selem_get_playback_dB_range(elem, &min, &max);
printf("min: %ld, max: %ld\n", min, max);
snd_mixer_selem_channel_id_t chn;
for (chn = 0; chn < 32; chn++)
for (i = -1000; i <= 1000; i++)
if (x = snd_mixer_selem_set_playback_dB(elem, chn, i, 0))
;//printf("%d: %d %s\n", chn, x, snd_strerror(x));
else
printf("Volume successfully set in dB!\n");
if (snd_mixer_selem_has_playback_switch(elem))
snd_mixer_selem_set_playback_switch_all(elem, true);
snd_mixer_selem_get_playback_switch(elem, 0, &mute_state);
if (!mute_state)
printf("System Muted.\n");
else
printf("System unmuted.\n");
snd_mixer_close(handle);
int main()
SetAlsaMasterVolume(100);
return 0;
正如您在此示例中看到的,我尝试自己设置每个通道,这与“snd_mixer_selem_set_playback_dB_all”所做的相同,但我想尝试一下是否得到不同的结果。
此示例的输出如下所示:
最小:15774463,最大:191
系统取消静音。
在我扩大 dB 值范围之前,我测试的输出是:
最小:1,最大:191
也许我在这里遗漏了一些东西...... 希望你能帮帮我!
编辑:
要编译这个脚本,我使用以下命令:
gcc test.c -lasound -o 测试
【问题讨论】:
15774463 显然是错误的。检查所有函数的返回值。 我已经检查过了。但是 snd_mixer_selem_get_playback_volume_range 例如表现正常(最小值:0,最大值:65536)正如我所提到的,在我尝试将诸如 200000 之类的极高值设置为音量级别之前,最小值的值为 1。我不知道如何重置这个。重启并不能解决问题。 我还检查了 snd_mixer_selem_get_playback_dB 的值,无论我设置什么音量,它总是返回值 15774463。 调用snd_mixer_selem_get_playback_dB_range
的返回值(不是输出参数的值)是什么?
欧。那将是-22(EINVAL):P所以已经有问题了......但是那里可能有什么问题??
【参考方案1】:
我遇到了类似的问题。原因似乎是脉冲音频的干扰。不过,杀死它有点困难。一旦我跑了
mkdir -p ~/.pulse
echo autospawn=no > ~/.pulse/client.conf
killall pulseaudio
pulseaudio 死了又死了,而我正在编写的 ALSA 程序能够从混音器获取 dB 信息。
或者,您可以通过直接与卡交谈来完成 pulseaudio 的结束。改变
const char *card = "default";
到
const char *card = "hw:0";
看看这对你有什么作用。
【讨论】:
以上是关于从 C 代码中以 dB 为单位设置 ALSA 主音量的主要内容,如果未能解决你的问题,请参考以下文章
android2.3采用alsa作为音频系统,在asound.conf中的扬声器音量设置问题。
如何在android java中以像素为单位设置ImageView的边距?