在Linux中使用C语言发出蜂鸣声

16

我希望能够使用系统蜂鸣器(如果蜂鸣器不可用/不可访问则仅使用扬声器)生成特定频率和长度(用于不同的声音信号)的哔声声音。我知道可以使用ioctl来实现这一点,但那需要root权限,而我不想要。

我知道可以使用"beep"命令来实现,但这会引入外部依赖项,如果可能的话应该避免使用(完全没有外部依赖项,只使用基本的Linux库和C语言)。

目前我有以下代码(但这需要超级用户权限才能运行):

#include <stdlib.h>
#include <fcntl.h>
#include <linux/kd.h>

int main(int argc, char *argv[])
{
 int fd = open("/dev/console", O_RDONLY);
 if (fd == -1 || argc != 3) return -1;
 return ioctl(fd, KDMKTONE, (atoi(argv[2])<<16)+(1193180/atoi(argv[1])));
}
如果没有其他方法,我会使用蜂鸣声,但我真的想避免依赖并将蜂鸣直接集成到我的脚本中,但我相信这里会有人知道解决方案/变通方法。我不太想要外部库,因为程序应尽可能轻量化。

如果在桌面环境下运行,则可以使用ALSA。您还可以使用“play”命令...有些桌面环境会有通知... - Basile Starynkevitch
@BasileStarynkevitch,这样做会不会过于复杂了?我只想要一个特定频率和长度的简单蜂鸣声。正如我已经告诉Pablo的那样,我希望尽可能保持轻量级,但我想使用beep或suid来获取root访问权限是正确的方法,对吗? - omnidan
看看这个链接是否有帮助:https://dev59.com/okbRa4cB1Zd3GeqPxiRO。@paxdiablo声称它也可以从用户账户中运行。 - Pavan Manjunath
@PavanManjunath 我之前看过这篇文章,但它只是给我返回了“无法打开/dev/console进行写入。打开:权限被拒绝”。 - omnidan
toot 是一个跨平台的 C 文件,尝试调用多个声音生成器来产生蜂鸣声。 - renataflow
5个回答

7
请查看标准的Linux beep源代码。 http://www.johnath.com/beep/beep.c 它使用KIOCSOUND ioctl来“哔哔”声,但您不需要超级用户权限即可播放。 我已将其配置为可由“beep”组中的用户读取和执行。
因此,我的标准用户UID 1000位于GID 501的组中(我称之为“beep”)。 接下来,我必须chmod 4750 /usr/bin/beep,现在我可以播放20-20000Hz范围内的蜂鸣声而无需请求超级用户权限。

4
最基本的蜂鸣声仍然是 '\a' ,如果您的终端支持它:
fprintf(stdout, "\aBeep!\n" );

是的,但那只是一个频率。 - omnidan
我说它很基础...对此感到抱歉。(这个反应可能仍然对以后访问此页面的人有用。) - wildplasser

3

我认为唯一的方法是使用suid来赋予我的程序root权限,或者使用已经有suid的beep。我想我只需要添加一个依赖项,因为beep也不算太大。

谢谢所有的回答,我相信其他库对于更复杂的信号很棒,但我需要一个非常简单的!

我认为这个问题可以标记为已解决/关闭了。

如果有人找到了在没有超级用户权限的情况下创建蜂鸣声的方法,我仍然对此解决方案感兴趣 :)

再次感谢大家。


1

使用open("/dev/tty", O_RDONLY);代替/dev/console可以在终端控制台上正常工作,而不需要超级用户权限即可使用声音。但是,在X会话中的虚拟控制台将无法使用声音,即使是超级用户也无法使用。


有一个 beep 命令,就像在 https://github.com/NaWer/beep/tree/master/Music 中一样。 - U. Windl

0

尝试使用音频库,例如OpenAL


我希望让程序尽可能保持轻量级。 - omnidan
然后只需输出一个响铃字符\a,将声音制作留给终端仿真器。当然,您无法更改该声音的音调和音量... - Basile Starynkevitch
@BasileStarynkevitch 当然,那也是可能的,但我想要特定的频率来稍微区分一下信号。 - omnidan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接