#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/kd.h>
int main(void)
{
int freq[] = { /* C D E F G A B C */
523, 587, 659, 698, 784, 880, 988, 1046 };
int i;
for (i=0; i<8; i++)
{
ioctl(STDOUT_FILENO, KIOCSOUND, 1193180/freq[i]);
usleep(500000);
}
ioctl(STDOUT_FILENO, KIOCSOUND, 0); /*Stop silly sound*/
return 0;
}
6条答案
按热度按时间4ktjp1zp1#
取自here:
s3fp2yjn2#
可以,打开一个控制台设备(例如/dev/console或/dev/tty 0),然后向其发出KIOCSOUND ioctl命令,如console_ioctl(4)手册页中所述。
这是令人厌恶的和Linux特有的,但我认为它回答了你的问题。
编辑:难以置信的是,ALSA的内核中有一个PC扬声器驱动程序,它可以让你在PC扬声器中播放数字声音。它的音质会很差,而且会占用很多CPU:)
bgibtngc3#
如果您 * 真的 * 想这样做,请查看beep命令的源代码:http://www.johnath.com/beep/beep.c
wr98u20j4#
如果芯片组中仍然有一个8253等效物连接到类似扬声器的东西,您可以根据数据表寄存器或古老的PC指南(我很欣慰地承认,我的头脑中不再有这些信息)从内核模块或以root身份调用ioperm()后访问它。
曾经也有一个内核PWM“模拟”音频驱动程序用于PC扬声器。我相信那是我第一次编译内核。那是在内核模块出现之前,或者至少是在它们进入流行发行版之前。
7fyelxc55#
在我使用Ubuntu 16.04的情况下,“ioctl”函数不起作用。
所以,最后,下面的代码在没有安装任何附加库的情况下运行良好。
字符串
如果代码的文件名为“beep.c”,则可按如下方式编译:
gcc哔声. c-激光声-lm -o哔声
并且可以如下执行:
./哔声
f4t66c6m6#
计时器甚至存在于现代系统中的地址0x41 .. 0x43和0x61上。(我在Forth中有代码,运行在8核AMD的MSI主板上)。使用0x65 ioperm系统调用(允许解锁端口)并以root权限运行解决了玩音阶的罗塞塔代码挑战。
将0xB6存储到地址0x43(解锁定时器)
将频率的低字节设置为0x42,然后设置高字节。(选择例如2000作为频率)
通过将3存储到端口0x61开始发出蜂鸣声
这是玩音阶的罗塞塔代码挑战。Musical_scale
Forth代码是最具启发性的。