MIDI再生:FM音源YMF825+Arduino編
2020.01.18 / 2023.02.23更新
YouTube 動画でポイントを説明しています。画像をクリックすると再生できます。
今回は、ヤマハのFM音源YMF825ボードとArduinoをSPI接続して、ラズパイからのMIDI出力をttymidiによりUSBシリアル経由でArduinoに流し込み再生します。
ttymidiは、Arduinoが追加のハードウェアを使用することなく、MIDIアプリケーションと通信できるようにします。
■準備するもの
使用する機材が多いので、下記に列挙しておきます。
Raspberry Pi Zero WH GPIOピンヘッダー ハンダ付け済み Wi-Fi & Bluetooth作動確認済(ヒートシンク、SDカード付き
ヤマハFM音源LSI YMF825搭載モジュール YMF825Board
ヤマハのFM音源チップYMF825(SD-1)を搭載した音源ボードです。ヤマハ独自のFMシンセサイザを搭載し、数種類のパラメータ指定により豊かなサウンドを再生することが可能です。
ArduinoやRaspberry Pi等のマイコンボードから、SPIを通して直接YMF825のレジスタを制御することで発音させます。スピーカーアンプも搭載しているので、アンプ回路を別途外部に用意する必要がありません。
・4オペレータのFM音源
・最大16音同時に発音可能
・FMの基本波形29種類内蔵、アルゴリズム8種類
・SPIによるシリアルインタフェース
・スピーカアンプ内蔵
・3バンドイコライザ内蔵
・16 bitモノラルD/Aコンバータ内蔵
・動作電圧:5V
細ピンヘッダ 1×9
・極数:9/列数:1
・ピッチ:2.54mm
・取付穴径:Φ0.80±0.05mm
YMF825 をブレッドボードに挿して使用する場合に必要になります。秋月さんでYMF825を購入するのであれば、一緒に買ってしまいましょう。
当然、はんだ付けが必要になります。
また、YMF825には、3.5mmヘッドフォン出力の他に、SPEAK OUTが2端子あるので、2ピンのピンヘッダもはんだ付けすると、ボードが安定します。
Arduino Nano V3.0
・Ch340G Replace FT232RL
・Operating Voltage(logic level):5V
・8 analog inputs ports:A0~A7
・14 Digital input / output ports:TX,RX,D2~D13
・6PWM ports:D3,D5,D6,D9,D10,D11
・1 pair of TTL level serial transceiver ports RX / TX
ブートローダー付きの製品を選ぶと楽です。Nano でなくてもよいのですが、YMF825と合わせて下記のブレッドボードに収まります。
サンハヤト SAD-101 ニューブレッドボード
・部品やリード線を差すだけで回路が組み立てられる
・使用可能線径:AWG#22~#30(0.3φ~0.8φ)
・絶縁抵抗:1,000MΩ以上(DC500V/1min)
・静電容量:10pF以下(リード径0.6φ、1MHz)
・抵抗値:10mΩ(リード径0.6φ、1kHz)
・電流容量:MAX 3A
・端子部材質:ニッケルメッキ
・ポイント数:408
YMF825BoardとNanoがきれいに収まります。ちょっとお高いですがよい製品です。
変換名人 スマートフォン用 USBケーブル データ転送&充電対応 microB オス - MiniB オス USBMCA/M5A20F
Raspberry Pi Zero WH と Arduino Nano を繋ぐケーブルです。
AGPtEK R08 ポータブル FMラジオ MP3プレーヤー 録音/音楽再生機能付き 32GBマイクロSDカードに対応(ブラック)
本体寸法:約(幅)103×(高さ)62×(奥行)23mm /
本体重量:約118g /
バッテリー:3.7V リチウムイオン電池 800 mAh(充電式)(付属します) /
入力端子:φ3.5mm 外部音声入力ジャック /
日本向け受信周波数:76-108 MHz
※スピーカー用に使用しています。LINE-INがあるので便利です。
ステレオ ミニプラグ 17cm
・ステレオ ミニプラグコード (オスオス)
・長さ約:17cm 1個
・プラグ径3.5mm 3芯タイプ 金メッキ端子
・コード径約3mm 高品質シリコンゴム やわらかく使い勝手が良いです。
ミニプラグ付きのスピーカーを使うのであれば必要ありません。
その他必要なもの
ジャンパワイヤ(オス~オス) 7本
Raspberry Pi Zero 用電源ケーブル・アダプター
はんだゴテ、はんだ等
■構成図
ラズパイ・ゼロWHとArduino Nanoは、USBケーブルでシリアル接続しています。また、ArduinoとYMF825はSPI接続です。
PCM5101AのDACは普段音楽を聴くためで、MIDI再生には関係ありません。ラズパイとArduinoはUSBシリアル接続ですので、DACと干渉しあうことはありません。
構成図には色々記載されていますが、要は青枠内です。
OSには、Raspbian Stretch を使用していますが、Stretch Lite でもかまいません。
Raspberry Pi の設定は、パソコンからSSH接続にて行っています。
■YAMAHA YMF825 Board と Arduino Nano の結線 (SPI接続)
YAMAHA YMF825 Board の表と裏です。ピンの脇に刻印があるので、配線は間違えないと思います。
YMF825Board | - | Arduiono Nano |
SS | - | D10:SS (chip select) |
MOSI | - | D11:MOSI (serial data output) |
MISO | - | D12:MISO (serial data input) |
SCK | - | D13:SCK (serial clock) |
GND | - | GND:ground |
5Vin | - | 5V :power |
RST_N (reset) | - | D9 |
Audio Out | | |
3.3Vin | | |
実際に配線すると、こんな感じになります。中央にあるDACは関係ありません。右側のノートパソコンからSSH接続で設定を行っています。
■前準備
Arduino Nano に転送するソースコードのビルドは、PlatformIO で行います。
Arduino IDE でも構いませんが、使っていないのでよくわかりません。
Arduino開発環境構築 PlatformIO
まずは、ソースコードを配置するディレクトリを作成します。
$ mkdir -p /home/pi/ymf825midi
$ cd /home/pi/ymf825midi
$ platformio init -b nanoatmega328
■ソースコードのダウンロードと編集
YMF825Board Sample Module のダウンロード
https://github.com/yamaha-webmusic/ymf825board/tree/master/sample2/
YMF825をMIDI音源化するためのソフトウェアモジュールです。
/common 内のファイルと、 /arduino 内のファイル全てを、/home/pi/ymf825midi/srcフォルダにダウンロードします。
※2023.02.23現在、サイトは削除されているようです。
補足:fmsd1_ino.cpp
下記のようにArduino UNO(atmega328p)専用のモジュールです。ピン番号が固定されています。
ざっとソースコード群を見たところ他のマイコンボードへの移植はかなり面倒そうです。
void initSPI(void)
{
// init SPI
/*
* Conditions only for Arduino UNO
* SPI master
* RST_N- Pin9
* SS - Pin10
* MOSI - Pin11
* MISO - Pin12
* SCK - Pin13
*/
pinMode(10, OUTPUT);
digitalWrite(10, HIGH);
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SPI_CLOCK_DIV4); // 4MHz
SPI.setDataMode(SPI_MODE0);
SPI.begin();
}
ymf825board_sample2.ino (機能追加版)
Ref.YMF825BoardをArduinoでMIDI音源化する
ymf825board_sample2.ino には、MIDIデータを受信する処理がないので、このシリアルデータを受信するスケッチファイルをダウンロードして、
/home/pi/ymf825midi/src/ymf825board_sample2.inoを上書きします。
ここで、ラズパイからMIDIデータをシリアル接続で受け取る際のボーレートを追記します。
115200にしてみてもよかったのですが、小心者なので、38400程度にしておきました。
$ vi src/ymf825board_sample2.ino
void setup() {
// put your setup code here, to run once:
initSPI();
initSD1();
Fmdriver_init();
MIDI.setHandleNoteOn(noteOn);
MIDI.setHandleNoteOff(noteOff);
MIDI.setHandleProgramChange(programChange);
MIDI.begin(MIDI_CHANNEL_OMNI);
Serial.begin(38400); ← 追記
}
■ソースコードのビルド
ビルドします。
$ platformio run
...
Compiling .pio/build/nanoatmega328/src/ymf825board_sample2.ino.cpp.o
/home/pi/ymf825midi/src/ymf825board_sample2.ino:1:18: fatal error: MIDI.h: No such file or directory
**************************************************************
* Looking for MIDI.h dependency? Check our library registry!
*
* CLI > platformio lib search "header:MIDI.h"
* Web > https://platformio.org/lib/search?query=header:MIDI.h
**************************************************************
MIDI.hがないと怒られたので、MIDIライブラリーを追加します。
$ platformio lib search "header:MIDI.h"
Found 2 libraries:
MIDI Library
============
#ID: 62
Enables MIDI I/O communications on the Arduino serial ports
Keywords: midi
Compatible frameworks: Arduino
Compatible platforms: Atmel AVR, Atmel SAM, Teensy
Authors: Francois Best
.....
$ platformio lib install 62
Library Storage: /home/pi/ymf825midi/.pio/libdeps/nanoatmega328
LibraryManager: Installing id=62
Downloading [####################################] 100%
MIDI Library @ 4.3.1 has been successfully installed!
環境設定ファイルにライブラリー情報を追記します。
$ vi platformio.ini
[env:nanoatmega328]
board = nanoatmega328
framework = arduino
platform = atmelavr
lib_deps =
62
再度、ビルとして、Arduino に転送します。
$ platformio run -t upload
■ttymidi のインストール
ttymidiは、外部シリアルデバイスがALSA MIDIアプリケーションとやりとりできるようにするGPLライセンスのプログラムです。
ttymidiは、Arduinoが追加のハードウェアを使用することなく、MIDIアプリケーションと通信できるようにします。
Ref.http://www.varal.org/ttymidi/
TTYMIDI on the Raspberry Pi
Raspberry Pi用のTTYMIDIをインストールします。
Ref.http://siliconstuff.blogspot.com/2012/08/ttymidi-on-raspberry-pi.html
まずは、ALSAの開発環境をインストールします。
$ sudo apt-get install libasound2-dev
ttymidi をインストールします。
$ wget http://www.varal.org/ttymidi/ttymidi.tar.gz
$ tar -zxvf ttymidi.tar.gz
$ cd ttymidi/
$ make
gcc src/ttymidi.c -o ttymidi -lasound
src/ttymidi.c:477:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
main(int argc, char** argv)
^~~~
/usr/bin/ld: /tmp/cc0IcPbX.o: シンボル 'pthread_join@@GLIBC_2.4' への未定義参照です
//lib/arm-linux-gnueabihf/libpthread.so.0: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
Makefile:2: ターゲット 'all' のレシピで失敗しました
make: *** [all] エラー 1
gcc でスレッド用のライブラリを指定します。
$ vi Makefile
gcc src/ttymidi.c -o ttymidi -lasound
↓変更
gcc src/ttymidi.c -o ttymidi -lasound -lpthread
$ make
gcc src/ttymidi.c -o ttymidi -lasound -lpthread
src/ttymidi.c:477:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
main(int argc, char** argv)
$ sudo make install
install -m 0755 ttymidi /usr/local/bin
■MIDIファイルの再生
Raspberry Pi Zero WH に接続されているデバイスを確認します。
$ platformio device list
/dev/ttyUSB0
------------
Hardware ID: USB VID:PID=1A86:7523 LOCATION=1-1
Description: USB2.0-Serial
/dev/ttyAMA0
------------
Hardware ID: 20201000.serial
Description: ttyAMA0
現在のボーレートをみてみます。
$ stty < /dev/ttyUSB0
speed 9600 baud; line = 0;
min = 0; time = 0;
-brkint -icrnl -imaxbel
-opost -onlcr
-isig -icanon -iexten -echo -echoe -echok -echoctl -echoke
現在のMIDIポートの入出力を確認します。
$ aconnect -iol
client 0: 'System' [type=カーネル]
0 'Timer '
1 'Announce '
client 14: 'Midi Through' [type=カーネル]
0 'Midi Through Port-0'
バックグランドで、ttymidi を動かします。
$ ttymidi -s /dev/ttyUSB0 -b 38400 &
再度、MIDIポートの入出力を確認してみます。
$ aconnect -iol
client 0: 'System' [type=カーネル]
0 'Timer '
1 'Announce '
client 14: 'Midi Through' [type=カーネル]
0 'Midi Through Port-0'
client 128: 'ttymidi' [type=ユーザ,pid=1468]
0 'MIDI out '
1 'MIDI in '
ボーレートも確認してみます。
$ stty < /dev/ttyUSB0
speed 38400 baud; line = 0;
....
ポートを指定して、MIDIファイルを再生しましょう。
$ aplaymidi -p 128:1 Aria.mid
スピーカーから音が流れましたら、成功です。
■注意点
Arduino のコードを書き換える際には、ttymidi がシリアルポートを占有しているので、
バックグランドプロセスをKILLしてから、行ってください。
■HEXファイルの保存
ビルド環境の維持が難しい場合には、HEXファイルを保存しておいて、avrdude などのツールで直接マイコンボードへ書き込めるようにしておくのもよいかもしれません。
$ ls -l ~/ymf825midi/.pio/build/nanoatmega328
drwxr-xr-x 2 pi pi 4096 2月 23 18:51 FrameworkArduino
-rwxr-xr-x 1 pi pi 21344 2月 23 18:51 firmware.elf
-rw-r--r-- 1 pi pi 24289 2月 23 18:51 firmware.hex
-rw-r--r-- 1 pi pi 325962 2月 23 18:51 libFrameworkArduino.a
-rw-r--r-- 1 pi pi 8 2月 23 18:51 libFrameworkArduinoVariant.a
drwxr-xr-x 3 pi pi 4096 2月 23 18:51 libc95
drwxr-xr-x 2 pi pi 4096 2月 23 18:51 src
$ avrdude -v -p atmega328p -c arduino -P /dev/ttyUSB0 -b 57600 -p m328p -D -U flash:w:firmware.hex:i
■参考文献
FM音源YMF825を使ってみる[MIDI音源編]
http://www.umek.topaz.ne.jp/mameduino/ymf825midi_tg/
Windows と YMF825を接続する場合には下記も参考になると思います。
MIDIケーブルなしでArduinoとMIDIを送受信する方法
http://spinelify.blog.fc2.com/blog-entry-83.html
|