ギターコード演奏機能

孫の手MIDIバイオリンにギターのコードを演奏できるように変更した。
ロータリーエンコーダーを右回転させるとダウンストローク、左回転させるとアップストロークと解釈して、ネックの7つのCDSにC, Dm, Em, F, G, Amの6つのコードを割り当てて、残りの1つと開放にはミュートを割り当てた。

GarageBandで鳴らしたのをSoundCloudにアップロードした。

#define NOTE_ON 144
#define NOTE_OFF 128
#define CONTROL_CHANGE 176
#define ALL_NOTE_OFF 120

volatile int state = 0;
volatile boolean Flag_A = true;
volatile boolean Flag_B = false;

#define MAX_GENS (6)
#define DOWN_STROKE (1)
#define UP_STROKE   (-1)
#define NN          (-1)

static int flat0[MAX_GENS] = {52, 57, 62, 67, 71, 76};
static int offset[6][MAX_GENS] = {
  {0, 3, 2, 0, 1, 0},
  {NN, 0, 0, 2, 3, 1},
  {0, 2, 2, 0, 0, 0},
  {1, 3, 3, 2, 1, 1},
  {3, 2, 0, 0, 0, 3},
  {0, 0, 2, 2, 1, 0}
};
int current_note[MAX_GENS] = {NN, NN, NN, NN, NN, NN};

int gen_index = -1;

void setup()
{
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  attachInterrupt(0, Fall_A, FALLING);
  attachInterrupt(1, Change_B, CHANGE);
  pinMode(4, INPUT);
  pinMode(5, INPUT);
  pinMode(6, INPUT);
  pinMode(7, INPUT);
  pinMode(8, INPUT);
  pinMode(9, INPUT);
  pinMode(10, INPUT);
  Serial.begin(31250);
  //Serial.begin(115200);
  sendMidi(CONTROL_CHANGE, ALL_NOTE_OFF, 0);
}

void loop()
{
}

void Fall_A()
{
  if (!Flag_A) { return; }
  Flag_B = true;
  Flag_A = false;
}

void Change_B()
{
  if (!Flag_B) { return; }
  if (HIGH == digitalRead(2)) {
    int stroke = 0;
    if (HIGH == digitalRead(3)) {
      state--;
      stroke = UP_STROKE;
      gen_index--;
      if (gen_index < NN) {
        gen_index = NN;
      }
    } else {
      state++;
      stroke = DOWN_STROKE;
      gen_index++;
      if (gen_index > MAX_GENS) {
        gen_index = MAX_GENS;
      }
    }
    Flag_B = false;
    Flag_A = true;
    
    int code_index = NN;
    if (HIGH == digitalRead(4)) {
      code_index = 0;
    }
    if (HIGH == digitalRead(5)) {
      code_index = 1;
    }
    if (HIGH == digitalRead(6)) {
      code_index = 2;
    }
    if (HIGH == digitalRead(7)) {
      code_index = 3;
    }
    if (HIGH == digitalRead(8)) {
      code_index = 4;
    }
    if (HIGH == digitalRead(9)) {
      code_index = 5;
    }
    if (HIGH == digitalRead(10)) {
      code_index = NN;
    }
    
    if (code_index == NN) {
      for (int i = 0; i < MAX_GENS; i++) {
        if (current_note[i] != NN) {
          sendMidi(NOTE_ON, current_note[i], 0);
        }
      }
    } else {
      if ((gen_index >= 0) && (gen_index <= 5)) {
        if (current_note[gen_index] != NN) {
          sendMidi(NOTE_ON, current_note[gen_index], 0);
        }
        if (offset[code_index][gen_index] != NN) {
          int new_note = flat0[gen_index] + offset[code_index][gen_index];
          current_note[gen_index] = new_note;
          sendMidi(NOTE_ON, current_note[gen_index], 127);
        }
      } else {
      }
    }
  }
}

void sendMidi(int cmd, int pitch, int velocity)
{
  Serial.write(cmd);
  Serial.write(pitch);
  Serial.write(velocity);
}

カテゴリー: Arduino, Magitalion タグ: , , , , パーマリンク

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください