BLE-MIDI音源モジュールを作る

 半田付け不要かつ予算3000円程度*1で十分な、BLE-MIDI接続の音源モジュールを作成したので紹介します。
※今までに無いような新しい音や、よりリアルな音を追求するような目的の音源モジュールではありません。チップ単体では僅か数ドルで供給される安価な市販音源チップを搭載したモジュールをBLE-MIDIで制御できるようにしただけで、本質的に独自のシンセサイザーを自作する企図ではありません。
 

きっかけ

 AKAI MPK mini Playという音源内蔵MIDIキーボードがあります。国内外の各社から発売されている小型MIDIキーボードの多くはDAWへのデータ入力に特化し、音源は内蔵していませんがMPK Playは音源を内蔵しているのです。他社製品と大きく異なる特徴なのにその詳細は全くと言っていいほど訴求されず、音源のスペックはおろかMIDIインプリメンテーションチャートすら公開されていません。新型のMPK mini Play MK3が発売になりましたが、相変わらず音源についてはその実体が謎なままなのです。

 検索してみると独自に調査した方がいて、MPK Mini Play | kaguyadepthに比較的詳しい情報がまとめられています。MPK mini本体の鍵盤から演奏できるだけではなく、USB-MIDI経由で鳴らせる音源として使用することもできるようです。
 この内蔵音源に対する公式の素っ気なさ過ぎる雰囲気から察するに、自社開発音源ではなく外販されている音源チップを載せただけのものかと推測されます。上記で調査されたCC/NRPNやEQが存在する特徴から推測してみると、かつては多く出回っていたYAMAHA製音源チップ(FM音源XG対応のAWM2音源)では無さそうです。或いは、かつてのWAVE BLASTER互換MIDIドーターボードに採用されていたり、TASCAMのポータブルMTRに内蔵されたMIDI音源チップとして採用されていたフランスのDream社のSAMシリーズ*2でもなさそうです。他に、現在市販されている音源チップを調べてみるとフィンランドのVLSI社*3のVS1xxxシリーズというのがあるようで、これを使っているのかとも思ったのですがEQはあるけどフィルタが無いので違うっぽいです。
 結局MPK mini Playの音源の実体は特定できていないのですが、このような調べ物をしていた経緯で、VLSIのVS1053bというGM対応音源チップの存在を知りました。
 

VLSI VS1053

 VS1053bは単なるGM音源チップという訳ではなく、Ogg Vorbis/MP3/AAC/WMA/FLAC/MIDI AUDIO CODECとして商品化されている多機能なチップです。すなわち、単にMIDI信号を入力したら出音が得られるだけのチップという訳ではありません。各種オーディオファイルを再生するのと同様に、SMF(format0)をマイコンから送り付けたら再生できるという機能のためにGM音源相当の機能を持っています。
 そうではなくて、(一般の音源モジュールと同様に)リアルタイムに入力されるMIDI信号に応じた出音が欲しいという需要にも対応していて、VS1053bのGPIO0=Low, GPIO1=Highとして起動すると、UARTに入力されたMIDI信号をリアルタイムに発音するように動作させることも一応はできるようになっています*4
 なお、VS1xxxシリーズのチップは複数ありますが、数字が大きければ上位製品という訳でもないようです。音源機能を持っていないチップもありますし、音源機能があっても音色数が少なくGM準拠の127音色のバリエーションを網羅していなかったりします。*5

秋月で購入できるVS1053b

 日本国内でも入手性は悪くないようで、身近なところではVS1053bのチップ単体は秋葉原秋月電子でも普通に販売されています。ですが、VS1053bはLQFPパッケージのため、手作業ではんだ付けするのは困難です(少なくとも私の技量ではできません)。
MP3デコーダ VS1053b: 半導体(モジュール) 秋月電子通商-電子部品・ネット通販
 このため、同じく秋月ではDIP変換基板に実装された形態のものも販売されています。
