• Column

【HAGIWO MOD1】 スネア×ハイハットシーケンサー(P4M2025 ver)/プログラムコード[モジュラーシンセ] 

HAGIWO MOD1用にプログラミングしたスネア&ハイハット・シーケンサーです。

サンプラーのスネア・クローズハイハット&オープンハイハットの組み合わせに適したセッティングです。

何度か類似のプログラミングを投稿していますが、こちらがひとまずの完成版になります。

2025年7月20日に渋谷CIRCUS TOKYOで開催された「Patching for Modular」のライブで使ったシーケンサーです。

1つ目のシーケンサー、2つ目のシーケンサーとも、ライブ演奏で使いやすいスネア・ハットパターンをプログラミングしております。

1つ目のシーケンサーはスネアに特化しており、POT1でリズムパターンを設定します。ノブを回すごとにトリガー回数が増え、最大値で16ステップ全てのトリガーが鳴ります。ステップはシフトレジストしており、1周目は5ステップ目から有効になります。主にスネア音源との相性が良いシーケンサーです。

2つ目のシーケンサーも16ステップで固定されており、POT2でトリガー回数を設定します。また、POT3はランダムコイントスで、POT2で設定したパターンを、さらに確率的に2つの出力に振り分けます。こちらは1ステップ目から有効です。主にクローズハイハット、オープンハイハット音源の組み合わせと相性が良いシーケンサーです。

プログラミング内の  {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},の箇所が16ステップシーケンスの書き込み部分にあたります。「0」がトリガーなしで「1」がトリガー発生です。数字を書き換えることで、お好みのリズムパターンに変更できます。

※機能を一部修正しました。リセットインが加わり、不規則なパフォーマンスにも対応するようになりました。

注意事項1:chatGPTで作成したプロンプトです。プログラミング知識は一切ないため、動作の安定性は保証はできません。趣味用途でお使いください

[機能紹介]

※入力したクロックをもとに、リズムパターンを生成するモジュールです。

※トリガー長は5msで設定しています。トリガー長は delayMicroseconds(5000); の箇所で変更可能です。(5ms=5000)

POT1:出力1のリズムパターンを設定します。

POT2:出力2のリズムパターンを設定します。

POT3:リズムパターンのループ回数を設定します。デフォルトは16ステップですが、ツマミを回していくと、14ループ→12ループとループ数が短くなります。デフォルト位置に届くと、クロックに同期した16ステップのリズムパターンに戻ります。

F1:トリガーIN

F2:リセットIN

F3:出力1のトリガー出力

F4:出力1のトリガー出力

P4:???

LEDF1に連動する

[プログラム](ArduinoでMOD1にプログラミングしてください)

▼次の行からコピーペースト▼

// ===== Robust 2-output trigger sequencer =====

const int numSteps = 16;

// pins

const int trigInPin = 17;

const int resetPin = 9;

const int out1Pin = 10;

const int out2Pin = 11;

const int ledPin = 3;

const int pot1Pin = A0;

const int pot2Pin = A1;

const int loopPotPin= A2;

const unsigned long trigLen = 5000UL;

// — fixed patterns —

const bool fixedPatterns1[16][numSteps] = {

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0},

{0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0},

{0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0},

{0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0},

{0,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0},

{0,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0},

{0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0},

{0,0,0,1,0,0,1,0,1,0,1,1,0,0,1,0},

{1,0,0,1,0,0,1,0,1,0,0,0,0,1,0,0},

{0,1,1,0,1,0,1,1,0,1,0,1,1,0,1,1},

{0,1,0,1,0,1,1,0,1,0,1,1,0,1,1,1},

{1,0,1,1,0,1,1,1,0,1,1,1,0,1,1,1},

{1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1},

{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}

};

const bool fixedPatterns2[16][numSteps] = {

{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},

{0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0},

{0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0},

{0,1,0,0,1,0,0,0,0,0,0,1,0,0,0,0},

{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},

{0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0},

{0,1,0,0,0,1,0,0,0,1,0,0,1,1,0,0},

{0,1,0,0,0,1,0,0,1,1,0,1,1,0,0,0},

{0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,0},

{0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,1},

{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},

{0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1},

{0,1,0,1,1,1,1,0,0,1,0,1,0,0,1,0},

{1,1,1,1,1,0,1,1,0,1,1,0,1,1,1,1},

{1,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1},

{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}

};

// — state —

int step = 0;

bool lastTrig = LOW;

bool lastReset = LOW;

unsigned long t1 = 0, t2 = 0;

// — helpers —

int readPatternIndex(int pin) {

int v = analogRead(pin);

if (v >= 1018) return 15;

return v / 64;

}

int getLoopLength() {

static const int table[9] = {16,8,7,6,5,4,3,2,1};

int pos = map(analogRead(loopPotPin),0,1023,0,8);

return table[pos];

}

// — setup —

void setup() {

pinMode(trigInPin, INPUT);

pinMode(resetPin, INPUT);

pinMode(out1Pin, OUTPUT);

pinMode(out2Pin, OUTPUT);

pinMode(ledPin, OUTPUT);

}

// — loop —

void loop() {

bool trig = digitalRead(trigInPin);

bool reset = digitalRead(resetPin);

if (reset && !lastReset) step = 0;

if (trig && !lastTrig) {

int loopLen = getLoopLength();

int s = step % loopLen;

int p1 = readPatternIndex(pot1Pin);

int p2 = readPatternIndex(pot2Pin);

if (fixedPatterns1[p1][s]) {

digitalWrite(out1Pin, HIGH);

digitalWrite(ledPin, HIGH);

t1 = micros();

}

if (fixedPatterns2[p2][s]) {

digitalWrite(out2Pin, HIGH);

t2 = micros();

}

step = (step + 1) % numSteps;

}

unsigned long now = micros();

if (digitalRead(out1Pin) && now – t1 >= trigLen) {

digitalWrite(out1Pin, LOW);

digitalWrite(ledPin, LOW);

}

if (digitalRead(out2Pin) && now – t2 >= trigLen) {

digitalWrite(out2Pin, LOW);

}

lastTrig = trig;

lastReset = reset;

}