【Linuxで音ゲーを実行#2】MIDIキーボードを接続しても音が出なかった

NECのノートパソコンLaVie LS350/AにLinux Mint 20.3をインストールしました。直後にUSB経由でMIDIキーボード「Akai professional MPK mini mk2」を接続しましたが音が出ません。JACKを使ってFluidSynth経由のサウンドシステムを構築することで音が出ました。

# 短く言うと

:::note warn
Linux mint 20.3なPCにMIDIキーボードを接続しましたが音が出ませんでした。
:::
:::note info
JACKを使って「MIDIキーボード」→「FluidSynth」→「JACK」→「ALSA」→
と数珠つなぎしてサウンドシステムを構築したら音が鳴りました。
:::

FluidSynthのフロントエンドQsynthをインストールします：
```:Terminal
sudo apt install qsynth
```
JACKのフロントエンドQjackCtlをインストールします：
```:Terminal
sudo apt install qjackctl
```
- MIDIキーボードをPCに接続します。
- Qsynthを起動してサウンドフォント（sf2ファイル）を指定します。
    - 「Setup」>>「SoundFonts」。指定後「restart」
    - デフォルトでは以下に格納されています。/usr/share/sounds/sf2/*.sf2
- QjackCtlを起動してMIDIキーボードとFLUID Synthを接続します。
    - 「接続」>>「ALSA」。MIDIキーボードとFLUID Synthを「接続」

＜＜前の記事　[【Linuxで音ゲーを実行#1】Linux Mintをインストールしたらヘッドホンから音が出なかった][21]

[21]: https://qiita.com/johnnystg/items/62ea57bd2c487a17000f

[【Linuxで音ゲーを実行#3】]　次の記事＞＞

# はじめに

MIDIキーボードを使って音ゲーで遊びたいと思いました。都合よく使っていないノートPCがありましたし、中古のMIDIキーボードも手に入れました。しかし、Linux MintをインストールしてUSBでMIDIキーボードを接続しても音が出ませんでした。

※この記事は[【Linuxで音ゲーを実行】][31] の2番目の記事です。

[31]: https://qiita.com/johnnystg/items/b113e1794bfda040cd83

# 今回の環境

- NEC LaVie LS350/A(音声出力デバイスとして「スピーカー」と「アナログヘッドフォン」)
   - MIDIを発音するためのハードウェアシンセサイザーは無い
   - 改めてソフトウェアシンセサイザーをインストールする
- MIDIキーボード「Akai professional MPK mini mk2」
- Linux Mint 20.3 Cinnamon
    - ALSA[^41] (初期状態でインストール済み)
    - PulseAudio[^42] (初期状態でインストール済み)

[^41]: Linuxカーネルコンポーネントのひとつ。カーネルモジュール/ライブラリーで構成されている。バックグラウンドで動作しサウンドカードハードウェアの自動設定や複数のサウンドデバイスの取扱いを行うアプリケーション群。

[^42]: サウンドサーバのひとつ。バックグラウンドで動作し異なる音声データをミキシングして出力装置(ここではALSA)へ単一の統一された音声を送る。
 
# MIDIキーボードを接続するだけでは音は出ない
:::note warn
マルチメディアアプリを起動するとPulseAudioが自動でアプリを数珠つなぎにして発音します。しかし、MIDIには対応しません。
:::

:::note info
Linuxでは、MIDIを扱うとき手動で接続設定を行います。
:::

Linux MintなPCにUSBケーブルを使ってMIDIキーボードを接続しました。通電はしましたが全く反応がありません。

Youtubeの視聴やVLCを使ったマルチメディアの再生ではPulseAudioが __自動__ で以下のようなサウンドシステムを構築してくれます。

__「マルチメディアアプリ→PulseAudio→ALSA→物理音声出力デバイス」__

デフォルトの状態では、PulseAudioはMIDIを扱わないようになっているようで、MIDIキーボードを接続しても認識してくれません。そこで今回は [USB MIDI キーボード - ArchWiki][51] に従い、PulseAudioを使わずに手動でMIDI音を出してみます。

[51]: https://wiki.archlinux.jp/index.php/USB_MIDI_%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89


# aconnectコマンドを使ってMIDI音を出す

:::note info
「Virtual Keyboard→Fluid Synth→ALSA→物理音声出力デバイス」と数珠つなぎしてMIDI音を出してみます。
:::

## alsa-utils とVirtual Keyboard を準備する

:::note info
alsa-utils がインストールされているか確認します。
:::

:::note info
「virtual Keyboard」をインストールして、動作確認をします。
:::

alsa-utilsがインストールされているか確認します。Linux Mint 20.3 ではすでにインストールされているはずです：
```:Terminal
apt list --installed | grep alsa-utils
```
```
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
alsa-utils/focal-updates,now 1.2.2-1ubuntu2.1 amd64 [インストール済み]
```

$ | aseqdump を実行します。以下のように出力されます：
```:Terminal
aseqdump
```
```
Waiting for data at port 128:0. Press Ctrl+C to end.
Source  Event                  Ch  Data
```

待機しています。「Ctrl+C」で終了します。

次に「Virtual Keyboad」をインストールして動作確認します：
```:Terminal
sudo apt install vkeybd
```
```:Terminal
vkeybd &
```
バーチャルキーボードの鍵盤を押してもMIDI音はでません。

$ | aconnect -i でMIDI入力ポートを確認します：
```:Terminal
aconnect -i
```
```
＃前略
client 14: 'Midi Through' [type=カーネル]
    0 'Midi Through Port-0'
client 128: 'Virtual Keyboard' [type=ユーザ,pid=15707]
    0 'Virtual Keyboard'
```

また、$ | aconnect -o でMIDI出力ポートについても確認します：
```:Terminal
aconnect -o
```
```
client 14: 'Midi Through' [type=カーネル]
    0 'Midi Through Port-0'
```
MIDI入力ポートに「Virtual Keyboard」ありますのでclient番号を確認しておきます（ここでは __「client 128」__ ）。このほかに、外部入出力（ここでは「client 14」）も表示されています。

$ | aseqdump -p でイベントの確認をします。「IN_client番号_###」 をVirtual Keyboard のclient番号に置き換えてください（ここでは __128__）：
```:Terminal
aseqdump -p 「IN_client番号_###」
```
```
Waiting for data. Press Ctrl+C to end.
Source  Event                  Ch  Data
128:0   Note on                 0, note 64, velocity 127
128:0   Note off                0, note 64, velocity 0
128:0   Note on                 0, note 67, velocity 127
128:0   Note off                0, note 67, velocity 0
```
鍵盤を押すとMIDIデータが入力できていることがわかります。しかし、まだMIDI音はでません。ひとまず「Ctrl+C」を押して$ aseqdumpを終了します。

## Fluid Synth を使ってMIDI音を出す

:::note info
ソフトウェアシンセサイザー「FluidSynth」を使ってMIDI音を出します。
:::

FluidSynthをインストールします：
```:Terminal
sudo apt install fluidsynth
```

Virtual Keyboard を起動します：
```:Terminal
vkeybd &
```
[MIDI-WineHQ Wiki][61]を参考にしてFluidSynthをデーモンモードで起動します。「これらのソフトウェアシンセサイザーは、無音以外のものを生成するために、デジタル化されたサウンドサンプルコレクション（パッチおよびサウンドフォントと呼ばれる）を必要とします」のでsf2ファイルを指定します。Linux Mint ではデフォルトでのsf2ファイルの格納場所が異なっていたので訂正しました。

[61]: https://wiki.winehq.org/MIDI

FluidSynth をデーモンモードで起動します：
~~$ | fluidsynth -l -s -i -aalsa -o audio.alsa.device=default /usr/share/midi/sf2/mypatches.sf2~~

```:Terminal
fluidsynth -l -s -i -a alsa -o audio.alsa.device=default /usr/share/sounds/sf2/FluidR3_GM.sf2
```
$ | aconnect -i でMIDI入力ポートを確認します：
```:Terminal
aconnect -i
```
```
＃ 前略
client 14: 'Midi Through' [type=カーネル]
    0 'Midi Through Port-0'
client 128: 'Virtual Keyboard' [type=ユーザ,pid=15707]
    0 'Virtual Keyboard'
```
また、$ | aconnect -o でMIDI出力ポートについても確認します：
```:Terminal
aconnect -o
```
```
client 14: 'Midi Through' [type=カーネル]
    0 'Midi Through Port-0'
client 129: 'FLUID Synth (35286)' [type=ユーザ,pid=35286]
    0 'Synth input port (35286:0)'
```
$ aconnect コマンドで __「Virtual Keyboard → FLUID Synth」__ となるように接続します。「IN_client番号_###」「OUT_client番号_###」をそれぞれのclient番号に置き換えてください（ここでは __128__ と __129__ ）：
```:Terminal
aconnect 「IN_client番号_###」「OUT_client番号_###」
```
__「Virtual Keyboard → FLUID Synth → ALSA → 物理音声出力デバイス 」__ となり音が出るはずです。

※「→ FLUID Synth → __（ALSAに偽装した）PulseAudio__ → ALSA →」とすべきですがここでは省略します。

# MIDIキーボード、Qsynth、QjackCtlを使ってMIDI音を出す
:::note info
FluidsynthとJACKのフロントエンドを使ってMIDI音を出します。
:::

実用ではFluidsynthをJACKと組み合わせることが多いようです。また、気軽に使えるGUIでサウンドシステムを構築します。

## QsynthとQjackCtlをインストールする

とりあえずaptをupdateします：
```:Terminal
sudo apt update -y
```
Qsynthをインストールします：
```:Terminal
sudo apt install -y qsynth
```
QjackCtlをインストールします：
```:Terminal
sudo apt install -y qjackctl
```

## MIDIキーボードを接続する

MIDIキーボード「Akai professional MPK mini mk2」をPCに接続し、動作確認をします。
$ lsusb コマンドを使います：
```:Terminal
lsusb
```
$ lsmod コマンドを使います：
```:Terminal
lsmod | grep usb
```
「MPK mini 2」の表示は出ませんが、「USB」「Audio」など関係しそうなものが表示されます。

$ aconnect コマンドでMIDI入力ポートを確認します：
```:Terminals
aconnect -i
```
```
＃ 前略
client 14: 'Midi Through' [type=カーネル]
    0 'Midi Through Port-0'
client 20: 'MPKmini2' [type=カーネル,card=1]
    0 'MPKmini2 MIDI 1 '
```
MPKmini2が候補に上がっています。ここではclient番号は20です。

$ | aseqdump -p でイベントの確認をします。「IN_client番号_###」 をMPKmini2のclient番号に置き換えてください（ここでは __20__）：
```:Terminal
aseqdump -p 「IN_client番号_###」
```
```
Waiting for data. Press Ctrl+C to end.
Source  Event                  Ch  Data
 20:0   Note on                 0, note 72, velocity 58
 20:0   Note off                0, note 72, velocity 0
 20:0   Note on                 0, note 76, velocity 73
 20:0   Note off                0, note 76, velocity 0
```
鍵盤を押すとMIDIデータが入力できていることがわかります。しかし、まだMIDI音はでません。ひとまず「Ctrl+C」を押して$ aseqdumpを終了します。

## Qsynth とQjackCtl を起動/設定する
:::note info
ランチャーの「サウンドとビデオ」からQsynth とQcakCtlを起動/設定します。
:::
- Qsynthを起動してサウンドフォント（sf2ファイル）を指定します。
    - 「Setup」>>「SoundFonts」。フォントを指定後「restart」します。
    - フォントはデフォルトでは以下に格納されています。/usr/share/sounds/sf2/*.sf2
- QjackCtlを起動してMIDIキーボードとFLUID Synthを接続します。
    - 「接続」>>「ALSA」。MIDIキーボードとFLUID Synthを「接続」します。

以上の操作で、
__「MPKmini2 → Qsynth → QjackCtl → ALSA → 物理音声出力デバイス 」__
となり音が出るはずです。

# おわりに
:::note warn
デフォルトでは、PulseAudioはMIDIデータを扱いません。
:::
:::note info
一般的にはFluid synthとJACKのフロントエンドを使って手動でMIDIデータを扱います。
:::
:::note alert
QcakCtlを起動するとPulseAudioが休止します。
:::

MIDIキーボードをPCに接続するだけではMIDI音は出ませんでした。そこでQsynth とQjackCtlをインストール/設定することでMIDI音を出しました。
しかし、JACKを起動するとPulseAudioが休止してしまい、例えばyoutubeを視聴することができなくなります。これはALSAが受け付けられるソフトウェア（サウンドサーバーやドライバ）がひとつだけだからです。

:::note alert
以下は並列できません。ALSAが受け付けられるソフトウェアはひとつだけです！
:::

○： __「MIDIキーボード → Qsynth → QjackCtl → ALSA → 物理音声出力デバイス 」__
×：＿＿＿＿＿「 ~~youtubeなど → PulseAudio →~~ ALSA → 物理音声出力デバイス 」


＜＜前の記事　[【Linuxで音ゲーを実行#1】Linux Mintをインストールしたらヘッドホンから音が出なかった][21]

[21]: https://qiita.com/johnnystg/items/62ea57bd2c487a17000f

[【Linuxで音ゲーを実行#3】]　次の記事＞＞