有没有办法播放 WAV /dev/console
?(无需 root 权限)
和 shell 命令一样
/dev/urandom > /dev/console
产生随机声音
cat music.wav > /dev/console
不起作用。
我可以使用/dev/dsp
,但声音不是来自内置 PC 扬声器。
答案1
TL; DR
不可以。使用aplay
或mplayer
。
为什么不?
您的想法有两个问题。首先,写入/dev/console
会导致写入的字符显示在系统控制台中,这通常用于向用户显示错误通知(我相信),而不是用于播放声音。如果您以某种方式通过写入获得声音,我猜这是因为每个字符都是 的概率为 1/256,这会发出短暂的哔哔声。
第二个问题是,即使.wav
音频流不那么复杂,并且(通常)不像许多其他格式那样经过压缩,它也不是原始的、明确的音频流。事实上(如果我没记错的话)永远不可能存在原始的、明确的音频流。您总是(至少)需要一个指定样本分辨率和速率的标头,以便对数据进行任何有用的操作。如果 Linux 内核的职责之一是解码各种音频格式,我会感到非常惊讶。这通常最好由用户空间中的程序来完成。
题外话:
Windows 9x 系列(至少是其中的一部分)在内核中对图标进行图像解码。事实证明,这是一个不太好的想法,并导致了许多次蓝屏。
建议的解决方案
如果您想从命令行播放 wav,有一系列程序可以为您解码文件并将其传达给内核,通常使用 ALSA 接口。我建议使用 aplay,它在大多数系统上都可用,而且相当简单,或者 mplayer,它也广泛分布,但复杂度要大得多。如果您的系统支持声音,那么很可能至少安装了其中一个。
答案2
这应该是可能的,但你是否同意所产生的质量则是另一回事。
首先,wav 是脉冲编码调制 (pcm),pc 扬声器基本上是一个开启或关闭的故事,因此有两个选项......分析 wav 想要实现的频率(如果同时有多个频率,则会很难)然后让扬声器重现该频率,或者接受它只能“开启”或“关闭”的事实,如果 wav 中的数据达到某个预设音量/pcm 阈值,则只需“打开或关闭”即可。
此外,wav 的采样率可能比扬声器硬件所能处理的采样率高得多(对此并不确定,但不能设置除‘物体可以处理的电压’或‘零’之外的其他振幅,而中间没有任何中间值,这是这里更大的问题。
现在...对于方法 1,您要研究的是 ioctl(x,KIOCSOUND,1193180/desired-freq-in-hz); 0 显然表示关闭。/dev/console 上 fd 上的 KDMKTONE ioctl 似乎应该在 jiffies 中指定的时间段内产生指定的音调。
但是如果你想正确地做这件事,我会拿起扬声器所连接的芯片的数据表,直接处理这个问题,甚至不用理会/dev/console 或任何 linux 的东西……所以你确实可以,只需打开电压,或者关闭它。这会发出 pcm 调制的声音……只是在“响亮”和“无”之间没有任何幅度变化。
可能所有方法听起来都很糟糕......但对于通常同时包含多个频率的音乐来说,首先分析频率然后播放频率是行不通的。
整个 ioctl KIOCSOUND/KDMKTONE 似乎依赖于内核中的时钟周期设置,以及 /dev/console 的存在和打开的文件描述符。它们似乎不仅仅是“寻址与 PC 蜂鸣器相连的芯片的 i/o 引脚”。
可编程中断定时器 (PIT) intel 8259 i/o 端口 $0042 r/w PIT 计数器 2、盒式磁带和扬声器 (XT、AT、PS/2)
基本上,通常的方法是用所需的频率对其进行编程,然后它会发出哔哔声,但您想要的只是“开”或“关”,所以基本上是 0hz 或非常低的 hz,然后当来自 wav 的数据从“1”变为 0 时重新编程 PIT 以再次将其关闭...等等。处理 wav 文件的采样率取决于软件。(取平均值或如果太高则跳过样本 - 无论如何它是模拟的,您只能产生数字输出;)