Pull to refresh

Простой синтезатор на Arduino

Reading time3 min
Views22K


Всем привет.

Две недели назад я приобрел Arduino Duemilanove. Помигал светодиодом, поиграл с LCD, и далее по списку из папки Examples. Остановился на стандартном примере Play Melody и решил его немного развить. Сразу скажу — я чайник в создании и обработке звука, поэтому и термины, и эффекты для будущего синтезатора (если его можно так назвать) придумывал в процессе.


Функции




Клавиши

Всего четыре клавиши с разницей примерно 130 Гц, частота повышается слева направо. Кнопок побольше под рукой не оказалось, использовал мелкие, которые шли в комплекте с Arduino.

Эффект

Эта кнопка меняет множитель-функцию частоты. Функция меняется с заданным шагом и на заданном промежутке, и даже если клавиша не зажата, эффект будет продолжаться. Например, при выборе функции X*X (где X меняется от 0 до 1) получается что-то вроде диско-выстрела. Пока в коде только три эффекта: sin(x) (0;3.14), x*x (0;1), 1-x(0;1).

Запись

Здесь все просто, на каждой итерации записываем значение частоты в массив, а когда массив заполнен, воспроизводим его значения в цикле. Правда, играть на фоне полученного «семпла» не получается, игра на клавишах создает дополнительную задержку и он сильно тормозит (у кого есть решение, буду рад). Позже добавил светодиод рядом с кнопкой, светится во время записи.

Бит

Меняет промежуток между отдельными двойными сигналами и ширину сигналов. Если зажать клавишу и покрутить B, звук похож на постепенную остановку прыгающего мяча и наоборот.

Частота

Меняет промежутки между отдельными сигналами.

Схема


Шесть кнопок, два потенциометра, динамик и светодиод + Arduino. Динамик и кнопки подключены подряд к цифровым входам 2, 3, 4, 5, 6, 7, 8, светодиод к 13; потенциометры к аналоговым входам 0 и 1;

Код


#include <Math.h>

float M=1;
float x=0;
int F,N,i,pl,d1,d2,d3,d4,d5,d6;
int eff=0;
int limit=0;
float st;
int arr[700];
int timer=0;
int rec=0;
int buf=0;
int beat=0;

void play(int F,int N, float M){
  for(i=0;i<N/50;i++){
    digitalWrite(2, HIGH);
    delayMicroseconds((F+1000)*2*M);
    digitalWrite(2, LOW);
    delayMicroseconds((F+1000)*2*M);
  }
  if(N!=50){
    delay(N*0.1);
  }
}

void button(int num){
  F-=150*(num-1);
  pl=1;
  eff=buf;
  if(eff!=0){
    x=0;
  }
  if(rec==1){
    arr[timer]=F+1000;    
  }
}

void setup()
{
  pinMode(8, INPUT);
  pinMode(7, INPUT); 
  pinMode(6, INPUT);
  pinMode(5, INPUT);
  pinMode(4, INPUT);
  pinMode(3, INPUT);
  pinMode(2, OUTPUT); 
  pinMode(13, OUTPUT);
}

void loop()
{
  F = analogRead(A0);
  N = analogRead(A1);
  d1 = digitalRead(3);
  d2 = digitalRead(4);
  d3 = digitalRead(5);
  d4 = digitalRead(6);
  d5 = digitalRead(7);
  d6 = digitalRead(8);
  if(x>limit){
    if(buf<4){
      buf=eff;
    } else {
      buf=0;
    }
    eff=0;
    x=0;    
  }
  if(rec==1){
    timer++;
    arr[timer]=0;
    if(pl==0){
     delayMicroseconds(F);     
    }
    digitalWrite(13, HIGH);
  } else if(rec==2){
    timer++;
  }  
  if(eff==0){
    pl=0;
  }else{
    x+=st;
  }
  if(N<50){
    N=50;
    eff=buf;
  }
  if(d1==1){
    button(1);
  }
  if(d2==1){
    button(2);
  }
  if(d3==1){
    button(3);
  }
  if(d4==1){
    button(4);
  }
  if(d5==1){
    if(buf>3){
      buf=0;
    }
    eff=buf;
    eff++;
    pl=1;
  }
  if(d6==1){
    if(rec==0){
      rec=1;
    }else if(rec==2){
      rec=0;
      timer=0;
    }
  }
  if(rec==2 && arr[timer]!=0){
      play(arr[timer],N,1);
  }
  if(pl==1){
    if(eff==0){
      play(F,N,1);
    } else if(eff==1){
      limit=3.14;
      st=0.025;
      M=sin(x);
    } else if(eff==2){
      limit=1.2;
      st=0.01;
      M=x*x; 
    } else if(eff==3){
      limit=1; 
      st=0.025;  
      M=x+0.5;
    }       
    play(F,N,M); 
  }
  if(rec==1 & timer>698){
      timer=0;
      rec=2;
      digitalWrite(13, LOW);
  }
  if(timer>698){
    timer=0;
  }
}

Корпус




Так как это не претендует на готовое устройство, я сделал картонный корпус, собрал схему на макетной плате и поместил внутрь. Паяльник остался нетронутым.

Улучшения


Очевидное улучшение клавиш — подключить клавиатуру, где каждая клавиша меняет сопротивление на единственный аналоговый вход. Можно добавить вывод mini-jack для записи непосредственно на компьютер или подключения к усилителю, составить целую библиотеку эффектов… список ограничен вашей фантазией.
Tags:
Hubs:
+28
Comments17

Articles

Change theme settings