ヤマハ製の音源 IC YMZ294 を使ってみた

\[ \newcommand{dn}[3]{\frac{\mathrm{d}^{#3} #1}{\mathrm{d} #2^{#3}}} \newcommand{\d}[2]{\frac{\mathrm{d} #1}{\mathrm{d} #2}} \newcommand{\dd}[2]{\frac{\mathrm{d}^2 #1}{\mathrm{d} {#2}^2}} \newcommand{\ddd}[2]{\frac{\mathrm{d}^3 #1}{\mathrm{d} {#2}^3}} \newcommand{\pdn}[3]{\frac{\partial^{#3} #1}{\partial {#2}^{#3}}} \newcommand{\pd}[2]{\frac{\partial #1}{\partial #2}} \newcommand{\pdd}[2]{\frac{\partial^2 #1}{\partial {#2}^2}} \newcommand{\pddd}[2]{\frac{\partial^3 #1}{\partial {#2}^3}} \newcommand{\p}{\partial} \newcommand{\D}[2]{\frac{\mathrm{D} #1}{\mathrm{D} #2}} \newcommand{\Re}{\mathrm{Re}} \newcommand{\Im}{\mathrm{Im}} \newcommand{\bra}[1]{\left\langle #1 \right|} \newcommand{\ket}[1]{\left|#1 \right\rangle} \newcommand{\braket}[2]{\left\langle #1 \middle|#2 \right\rangle} \newcommand{\inner}[2]{\left\langle #1 ,#2 \right\rangle} \newcommand{\l}{\left} \newcommand{\m}{\middle} \newcommand{\r}{\right} \newcommand{\f}[2]{\frac{#1}{#2}} \newcommand{\eps}{\varepsilon} \newcommand{\ra}{\rightarrow} \newcommand{\F}{\mathcal{F}} \newcommand{\L}{\mathcal{L}} \newcommand{\t}{\quad} \newcommand{\intinf}{\int_{-\infty}^{+\infty}} \newcommand{\R}{\mathcal{R}} \newcommand{\C}{\mathcal{C}} \newcommand{\Z}{\mathcal{Z}} \newcommand{\bm}[1]{\boldsymbol{#1}} \]

YMZ294でロックマン pic.twitter.com/W3yztZKuT6

— Канадэ (@kanade_k_1228) November 26, 2021

必要な部品

チュートリアル

  1. リポジトリのページ右上の Code から、zip を選択しダウンロード
  2. ダウンロードした zip ファイルを Arduino IDE に取り込む(Sketch > Include Library > Add .ZIP Library…)
  3. サンプルコードを開きます (File > Examples > YMZ294 > 00_include ) 見つからない場合は、Arduino IDEを再起動すると見つかると思います
  4. 検証(✓マーク)を押してみて、エラーが起きなければ、無事にインストール完了です!
  5. Arduino と YMZ294 を配線で繋ぎます

  1. サンプルコードから、01_sound を開いて、書き込んだら、音が鳴るはずです!

トラブルシューティング

YMZ294 のしくみ

音が生成されるまでの流れを解説するよ! データシートの図を参照してね!

  1. 楽音発生器
    • ある決まった周波数の矩形波(四角形の波)を生成します
    • 正弦波(音叉のようなきれいな音)ではない
    • 基準クロックを分周して生成している
  2. ミキサー
    • 各チャンネルごとの ON/OFF を切り替えます
    • (リアルのミキサーと違って)音量はここでは調整しないことに注意
  3. 音量調整
    • 各チャンネルごとの音量を調整します
    • 音量はデシベル値で設定します
      • デシベルは dB = log10 対数であることに注意

YMZ294 のしくみ(詳細版)

「ノイズ」「エンベロープ」という機能を使うとより豊かな表現ができるよ!

  1. 楽音発生器
  2. ノイズ発生器
  3. ミキサー
  4. エンベロープ発生器
  5. 音量調整

ライブラリの使い方

「sample」の中にサンプルコードがあるのでいろいろ試してみて!

  1. YMZ294 のピンがどこに繋がっているかを設定します
    • YMZ294 sound()
  2. setup 関数の中で、ピンのセットアップと、YMZ294 のリセットをします
    • sound.setup_pin()
    • sound.reset_registers()
  3. 音の設定をして再生します

高度な使い方

好きな音楽を再生する

  1. MIDI エディタで曲を打ち込む
    • Dominoがおすすめ
    • Domino 用のテンプレートファイルが sample/07_play_music/template.dms にあります
    • 曲を打ち込んだら .mid ファイルを出力
  2. .midi.h に変換する
    • Midifles に変換プログラムがあるので、
    • cd
    • git clone https://github.com/kanade-k-1228/midifile.git
    • cd midifile
    • make library
    • make programs
    • make midi2ymz
    • して、プログラムをビルドしてください
    • bin/midi2ymz ???.mid > ???.h で変換します(??? は自分で作った midi ファイル名を入れる)
  3. include して書き込む
    • ???.hsample/07_play_music 内に移動します
    • 07_play_music.ino の先頭の #include "XXX.h"#include "???.h" に書き換えます
    • エラーが出た場合
      • メモリが足りない?
      • PROGMEM が悪さをしてる?

sample/06_play_rockmanloop() を見ると、たくさんの play_sound()delay() が並んでいます。このやり方では、Arduino のプログラムメモリを無駄遣いしてしまい、長い曲を再生できません。このため、ここだけのデータフォーマットを作って曲のデータを表現しています。

15 0:Delay 1:Sound 切り替えます
IF Delay
14 0 Delay Time [ms]
IF Sound
14 13 Chip Sellect 複数接続しない場合、チップセレクトは不要です
12 11 Channel 1~3 のチャンネル番号を指定 0 番は予約済(ノイズ周波数に使う予定)
10 4 Note Number
3 0 Velocity

複数接続

YMZ294 は 矩形波 3 チャンネルしかありません。ファミコンは矩形波 2 Ch + 三角波 1 Ch + ノイズ 1 Ch あるので、ファミコンの曲を再生しようとすると少し足りなかったりします。

ノイズを再生しようとすると、ノイズと矩形波の個別の音量調整ができないので、結局チャンネルを一つつぶすことになります。

YMZ294 には、「/CS」(チップセレクト)というピンがあり、これを使って複数の YMZ294 を並列に接続できます。

Arduino ピンが足らなくなるので、シフトレジスタを使って拡張します。