Arduinoで雷電風リズムマシン

こないだの続きです。

今回の動画では、音声をライン入力で別録音→aviutlで映像と結合してx264出力にしたのと、aviutlの拡張編集を使って解説用の文字などを入れるという2点を変えてみました。どうでしょうかね。
今までは音声をヘチョいスピーカーから出して、それをiPhoneの内蔵マイクで録音、というハイテクなんだかローテクなんだかよくわからない録音の仕方をしていましたが、こういうものを作ってライン入力にしました。
ブレッドボード→シールド変換ケーブル
どなたさまのご家庭にでも必ずある……かどうかは分からないものの、安ギター収集のケがある人の家にはゴロゴロ転がっているギター用のシールドです。
こいつのプラグを片方ちょん切って、皮膜をむいて、ブレッドボード用の端子にハンダ付けしました。まさかこんなところで安ギター用品(と、ファミコンをテレビにつなげるためのスキル)が役に立つとは。
今までスピーカーをつなげていた代わりにこのケーブルをつなげて、そこからPCのLine Inに接続して録音しました。

回路はこんなです。
雷電風リズムマシン ブレッドボード雷電風リズムマシン 回路図
デジタル入力とアナログ入力を別のブレッドボードに作りました。そろそろプロトタイプシールドとか買った方がいい気がしてきた。配線めんどい。

雷電風リズムマシン ディップスイッチ
左側のブレッドボード。なんだかややこしそうですが、やってることはシンプルです。
ここで新しく使ってるのはDIPスイッチというものです。

秋月で50円。動画見ると分かりますがスイッチが結構固いですこれ。
5V→スイッチ→デジタル入力のピン→10kΩ抵抗→GND という感じの接続を8個分。このスイッチひとつが8ビートのビート1つ分になります。

雷電風リズムマシン アナログ入力
右側のブレッドボード。半固定抵抗がひとつ増えています。フセン貼ったのは、自分でどの入力が何だったか分からなくなるので。3つ以上は「たくさん」です。
前回、音の長さを1/4とプログラム内で固定で計算してましたが、これを変えられるようにするためです。
どうでもいいんだけど、半固定抵抗ってカラーリングがコイツにすげえ似てる。

プログラム自体はそんなに変わってません。

// Analog pin setting
const int AIN_TEMPO = 0;
const int AIN_INTERVAL = 1;
const int AIN_LENGTH = 2;

// Digital pin setting
const int BEAT_COUNT = 8;
const int RHYTHM_1 = 2;
const int RHYTHM_2 = 3;
const int RHYTHM_3 = 4;
const int RHYTHM_4 = 5;
const int RHYTHM_5 = 6;
const int RHYTHM_6 = 7;
const int RHYTHM_7 = 8;
const int RHYTHM_8 = 9;
const int RHYTHM[BEAT_COUNT] = 
  {RHYTHM_1, RHYTHM_2, RHYTHM_3, RHYTHM_4, 
   RHYTHM_5, RHYTHM_6, RHYTHM_7, RHYTHM_8};

// Output pin setting
const int SOUND_OUT = 10;
const int LED_OUT = 13;

// note
int note_length = 200;
int click_length = note_length / 4;
int note_hz = 440;

void setup() {
  for (int i = 0; i < BEAT_COUNT; i++){
    pinMode(RHYTHM[i], INPUT);
  }

  // initialize the digital pin as an output.
  pinMode(SOUND_OUT, OUTPUT);
  pinMode(LED_OUT, OUTPUT);
}

// the loop routine runs over and over again forever:
void loop() {
  set_note();
  for (int i = 0; i < BEAT_COUNT; i++){
    set_tempo();
    if (digitalRead(RHYTHM[i]) == HIGH){
      if (i == 0){
        snd(note_hz * 2, click_length);
      }else if (i == 4){
        snd(note_hz * 1.4, click_length);
      }else{
        snd(note_hz, click_length);
      }
      delay(note_length - click_length);
    }else{
      delay(note_length);
    }
  }
}

void snd(int hz, int dur)
{
  digitalWrite(LED_OUT, HIGH);
  tone(SOUND_OUT, hz, dur);
  delay(dur);
  digitalWrite(LED_OUT, LOW);
}

void set_note()
{
  note_hz = (((analogRead(AIN_INTERVAL)) + 10) * 3);
}

void set_tempo()
{
  note_length = (analogRead(AIN_TEMPO) + 4);
  click_length = note_length / ((analogRead(AIN_LENGTH) >> 5) + 1);
}

変わったところは、

  • スイッチの数(8個)分のデジタル入力ピンの定義と初期化
  • loop()内で、毎回必ず音を鳴らしていたのを、スイッチがONの拍だけ鳴らすように分岐を入れた
  • set_tempo()内で、click_lengthが1/4固定だったものを、アナログ入力ピン3によって変えられるように変更

この3ヶ所。3つ目はちょっと説明を入れます。
Arduinoのアナログ入力は0~1023の1024通りの数値が入ってくるわけですが、それではちょっと細かすぎるので、>> 5という風に数を丸めています。
これはビットシフト演算子と呼ばれるもので、要するにここで書かれた回数だけ2でかけたり割ったりしてます。
ここでは>> 5だから、1024÷2÷2÷2÷2÷2で、0~1023を、0~31までという感じに荒くしてるってことです。
で、0だと困る(音を一旦鳴らしに行くと、そのまま帰ってこない)ので+1。やっつけです。
音程の方もうまく丸めればちゃんとしたドレミの音程が鳴るんですが、そこはまあキーボードとかでは鳴らないような妙な周波数の音が鳴った方が楽しいので、そのまんまです。

この回路とプログラムでめでたく雷電(らいでぃーん)のイントロっぽい音を奏でるリズムマシン(もどき)の完成でございます。

このままシンセっぽい音を作って、1チップYMOとかそういうのをやりたいところなのですが、Arduinoのtone()関数は一度にひとつの音しか鳴らせないという、如何ともし難い制限があるので、このチッチキチッチキをもってYMOっぽい音を鳴らすのはおしまいです。無念。
次は何作りましょうかね。

おまけ
最後のピッコロっぽいパートだけ鳴らしてみたりなんかして。

コメントを残す