YMZ294を追加しました
前回のMIDI音源プログラムに音源ICとしてYMZ294を追加しました。
ソースコードはv2.0.0としてタグ打ちしました。
GitHub - nyannkov/nano_midi: usb midi and cdc device running on Longan Nano
外観はこんな感じです。
なぜ両面スルーホールの表側でもスズメッキ配線をしてしまったのか。
作成完了寸前にこの過ちに気づき、作り直そうか考えましたが
面倒くさすぎるので諦めました。
とりあえず短絡しないように裏側のスズメッキ線をちょっぴり浮かせて紙を差し込んでいます。
【追加】2020/6/7 youtubeに演奏している様子をアップしました。 www.youtube.com
回路図
回路図です。
シフトレジスタは秋月で一つ30円のSN74HC164Nを使用しました。
また、YMZ294のマスタークロック(φM)は、クリスタルオシレータではなくLongan Nanoのタイマー出力としました。
音色の制御について
今回はプログラムチェンジに対する処理は実装せず、MIDIチャンネルごとにエンベロープの形状や周波数、ノイズ/トーンの選択などを設定するようにしました。
以下の図は各MIDIチャンネルに対する設定情報になります。
記号 | 内容 | 値の範囲 |
---|---|---|
ch | MIDI チャンネル(本来のチャンネル番号から1差し引いた値) | 0-15 |
en | チャンネルEnabled(falseの場合、MIDIメッセージを無視する) | true/false |
mx | ミキサー設定 | noise/tone |
em | エンベロープモード(onの場合、エンベロープ発生器で音量制御する) | on/off |
es | エンベロープの形状(レジスタ$0Dに対応) | 0x00-0x0F |
ep | エンベロープ周波数(レジスタ$0B-$0Cに対応) | 0x0000-0xFFFF |
np | ノイズ周波数(レジスタ$06に対応) | 0x00-0x1F |
設定変更についてですが、例えばMIDIチャンネル10を有効化し、ノイズ周波数を0x10に設定したい場合、コマンドは以下のような書式としました。
:ymz294 -ch 9 -en true -np 0x10
":ymz294 -ch 番号" の後に、設定値を記述していく感じです。
デフォルト値はチャンネル10(パーカッション)以外を有効とし、エンベロープモードは全てoffとしました。 なお、設定の保存処理は未実装ですが、そのうち実装しようと思います。
MIDI音源プログラムをLongan Nanoに移植しました
以前作成したYMF825 Boardを使ったMIDI音源プログラムをLongan Nanoに移植しました。色々と手直しも入っています。
ソースコードはここに置きました。
外観はこんな感じです。だいぶ小さくなりました。
以下、動作させるまでの流れについて簡単に記載したいと思います。
【追加】2020/6/5 音源ICとしてYMZ294を追加しました。YMZ294を追加しました - にゃんこ府
目次
配線
Longan NanoとYMF825 Boardの結線は次のようにしました。
【修正】2020/5/4 N_RSTへの配線をA8からB11に変更しました。
Longan Nano | YMF825 Board |
---|---|
N_RST | |
B15 | MOSI |
B14 | MISO |
B13 | SCK |
B12 | SS |
G | GND |
3.3V | 3.3V |
5V | 5V |
YMF825 Boardは2電源で使用するための回路変更を行っています。
また、Longan NanoのG端子は端っこにある方を使用しました(もう一つの端子を使用したところ、なぜか2V付近まで持ち上がってCPUが飛んだ)。
ビルド&書き込み
前回の記事の PlatformIO+VSCode+RV-Linkを使用する方法によって行いました。
デバイスドライバのインストール
Windows10の場合、書き込んだLongan Nanoを接続するだけで標準ドライバがインストールされました。
デバイスマネージャはこんな感じです。
MIDI演奏
以下の画面はKbMedia Playerのデバイス設定ウィンドウになります。
画像のようにnano_midiを選択してからMIDIファイルを再生すると、YMF825からメロディが鳴りました。
KbMedia PlayerはKobarinさんのサイトからダウンロードできます。とても使いやすいのでおススメです。
なお、MIDI Message Parserに登録している音源ドライバ(single_ymf825)ですが、同一チャンネルに和音があったり演奏中にプログラムチェンジが発生すると、正しく音を鳴らすことが出来ないため、正直残念なメロディになってしまうことが多いです。
とりあえずうまく演奏できるMIDIを探したり、この音源に合わせ込んだMIDIファイルを作成したりして楽しんでいます。
【追加】2020/7/5
同一チャンネルに和音があった場合でも演奏できる音源ドライバ(music_box_ymf825)を追加して、クロノ・クロスの「夢のかけら」を演奏してみました。
www.youtube.com
演奏できる音色は一種類のみですが、コマンドによって音色の変更、
パーカッションON/OFFの切り替えを行えるようにしてみました。
デフォルトはオルゴール、パーカッションOFFとしています。
コマンドの詳細等はリポジトリのwikiにまとめ中です。
〇wiki
Home · nyannkov/nano_midi Wiki · GitHub
CDC通信
最後にCDC通信です。Tera Termを使用してLongan Nanoと通信している様子をGIFアニメにしてみました。
前半は初投稿の記事に記述したゲートウェイモードの動作で、音色パラメータの調整など直接ICとやり取りしたい場合に使用しています(なおどうでもいいですが、ソースコード内ではhex modeに変更しています)。
後半は今回実装したコマンドモードの動作で、コロンから始まる文字列をコマンドとして取り扱い、スペースとタブで区切った後続文字列をコマンド処理の引数として渡せるようにしました。今後、対応音源が増えた際に使用する予定です。
Longan NanoでLongan Nanoをデバッグ(RV-LINK)
少し遅いですが秋月で830円(税込)で販売しているRISC-Vマイコン(GD32VF103CBT6)の開発ボードLongan Nanoを買いました。フルカラーIPS液晶に加えてTFカードスロットも付いて、この値段は嬉しいです。
このボードですが、NXPのLPC-Link2みたいな感じで、RV-LINKと呼ばれるデバッガにすることが出来るようです。サポートターゲットはGD32VF103に限られますが、一つ830円と安価なため、今回はこの方法で書き込み&デバッグを行うことにしました。
〇 Longan NanoのRV-LINK化とVSCode+PlatformIOによるデバッグ方法:
Using RV-LINK · Longan DOC
上記サイトに具体的な方法が記載されていますので、問題がなければ比較的スムーズにデバッグまでたどり着けるのではないかと思います。 ただ、私の環境では、gdbでRV-LINKに接続する箇所で、下記のようなエラーが発生してしまいました(OSはWindows10 Homeを使用)。
.pioinit:14: Error in sourced command file: COM3: No such file or directory.
このエラーについては、VSCode自体を管理者として実行することによって回避することが出来ました。 どうやらgdbを管理者として実行しないと、RV-LINKに対するCOMポート番号を認識してくれない 状態に陥っていたみたいです (この後、なぜか管理者として実行しなくてもデバッグできるようになりました。結果的には良かったのですが、、)。
〇デバッグ画面
〇サンプルBad Apple!!実行中。サンプルの場所はここです。
RISC-VもPlatformIOも初めてなので、色々楽しいです。
イース PALACEをYMF825で鳴らしてみました
イース 神殿のBGMのPALACEを打ち込んで、YMF825で鳴らしてみました。
原曲で使われている、鋭くも柔らかく透き通った矩形波みたいな音を、前回はうまく再現できずに諦めたのですが、
今回、
矩形波とアルゴリズム0(WSはともにsin波)で作成した矩形波のような音を同時に鳴らすと、少しはそれっぽい音になることを打ち込み中に気づくことが出来ました。
具体的には下記の二つの音(ymf825_tone_table.c内に定義)を使用しました。
const uint8_t ymf825_tone_table[128][30] = { ... /* 081_lead_1(square) */ { 0x00,0x40, 0x20,0x0A,0xF0,0xFC,0x00,0x30,0x00, 0x00,0x57,0xF2,0x2C,0x16,0x10,0x30, 0x00,0x2F,0xF3,0x9B,0x00,0x20,0x41, 0x00,0xAF,0xA0,0x0E,0x00,0x10,0x40 }, ... /* 101_FX_5(brightness) */ { 0x00,0x40, 0x20,0x0A,0xF0,0xFC,0x00,0x43,0x00, 0x20,0x5E,0x60,0x3C,0x07,0x10,0x30, 0x00,0x2F,0xF3,0x9B,0x00,0x20,0x41, 0x00,0xAF,0xA0,0x0E,0x00,0x10,0x40 }, ... };
〇関連記事
nyankov.hatenablog.com
YMF825でMIDI音源
NUCLEO-F767ZIを使用してMIDI音源を作成しました。Sound ChipはYMF825です。
【追加】2020/7/5 Longan Nanoでも動かせるようにしました。 nyankov.hatenablog.com
イースのBGM「FOUNTAIN OF LOVE」を打ち込んで、作成した音源で鳴らしてみました。
〇2019/8/31 詳細を追加しました。
目次
目的
FM音源ICで好きなゲームのBGMを鳴らしたい!
ハードウェア
FM音源
YMF825を使用しました。
マイコン(評価ボード)
たまたまあったNUCLEO-F767ZIを使用しました。
工作
評価ボードにARDUINOインタフェースがあったので、ユニバーサル基板で YMF825シールドを作成して合体させようと思ったら、ビミョーにはまらない。。そういうものなのでしょうか。
仕方がないので無理やりさしました。
曲がってますね。。
あと、YMF825Boardの2電源化には苦労しました。
ソフトウェア
開発環境
IDE
SEGGER Embedded Studioを使用しました。
https://www.segger.com/products/development-tools/embedded-studio/
デバッガ
Onboard DebuggerのST-LinkをJ-Linkに書き換えました。
〇方法はこちら
https://www.segger.com/products/debug-probes/j-link/models/other-j-links/st-link-on-board/
ソフトウェア設計
予備実験
はじめにYMF825Boardボードの動作確認を行いました。 下記のYAMAHA公式リポジトリにあるsample1 (ARDUINO用)のSPIドライバを STMicroのHALドライバに書き換えて動作確認を行いました。
2電源化対応で長い時間はんだ小手を押し付けてしまったため、ドレミ音が聞こえたときはホッとしました。
機能ブロック
こんな感じで設計しました。
USBD
USBDはSTM32_USB_Device_Libraryを使用して実装しました。
ターミナルソフトでYMF825を直接制御したかったため、 USBMIDIにUSBCDCを追加した複合デバイスクラスを実装することにしました。 ソースコードはSTM32_USB_Device_Library内のAUDIOクラスとCDCクラスをベースにして作成しました。 また、AUDIOクラスに関するコンフィギュレーションディスクリプタは 規格書のAppendix B. Example: Simple MIDI Adapter (Informative)に記述されているものに書き換えました。 そのため、今回は未使用ですが、MIDIOUTもホスト側から認識できていました。
USBMIDIに関してはpcm1723さんのブログで学ばせて頂きました。
Shell
大層な名前をつけてしまいましたが、 受信した文字列に従って処理を実行するだけです。
入力はゲートウェイモードとコマンドモードに分けました。
ゲートウェイモード
16進数を1 Byte単位で文字列にして送信した場合は、USBCDC-SPIゲートウェイとして動作するようにしました。終端文字は<CR>で、<LF>は無視します。
例えば5byte文字列 "073A"+<CR>を送信すると、2byte数値0x073AをYMF825に送信します。
また、YMF825専用の処理となってしまいますが、I_ADRの7bitが1の場合、SPI Readを行い、受信したデータを16進文字列にしてホスト側に送信するようにしました。
コマンドモード
:始まりの文字列(+<CR>)を受信した場合、上記モードとは別モードとして動作するようにしました。 これは例えば
:info
や
:cfg
といったコマンドを作成してシステムの監視や設定を行おうと考えていたためです。
ただ、今のところコマンドは未実装です。
MIDI Message Parser
『MIDI 1.0 規格書』と、悠人さんのサイトでMIDIについて勉強しながら、 MIDI Message Parserを作成しました。
MIDI Message Parserはインスタンスとして生成するようにし、NoteOnやControlChangeといった各々のMIDIメッセージに対するコールバック関数をこのインスタンスに登録するようにしました。
これは今後、音源ICを追加したとき、コマンドによって動的に音源ICを切り替えられるようにしたかったためです。
SoundSourceDriver
MIDI Message Parserに登録するコールバック処理です。この部分にMIDIメッセージ受信時の処理を記述します。
今回は、SoundSourceDriverの一つとして、single_ymf825というモジュールを作製しました。 MIDIチャンネルの番号を単純にそのままYMF825のtone numberにマッピングするようにしました。 そのため、各MIDIチャンネルの同時発音数は1となるので、動作としてはモード4(オムニオフ、モノモード)になるかと思います。 なので、同一チャンネルに和音があるようなMIDIファイルの場合、発音する音色は後勝ちとなります。 また、YMF825のToneParameterを更新するために、すべての音をOFFする必要があるようなので、 演奏中にProgramChangeを受信すると、音が途切れます。これ、何とかならないでしょうか。
あと、チャンネル10は常にノイズ音としました。
音色作成
「FM音源はパラメータが多い上に感覚的に理解しづらい」
ということはなんとなく分かっていたつもりでしたが、いざ作ろうと思ったら、本当に何をしていいのかわからずに途方にくれてしまいました。
なので本買いました。
この本のおかげで、自分が出したい音色の設計方針を学ぶことができました。
作製した音色情報はToneTableに登録するようにしました。動作としてはProgramChangeでこのテーブルを参照し、YMF825に情報を流し込むといった感じです。
とりあえずGM音源としてNo.1からNo.128までの音色を作製しようと頑張ったのですが、 挫折しました(コーラスとかストリングスとかオケヒとか、いったいどうしろと。。)。
※音色(楽器)に関してはAkiyoshi Ogataさんのサイトで勉強させていただきました。
MIDIファイルの作成
MIDIシーケンサー
くずさんの『世界樹5.7』を使用させていただきました。
https://openmidiproject.osdn.jp/Sekaiju.htmlopenmidiproject.osdn.jp
作成した音楽
イース ミネアの町のBGM 『FOUNTAIN OF LOVE』を素人なりに打ち込んでみました。 参考にしたのはPC-88版ですが、なかなか難しいですね。。