博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用树莓派(等)为 USB Midi 键盘增添连接方式
阅读量:5124 次
发布时间:2019-06-13

本文共 7467 字,大约阅读时间需要 24 分钟。

我在去年买了一个 M-Audio 的 Midi 键盘,用来连接电脑或者 iPad 弹琴。但是由于琴摆放的位置没有办法拉充电线,所以我能弹琴多久很大程度上取决于设备还有多少电。前一阵子从朋友手里白嫖了个橘子派,我就考虑用这个板子给我的 Midi 键盘做个无线连接的接口,而且还安装了 FluidSynth 让设备可以直接发出声音让我带耳机练琴。

这篇文章中我首先会介绍 FluidSynth 的配置,再介绍如何通过 Midi over BLE 广播信号,最后介绍如何通过 Midi over Wifi 来广播信号。你可以选择性的看需要的部分。

系统配置

由于我使用的是橘子派而不是树莓派,我遇到了一些只有这边才会遇到的问题,其他开发板可以选择性掠过本节。

橘子派能安装的最新版本 Armbian 内核关闭了 Midi 功能,为了能够使用,我重新编译了内核。(在编译选项中开启:Device Drivers > Sound card support > Advanced Linux Sound Architecture > Sequencer Support )

橘子派还需要在系统中启用声音,使用自带的配置工具 sudo armbian-config,启用 System > Hardware > Toggle hardware configuration > analog-codec 。

由于橘子派会等待网络服务激活后才进入系统,导致开机时间非常长,使用下面的命令关闭它:

sudo systemctl disable NetworkManager-wait-online复制代码

你还可以使用 systemd-analyze blame 命令查看服务的启动时间,关闭一些其他你不需要的服务。

安装

Debian 源中自带的 FluidSynth 版本比较低,是 1.x 的。由于旧版本的 FluidSynth 并不能自动连接 Midi 设备,我们需要手动编译新版。

为了安装依赖,我们先要调整 apt 源,在文件中取消几个 deb-src 源前面的注释。

sudo nano /etc/apt/sources.listsudo apt-get update复制代码

安装所有需要的依赖包然后编译。

sudo apt-get build-dep fluidsynth --no-install-recommendsgit clone https://github.com/FluidSynth/fluidsynthcd fluidsynth/mkdir buildcd buildcmake ..sudo make install复制代码

接下来在命令行中执行 fluidsynth 确认是否正常。如果出现了找不到库的情况的话,首先应该尝试更新链接库。

sudo ldconfig复制代码

如果这样不行的话,可以添加环境变量。(下面的代码是临时的,永久修改可以自己 Google 一下。)

export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH复制代码

确认可以正常运行之后就可以进入下一步骤了。

(本节参阅 )

获取 Sound Font

如果你尝试过直接用 apt 安装 FluidSynth 的话,你应该会看到它推荐的几个包:fluidr3mono-gm-soundfont、timgm6mb-soundfont、fluid-soundfont-gm。这些都是 Sound Font。但是他们可能不够好听,并不能达到你的要求,这时候你就可以去一些第三方网站下载,比如 。

FluidSynth 支持 SF2/SF3 格式的音源文件,不支持 SFZ,请注意不要搞错。自己下载的音源可以存到一个叫 sound-fonts 的文件夹下备用,使用 apt 安装的上述几个音源则安装在 /usr/share/sounds/sf2 文件夹下。

测试声音

先运行一次测试是否能够正常出声,这里我使用了 GM 音源。

fluidsynth -is -a alsa -m alsa_seq -g 5 -o midi.autoconnect=1 /usr/share/sounds/sf2/FluidR3_GM.sf2复制代码

解释一下参数:

  • a,m 输入输出使用的音频驱动。
  • is 作为服务静默运行。
  • g 力度阈值,这里设置的大一点,以防一些设备音量太小。
  • o 细节参数,这里设置了自动连接 Midi 设备 midi.autoconnect。

(本节参阅 )

运行之后弹一下连接的键盘,看看有没有声音,比较慢的设备可能需要等一段时间才会显示已连接。按照目前的设置,音量应该会蛮大的,如果声音特别小,可以打开 alsamixer 调整一下音量,并使用 sudo alsactl store 保存状态。确认可以正常演奏之后进行下一步。

启动服务

为了能够让 FluidSynth 开机启动我们需要自己写一个服务:sudo nano /etc/systemd/system/fluidsynth.service。在文件中输入:

[Unit]Description=FluidSynth DaemonAfter=sound.target[Service]EnvironmentFile=/etc/fluidsynthExecStart=/usr/local/bin/fluidsynth -is -a alsa -m alsa_seq -z 64 -c 2 -g $GAIN -o synth.cpu-cores=4 -o midi.autoconnect=1 ${FONT_PATH}[Install]WantedBy=multi-user.target复制代码

解释一下这里多出来的几个参数:

  • z 缓存大小,可以使用 64 128 256 等“整数”。
  • c 缓存个数,一般为 2 或 3。
  • o 多了一个设置 CPU 核心数的选项 synth.cpu-cores,你可以根据自己的开发板来设置。可以装一个 htop 数条条看几个核。

