arduinoとmozziでドラムとベースとハイハットのドラムマシンの作成メモ1。

#include <MozziGuts.h> // Mozziの基本ヘッダファイル
#include <Oscil.h> // オシレータのテンプレート
#include <tables/sin2048_int8.h> // サイン波のテーブル
#include <tables/TRIANGLE_WARM8192_int8.h>
#include <tables/BROWNNOISE8192_int8.h>
#include <mozzi_rand.h>

#include <ADSR.h>                      //エンベロープ
ADSR <AUDIO_RATE, AUDIO_RATE> envH;
ADSR <AUDIO_RATE, AUDIO_RATE> envB;


// SIN2048_DATA2048のデータをaSinに格納
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin(SIN2048_DATA);
Oscil <TRIANGLE_WARM8192_NUM_CELLS, AUDIO_RATE> triWarm(TRIANGLE_WARM8192_DATA);
Oscil <BROWNNOISE8192_NUM_CELLS, AUDIO_RATE> bNoise(BROWNNOISE8192_DATA);

// トリガー(発音タイミング)のためのヘッダ
#include <EventDelay.h>
EventDelay kTriggerDelay;

// スムースに値を変化させるためのヘッダ
#include <Line.h> 
Line <long> kick; // Line <型> 変数名
Line <long> kick1; 
Line <long> kick2; 


int freq, freq1, freq2, kstep;
int f1,f2,f3,f4, f5,f6, count;
int gain, gain1, gain2;
unsigned int attackBa, decayBa, sustainBa, releaseBa;
unsigned int attackHe, decayHe, sustainHe, releaseHe;


int dstep[16]={1,0,0,1,0,0,1,0,1,0,0,1,0,0,0,1};  //配列による16ステップのシーケンサ 1でオン 0でオフ
int hstep[16]={0,0,1,0,0,0,1,0,0,0,1,1,0,0,1,1};  //hihatのシーケンス
int bstep[16]={1,1,1,1,1,1,0,1,1,1,1,1,0,1,1,1};  //bass のシーケンス  

// コントロールレートをあらかじめ定義
#define CONTROL_RATE 256

void setup(){
 startMozzi(CONTROL_RATE);
 kTriggerDelay.start(100);// トリガーのタイミング指定(100ms)
 randSeed();
}


void updateControl(){
   // f5=map(mozziAnalogRead(1),0,1024,0,200);     // 可変抵抗の値を 0から200に調整する。
       f5=80;


   attackBa=0;
   decayBa=map(mozziAnalogRead(0),0,1024,0,250);
   sustainBa=0;
   releaseBa=(unsigned int)random(100);

   attackHe=0;
   decayHe= map(mozziAnalogRead(1),0,1024,0,250);
   sustainHe=0;
   releaseHe=(unsigned int)random(50) ;
   
   

   
   
   
   if(kTriggerDelay.ready()){
     
     switch (dstep[count]){    // キック 配列dstepが0か1かで音が鳴るか鳴らないか判断する。  

     case 0:
       f1=0;
       f2=0;
       f3=0;
       f4=0;
   
       kick.set(0, 0, 0);  // 配列が0の時は音が鳴らないようにパラメータを0にする
       kick1.set(0, 0, 0); 
       kick2.set(0, 0, 0);
       break;

     case 1:
       f1=f5*4;                   //ドラムの周波数を決定する f1→f2→f3→f4と変化する。
       f2=f5*2.5;
       f3=f5*1.5;
       f4=f5;
     
       kick.set(f1, f2, 15); // Lineによる値の変化設定(初期値, 目標値, ステップ数)
       kick1.set(f2, f3, 25); 
       kick2.set(f3, f4, 60);
       break;
      }                     //キック switch 終わり

     triWarm.setFreq(((int)rand(3)+1)*80);                 //bassの周波数
     
     envB.setADLevels((byte)255, (byte)100);                    // bassのエンベロープレベル   0~255
     envB.setTimes(attackBa, decayBa,sustainBa, releaseBa);     // bassのエンベロープタイム
     envB.noteOn();

   

       
     bNoise.setFreq(4000);                                 // hihatのノイズの周波数
     
     envH.setADLevels((byte)255, (byte)100);                   // hihatのエンベロープレベル 0~255
     envH.setTimes(attackHe, decayHe,sustainHe, releaseHe);    // hihatのエンベロープタイム 
     envH.noteOn();
     
     
     
     switch (bstep[count]){    // bass 配列bstepが0か1かで音が鳴るか鳴らないか判断する。  
     case 0:                 //0のときゲイン0
       gain1=0;            
       break;
     case 1:                  //1のときゲインはエンベロープ
       gain1=1;
       break;
      }                      //bass switch終わり


      switch (hstep[count]){    // hihat 配列hstepが0か1かで音が鳴るか鳴らないか判断する。  
     case 0:                 //0のときゲイン0
       gain2=0;            
       break;
     case 1:                  //1のときゲインはエンベロープ
       gain2=1;
       break;
      }                      //hihat switch終わり

      


   
      count +=1;                 //  カウントを増やす 16になったらゼロにする 
      if(count==16){
         count=0; }       
       kTriggerDelay.start(100);
       
  }    //  kTrigger if文終わり

     
   freq = kick.next(); // 変数freqにスムースな値の変化の結果を代入

   if(freq>f2&& freq<=f1){             // f1→f2の時はkick
     freq=kick.next();
     }else  if(freq>f3&& freq<=f2){     // f2→f3の時はkick1
     freq=kick1.next();
     }else  if(freq>f4&& freq<=f3){      // f3→f4の時はkick2 になるように
     freq=kick2.next();
     }

   if(freq > f4 && freq <= f1){
     aSin.setFreq(freq); // f4より大きい限り音を出力
     } else{
     kick.set(0, 0, 0); // スムースな値の変化設定の初期化
     aSin.setFreq(0); // 周波数を0に設定
     }

     
  
}        //void updateControl()終わり 

int updateAudio(){
 envB.update();
 envH.update();
 return (int)(( aSin.next()+ ( (gain1*(envB.next()*triWarm.next() )>>8))+( (gain2*(envH.next()*bNoise.next() )>>11)) ));        // サイン波とノイズを足す ノイズはgainで256倍されているので8ビットシフト(=1/2^8倍)で音量を小さくする
}


void loop(){
 audioHook();
} 

lineを複数使ってキックの音を作っています。

ADSRでエンベロープを作っています。

あとはシーケンサーを作ります。



よろしければサポートお願いします!