MIDI 键盘配置(Ubuntu):搞定 Jack
- Published on
以下内容参考: Ted's Linux MIDI Guide
新买了一个 MIDI 小键盘,插到苹果手机上在 GarageBand 或其他合成器 APP 中立马就能弹出声响,但是连到电脑后发不出任何声音。但这其实不是根本问题所在,刚开始玩,对各种音频工作站(DAW, digital audio workstation)还很陌生,现在想来上午因为系统配置问题,工作站本身应该就没有正常运行起来(虽然软件成功安装并打开了)。而这可能又关系到 Linux 音频系统中三个我一直晕晕乎的关键词,分别是 ALSA, PulseAudio 还有 Jack,上一次因为 Sonic Pi 启动不起来就折腾过很久,今天又来一次,好像终于又清楚一些了。没有再去看更多的资料,当前的理解就是 ALSA 是更底层的框架,属于 Linux 系统内核中的一部分,会直接和音频相关的软硬件、声卡、驱动等打交道;Jack 与 PulseAudio 是在此之上的软件,功能也有重合之处,特别是 PulseAudio 好像总碍 Jack 的事,后面就涉及停止它运行的部分;PulseAudio 如此挡道又不能卸载它的原因是它俩之上还有很多更靠近用户的功能性软件依赖于它们,像音视频播放器、音频编辑器、合成器这些。所以,接下来真正要解决的核心问题是如何让 Jack 正常运行起来。
后面内容概括起来如下:
先关掉所有音频相关的软件
掐掉 PulseAudio
Jack 跑起来
FluidSynth 或其他合成器跑起来
MIDI 键盘与合成器 MIDI 端口连起来
Time to play!
低延迟(low-latency)内核与音频组(audio group)
音乐是时间的艺术,时间分辨率还有延迟等问题就很重要,看了指南才知道 Linux 有低延迟内核,当前我的版本并不是,后面再找时间更换。另外 Ubuntu 有一个 Studio 系统,默认安装的就是低延迟内核,以后换系统的时候可以考虑。
音频组还是有必要按照指南设置一下的,有在网上看到 Jack 是以用户的名义运行的软件,所以 root 下运行或许就有问题吧。(至于 Linux 系统中的组究竟干嘛用的,该怎样合理使用,又是另一个留给以后的坑了)
Ubuntu 系统在安装 jackd2
时自动就会新建音频组 (audio group),所以只需要安装完成后直接去把用户加入到这个组内。
查看当前用户处于哪些组内:
groups
添加用户到组内
sudo gpasswd -a username audio
上面命令中的 username
要用自己的用户名替代
切换至用户身份
从下图可以看出,当把用户加入到音频组后,再用 groups
命令查看时还是不见 audio
,原来是因为当前还在 root
身份下,而 root
并没有被加入到音频组内,所以要把身份先切换回用户(su - username
),然后就能看到音频组啦。
ALSA 的使用
查看系统内的声卡设备
cat /proc/asound/cards
参考指南,hw:1 和 hw:2 应该是系统的声卡,看不出什么区别,前面已试过,只有 2 能播放音乐,1 不知道干嘛的,而 hw:0 也不知道是什么,不管它,3 是外接小音箱,4 是键盘。前面参考指南都是用系统声卡播放音乐,下面用小音箱试试看。
指定声卡播放音乐
aplay -D hw:3 seg.wav
果然 hw:
后面接不同的数字就会是对应设备播放音乐。
FluidSynth 合成器
我的 MIDI 键盘本身只是一个控制器,是不能发出声音的,需要把它和模拟或数字的合成器接在一起才会有声音,而 FluidSynth 就是一种数字合成器,在终端里就能安装使用 (sudo apt install fluidsynth
直接安装)。下面先不涉及 Jack 以及 MIDI 键盘,只是让它直接播放 MIDI 文件或是以服务器(server)的形式播放别的软件(client)发给它的 MIDI 文件。
直接播放 MIDI 文件
fluidsynth --audio-driver=alsa -o audio.alsa.device=hw:3 /usr/share/sounds/sf2/FluidR3_GM.sf2 bach_846.mid
上面的命令指定了驱动,播放的设备,使用的声音以及 MIDI 文件。bach_846.mid 是按 Ted 给出的链接,在网站下载的。
以服务器状态(server)播放 MIDI 文件
因为要用到 aplaymidi
做为 FluidSynth 的用户(client)来请求它播放 MIDI 文件,而 aplaymidi 属于 alsa-utils
,所以要先安装一下.
sudo apt install alsa-utils
fluidsynth --server --audio-driver=alsa -o audio.alsa.device=hw:3 /usr/share/sounds/sf2/FluidR3_GM.sf2
可以看到,第二行命令和前面基本一样,只是注明了 server
状态,另外没有给出要播放的 MIDI 文件名,这个请求会从别的软件即 aplaymidi 那里发出,如下:
另外打开一个终端窗口(原来那个被以服务器状态持续运行并等待的 FluidSynth 占用)
aplaymidi -l
aplaymidi -p 129:0 bach_846.mid
第一行命令是用来看系统内当前有哪些 MIDI 设备,以及它们各自的端口,可以看到 FluidSynth 占用的是 129:0 端口,所以第二行命令就是 aplaymidi 把 MIDI 文件发送到 129 端口去,然后就能听到 FluidSynth 根据 MIDI 文件合成出来的音乐啦。退出 FluidSynth 只需要输入 quit
。如下图所示,退出后系统内 MIDI 设备中就没有它的踪影了。
Jack
移除阻碍 PulseAudio
上次 Sonic Pi 启动不了就是因为它俩打架,因为 PulseAudio 的干扰,Jack 一直运行失败,后者的官方指南也给出了好几种暂时停掉 PulseAudio 的方法,云里雾里坑赤坑赤试了老半天。
现在分析我的糊里糊涂,感觉原因有很多:
首先就是对 ALSA、它俩以及应用层软件相互之间的纠缠关系捋不清,再加上内核、驱动、声卡、硬件设备这些概念跟着凑热闹,脑袋自然两个大。
还有就是对 server 与 client 的工作模式不理解,最熟悉的就是 web,看见它俩立马就想网络(这里的网络就是单一对应互联网),但又想不通这跟网络有什么关系,前面看 Ted 对 FluidSynth 的两种工作方式的讲解才终于明白了。就是一种沟通机制吧,或者说模式,会应用在各种可能适合的问题域和场景中吧。说到这里还想起一个事例,前段时间有一期随机波动的主题和家居有关,zhiqi 就谈到了智能家居,讲到国外一个调查发现智能家居的用户多数都对其基本原理不了解,直觉地以为是自己的 IPad 应用直接给房间内的智能硬件发送了一个信号,所以灯亮或灯灭了,但实际情况是软件应用通过网络给服务商的服务器发送了信号,而后者又反过来控制了灯亮或灯灭。听完简直惭愧,怎么说我过去也在 CodeLab 工作了两年,还用来用去的!但 zhiqi 如果不说,如果我不细想,很可能还是会凭直觉做出错误地判断。就算主要是因为我笨(知识没有灵活迁移),一定程度还是说明网络这个抽象概念不好深入理解,特别是操作层面上,因为首先看不见就增加了难度,然后绝大多数人又没有横向剖面上操纵控制它的经验(接入不算),即使是非常小的局部的网络也没有。类似的,大数据也是,都需要在实际的操纵经验中习得不同尺度、模式下思考解决问题的方法。这样想来,科学技术领域的开放就非常有意义,理论上给了大家接触的机会。另外从学习的角度说,元认知(所谓 meta-learning)的意识也非常重要,既要接地又要拔高。
第三个方面关系到桌面应用和终端程序,为了方便大家使用,围绕这些软件还有很多 control 类或是图形显示类软件,所以最开始按照网上指南各种安装时就会搞不清他们究竟是干嘛用的,一会儿在终端里发命令,有一会儿又去 GUI 里点点点,搞不清一系列操作和 Jack 它们以及问题的实质是什么关系
乌拉乌拉扯这么多,收回来说停掉 PulseAudio 的方法,Ted 指南里给出了 3 种,我就用下面这个方法:
echo "suspend 1" | pacmd
前面说过因为有些应用软件是需要 PulseAudio 才能正常运行的,所以完事之后还要重启 PulseAudio:
echo "suspend 0" | pacmd
Jack 配置
安装过 jackd2 之后(sudo apt install jackd2
),如下启动:
jackd -d alsa --device hw:3 --rate 44100 --period 128
JACK 默认采样率是 48000,但是 FluidSynth 是 44100,所以这里改小;另外 period 设为 128 帧,不同于默认的 1024,有助于减少延迟。
过程中我有遇到下面这个报错,也没查出到底在说啥,就按它给出的方法修改了环境变量
另外参照 Ted 指南安装了 jack-tools (sudo apt install jack-tools
),然后使用它自带的 jack-play 播放音频文件,测试 jack server 正常工作:
export JACK_PLAY_CONNECT_TO=system:playback_%d
上面这行命令表示让 jack-play 使用系统当前默认的音乐播放设备,我这里就是外接的小音箱。
jack-play test.wav
输入上面这个命令后,如果 Jack 正常,音乐就会响起来
Jack 如果正常了,新打开一个终端窗口,按照上面运行 FluidSynth 的方法让它也跑起来,此时的状态就是两个终端内,分别运行着 Jack server 和 FluidSynth server。
MIDI 键盘配置
查看 MIDI 设备和对应端口
aconnect -l
如上图所示能看到我的 MIDI 键盘与 FluidSynth 各自对应的 MIDI 端口,32 和 128,把他们连起来就可以啦:
aconnect 32:0 128:0
前面我已连接好,现在就可以弹出声音啦!
DAW 配置
当 Jack 运行起来之后,直接打开音频工作站如我今天摸索使用的 Stargate 可能还是没有声音,需要找到相应的硬件设置,例如把 Audio Driver 从默认的 ALSA 改为 JACK,就可以啦!Ted 指南里也有说 RoseGarden 类似的可能也要手动改一下。