文件中还把音源文件名和力度放在了环境文件中方便设置。新建环境文件:sudo nano /etc/fluidsynth,在文件中输入:

FONT_PATH=/home/megabits/sound-fonts/SalC5Light2.sf2GAIN=1.5复制代码

这个应该就不用我太多解释了。这里将力度设置为 1.5 是我试出来在橘子派上比较合适的音量,你可以自己调。假如你的 Midi 键盘有音量滑杆那就更方便了。

激活服务:

sudo systemctl enable fluidsynthsudo systemctl start fluidsynth复制代码

之后理论上就应该能正常弹琴了。假如听不到声音,可以用 journalctl -u fluidsynth 来查看服务的日志,看看是出了什么问题。

参考文章:

Midi over Bluetooth Low Energy

安装 BlueZ

首先要下载 BlueZ,由于 BlueZ 默认是没有开启 Midi 功能的,所以需要自己编译。这里使用的 BlueZ 是一个经过修改的版本,提供了 Midi Server 的功能。

git clone https://github.com/oxesoft/bluezsudo apt-get install -y autotools-dev libtool autoconfsudo apt-get install -y libasound2-devsudo apt-get install -y libusb-dev libdbus-1-dev libglib2.0-dev libudev-dev libical-dev libreadline-devcd bluez./bootstrap./configure --enable-midisudo make install复制代码

之后测试一下开启服务端并用其他支持 Bluetooth Midi 的软件来搜索,如 iOS 下的 Garageband。

sudo btmidi-server -v -n "Midi over BLE"复制代码

如果出现了 MGMT_OP_SET_LE failed: Not Supported,就说明设备不支持 BLE。在确认一切正常后打开另外一个终端窗口,连接好 Midi 设备并扫描。注意在这之前要先用别的设备连接上 Bluetooth Midi,BlueZ 只有在有设备连接时才会创建 Midi 通道。

aconnect -l复制代码

在列表中找到你自己的蓝牙设备和创建的 "Midi over BLE"。比如我的输出结果是:

client 0: 'System' [type=kernel]    0 'Timer           '    1 'Announce        'client 14: 'Midi Through' [type=kernel]    0 'Midi Through Port-0'client 20: 'Keystation 88' [type=kernel,card=1]    0 'Keystation 88 MIDI 1'    1 'Keystation 88 MIDI 2'client 128: 'Midi over BLE' [type=user,pid=2104]    0 'Midi over BLE   '复制代码

这里可以看到我的键盘 "Keystation 88" 编号是 20,"Midi over BLE" 默认编号是 128。

aconnect 20:0 128:0 复制代码

这样就可以把两个通道连接起来了。去键盘上按几个键,看看连接的设备会不会发出声音。一切正常就可以进行下一步了。

启动服务

新建一个服务:sudo nano /lib/systemd/system/btmidi.service,在文件中输入:

[Unit]Description=MIDI Bluetooth connectAfter=bluetooth.targetRequires=bluetooth.target[Service] ExecStart=/usr/local/bin/btmidi-server -n "Midi over BLE"[Install]WantedBy=multi-user.target复制代码

激活服务:

sudo systemctl enable btmidi.servicesudo systemctl start btmidi.service  复制代码

接下来配置自动连接 Midi 通道,这里我们使用 udev 来在蓝牙设备发生变化时自动连接。首先来写一个连接脚本:

touch linkble.shchmod a+x linkble.shnano linkble.sh复制代码

在文件中输入:

#!/bin/bashsleep 1/usr/bin/aconnect 'Keystation 88':0 'Midi over BLE':0复制代码

注意这里要把键盘的名字改成自己的。之所以要用设备名来连接,是因为设备编号是不稳定的。接下来建立规则 sudo nano /etc/udev/rules.d/44-bt.rules,在文件中输入:

ACTION=="add|remove", SUBSYSTEM=="bluetooth", RUN+="/home/user-name/linkble.sh"复制代码

刷新规则:

sudo udevadm control --reload-rules复制代码

这样就可以在其他设备连接到 BLE 的时候自动连接通道了。

参考文章:

Midi over Wifi

安装 raveloxmidi

首先需要激活虚拟 Midi 设备模块,由于我们使用的工具 raveloxmidi 会以独占方式访问 Midi 设备,我们必须用一个虚拟设备来传递信号。

modprobe snd-virmidiaconnect -l复制代码

如果输出中出现了虚拟 Midi 设备就说明设置成功了。为了能让模块永久启用,我们来建立一个配置文件 sudo nano /etc/modules-load.d/snd-virmidi.conf,在文件中输入:

snd-virmidi复制代码

保存并重启。

接下来安装 raveloxmidi:

sudo apt-get install -y git pkg-config libasound2-dev libavahi-client-dev autoconf automakesudo apt-get install avahi-daemongit clone -b experimental https://github.com/ravelox/pimidi.gitcd pimidi/raveloxmidi/ && ./autogen.sh && ./configure && make -j2sudo make install复制代码

