MozziWS 2_4

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

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

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

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

(サンプルのEnvelope/”Ead_Envelope.ino”(Tim Barrass 2012.)を参考にしています。)

 1#include <MozziGuts.h>
 2#include <Oscil.h> //オシレーターのテンプレート
 3#include <tables/sin2048_int8.h> // サイン波のテーブル
 4#include <Ead.h> // アタック, ディケイのための指数関数
 5#include <EventDelay.h> //Arduinoのdelayの代わり
 6#include <mozzi_midi.h> //MIDI変換用
 7#include <mozzi_rand.h> //ランダム用
 8 
 9#define CONTROL_RATE 256 //コントロールレートの設定
10 
11Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA);
12EventDelay kDelay; // 遅延処理によるエンベロープトリガー
13Ead kEnvelope(CONTROL_RATE);  //エンベロープ用インスタンス
14 
15int gain;
16int pin = 0;
17 
18void setup(){
19  randSeed(); // ランダムジェネレータの初期化 (スケッチのループ毎に異なる値を出す)
20  startMozzi(CONTROL_RATE); // Mozziの初期化と処理開始
21  kDelay.start(1000);
22  aSin.setFreq(440); // 周波数を指定
23 
24}
25 
26void updateControl(){
27 
28  if(kDelay.ready()){
29    unsigned int duration = rand(200u) + 200; //duration(音の長さ)をランダムに設定
30    unsigned int attack = rand(75); //アタックをランダムに設定
31    unsigned int decay = duration - attack; //ディケイを設定
32    kEnvelope.start(attack,decay); //エンベロープスタート
33    kDelay.start(duration+500); //トリガー
34  }
35  gain = (int) kEnvelope.next(); //出力用変数に結果を格納
36}
37 
38int updateAudio(){
39  return (gain*aSin.next())>>8; // オーディオの繰り返し出力処理 (シフト演算によるゲイン調整)
40 
41}
42 
43void loop(){
44  audioHook(); // 再生のために必要
45 

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

NEXT 次へ

MAIN PAGE メインページへ