MP3デコーダ VS1053b DIP化基板モジュール: 半導体(モジュール) 秋月電子通商-電子部品・ネット通販
 スクラッチから製作する場合にはこのDIP変換基板に実装されたVS1053bを使うのが良さそうに思えます。
 が、VS1053bを動作させるには最低限、アナログ系の3.3V電源とデジタル系の1.8V電源の2系統が必要で、クロックとして12.288MHzの水晶振動子も必要で、その他パスコンの類の外付け部品も必要です。残念ながら秋月のDIP変換基板にはこれらの必須パーツは搭載されていませんし、そのための回路パターンもありません。
 

中華モジュールのVS1053b

 一方、VS1053bを搭載した中華モジュールを探してみると、3.3Vと1.8Vのレギュレータを搭載し、水晶振動子その他必要な外付け部品をまるっと搭載して電源と信号線だけ外部から与えればVS1053bを動かせそうな様態となっているものが複数種類存在します。Arduinoのシールド形状のものだったり、汎用的なピンヘッダを備えた基板だったりといくつかバリエーションがあるようです。が、いずれのモジュールもGPIO0,GPIO1が引き出されていないようで、VS1053bをリアルタイムMIDIモードで起動することはできないようです。
 ですが、調べてみるとGPIOを使用せずともSPI通信経由でVLSI社が提供するプラグインを適用するとリアルタイムMIDIモードを起動することもできるようです。つまり、SPI通信可能なマイコンを併用するならばGPIO0,GPIO1が引き出されていない中華モジュールでも支障ないことになります。

 価格だけで見れば秋月のDIP変換基板を使用する方が安価ですが、他に必要な外付け部品の多さを考えると中華モジュールとの価格差はそれほど大きくなく、はんだ付けの面倒も回避できます。このため今回は中華モジュールを選択することにしました。
 私が購入したモジュールは"LC technology VS1003/1053 MP3 CODEC"のシルク印刷があるもので、Amazon.co.jpでVS1053で検索して現れる製品の中にはVS1053ではなくVS1003(GM非対応)を搭載しているモジュールが混在しています*6。購入時には商品名だけではなく、本当にVS1053bを搭載した製品なのか商品ページに記載された仕様をよくチェックしましょう*7

 

組み合わせるマイコン

 前提として、VS1053bのI/O電圧はTyp2.8VでMax3.6Vとなっていますので、3.3V系のマイコンと組み合わせれば問題無く動作します*8
 VS1053bのリアルタイムMIDIモードをSPI通信でトリガするためだけにマイコンを使用するのはさすがにアホっぽいので、何らかの有意な機能性も付与したいところです。そう考えると、ESP32なら3.3VですしBluetoothが使えるのでBLE-MIDIが実装できます。DIN5ピンだったりTRS-MIDIだったりする有線のMIDI INを実装するにはフォトカプラを使用したMIDI入力回路を組んでESP32のUARTに入力する必要がありますが、BLE-MIDIだけなら外付け部品一切なしでESP32 devboardだけで済みます。ユニバーサル基板へのはんだ付けも、ブレッドボードすら要らずに、ジャンパ線でVS1053bモジュールとESP32 devboardを繋ぐだけで動くものが作れます。
 というわけで、今回はESP32を使うことにしました。

 

製作

 表記上はハードウェア編とソフトウェア編に分けて書いていますが、実際にはESP32の各ピンを何の用途に使用するか決めながら作りましたので、同時進行になるかもしれません。

ハードウェア編

 軽く探してみた限りでは中華VS1053bモジュールの仕様書が存在しないようですが、入出力のピンアサインは基板上にシルク印刷されていますので、特に困ることは無いと思います。

