電子趣味の部屋

電子系のガジェットやアプリ開発等の趣味の話題を書いてます

Raspberry PiでUSB接続のMIDI音源デバイスを作る方法

サウンドフォントを使用できるMIDI音源デバイスが欲しいと思い、Raspberry Piを使用して作ってみました。
PCからはUSB-MIDIデバイスとして認識されます。
今回はRaspberry Pi Zero 2Wを使用しましたが、他の機種でも同じ方法でできると思います。

DAC

音声はI2S,I2C接続のDACから出力するようにしました。
今回使用したのは、Waveshare PCM5122-Audio-Board-Aです。

I2S,I2C接続のDACであれば同様の方法で使用できると思います。

OS

OSはTrixieやBookwormは動作が重く、もうすぐサポートが切れてしまいますが、bullseyeのLiteを使用しました。
downloads.raspberrypi.org

手順

I2C有効化

raspi-configでInterface OptionsよりI2Cを有効化してください。

sudo raspi-config

設定後、再起動します。

sudo reboot
パッケージ更新

とりあえず、最新化します。

sudo apt update && sudo apt upgrade -y
I2Cツールのインストール
sudo apt install -y i2c-tools
Waveshare PCM5122-Audio-Board-Aのセットアップ

PCM5122が検出されることを確認(通常は0x4C, 0x4D, 0x4E, 0x4F のいずれか)

sudo i2cdetect -y 1

PCM5122デバイスが card 1 として「IQaudIODAC」で表示されることを確認:

card 1: IQaudIODAC [IQaudIODAC], device 0: IQaudIO DAC HiFi pcm512x-hifi-0
ALSA 設定

/etc/asound.conf を編集して以下を記述してください。(管理者権限 sudo でエディタ実行)

pcm.!default {
    type hw
    card 1
}
ctl.!default {
    type hw
    card 1
}
FluidSynth インストールと設定

インストール

sudo apt install -y fluidsynth fluid-soundfont-gm alsa-utils

FluidSynth スクリプト作成

mkdir -p ~/midi-synthesizer

~/midi-synthesizer/midi_synth.sh を編集(新規作成)して以下を記述してください。

#!/bin/bash
exec /usr/bin/fluidsynth -s -a alsa -m alsa_seq \
  -o audio.alsa.device=hw:1,0 \
  -o synth.polyphony=128 \
  -o synth.gain=0.8 \
  /usr/share/sounds/sf2/FluidR3_GM.sf2

スクリプトを実行可能にする

chmod +x ~/midi-synthesizer/midi_synth.sh

テスト実行

~/midi-synthesizer/midi_synth.sh

プロンプト > が表示されたら成功(Ctrl+C で終了)

USB-MIDI設定

/boot/config.txt を編集して以下を記述してください。(管理者権限 sudo でエディタ実行)
末尾に追加

# USB OTG for MIDI
dtoverlay=dwc2

/boot/cmdline.txt を編集して以下を記述してください。(管理者権限 sudo でエディタ実行)
rootwait の後に追加

modules-load=dwc2,g_midi

編集する行の全文です。
編集前:

console=serial0,115200 console=tty1 root=PARTUUID=xxx rootfstype=ext4 fsck.repair=yes rootwait

編集後:

console=serial0,115200 console=tty1 root=PARTUUID=xxx rootfstype=ext4 fsck.repair=yes rootwait modules-load=dwc2,g_midi
再起動
sudo reboot
USB-MIDIデバイス確認
sleep 5 && aconnect -l

出力例:

client 24: 'f_midi' [type=kernel,card=2]
    0 'f_midi          '

f_midi が表示されたら成功です

FluidSynth起動
~/midi-synthesizer/midi_synth.sh
別のターミナルで MIDI ポートを接続
aconnect 24 128

確認:

aconnect -l

出力例:

client 24: 'f_midi' [type=kernel,card=2]
    0 'f_midi          '
        Connecting To: 128:0
client 128: 'FLUID Synth (736)' [type=user,pid=736]
    0 'Synth input port (736:0)'
        Connected From: 24:0

上手く接続できない場合は、aconnect -lでクライアント番号を確認して、aconnect [f_midiのクライアント番号] [FLUID Synthクライアント番号]を実行してください。

PC側で USB-MIDI デバイスが認識されることを確認

Windowsの場合、デバイスマネージャーを起動し、「サウンド、ビデオ、およびゲームコントローラー」にMIDIデバイスが存在することを確認する。
デバイス名は環境によって違うようですが、手元のWindows11のPCでは「MIDI function」として認識されました。

自動起動 (サービス化)

自動起動サービス作成
/etc/systemd/system/midi-synth.service を編集(新規作成)して以下を記述してください。(管理者権限 sudo でエディタ実行)
以下を記述(実行ユーザ は自分のユーザー名に置き換え):

[Unit]
Description=Raspberry Pi MIDI Synthesizer
After=network.target sound.target
Wants=network-online.target

[Service]
Type=simple
User=実行ユーザ
ExecStart=/home/atsuhisa/midi-synthesizer/midi_synth.sh
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

自動接続スクリプト作成

~/midi-synthesizer/auto-connect.sh を編集(新規作成)して以下を記述してください。

#!/bin/bash
sleep 6
aconnect 24 128 2>/dev/null

実行権限追加

chmod +x ~/midi-synthesizer/auto-connect.sh

自動接続サービス作成

/etc/systemd/system/midi-auto-connect.service を編集(新規作成)して以下を記述してください。(管理者権限 sudo でエディタ実行)
以下を記述(実行ユーザ は自分のユーザー名に置き換え):

[Unit]
Description=Auto-connect MIDI ports
After=midi-synth.service
Wants=midi-synth.service

[Service]
Type=oneshot
User=実行ユーザ
ExecStart=/bin/bash -c 'sleep 6 && /home/atsuhisa/midi-synthesizer/auto-connect.sh'
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

サービス有効化

sudo systemctl daemon-reload
sudo systemctl enable midi-synth.service
sudo systemctl enable midi-auto-connect.service
sudo systemctl start midi-synth.service
sudo systemctl start midi-auto-connect.service

確認

sleep 10 && aconnect -l

出力例:

client 24: 'f_midi'
    Connecting To: 128:0
client 128: 'FLUID Synth (853)'
    Connected From: 24:0

f_midiFLUID Synth に自動接続されていることを確認

再起動確認
sudo reboot

再起動後:

sleep 10 && aconnect -l

f_midi が自動接続されていることを確認

サウンドフォントファイルの変更

サウンドフォントファイルを変更したい場合は、~/midi-synthesizer/midi_synth.sh のsf2ファイルのパスを変更してください。
今回の設定例で/usr/share/sounds/sf2/FluidR3_GM.sf2の部分を変更してください。

#!/bin/bash
exec /usr/bin/fluidsynth -s -a alsa -m alsa_seq \
  -o audio.alsa.device=hw:1,0 \
  -o synth.polyphony=128 \
  -o synth.gain=0.8 \
  /usr/share/sounds/sf2/FluidR3_GM.sf2