如何使用 alsa 库 API 与耳机和扬声器一起使用?
Posted
技术标签:
【中文标题】如何使用 alsa 库 API 与耳机和扬声器一起使用?【英文标题】:How to use alsa library API to work with Headphone and Speaker? 【发布时间】:2019-09-14 09:37:40 【问题描述】:我想使用 c 程序为扬声器和耳机实现(静音/取消静音和音量增大/减小)。使用 amixer 命令行实用程序,如此链接 https://askubuntu.com/questions/371970/how-to-switch-between-headphones-and-speakers-manually-from-command-line 所示,它可以工作,我需要使用 C 程序实现相同的东西.
所以我尝试了不同的方法。 我看到了这个关于 Master 音量控制的例子 Set ALSA master volume from C code
对于主控的静音/取消静音 Linux ALSA/Sound-API Questions - How do you mute?
这两种解决方案都非常适合主配置。 但在我的情况下,我想为扬声器和耳机实现相同的功能。因此,如果我用扬声器或耳机+L0 替换 selem_name 而不是“Master”,我发现使用 amixer 命令会引发错误。
这里我需要将“扬声器”或“耳机”静音/取消静音。
如果我在下面的代码中使用 *selem_name = "Speaker" 或 "Headphone",则会引发如下所示的错误:
是否给定的selem_name 无效? 如果是这样,我如何列出扬声器和耳机的有效 selem_name? 我使用它从 amixer 命令行实用程序中找到的那个。
我必须为扬声器和耳机使用什么 API?
Errorr eturn by test.c program:
alsa: simple.c:346: snd_mixer_selem_has_playback_switch: Assertion
`elem' failed.
Aborted
//test.c
#include<stdio.h>
#include<alsa/asoundlib.h>
void SetAlsaSpeakerMute()
snd_mixer_t *handle;
snd_mixer_selem_id_t *sid;
const char *card = "default";
const char *selem_name = "Speaker";
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);
if (snd_mixer_selem_has_playback_switch(elem))
snd_mixer_selem_set_playback_switch_all(elem, 0);
snd_mixer_close(handle);
int main()
SetAlsaSpeakerMute();
return 0;
//For const char *selem_name = "Master" this program works fine.
//This can mute Mixer of default sound card
void SetAlsaMasterMute()
snd_mixer_t *handle;
snd_mixer_selem_id_t *sid;
const char *card = "default";
const char *selem_name = "Master";
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);
if (snd_mixer_selem_has_playback_switch(elem))
snd_mixer_selem_set_playback_switch_all(elem, 0);
snd_mixer_close(handle);
是否有任何解决方案可以将特定设备(扬声器和耳机)静音/取消静音?感谢所有帮助。
【问题讨论】:
哪一行是simple.c:346
?
返回错误信息。它显示位于 alsa 库文件 simple.c 中的 alsa 库函数 snd_mixer_selem_has_playback_switch() 给出错误。
此代码缺少错误处理。对于任何返回错误代码的函数,你必须检查它。
是的。但它只是一个示例代码。它不能解决我关于静音/取消静音耳机和扬声器@CL的问题
我认为这个问题不值得结束——它是关于(libalsa 的)编程的。
【参考方案1】:
同样,对于您正在使用的控件名称,elem 变量似乎为 NULL。
您应该检查混音器连接的控制 ID(名称、索引、接口)和控制设备。 “默认”设备名称通常重定向到脉冲音频(仅 Master / PCM 控件)。如果您对 amixer 使用 '-c 0',正确的设备名称是 'hw:0' (const char *card = "hw:0";)。
【讨论】:
以上是关于如何使用 alsa 库 API 与耳机和扬声器一起使用?的主要内容,如果未能解决你的问题,请参考以下文章