我是汇编语言新手
我们的电脑一直发出声音(mp3、wav、mp4、ogg 等)。
如何用汇编语言直接与说话者交流?在 C 中,您可以使用“Beep()”并将声音的持续时间(以毫秒为单位)和赫兹传递给扬声器。我怎样才能用 GNU 汇编语言做到这一点?
我的电脑规格: 戴尔 Optiplex 960; Ubuntu 23.04 LTS x86-64 架构。
有人可以留下并举例说明如何做到这一点吗?粘贴一些源代码? 对每条指令的相对作用留下评论也会非常有帮助。
我试图找到一些教程,但有点迷失了。大多数 NASM 教程(不像我使用的 GNU)都会使用系统默认声音,即Windows 上的铃声,或 Linux Ubuntu 上的通知声。
更新:根据 Dell Optiplex 960 的在线服务手册,内置扬声器是可选设备。因此,您的计算机可能没有内置扬声器,并且有关使用 PC 扬声器接口的评论和答案不会有太大帮助。关于 PCM 音频的一些评论位于此答案的底部。
由于我多年来一直在维护常见的 Linux 蜂鸣实用程序 https://github.com/spkr-beep/beep,我建议在 Linux 上为 PC 扬声器使用正确的 API,而不需要特权访问。
这相当于一个程序
open(2)
众所周知的设备文件/dev/input/by-path/platform-pcspkr-event-spkr
struct input_event
(在linux/input.h
中定义)与e.type = EV_SND
,e.code = SND_TONE
,e.value = frequency_in_Hz
(0
的频率将使PC扬声器静音)write(2)
该结构到文件描述符close(2)
文件描述符所以基本上,您只需要编写一个程序,将几个字节写入文件即可。
如果您希望您的程序启动一个提示音,然后等待,然后停止该提示音,您的程序还需要等待定义的时间。
nanosleep(2)
系统调用和来自 struct timespec
的 time.h
可以为您提供帮助。
这让您只需要弄清楚如何执行系统调用
open(2)
、write(2)
和 close(2)
。好吧,如果您事后 close(2)
,那么 exit(2)
并不是真正需要的,并且 nanosleep(2)
可能也是必需的。
汇编中的任何 Linux“hello world”程序都应该是一个很好的起点:它已经实现了
write(2)
和 exit(2)
,这应该是从添加其他系统调用开始的好地方。
请注意,您可能需要显式安装并加载
pcspkr.ko
内核模块,并确保您的计算机确实连接了物理 PC 扬声器(扬声器或压电蜂鸣器)。安装操作系统的 beep
软件包可以为您节省一些手动系统管理工作。
如果您想通过 PCM 音频而不是通过 PC 扬声器产生声音,API 可能会比仅仅将几个字节写入一个文件更复杂。虽然为 PCM 音频准备一个简单的内存缓冲区,使用方波到
write(2)
到 open(2)
ed PCM 音频设备具有相当的复杂性,但处理缓冲区耗尽和重新填充缓冲区将更加复杂,就像处理不同的缓冲区一样。 PCM 声音 API。