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