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でエンベロープを作っています。
あとはシーケンサーを作ります。
いいなと思ったら応援しよう!
よろしければサポートお願いします!