假如你的网络不支持 ipv6,则需要配置一下 avahi-daemon,打开文件:sudo nano /etc/avahi/avahi-daemon.conf,按照下面的值来设置,注意一些行需要取消注释。

use-ipv6=nopublish-addresses=yespublish-aaaa-on-ipv4=no复制代码

打开 aconnect -l 来看一下设备在其中的编号,看一下 Midi 键盘的编号和第一个虚拟设备的编号,我的是 28:0 24:0,把它们连接起来。注意这里的顺序,一定是把键盘通道发送给虚拟设备通道。

aconnect 28:0 24:0复制代码

接下来查看硬件编号:

amidi -l复制代码

我这里第一个虚拟 Midi 设备的编号是 hw:2,0,记住这个值。为 raveloxmidi 建立一个配置文件:/etc/raveloxmidi.conf,在文件中输入:

alsa.input_device = hw:2,0network.bind_address = 0.0.0.0logging.enabled = yeslogging.log_level = normal复制代码

接下来启动测试:

sudo raveloxmidi -dN -c /etc/raveloxmidi.conf复制代码

如果程序正常运行了你应该就可以在其他地方连接它。这里以 macOS 上的 Garageband 为例:

打开 “音频 Midi 音频设置” 并在菜单中打开显示 “Midi 音频工作室”。之后在 “Midi 音频工作室” 的菜单或者工具栏上打开 “Midi 网络设置”。启用 “会话1”。在目录中选择 raveloxmidi,点连接。

打开 Garageband 弹几个音试一试,如果正常出声就是成功了。

启动服务

新建一个服务:sudo nano /etc/systemd/system/raveloxmidi.service,在文件中输入:

[Unit]After=local-fs.target network.targetDescription=raveloxmidi RTP-MIDI network server[Install]WantedBy=multi-user.target[Service]User=rootExecStartPre=/usr/bin/aconnect 'Keystation 88':0 24:0ExecStart=/usr/local/bin/raveloxmidi -dN -c /etc/raveloxmidi.conf复制代码

注意 Midi 设备的名称要改成自己的。激活服务:

sudo systemctl enable raveloxmidi.servicesudo systemctl start raveloxmidi.service复制代码

服务没有启动成功也没关系,可能是因为我们之前已经手动连接过一次 Midi 设备了,重启试试就好。

(本节参阅:)

参考文章:

常见问题

FluidSynth 无法打开默认声卡

遇到这种情况可能是你开机的时候 Alsa 没有把第一个输出设备分给你的声卡,而是分给了虚拟 Midi 或 USB 设备。首先我们来看一下你的音频设备都有什么:

aplay -l复制代码

列出的内容可能是这样的:

0 snd_virmidi 1 snd_usb_audio 2 (null)复制代码

这其中的 0 和 1 号卡都不是输出声音的设备,我们可以降低他们的优先级。打开 Alsa 的配置文件,为每一个设备设置 -2 的优先级:

sudo nano /etc/modprobe.d/alsa-base.conf复制代码
options snd_virmidi index=-2options snd_usb_audio index=-2复制代码

重启之后应该就可以了,另外你还需要修改 Midi over Wifi 的配置文件,更新声卡编号。

参考文章:

破音

如果 FluidSynth 出现了破音的现象,你需要考虑两方面原因。

假如破音时和负载有关的,你可能需要增加使用多 CPU 核心选项。

假如是定时的,大概一秒一次这种的,可能是由于 schedutil 导致的,这个调整 CPU 频率的工具对音频应用非常不友好。你需要配置它锁住 CPU 频率或者采用比较保守的方案来调整频率才不会出问题。

后记

弄 Midi 这档子事坑还是挺多的,我折腾了一周左右遇到了各种各样的问题,现在给大家总结一下,假如后来有人要做类似的事情,就可以省点心了。

转载于:https://juejin.im/post/5d52e3aa5188255b0743ffe5

你可能感兴趣的文章
java处理url中的特殊字符%等
查看>>
你的第一个Django程序
查看>>
Tomcat免安装版的环境变量配置以及Eclipse下的Tomcat配置和测试
查看>>
Unity3D性能优化之Draw Call Batching
查看>>
grafana授权公司内部邮箱登录 ldap配置
查看>>
treegrid.bootstrap使用说明
查看>>
[Docker]Docker拉取,上传镜像到Harbor仓库
查看>>
javascript 浏览器类型检测
查看>>
nginx 不带www到www域名的重定向
查看>>
记录:Android中StackOverflow的问题
查看>>
导航,头部,CSS基础
查看>>
[草稿]挂载新硬盘
查看>>
[USACO 2017 Feb Gold] Tutorial
查看>>
关于mysql中GROUP_CONCAT函数的使用
查看>>
OD使用教程20 - 调试篇20
查看>>
Java虚拟机(JVM)默认字符集详解
查看>>
Java Servlet 过滤器与 springmvc 拦截器的区别?
查看>>
(tmp >> 8) & 0xff;
查看>>
linux命令之ifconfig详细解释
查看>>
NAT地址转换
查看>>