Arduino+YMZ294で12beatのリズムを刻む

前回は矩形波のチャンネルを鳴らしましたので、今回はノイズをリズムマシン風に鳴らします。

こんな感じ。

またYMOっぽくするのもアレなので、三連符というか6拍子、いやbeatmania的に表記して12BEATってことにします。グラディウスIIも沙羅曼蛇も、なんであんなに12BEAT曲多いんですかね。好きだけど。
例によってアナログ入力からテンポ変更可能で、後半は暴走気味。

スケッチはこんなです。

#include <YMZ294.h>

// Output Pins
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.SetVolume(CH_A, 0b00001111);
  ymz.SetFreqBit(CH_A, 0);
  ymz.SetVolume(CH_B, 0b00001111);
  ymz.SetFreqBit(CH_B, 0);
  ymz.SetVolume(CH_C, 0b00001111);
  ymz.SetFreqBit(CH_C, 0);
}

byte beats[6][2] = {
  {0b00001, 8},
  {0b00010, 12},
  {0b00001, 8},
  {0b01000, 64},
  {0b00001, 8},
  {0b00010, 16},
};
 
void loop() {
  static word noteGate = 192;
  static unsigned long lastMSec = 0;
  static byte state = 0;
  static byte step = 0;

  unsigned long diffMSec = millis() - lastMSec;

  noteGate = (analogRead(0) >> 2);
  
  switch (state){
    case 0: // Note Off to On
      ymz.SetNoiseFreqBit(beats[step][0]);
      TurnNoise(true);
      state = 1;
      break;
    case 1: // Step Time Over
      if (diffMSec > beats[step][1]){
        TurnNoise(false);
        state = 2;
      }
      break;
    case 2: // Gate Time Over (Note Off)
      if (diffMSec > noteGate){
        state = 0; // Initialize
        lastMSec = millis();
        if (++step >= (sizeof(beats) / 2))
          step = 0;
      }
      break;
  }
}

void TurnNoise(bool isNoise){
  if (isNoise)
    ymz.SetMixer(0b000, 0b000);
  else
    ymz.SetMixer(0b111, 0b000);
}


プロトシールドもどきに乗せ換えましたが、回路自体は前回と同じなので省略。
delay()関数を使わずに、自前でStepTime/GateTimeを実装したら、ものすごく面倒くさいコードになりました。

YMZ294(のNoise Channel)まめちしき

  • 矩形波3chともオフにすると鳴りません
  • 矩形波Volumeを0にしてると鳴りません
  • 5bitの周波数入力に0を突っ込んでもNoiseは出ます
  • ので、音を止めるにはMixerのNoise 3bitに1を突っ込んで黙らせる必要があります

……このまめちしきが役に立つ人って相当レアというか、多分いないと思いますが。


コメントを残す