YMZ294を追加しました

前回MIDI音源プログラムに音源ICとしてYMZ294を追加しました。

ソースコードはv2.0.0としてタグ打ちしました。

GitHub - nyannkov/nano_midi: usb midi and cdc device running on Longan Nano

外観はこんな感じです。
f:id:nyankov:20200602215924j:plain

なぜ両面スルーホールの表側でもスズメッキ配線をしてしまったのか。

作成完了寸前にこの過ちに気づき、作り直そうか考えましたが

面倒くさすぎるので諦めました。

とりあえず短絡しないように裏側のスズメッキ線をちょっぴり浮かせて紙を差し込んでいます。

【追加】2020/6/7 youtubeに演奏している様子をアップしました。 www.youtube.com

回路図

回路図です。

f:id:nyankov:20200603221408p:plain

シフトレジスタは秋月で一つ30円のSN74HC164Nを使用しました。

また、YMZ294のマスタークロック(φM)は、クリスタルオシレータではなくLongan Nanoのタイマー出力としました。

音色の制御について

今回はプログラムチェンジに対する処理は実装せず、MIDIチャンネルごとにエンベロープの形状や周波数、ノイズ/トーンの選択などを設定するようにしました。

以下の図は各MIDIチャンネルに対する設定情報になります。

f:id:nyankov:20200605153257j:plain

記号 内容 値の範囲
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としました。 なお、設定の保存処理は未実装ですが、そのうち実装しようと思います。

他にもいくつかコマンドを実装しましたが、詳細はgithubwikiにまとめようと考え中です。

MIDI音源プログラムをLongan Nanoに移植しました

以前作成したYMF825 Boardを使ったMIDI音源プログラムをLongan Nanoに移植しました。色々と手直しも入っています。

ソースコードはここに置きました。

github.com

外観はこんな感じです。だいぶ小さくなりました。

f:id:nyankov:20200425121532j:plain

以下、動作させるまでの流れについて簡単に記載したいと思います。

【追加】2020/6/5 音源ICとしてYMZ294を追加しました。YMZ294を追加しました - にゃんこ府

目次

配線

Longan NanoとYMF825 Boardの結線は次のようにしました。

【修正】2020/5/4 N_RSTへの配線をA8からB11に変更しました。

Longan Nano YMF825 Board
A8B11 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を接続するだけで標準ドライバがインストールされました。
バイスマネージャはこんな感じです。

f:id:nyankov:20200425113042j:plain

MIDI演奏

以下の画面はKbMedia Playerのデバイス設定ウィンドウになります。
画像のようにnano_midiを選択してからMIDIファイルを再生すると、YMF825からメロディが鳴りました。

f:id:nyankov:20200425191302j:plain

KbMedia PlayerはKobarinさんのサイトからダウンロードできます。とても使いやすいのでおススメです。

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に変更しています)。
後半は今回実装したコマンドモードの動作で、コロンから始まる文字列をコマンドとして取り扱い、スペースとタブで区切った後続文字列をコマンド処理の引数として渡せるようにしました。今後、対応音源が増えた際に使用する予定です。

f:id:nyankov:20200425150011g:plain

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ポート番号を認識してくれない 状態に陥っていたみたいです (この後、なぜか管理者として実行しなくてもデバッグできるようになりました。結果的には良かったのですが、、)。

デバッグ画面

f:id:nyankov:20200307225822p:plain

〇サンプルBad Apple!!実行中。サンプルの場所はここです。

f:id:nyankov:20200307231136j:plain

RISC-VもPlatformIOも初めてなので、色々楽しいです。

イース PALACEをYMF825で鳴らしてみました

イース 神殿のBGMのPALACEを打ち込んで、YMF825で鳴らしてみました。

youtube
www.youtube.com

ニコニコ動画
www.nicovideo.jp

原曲で使われている、鋭くも柔らかく透き通った矩形波みたいな音を、前回はうまく再現できずに諦めたのですが、
今回、 矩形波アルゴリズム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

ソースコード

github.com

イースのBGM「FOUNTAIN OF LOVE」を打ち込んで、作成した音源で鳴らしてみました。

www.youtube.com

〇2019/8/31 詳細を追加しました。

目次

目的

FM音源ICで好きなゲームのBGMを鳴らしたい!

ハードウェア

FM音源

YMF825を使用しました。

マイコン(評価ボード)

たまたまあったNUCLEO-F767ZIを使用しました。

工作

評価ボードにARDUINOインタフェースがあったので、ユニバーサル基板で YMF825シールドを作成して合体させようと思ったら、ビミョーにはまらない。。そういうものなのでしょうか。

仕方がないので無理やりさしました。

f:id:nyankov:20190825235533j:plain 曲がってますね。。

あと、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ドライバに書き換えて動作確認を行いました。

yamaha-webmusic.github.io

2電源化対応で長い時間はんだ小手を押し付けてしまったため、ドレミ音が聞こえたときはホッとしました。

機能ブロック

こんな感じで設計しました。

f:id:nyankov:20190825131012p:plain

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さんのブログで学ばせて頂きました。

pcm1723.hateblo.jp

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を作成しました。

www1.plala.or.jp

MIDI Message Parserはインスタンスとして生成するようにし、NoteOnやControlChangeといった各々のMIDIメッセージに対するコールバック関数をこのインスタンスに登録するようにしました。

これは今後、音源ICを追加したとき、コマンドによって動的に音源ICを切り替えられるようにしたかったためです。

SoundSourceDriver

MIDI Message Parserに登録するコールバック処理です。この部分にMIDIメッセージ受信時の処理を記述します。

f:id:nyankov:20190831125543p:plain

今回は、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さんのサイトで勉強させていただきました。

akiyoshiogata.com

MIDIファイルの作成

MIDIシーケンサー

くずさんの『世界樹5.7』を使用させていただきました。

https://openmidiproject.osdn.jp/Sekaiju.htmlopenmidiproject.osdn.jp

作成した音楽

イース ミネアの町のBGM 『FOUNTAIN OF LOVE』を素人なりに打ち込んでみました。 参考にしたのはPC-88版ですが、なかなか難しいですね。。