前回の記事投稿(2019年7月)から3年ぶりになる久々の記事投稿になります、YMF825の続きモノになります。内容はMIDIケーブルレスでUSB一本でOKという記事です。

前回の記事のMIDI編ではMIDIケーブル経由でPCとArduino間のMIDIデータ通信を行いましたが、今回はMIDIケーブルを使わないでUSBケーブルでのMIDIデータ通信を行います。と言ってもシーケンサーからArduino まではMIDIデータを使っての通信になりますので論理的にはMIDIデータ通信になってます、そのことから仮想MIDIとここでは呼ぶことにしてます。

今回の構成

  1. MIDIシーケンサソフト:DOMINO(フリーソフト)
  2. YMF825MIDI音源化モジュール:ArduinoNano + YMF825
  3. スピーカー:ダイナミックスピーカー(アンプ無orアンプ有どちらも可)

注)前回の構成での「USB-MIDI変換ケーブルUX16」(Yamaha)と「MIDI-Serial変換モジュール」(aitendo) の2点は必要ありません。

【構成】

前回記事同様にMIDIデータ入力からスピーカーの音出しまでのデータの流れを書いてみました。
MIDI編の構成に書かれてた「USB-MIDI変換ケーブルUX16」(Yamaha)と「MIDI-Serial変換モジュール」(aitendo) の2点は削除されてます。

【構成要素】

MIDIシーケンサソフト:DOMINO

MIDIシーケンサとはMIDIデータを時系列に処理をしてMIDIストリームデータとして吐き出していくソフトのことです、ここではフリーソフトとして有名なDOMINOを使ってみます。

TAKABO SOFTさんのサイトからダウンロードします。

インストーラタイプでないので起動は解凍フォルダ内のDomino.exeのオープンになります。

起動すると下図の画面になります

DOMINO起動画面

Hairless MIDI to Serial Bridge

MIDIポートとSerialポート間を接続するフリーソフトです。作者のGitHubページうからダウンロードできます。MIDIシーケンサDOMINOからのMIDIデータを受け取ってSeirial(USB)へ受け渡し(Bridge)を行います。

ダウンロードしたexeファイルはインストーラタイプではないのでexeファイルをダブルクリックして起動するだけで使用できます。

Windows版の最新バージョン(v0.7)をダウンロードしました。(WIndows11環境で動作OKでした)

MIDI規格の32150bpsという転送速度が設定できないため、これに近い速度の38400bpsを設定します。そのためArduinoスケッチの方でもそれの対応が必要です。(詳細は後述の使い方を読んでください)

余談ですが、Hairlessとは変わった名前と思い上記作者のGitHubページを読んでみると名前の由来に関して少し記載がありました。YakShaving(ヤクの毛刈り)に起因するように書いてありました。このYakShavingは初めて聞く言葉でしたがソフトウェアの世界ではよく使われる言葉の様です。目標に到達するまでにいくつもの問題に遭遇し、それらを一つ一つ解決していく様を動物のヤクの毛刈りから織物までにたどり着く過程を例えたことが由来の様です。参考サイト

loopMID

仮想MIDIケーブルというフリーソフトです、PC内に仮想のMIDIケーブルを形成します。上記HairleesMIDIとDominoを接続するために使います。

作者のサイトからダウンロードします。こちらはインストーラタイプなのでexeファイルを起動させてインストールをしていきます。

YMF825MIDI音源化モジュール

Arduino+YMF825ボードの構成でMIDI音源を具現化したモノのことです。ArduinoNanoを使用しMIDI音源として動作するためにプログラムしたスケッチをダウンロードします。

【YMF825のMIDI音源化】

この部分に関しては、前回と同じ構成になり変更はありません。動作の流れは以下のようになります。

  1. シリアルデータを受信(ArduinoNanoのRX0端子から受信)
  2. MIDIデータを解析
  3. 解析データに従って、音色・ノートをYMF825にSPI経由で送信
  4. スピーカー端子から音声信号が送出され、スピーカーから演奏楽曲が聞こえる。

MIDI音源対応スケッチファイルの準備

MIDI音源スケッチはYamahaサイトにアップされているサンプルスケッチ「ymf825board_sample2.ino」(YMF825をMIDI音源化するC言語のソフトウェアモジュール)をベースに修正を加えたものを使います。

注)YamahaのYMF825公式サイトは既にクローズされており代替サイトが有志の方により引き継がれて公開されています。

このYamahaのサンプルスケッチでは演奏データは外部からMIDIデータを受けて演奏するようには書いてなくて、内部で0X3C(60)ド→0X48(70)ド(1Oct上)の間を半音単位でループ演奏するように書いてあります。

そのため、このループ演奏プログラムを削除して新たに「MIDIデータ受信⇒MIDIデータ解析部への転送」のプログラムを追加します。

MIDIデータ転送プログラム製作に当たっては、MIDIライブラリの中のSampleプログラムとQiita内でこのMIDIライブラリを解析した記事がありましたのでこれらを参考に作成しました。Callbacksというサンプルプログラムを参考にしました。場所はArduino > libraries > MIDI_Library > examples > Callbacksにあります。

