8. 音量エンベロープをかけてみる

次に音量エンベロープ(時間的な音量変化)についてです。
Mozziには“Ead”というエンベロープ用のクラスが用意されています。(他に”ADSR”エンベロープも用意されています)
46行目の”kEnvelope.start(attack,decay)”でアタックとディケイの設定を行っています。
これにより音の立ち上がりと減衰を表現できます。

また、オシレーターに対する音量エンベロープのトリガーを、“EventDelay”で実装しています。
Arduinoには”delay()”という命令が用意されており、プログラムの定期動作を制御できますが、この”delay()”処理はMozziのオーディオ処理とぶつかってしまうので使えません。
コンパイルはできますが、うまく動作しなくなってしまいます。(同様の理由でmillis(), micros(), delayMicroseconds()も使えません)
このため、Mozzi用のスケジューリング(遅延)処理である”EventDelay”が用意されています。

本スケッチは”EventDelay”とランダムジェネレータである”mozzi_rand”を用いて、
ランダムなタイミングで音を出力し、音量エンベロープにより減衰処理を行っています。
今回はサイン波のテーブルを用いています。
(サンプルのEnvelope/”Ead_Envelope.ino”(Tim Barrass 2012.)を参考にしています。)

#include <MozziGuts.h>
#include <Oscil.h> //オシレーターのテンプレート
#include <tables/sin2048_int8.h> // サイン波のテーブル
#include <Ead.h> // アタック, ディケイのための指数関数
#include <EventDelay.h> //Arduinoのdelayの代わり
#include <mozzi_midi.h> //MIDI変換用
#include <mozzi_rand.h> //ランダム用

#define CONTROL_RATE 256 //コントロールレートの設定

Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA);
EventDelay kDelay; // 遅延処理によるエンベロープトリガー
Ead kEnvelope(CONTROL_RATE);  //エンベロープ用インスタンス

int gain;
int pin = 0;

void setup(){
  randSeed(); // ランダムジェネレータの初期化 (スケッチのループ毎に異なる値を出す)
  startMozzi(CONTROL_RATE); // Mozziの初期化と処理開始
  kDelay.start(1000);
  aSin.setFreq(440); // 周波数を指定

}

void updateControl(){

  if(kDelay.ready()){
    unsigned int duration = rand(200u) + 200; //duration(音の長さ)をランダムに設定
    unsigned int attack = rand(75); //アタックをランダムに設定
    unsigned int decay = duration - attack; //ディケイを設定
    kEnvelope.start(attack,decay); //エンベロープスタート
    kDelay.start(duration+500); //トリガー
  }
  gain = (int) kEnvelope.next(); //出力用変数に結果を格納
}

int updateAudio(){
  return (gain*aSin.next())>>8; // オーディオの繰り返し出力処理 (シフト演算によるゲイン調整)

}

void loop(){
  audioHook(); // 再生のために必要

 
回路は以下を参考にしてください。
DAY2