LC Technology VS1003/1053 MP3 CODEC module PIN I/O

 少し特殊かも知れない点としては、一般的なSPI通信で制御するチップの多くは、CS(Chip Select)という信号線で制御対象となるチップを指定しますが、VS1053bでは標準的にはXCSとXDCSの2種類のCS信号を使用します(なお、VS1053bでは信号線の名前の頭に"X"が付いているものは負論理(Active Low)を意味しています)。XCSは制御用のCS、XDCSはデータ用のCS信号として使い分けます*9。つまり、VS1053bの各種レジスタにアクセスする際はXCSをアクティブにし、MIDIデータを送信する際にはXDCSをアクティブにするといった具合にXCSとXDCSを使い分ける必要があります。
 前述の通りはんだ付け不要な構成としたので、ジャンパ線でESP32とVS1053bモジュールを接続するだけでハードウェアの製作は終わりです*10。今回購入したVS1053bモジュールもESP32 devboardもオスのピンが生えてますので、両端メス-メスのジャンパ線を使用します。

 すると、本当にジャンパ線でつないだだけですが、このようなものが出来ます。

BLE-MIDI Synth module (VS1053b+ESP32)

 

ソフトウェア編

 ESP32の仕様制約(SPI通信用のピンや、I/Oどちらにもアサインできるピンとそうではないピンなど)を踏まえたうえで、どのピンを何の信号線として使うと、無理なくジャンパ線が引き回せるかを考えつつ、使用するピンを決定したら後はVS1053bのデータシートを見ながら普通にコードを実装すれば完成します。
 データシートから読み取れる注意点としては、以下が挙げられます

  • MIDIの各バイト(ステータスバイト及びデータバイト)は8bit*11だが、SPI通信でVS1053にMIDIメッセージを送信する際は、ステータスバイトもデータバイトも16bitで送信する
    • つまりMSB8bitを0埋めしてLSB8bitに送信対象MIDIバイト(ステータスバイトまたはデータバイト)を送る
    • つまり2byteのMIDIメッセージを送る場合には4byte、3byteのMIDIメッセージを送る場合には6byteのSPI通信を行う
    • つまりSPI通信速度は必ずMIDIのbaudrate(312500bps)の2倍以上に設定する必要がある

 ドキュメントに書かれていない注意事項としては、以下が挙げられます。

  • VS1053bのリアルタイムMIDIを有効にするためのVLSIが公開しているプラグインが2種類存在する
  • 無音状態でVolume(CC#7)とExpression(CC#11)とNoteOnVelocityを全て127とするような大きな音量で発音させると一部の音域の一部の音色や、一部のパーカッションが正常に発音されないことがある
    • Volume, Expression, Velocityを下げるとこの問題は発生しない
      • Volume=127, Expression=127ならVelocity<88とすれば概ねこの問題は発生しない(全音全音域を確認したわけではない)
      • Volume=127, Expression=100ならVelocity<112とすれば概ねこの問題は発生しない(全音全音域を確認したわけではない)
      • Volume=100, Expression=100ならVelocity=127でもこの問題は発生しない
    • SCI_VOLレジスタの設定値で音量を下げるような設定をしても回避できない*12
    • 恐らくVS1053bのデジタル系(DSP)の演算バグではないか*13
    • (私の実装がおかしい、或いはチップの個体不良の可能性もありますが…)
    • workaroundとしてBLE-MIDI側からMIDI CC#7とCC#11を受信した際には、VS1053に送信する際にデータバイトの値を100/127(約0.78)倍した値を送信することにした
      • 演奏時のベロシティの分解能を下げるよりも、リアルタイムで可変させることが少ないCC#7とCC#11の分解能を落す方がマシという判断

 

その他注意事項

  • VS1053bの音声出力をそのままオーディオインタフェースやアンプなどの外部機器に繋ぐと機器を破壊する可能性があります!
    • VS1053b及び殆どのVS1053bモジュールの音声出力はイヤホンやヘッドフォンに繋ぐ前提のオーディオ出力になっています
    • 一般的にはGNDである結線がGNDではなく、VS1053bのGBUF*14と呼ばれるピンに接続されており1.23Vの電圧が出力されています
    • つまり、VS1053bと電源を共有する外部機器と音声出力を繋いでしまうと、1.23VがGNDにショートし、機器を破壊する可能性があります!
      • 例えば、PCのUSBポートからESP32 devboardに給電し、ESP32 devboardからVS1053bモジュールに給電している状態で、PCのオーディオ入力にVS1053bモジュールの音声出力を接続したらショートします
      • 同様の条件で、PCにUSB接続したオーディオインタフェース*15の入力にVS1053bモジュールの音声出力を繋いでも同様にショートします
    • これは以下のような回避策が考えられます
      • VS1053bの音声信号には1.23VのDC成分が乗っている状態なのでコンデンサで直流成分をカットして外部機器に入力する(そしてGNDにはGBUFを繋がない)
      • モバイルバッテリ等を利用して外部機器とGNDを共有しない電源でVS1053bを駆動する
      • トランスを利用してDC成分を除去する(トランスは二次側にDC成分を通しませんが、VS1053bを繋いだ一次側には常時DC成分が印加された状態となるため発熱することが想定されます。元々イヤホン・ヘッドフォンを駆動できる程度の電力しか供給されませんが、念のため異常発熱していないか注意が必要なためお勧めしません。)

 

ソースコードとか

 販売禁止と明示してはいないものの、過去の別な投稿で公開した結線図を基にしたと思われる特殊電源変換ケーブルがフリマアプリで販売されたり、別な投稿で公開したKORG NTS-1用カスタムオシレータプログラムを導入したと思われるNTS-1がフリマアプリで販売されていたりと、不愉快な経験があるので公開しないかもしれません*16
 コメント量や実装によりますが概ね500行~1000行程度のコード量で実装できるかと思います。この類の開発に慣れていてMIDIもSPIも熟知しているような方なら数時間レベルでしょうし、(MIDIメッセージの仕様を知っている前提で、)ESP32でBLE-MIDIバイスの開発が初めての方でも、今はライブラリを公開している方がいるのでそれを使用すれば1日あれば十分に実装できるのではないかと思いますので、連休に作って遊ぶにはちょうどよいかと思います。
 



以上。

*1:製作時。急激な円安などの要因で今後の価格変動がどうなるかは判りませんので悪しからず。

*2:特徴的なCC/NRPNなので対応するMIDIメッセージが判れば分解せずともほぼ間違いなく特定可能。

*3:以下、本投稿中のVLSIの記載は一般名詞のVLSIではなくVLSI社を指します。

*4:大量のMIDIメッセージを短時間に送り付けるとUARTバッファが溢れると書いてあるので、その対策が含まれた後述のリアルタイムMIDIプラグインを使用してSPI経由でMIDIメッセージを送る方が良さそうです。

*5:なお、VS1053とVS1053bは何が違うのか良く判りません。VS1053のデータシートに特に説明もなくVS1053bと書かれていたりするので、事実上同じものを指していると考えて問題なさそうです。

*6:紛らわしいですが、MP3 CODECのような用途で使用するならピンコンパチのVS1003でも大差ないので。

*7:特に安価な製品はVS1003搭載っぽい傾向を感じます

*8:5V系のマイコンを組み合わせる場合は、レベル変換回路が必要になります。

*9:信号線を減らしたければXCSを反転した状態をXDCSとして動作させることも可能。

*10:小型化やケースへの固定を真面目に考えるなら、ユニバーサル基板とピンソケットを使用して所謂ドーターボード形式にして実装すると良いと思います。

*11:データバイトは8ビット目は必ず0で有効下位7bit

*12:SCI_VOLレジスタはアナログ系に対するゲイン制御っぽい?

*13:VS1053bは多様なバグがあるようで、それを回避するためのプラグインがVLSIによって公開されています。ただし、複数のプラグインをロードすることはできませんので、今回はリアルタイムMIDI有効化プラグインだけしか使えません。

*14:Ground buffer?

*15:一部のRoland製オーディオインタフェースのようなグランドを切り離すGround Lift機能があれば、それを有効にすれば問題無いと思われますが…

*16:個人的に使用する目的でご利用いただくのは全く問題無いのですが、売るならレベニューシェアを求めるようなライセンスを考えるのも面倒なので。