前回は矩形波のチャンネルを鳴らしましたので、今回はノイズをリズムマシン風に鳴らします。
音声プレーヤー
こんな感じ。
また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を突っ込んで黙らせる必要があります
……このまめちしきが役に立つ人って相当レアというか、多分いないと思いますが。