見出し画像

Arduinoによるシンセ開発!シーケンサー実装とEventDelayの処理について

以前p5.jsで制作していたシンセと同じロジックでシーケンサーを実装します。
基本的には構造としては
・ステップの配列を宣言しておく
・キーが押されたらそのステップに音階を代入する
・スタートボタンが押されたらシーケンサーを再生する
・再生が始まったらMozziのEventDelayで一定時間ごとに配列内の音階を発音する
至極シンプルです。

delay()は使えません

Mozziライブラリを使用するときにはdelay関数を使用することはできません。
正確に言うとdelay関数を使うと波形が格納されたウェーブテーブルの再生サイクルに影響が出るようで、なんかものすごく変な音が出ます。
以前Mozziのライブラリを見てみた時の記事でも書いたのですが、おそらくウェーブテーブルで定義している波形の動きを高速で再生しているのだと思いますが、delay関数を使うとこの波形発音が阻害されるのではないかと思います。

EventDelayを使います。

コードです

#define MOZZI_CONTROL_RATE 64
#include <Mozzi.h>
#include <Oscil.h> 
#include <EventDelay.h>
#include <tables/sin2048_int8.h>

Oscil <SIN2048_NUM_CELLS, MOZZI_AUDIO_RATE> aSin(SIN2048_DATA);
EventDelay toggle;
bool noteOn = true; // 音のオンオフフラグ

void setup(){
  startMozzi();
  aSin.setFreq(440);
  toggle.start(100); // 待ち時間
}

void updateControl(){
  if (toggle.ready()){
    noteOn = !noteOn;  // 音のオンオフ
    toggle.start(100);  // 待ち時間を作る
  }

  if (noteOn){
    aSin.setFreq(440);  // 発音
  } else {
    aSin.setFreq(0);    // 停止
  }
}

AudioOutput updateAudio(){
  return MonoOutput::from8Bit(aSin.next());
}

void loop(){
  audioHook();
}

・EventDelayをinclide
・Event Delayのインスタンスtoggleを生成
・toggle.start();で待ち時間を設定
・待ち時間ごとに発音フラグのnoteOnがtureとfalseを繰り返す
こんな流れになっています。

動きはこんな感じ

ブザーを使うtone()関数とは違って処理が多いですが、慣れていくしかない様です。
MozziにおけるLチカみたいなもんでしょうか。

シーケンサーにする

動画の再掲です。

シーケンサーの実装はこのEventDelayと配列に格納した音階を再生するコマンドで組み合わせできます。Mozziでdelay()が使えないと言うことに気がつくまでだいぶ時間を要しましたが、わかってしまえばここまでできる様になりました。
嬉しいですね。

またがんばります!!

いいなと思ったら応援しよう!