Hobby Science&Experiment

愛と工作の日々

趣味でやっている工作や勉強したことのメモ書きです。

Arduino MIDIドラムシーケンサ(Drum Sequencer)

前回の記事でArduino MIDI libraryを使ってDAWのドラムを鳴らしました。今度はそこにプログラミングを加えて、一定のドラムパターンで演奏させてみたいと思います。多分これがドラムシーケンサーってやつなんじゃないでしょうか。
jakejake.hatenablog.com

下準備

前回の記事(上記リンク先)参照。DAWにはWaveform Freeを使用しました。

コード

{0,0,1,0}とかの部分は、4/4拍子で3拍目のみヒットがあることを示してます。16分音符にする場合は{0,0,・・・}を16個のアレーにすればよいわけです。
f:id:tara-chang:20210509182550p:plain
int DRUM[]の中身の楽器名を変えることで、ハイハットやライドなどを加えることもできます。BPMを指定すると一拍当たりの秒数(interval)に換算し、sleep(interval)に代入されます。あと、かっこいいのでコメント行を付けてみました(*ノωノ)

// Arduino MIDI Drum sequencer 
// Sending MIDI messages to the host PC.
// DAW: Waveform Free
//
// Author: Tara-chang
// 
// Revision History:
// Date        |    Author    |  Change
// ---------------------------------------------------
// 2021-05-09  |  Tara-chang  |  Initial Release

#include <MIDI.h> 
MIDI_CREATE_DEFAULT_INSTANCE();

#define CRUSH 49 //C#3
#define KICK 36 //C2
#define CLAP 39 //D#2
#define SNARE 38 //D2
#define RIDE 52 //D#3
#define HITOM 50 //D3
#define MIDTOM 48 //C3
#define LOWTOM 45 //A2
#define OPHIHAT 46 //A#2
#define CLHIHAT 42//F#2

int DRUM[] = {SNARE, KICK, CLAP, CRUSH};
const byte NUM_DRUM = sizeof(DRUM)/sizeof(DRUM[0]);
const byte NUM_BEAT = 4;
boolean RTM[NUM_DRUM][NUM_BEAT] = {
  {0,0,1,0},//SNARE
  {1,0,1,0},//KICK
  {1,1,1,1},//CLAP
  {1,0,0,0}//CRUSH
  };
//in order of SNARE, KICK, CLAP, CRUSH
byte nt = 0;
byte in = 0;
int BPM = 200; //X beats/60sec = 60/X sec/beat
int interval = 60/double(BPM)*(NUM_BEAT/4)*1000; // 

void setup()
{   
  Serial.begin(115200);
  MIDI.begin(4); 
}

void loop(){
  for (nt = 0; nt < 4; nt++){
    for (in = 0; in < 4; in++){    
      //String text = "(in,nt)=("+String(in)+","+String(nt)+")"+String(RTM[in][nt]);     
      if (RTM[in][nt]){
      MIDI.sendNoteOn(DRUM[in],127,1);  // ノートオン(pitch, velocity, channel)         
      MIDI.sendNoteOff(DRUM[in],0,1);   // ノートオフ       
      }
    }
    delay(interval);
    }
}

動作確認

ばっちりでした。今回は自分で全部書いたのですが、思ったように動くと嬉しいもんですね。
変数型の定義などC言語の勉強にもなりました。