curious4dev

中国旅行、Arduinoなどを使った電子工作、その他色々。

*

グラディウス2の3面 古代惑星のテーマをArduino+YMZ294で鳴らしてみた。

 

お疲れ様です。高橋です。

グラディウス2の3面、古代惑星のテーマをArduino+YMZ294で鳴らしてみました。

前に買ったスピーカーを2つ増設し、合計3スピーカー。そしてテンポを可変抵抗器で変えられるように少し回路をいじりました。右側の可変抵抗器がテンポ変更用です。スピーカーを増設した事は特に理由はありません。カッコ良さそうだったからやってみました。

gra201

(2015/02/04追記) 上記回路図は間違っています。YMZの4番と8番からは、GNDではなく、5Vに流れます。 

 

テンポを変えるには

SMFをYMZ用C言語に変換する際は、kalshagarさんのサイトで公開しているツールを使いますが、下記のような感じに変換されます。

 set_ch(ADDR_FREQ_A,79);
 set_ch(ADDR_FREQ_B,72);
 set_ch(ADDR_FREQ_C,48);
 delay(232);
 set_ch(ADDR_FREQ_A,0);
 set_ch(ADDR_FREQ_A,67);
 set_ch(ADDR_FREQ_B,0);
 set_ch(ADDR_FREQ_C,0);
 set_ch(ADDR_FREQ_C,55);
 delay(249);

set_chというメソッドにチャンネルと音程を渡して、音の長さ分delayするという物です。set_chというメソッドを実装する必要があるのと、delayでセットした長さは、意図したテンポにならないため、下記のように改造します。

まずは、set_chメソッドを実装します。中でYMZライブラリの周波数指定メソッドを呼ぶ形にします。

void set_ch(Channel ch, int note) {
 ymz.SetFrequency(ch, noteFreq[note]);
}

そして、 delay部分はuser_delayという感じにArduino側のメソッドを使うのではなく、一度ラップメソッドを呼ぶように修正し、

 set_ch(ADDR_FREQ_A,79);
 set_ch(ADDR_FREQ_B,72);
 set_ch(ADDR_FREQ_C,48);
 user_delay(232);
 set_ch(ADDR_FREQ_A,0);
 set_ch(ADDR_FREQ_A,67);
 set_ch(ADDR_FREQ_B,0);
 set_ch(ADDR_FREQ_C,0);
 set_ch(ADDR_FREQ_C,55);
 user_delay(249);

user_delayメソッドを実装します。Arduino側のdelayメソッドはミリ秒指定ですので、これを単純に早くするには割り算すれば良いので、お好みの早さになるように調整します。

void user_delay(int time) {
 delay(time / 1.8);
}

ですが、毎回テンポの調整の都度コンパイル&書き込みするのは面倒

テンポを可変抵抗器で変更出来るようにする

テンポを変えるには、アナログの何番かで可変抵抗器の値を受け付けて、それを割り算の分子にすれば良いので、下記のように修正します。下記の場合、kalshagarさんのツールが出力したテンポの0.7倍~7倍のテンポ変化が可能となります。

void user_delay(int time) {
 float input_delay = (float)map(analogRead(A2),0,1023,70,700)/100.0;
// delay(time / 1.8);
 delay(time / input_delay);
}

(2015/01/13追記)

スケッチを公開します。

gra2_3WithSpeedControl.zip

上記スケッチ内で読み込んでいるYMZ294.hは、wp.hrmux.comさんで公開しているYMZ294用ライブラリをArduinoIDEでライブラリ読み込んで下さい。

今のスケッチのままですと音がなっても自然に音が減衰していきませんが、エンベロープを設定すると音が低くなっていきます。YMZ294を買った時についてきたデータシートを見てみると、

ymz_env

こんな感じです。で、wp.hrmux.comさんで公開しているYMZ294用ライブラリにはSetEnvEnableと、SetEnvShapeというメソッドが用意されています。

SetEnvEnableでエンベロープを適用するチャンネルを設定し、SetEnvShapeでどの形にするかを決定します。つまり、こんな感じです。

ymz.SetMixer(CH_A, true);
ymz.SetMixer(CH_B, true);
ymz.SetMixer(CH_C, true);
ymz.SetEnvShape(1, 1, 1, 1);

これで、チャンネルA, B, CをエンベロープONにして、上記データシートの一番下の1, 1, 1, 1の波形にする感じです。

一度試したんですが他の事をやっている間に消してしまいましたが、確かコレで動いたと思います。

以上、よろしくお願い致します。

 - 耳コピArduino

  関連記事

異邦人・改 for Arduino+YMZ294

お疲れ様です。高橋です。 先日耳コピした異邦人、なんとなくYMZ294に合わない …

ファイナルファンタジー2 戦闘テーマ1

お疲れ様です。高橋です。 最近耳コピしてなかったので、耳コピしました。 3和音し …

異邦人/久保田早紀 for Arduino+YMZ294

お疲れ様です。高橋です。 毎日プログラム書くのは疲れるので、今日は耳コピの日です …

シャロム 海の音楽

お疲れ様です。高橋です。 長きに渡ったシャロムの耳コピは、この曲でそろそろ終わり …

シャロム オープニング

お疲れ様です。高橋です。   もう30年以上昔、MSX2を持っていた私 …

ArduinoでPSG音源(YAMAHA YMZ294)を鳴らしてみた。

お疲れ様です。高橋です。 先日秋葉原にて「Arduino」という物を買ってきまし …

シャロム 名前入力画面

お疲れ様です。高橋です。 前回に引き続き、シャロムを耳コピ。 今回は16小節の2 …

Castlevania SotN “Dance of Pales”を耳コピ

お疲れ様です。高橋です。 久々に耳コピ。Castlevania Symphony …

「FF5/ビッグブリッヂの死闘」をArduino+YMZ294で鳴らしてみた。

お疲れ様です。高橋です。 先日「YMZ294で鳴らすためのビッグブリッヂの死闘を …

YMZ294で鳴らすためのビッグブリッヂの死闘を作ってみた。

お疲れ様です。高橋です。 Arduino+YMZ294で鳴らすため、「ビッグブリ …