家庭娱乐 Linux MP3 播放器
想象一下,您躺在客厅沙发上,手持遥控器。您按下频道选择按钮,一个合成的声音说出“另类”。您继续按频道向上按钮,声音说出不同的音乐类别:“儿童”、“古典”和其他。您选择了“古典”类别,并在遥控器上按下 ENTER 键,声音开始以同样的方式列出专辑。您选择“约翰·威廉姆斯,西班牙吉他音乐”,接近 CD 音质的吉他音乐开始播放。
不,音乐不是从 CD 换碟机播放的,合成的声音实际上是交互式的,响应您的遥控器操作。存储的音乐是您完整的 CD 收藏,加上那些旧磁带(不知何故还在),数字化并压缩为 MP3 文件。整个播放过程由隐藏在您壁橱中的 Linux 服务器控制和播放,该服务器通过音频线连接到您的家庭娱乐放大器。
当我意识到上述情景已经触手可及时,我决定编写缺失的部分,并将它们以某种方式粘合在一起。
遥控器是我设计的核心部分。我使用的控制器名为“MouseREMOTE”,是“BigPicture”软件包的一部分,该软件包允许您将计算机的音频/视频信号远程传输到电视。作为一个“控制狂”,我之前购买了整个软件包,并将所有房屋灯光设置为远程控制。远程鼠标特别有用,因为它像任何其他音频/视频组件的控制器一样工作(它还可以控制基于 X-10 的家庭自动化设备)。除了通用遥控器上常见的其他所有按钮外,它还在正面有一个橡胶鼠标垫,在设备背面有两个按钮。当按下按钮时,控制器会向接收器单元发送射频信号,当接收器单元的按钮被按下时,它具有常规计算机鼠标直通功能,因此您仍然可以使用常规的串行或 PS/2 鼠标。远程鼠标软件数据包将插入到常规计算机鼠标发送的数据包流中。不幸的是,MouseRemote 仅附带 MS Windows 软件来为不同的按键分配操作。我安装了一条高质量音频线,从服务器机房的 Linux 声卡线路输出连接器一直连接到客厅放大器单元的 RCA 输入。
这就是我在硬件方面需要做的全部工作。对于软件支持,我必须修改鼠标服务器程序以接受 MouseRemote 单元发送的代码,并将它们管道传输到 MP3 播放器程序,该程序将根据远程鼠标的选择执行不同的功能。
我通过使用修改后的 gpm 程序读取代码来确定 MouseRemote 规范。MouseRemote 被检测为裸鼠标类型,并且每个事件返回三个字节的数据包。表 1 显示了事件返回的代码。如您所见,几乎所有按键都会返回一些代码,这使这款遥控器具有巨大的潜在通用性。
有一些特殊之处:鼠标按钮代码(位于控制器单元底部的左/右按钮)连续传输三次。一次只能按下一个按钮;当第一个按钮被按下时,另一个按钮将被忽略。您可以按住一个鼠标按钮并按下任何按键。如果您按住鼠标按钮,代码不会开始重复;只有鼠标垫(鼠标移动)代码会重复,没有明显的延迟。所有其他按键都以大约 1/20 秒的短延迟重复。
鼠标移动垫检测到三个级别的压力,鼠标驱动程序软件可以使用这些压力来加速移动。这些级别设置鼠标数据包中第二个和第三个字节的位 0、1 和 2。这些字节用于确定两个连续数据包之间移动的差异,因此压力越 Firm,移动速度越快。
我决定修改鼠标服务器 gpm(版本 1.13)。添加的关键功能是 gpm.c 文件中的 x10codes(参见代码清单 1)。函数参数 data 是一个由三个字节组成的数组,构成当前的鼠标数据包。MouseRemote 设备的检测不是确定性的。我依赖于其所有按钮都在特定范围内返回代码的属性;也就是说,正常鼠标移动返回的代码的可能但不概率的组合范围。特别是,第一个代码始终在 44 到 47 的范围内,第三个代码始终为 0x3F。普通鼠标必须以恰到好处的速度快速移动才能获得相同的代码。在不太可能发生的情况下,第二层安全措施是命名管道 /dev/x10 的存在。如果管道不存在,数据包将继续进行正常处理。我使用该命名管道连接到远程鼠标代码的读取器。
在所有可用于 Linux 的 MP3 播放器程序中,只有 mp3blaster 具有足够友好的用户界面,可以轻松控制要播放的目录和文件。该程序支持多个组,并且可以在目录之间进行交互式选择。我决定同时使用这两个功能。所有专辑都存储在不同的组中,并且在任何时候,我都可以切换到目录浏览并按层次结构选择专辑。预先录制的语音文件很好地指导您所处的位置和正在执行的操作(请参阅语音合成)。
假设您的所有 MP3 文件都位于某个分层目录结构中,例如在 /home/mp3 中,您需要将环境变量 MP3_ROOT 设置为它。这样,播放器将知道文件在哪里,并且在目录浏览期间,它将不允许您意外地将目录更改为高于它的目录。(请记住,我们离键盘和显示器太远,无法修复任何意外。)
mp3blaster 通过 -x 选项调用,我添加了该选项以激活所有远程功能。
为了充分利用 mp3blaster 的组功能,您需要手动将当前工作目录设置为 MP3_ROOT 目录(您的音乐层次结构开始的位置),启动 mp3blaster 并按下 F1、F5 键。F5 功能键会将所有目录添加为组,从而有效地列出您的所有专辑。然后,您可以通过按 F6 键保存列表。因此,现在,您将使用以下语法启动 mp3blaster
/usr/bin/mp3blaster -l
如果您愿意,可以从 init 脚本或空闲控制台运行该程序;这无关紧要,因为它将连接到遥控器单元并在后台执行其功能。现在,使用您的遥控器,您就能够浏览目录和播放歌曲。如您所见,语音合成也被编码进来以给您反馈。
mp3blaster 有两种操作模式:组和文件。组操作模式接受以下遥控器按键
频道 +:选择下一个专辑(组)。语音将播报专辑名称。
频道 -:选择上一个专辑(组)。语音将播报专辑名称。
播放/Enter:播放整个专辑。
A*B:此按键在组和文件选择模式之间切换。
文件选择模式更复杂,因为我们允许遍历目录结构并播放任意专辑。此模式下接受的遥控器按键为
频道 +:选择下一个子目录。语音将说出其名称。
频道 -:选择上一个子目录。语音将说出其名称。
A*B:此按键在组和文件选择模式之间切换。
POWER:切换到组模式。
播放/Enter:进入子目录并播放那里的所有 mp3 文件。
Shift:返回上一级目录。
播放:暂停后继续播放。
停止:停止播放,返回到我们开始播放的模式。
暂停:暂时停止播放。
音量 +:增加音量。
音量 -:降低音量。
Rew:播放上一首歌曲。
FF:播放下一首歌曲。
查看代码,将操作插入到 mp3blaster 的输入循环中的过程可以被视为有点 hacky,但大多数代码只是作为按键插入,这些按键无论如何都会为键盘的等效操作按下。更改的数量相当大,无法在此处打印,因此请参阅文件 src/main.cc 了解详细信息。
当想要在没有电脑显示器引导的情况下浏览您的 mp3 音乐专辑时,视觉的自然替代品是声音。我决定使用 festival,这是一个优秀的语音合成软件包。它不仅是一个当前的研究开发项目,每天都在增长和改进,而且是您安装后即可立即使用的项目。
festival 可以即时生成语音,当您以交互方式键入任何文本时,或者您可以管道输入文本文件,它将合成它。这些实时方法似乎都不够快,无法用于交互式菜单选择。我需要立即的语音响应,而即时生成会引入与专辑名称长度成正比的延迟,这对于正常使用来说是明显的且令人恼火的。解决方案是创建一个子目录,其中包含浏览期间要使用的所有语音文件。这样,MP3 播放器程序不必在浏览每个专辑名称时调用 festival 来生成它,而是可以使用缓存在该特定目录中的波形文件。这种方法的缺点是语音文件占用的磁盘空间,但与每个专辑 50 到 60MB 的实际 MP3 文件相比,该空间可以忽略不计。
一旦您使用 festival 程序生成语音文件,您可以通过简单地将它们管道传输到 /dev/audio 来测试每个文件。此外,您可能想要更改某些专辑的双元音(我发现西班牙双元音使国际专辑组的发音更好)。或者,您可以手动录制所有语音文件,从而消除对语音合成程序的需求。
代码清单 2 中的 Perl 脚本用于遍历 MP3 文件根目录下的所有子目录,并创建 mp3blaster 播放器使用的所有必要的语音文件。
为了生成必要的语音文件,您每次添加专辑或更改目录结构时都应运行此脚本。您可以运行带有 -clean 选项的脚本,以确保在创建新集合之前删除所有旧文件。
所有语音文件都存储在您的根 mp3 目录下的子目录 .vocals 中。它们是对所有后续子目录的口语化解释,因此也是所有专辑名称(它们只是某些终端节点上的子目录,并且仅包含 MP3 文件)。
Perl 脚本首先创建文本文件(带有扩展名 .txt 的原始子目录名称)。它们包含一个略微修改的名称,其中去除了所有非字母字符。这样做是为了帮助语音合成程序生成更精确的声音。最后,u-law 音频文件是根据这些文件的内容创建的。如果您对声音效果不满意,可以更改文本文件中的语音,删除语音文件并重新运行脚本,以获得最佳发音。
用于处理音乐的几乎所有技术的都已经可用。在我看来,如果没有 Linux 和开源软件,构建这样一个远程控制的 MP3 播放器会更加困难。由于我的 Linux 服务器 24/7 运行,因此在我想要听音乐时使用它也是有意义的。尽管我为此专门配备的系统相当简陋(Cyrix 6x86 以 166MHz 运行),但 MP3 播放器在播放时大约占用 40% 的 CPU 时间,即使在同时服务网页时也没有可听到的中断。除了压缩我的所有 CD 收藏并将它们作为 MP3 文件存储在我的 Linux 服务器上之外,我还数字化了我的旧磁带,并在对声音进行一些处理以改进它之后,将它们存储在相同的音乐层次结构树中。最后,我可以从我的客厅中移除所有 CD 和磁带,并将它们永久存放起来。现在,只需按一下遥控器按钮即可快速访问每首乐曲。

Goran Devic (goran@3dfx.com) 拥有奥斯汀德克萨斯大学计算机科学学士学位。他曾参与开发 Cirrus Logic 的 Laguna 3D 图形加速器 (5464/65),并在图形加速器领域获得三项已颁发专利和十项待批专利。他目前在 3dfx Interactive, Inc. 从事新一代图形加速器的开发工作。他将空闲时间与他一岁的儿子 Siddartha 一起度过。他的爱好包括古典吉他、摄影和东方灵修。