作成したスケッチのソースを以下に記載します。

#include <MIDI.h> //MIDIライブラリの読み込みを指定

extern "C" {
#include "fmif.h"
}
#include "fmsd1.h"

MIDI_CREATE_DEFAULT_INSTANCE(); //MIDIクラスからMIDIインスタンスを生成

void handleNoteOn(byte channel, byte pitch, byte velocity)
{
  Fmdriver_sendMidi(0x90);
  Fmdriver_sendMidi(pitch);
  Fmdriver_sendMidi(velocity);
}
void handleNoteOff(byte channel, byte pitch, byte velocity)
{
  Fmdriver_sendMidi(0x80);
  Fmdriver_sendMidi(pitch);
  Fmdriver_sendMidi(velocity);
}
void handleProgramChange(byte channel, byte number)
{
  Fmdriver_sendMidi(0xc0);
  Fmdriver_sendMidi(number);
}
void setup() {
  // put your setup code here, to run once:
  initSPI();
  initSD1();

  Fmdriver_init();
  MIDI.setHandleNoteOn(handleNoteOn);
  MIDI.setHandleNoteOff(handleNoteOff);
  MIDI.setHandleProgramChange(handleProgramChange);
  MIDI.begin(MIDI_CHANNEL_OMNI); //全てのチャンネルのメッセージを受信
  Serial.begin(38400); //HairlessMIDIで設定した転送速度と合わせる。
}

void loop() {
  // put your main code here, to run repeatedly:
  MIDI.read();
}

MIDIライブラリー(名称:MIDI_Library)をインストール後に上記スケッチをArduinoNanoにてコンパイル&書き込み処理をしてください。

【楽曲演奏するまでの設定の方法】

ここまででArduinoNano+YMF825を使用したMIDI音源モジュールができていると思うので、Domino上の楽曲データを演奏するところからスピーカー音出しまでの設定方法を説明していきます。

ハードウェア構成

MIDIケーブルが不要になったので以下の様にシンプルになります。

  • ArduinoNano
  • YMF825
  • スピーカー

loopMIDI設定

インストール済のloopMIDIを起動し仮想MIDIポートを作成します。

作成した仮想MIDIポートはWindows内部に存在するMIDIケーブルのようなもので、今回のケースではDomino(Out) ⇒ HaireleeMIDI(In)の間を接続するように使います。

手順を以下に説明します。

①loopMIDIを起動
起動直後の画面

➁画面左端の「+」ボタンをクリックすると画面中央のウィンド内に仮想MIDIポートが作成される。ポート名は特に変更しなければデフォルトの「loopMIDI Port」が使われます。(下図を参照)

以降、同様に「+」ボタンをクリックするたびに仮想MIDIポート追加されます、また逆に削除する場合は削除したいポートを選択後「ー」ボタンをクリックすることでできます。

但し、今回のケースでは作成するポートは1個のみですので作り過ぎた場合は「ー」ボタンで余分なポートを削除しましょう。

ポートが一つ作成されたら操作は終了です、但しloopMIDIのウィンドは閉じずにそのままにしておきます。

HairlessMIDI設定

このHairlessMIDIそのものはインストーラタイプでは無いので、実行ファイル「hairless-midiserial.exe」をそのまま起動させます。

①起動画面

➁Preferenceを開く

③Baud Rateに38400を選択する

④各ポートを選択する

USB-Serialポート(Arduino接続ポート)とloopMIDIポート(Domino接続ポート)をそれぞれ選択する。MIDIデータフロー中は下図の○の中が緑色点滅するので接続がうまく行っているかを確認できる。(上流側のDominoを再生状態にすることを忘れないように注意)

⑤MIDIデータをモニタリングすることも可能

Dominoの設定

Dominoから出力されるMIDIデータを仮想MIDIポートに流すための設定が必要。

①Domino環境設定を開く

➁MIDI-OUTを開きMIDI-OUTデバイスをloopMIDI Portに設定

Dominoで演奏し音出しを確認する。

ここまでの設定によりDomino上でMIDIデータの演奏の準備ができましたのでDomino上でお気に入りの楽曲の演奏を楽しんでください。

注意事項

  1. ArduinoIDEからのArduinoマイコンへのプログラム書き込み時には一時的にHairelessMIDIを閉じるかまたは出力ポートの選択を(NotConnected)にする必要があります。これはUSB(COM)ポートの競合が発生するためです。そのままですとArduinoIDE上でコンパイル終了後の書き込みフェーズでエラーが発生します。
  2. Dominoで再生してもArduinoMIDI音源が動作しない時はArduinoのリセットボタンを押してみてください。これで音が出ることが何度もありました。
  3. DominoがインポートできるSMF(MIDIフォーマット)はFormat0なので他のフォーマット(1,2)の場合はインポートする前にフォーマット変換が必要です。「SMFConverter for Windows」(Vectorなど)等の変換ソフトを使って変換してからインポートしてください。