2年前の記事に質問頂いたので、回答も兼ねて久しぶりにArduinoのスケッチを書きました。
前にYMZ294のエンベロープをいじった時は、MMLの解釈部分や外部入力からエンベロープを操作する部分など、やや複雑になっていたので、今回は出来る限りシンプルにしてみました。
こんなよーな音が出ます。
回路もシンプルにArduino UNOとYMZ294と水晶発振器を接続して、YMZ294の5pin(Sound Out)からスピーカーに出力してるだけのものです。
YMZ294は秋月電子で500円
スケッチはこちら。YMZ294ライブラリが必要になるので、ダウンロードして使用可能な状態にしておいてください。
#include <YMZ294.h> // YMZ294 defines const byte WRCS_PIN = 8; const byte A0_PIN = 9; const byte RESET_PIN = 10; YMZ294 ymz(WRCS_PIN, A0_PIN, RESET_PIN); void setup() { DDRD = 0b11111111; pinMode(WRCS_PIN, OUTPUT); pinMode(A0_PIN, OUTPUT); pinMode(RESET_PIN, OUTPUT); ymz.Reset(); ymz.SetMixer(0b111,0b000); ymz.SetEnvEnable(CH_A, 1); ymz.SetEnvEnable(CH_B, 1); ymz.SetEnvEnable(CH_C, 1); ymz.SetFrequency(CH_A, CalcFreqByMML(5, 'C')); ymz.SetFrequency(CH_B, CalcFreqByMML(5, 'E')); ymz.SetFrequency(CH_C, CalcFreqByMML(5, 'G')); } void loop() { static int freq = 0; ymz.SetEnvFrequency(freq); ymz.SetEnvShape(1,0,0,1); delay(250); freq += 10; if (freq > 240) freq = 0; }
setup()関数内では、
YMZ294を初期化(ymz.Reset)
矩形波3chのエンベロープを有効化(ymz.SetEnvEnable)
オクターブ5の音程C,D,E(ドミソ)を設定(ymz.SetFrequency)
しています。
loop()関数内では、
エンベロープに設定するための変数freqを用意して、YMZ294のエンベロープ周波数レジスタに設定(ymz.SetEnvFrequency)
エンベロープの形状1001(最大音量で鳴り始め、徐々に小さくなる音)を設定(ymz.SetEnvShape)
を、エンベロープ周波数を変えながら繰り返し24回鳴らしています。
エンベロープ使用時に注意する点は、
- 毎回SetEnvFrequencyとSetEnvShapeを両方呼ばないと音が鳴らない
- エンベロープ使用時は、チャンネル毎のボリューム(ymz.SetVolume)は無視される
- チャンネル毎に別のエンベロープを使用することはできない(3chとも共通の形状・周波数になる)
こんなところでしょうか。
エンベロープとノイズは扱いが難しいですが、使いこなせれば、単なる矩形波だけでは表現できない面白い音を鳴らす事ができると思います。
SetEnvFrequencyとSetEnvShapeの引数を変えて、色んな音を試してみてください。