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



Всем привет.

Две недели назад я приобрел 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 для записи непосредственно на компьютер или подключения к усилителю, составить целую библиотеку эффектов… список ограничен вашей фантазией.
Поделиться публикацией
Ой, у вас баннер убежал!

Ну. И что?
Реклама
Комментарии 17
    +1
    Очень интересно. Но все же оберните код в тег source lang="".
      +9
      стильно вышел корпус, видео в студи.
      +27
      Ну без демонстрации работы топик точно не завершён!
        +1
        Так покажите уже и что на нем можно слабать! :)
          +1
          Позже добавлю видео, но там ничего интересного, вот если б наложить несколько дорожек
          +4
          Реквестируем видео :)
            +1
            «Сектор-видео на барабане! Ролик в студию!»
              0
              а клавиши нарисованы? )
                0
                да, пощупал кнопки сквозь картон и просто нарисовал
                +1
                >Всего четыре клавиши с разницей примерно 130 Гц
                Это будет звучать очень негармонично, на этом ничего путного не сыграешь.
                Теория музыки говорит, что между нотами не абсолютная разница, а отношение. И, скажем, между До первой октавы к До второй октавы равно 1/2. Можете посчитать отношение между малыми секундами, при желании сделать более правдоподобно.
                А в целом, круто, что-то отличное от роботов на ардуино. Ждём фул-сайз версии. Круто было бы приделать к клавишам акселерометры и так сделать чувствительные к силе нажатия клавиши.
                  0
                  Между полутонами, соответственно, корень 12-й степени из двух. Это в равномерно темперированном звукоряде.
                  0
                  А может лучше было пульт (микшер) сделать? Подключать к нему стандартную клавиатуру или midi, читать сигнал, писать в память. Затем вторую «дорожку», третью и т.д.
                  А после все проигрывать.
                    0
                    Это уже совсем другое устройство…
                    0
                    Автор маладца) Респектищще)

                    Но вообще реализация с сопротивлениями какой-то уж больно «олдскул», мы же не в 60-70 годах, когда MIDI не было. Было бы интересно научить эту плату работать с мидей…

                    И еще скажу умную весчь. Вся «теплота и ламповость» на современных (даже весьма бюджетных) железках делается ни разу не синтом. Не есть конечно клевые модельки как правило «из прошлого», которые «изкаропке» звучат «как мы любим». Но я уже писал в камментах ранее что счастливый обладатель синта с «пластмассовым» звуком Novation Xio (кому интересно — в гугль). Сам по себе этот синт звучит ни хорошо ни плохо. В одиночку — плосковато, местами пласмасса, местами «хардбас». Есть повод расстраиватся какбэ… если бы ни одно но. Если через AUX SEND/RETURN к нему прицепить процессор эффектов и хотя бы (!) добавить ревера, он начинает звучать вполне себе ничего. По крайней мере я спокойно на нем накручивал звуки любимых EBM групп вроде Orange Sector`а. Так что сегодня в «сетапе» задача ситнезатора — «сгенерировать пилу/синус/пульс/треугольник/еще чего-то». Речь конечно не идет о секвенсорах или рабочих станциях, там задачи другие, да и на сцену с «пилой» лезть это больше к Апфексу Твину… НО из таких вот «наколеночных» синтах можно понаделать много интересных не замыленых эффектов банально на стадии программирования математики. Главное на этой стадии срегерировать интересный звук. А окрас ему придадут железные обработки, которые сейчас стоят начиная от 150$ и до…

                    Так что такие вещи это вполне себе интересная тема. Не только ради лулзов)
                      0
                      Вот например midi, только что закончил )

                      image
                      миди клавиатура с ультразвуковым датчиком
                        0
                        Реквестирую моар)))

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое