LoginSignup
9
5

More than 5 years have passed since last update.

arduino+mozziでドラムシンセサイザー(?)を作ってみた

Last updated at Posted at 2017-05-24

おことわり

シンセサイザーの事はほとんどわかりません。
これ↓は、おもしろい読み物として読んでいますが、、
http://makezine.jp/blog/2017/03/make-analog-synthesizers.html

なのでVCOとかLFOとかなんとなく使っています

パーツリスト

■AMAZONで購入
arduino UNO R3(の互換品)
3.5mmステレオジャック
LED
抵抗

■共立エレショップ(通販)
ボリューム(10KΩ Bカーブ)(http://eleshop.jp/shop/g/gE52362/)
・・大須で見つけられませんでした。。

■aitendo(通販)
つまみ(http://www.aitendo.com/product/12732)
・・これも大須ではみつけられず、、、

■秋月電子で購入(通販)
秋月バニラシールド(http://akizukidenshi.com/catalog/g/gP-09624/)
小型アンプ(http://akizukidenshi.com/catalog/g/gK-08217/)
小型スピーカー(http://akizukidenshi.com/catalog/g/gP-09271/)
つまみ付可変抵抗(10KΩ Bカーブ)(http://akizukidenshi.com/catalog/g/gP-08012/)

スケッチ

冗長な感じでうまくない。。

drumuino.ino

#include <MozziGuts.h>
#include <Oscil.h> // oscillator template
#include <tables/sin2048_int8.h> // sine table for oscillator
#include <tables/saw2048_int8.h>//saw table for oscillator
#include <tables/square_analogue512_int8.h> // square table for oscillator
#include <tables/triangle2048_int8.h>//triangle table for oscillator
#include <tables/noise_static_1_16384_int8.h>//noise table for oscillator


#include <Ead.h>
#include <EventDelay.h>



// use: Oscil <table_size, update_rate> oscilName (wavetable), look in .h file of table #included above
Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin1(SIN2048_DATA);
Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aSaw1(SAW2048_DATA);
Oscil <SQUARE_ANALOGUE512_NUM_CELLS, AUDIO_RATE> aSqu1(SQUARE_ANALOGUE512_DATA);
Oscil <TRIANGLE2048_NUM_CELLS, AUDIO_RATE> aTri1(TRIANGLE2048_DATA);
Oscil <NOISE_STATIC_1_16384_NUM_CELLS, AUDIO_RATE> aNoise1(NOISE_STATIC_1_16384_DATA);

Oscil <SIN2048_NUM_CELLS, AUDIO_RATE> aSin2(SIN2048_DATA);
Oscil <SAW2048_NUM_CELLS, AUDIO_RATE> aSaw2(SAW2048_DATA);
Oscil <SQUARE_ANALOGUE512_NUM_CELLS, AUDIO_RATE> aSqu2(SQUARE_ANALOGUE512_DATA);
Oscil <TRIANGLE2048_NUM_CELLS, AUDIO_RATE> aTri2(TRIANGLE2048_DATA);
Oscil <NOISE_STATIC_1_16384_NUM_CELLS, AUDIO_RATE> aNoise2(NOISE_STATIC_1_16384_DATA);


// use #define for CONTROL_RATE, not a constant
#define CONTROL_RATE 256 // powers of 2 please
EventDelay kDelay;
Ead kEnvelope(CONTROL_RATE);

int gain;
int t1;
int t2;
const int type1LED1=2;
const int type1LED2=3;
const int type1LED3=4;
const int type1LED4=5;
const int type1LED5=6;

const int type2LED1=7;
const int type2LED2=8;
const int type2LED3=10;
const int type2LED4=11;
const int type2LED5=12;


const int beat=13;

void setup(){
  kDelay.start(1000);
  Serial.begin(115200);
  Serial.println("start");

  pinMode(type1LED1,OUTPUT);
  pinMode(type1LED2,OUTPUT);
  pinMode(type1LED3,OUTPUT);
  pinMode(type1LED4,OUTPUT);
  pinMode(type1LED5,OUTPUT);
  pinMode(type2LED1,OUTPUT);
  pinMode(type2LED2,OUTPUT);
  pinMode(type2LED3,OUTPUT);
  pinMode(type2LED4,OUTPUT);
  pinMode(type2LED5,OUTPUT);

  pinMode(beat,OUTPUT);
  kDelay.start(2000);
  startMozzi(CONTROL_RATE); // set a control rate of 64 (powers of 2 please)
}


void updateControl(){
  int type1=mozziAnalogRead(0);
  int freq1=mozziAnalogRead(1);
  int type2=mozziAnalogRead(2);
  int freq2=mozziAnalogRead(3);
  int bpm=mozziAnalogRead(5);
  int attack=mozziAnalogRead(4);
  t1=map(type1,0,1023,0,5);
  t2=map(type2,0,1023,0,5);
  int f1=map(freq1,0,1023,5,25);
  int f2=map(freq2,0,1023,50,300);  
  int b=map(bpm,0,1023,70,180);
  int dt=60000/b;
  int a=map(attack,0,1023,1,dt);
  int d=dt-a;
  int test;
  ledoff();
  switch (t1){
    case 0:
      aSin1.setFreq(f1);
      digitalWrite(type1LED1,HIGH);
      break;
    case 1:
      aSaw1.setFreq(f1);
      digitalWrite(type1LED2,HIGH);
      break;
    case 2:
      aSqu1.setFreq(f1);
      digitalWrite(type1LED3,HIGH);
      break;
    case 3:
      aTri1.setFreq(f1);
      digitalWrite(type1LED4,HIGH);
      break;
    case 4:
      aNoise1.setFreq(f1);
      digitalWrite(type1LED5,HIGH);
      break;
    default:
        randomMode1(f1);
      break;
  }        
  switch (t2){
    case 0:
      aSin2.setFreq(f2);
      digitalWrite(type2LED1,HIGH);
      break;
    case 1:
      aSaw2.setFreq(f2);
      digitalWrite(type2LED2,HIGH);
      break;
    case 2:
      aSqu2.setFreq(f2);
      digitalWrite(type2LED3,HIGH);
      break;
    case 3:
      aTri2.setFreq(f2);
      digitalWrite(type2LED4,HIGH);
      break;
    case 4:
      aNoise2.setFreq(f2);
      digitalWrite(type2LED5,HIGH);
      break;
    default:
        randomMode2(f2);
      break;
  }        

  digitalWrite(beat,HIGH);
  if(kDelay.ready()){
    kEnvelope.start(a,d);
    kDelay.start(dt+5);
  }
  digitalWrite(beat,LOW);
    gain= (int) kEnvelope.next();
}
int updateAudio(){
  int aSig1;
  switch (t1){
    case 0:
      aSig1=aSin1.next();
      break;
    case 1:
      aSig1=aSaw1.next();
      break;
    case 2:
      aSig1=aSqu1.next();
      break;
    case 3:
      aSig1=aTri1.next();
      break;
    case 4:
      aSig1=aNoise1.next();
      break;
    default:
      aSig1=aSin1.next();
      break;    
  }
  int aSig2;
  switch (t2){
    case 0:
      aSig2=aSin2.next();
      break;
    case 1:
      aSig2=aSaw2.next();
      break;
    case 2:
      aSig2=aSqu2.next();
      break;
    case 3:
      aSig2=aTri2.next();
      break;
    case 4:
      aSig2=aNoise2.next();
      break;
    default:
      aSig2=aSin2.next();
      break;    
  } 
  int aSig;
  aSig=(aSig1*aSig2)/4;
  aSig=(gain*aSig)>>8;  
  return aSig; 
}

void loop(){
  audioHook(); // required here
}

void ledoff(){
  digitalWrite(type1LED1,LOW);
  digitalWrite(type1LED2,LOW);
  digitalWrite(type1LED3,LOW);
  digitalWrite(type1LED4,LOW);
  digitalWrite(type1LED5,LOW);
  digitalWrite(type2LED1,LOW);
  digitalWrite(type2LED2,LOW);
  digitalWrite(type2LED3,LOW);
  digitalWrite(type2LED4,LOW);
  digitalWrite(type2LED5,LOW);
}

void randomMode1(int f1){
  switch (random(4)){
    case 0:
      aSin1.setFreq(f1);
      digitalWrite(type1LED1,HIGH);
      break;
    case 1:
      aSaw1.setFreq(f1);
      digitalWrite(type1LED2,HIGH);
      break;
    case 2:
      aSqu1.setFreq(f1);
      digitalWrite(type1LED3,HIGH);
      break;
    case 3:
      aTri1.setFreq(f1);
      digitalWrite(type1LED4,HIGH);
      break;
    case 4:
      aNoise1.setFreq(f1);
      digitalWrite(type1LED5,HIGH);
      break;
  }          
}
void randomMode2(int f2){
  switch (random(4)){
    case 0:
      aSin2.setFreq(f2);
      digitalWrite(type2LED1,HIGH);
      break;
    case 1:
      aSaw2.setFreq(f2);
      digitalWrite(type2LED2,HIGH);
      break;
    case 2:
      aSqu2.setFreq(f2);
      digitalWrite(type2LED3,HIGH);
      break;
    case 3:
      aTri2.setFreq(f2);
      digitalWrite(type2LED4,HIGH);
      break;
    case 4:
      aNoise2.setFreq(f2);
      digitalWrite(type2LED5,HIGH);
      break;
  }  

}

回路図

mozziのサイトだと出力(9ピン)の高周波ノイズをカットするために
LPFの後にノッチフィルター入れてますが、高周波ノイズもいいんじゃないと思って
LPFしか入れてません。。
IMG_20170525_060631.jpg

操作部説明IMG_20170525_060556.jpg

デモ映像

arduinoのmap関数は、”数値をある範囲から別の範囲に変換します。fromLowと同じ値を与えると、toLowが返り、fromHighと同じ値ならtoHighとなります。”だそうなので可変抵抗を
振り切ると値が不安定になってしまいます。なのでその状態になった時は周波数のタイプを
ランダムで変えるようにしてみました。裏モード的な。。全然隠れてないけど、、

感想

mozziはarduino単独で音声を出すためのライブラリです。本家のサイト(http://sensorium.github.io/Mozzi/) をみると
サンプルがすごく豊富なのでコピペしていけばなんとなく使えてしまいます

9
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
5