А кнопку надо нажать (7 пин) и держать чтобы играла мелодия. Я на уно экспериментирую.
на предыдущей работает, на этой нет, ардуино нано, компилируется и заливается без ошибок
Странно, я проверил на своей нано - работает.
Может я что потерял?, вот ещё раз код.
//instrument definitions
#define ninstr 12 // piano xlphn guitar cmbll bell funky vibr metal violin bass trumpt harm
unsigned int ldness[ninstr] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}; // loudness
unsigned int pitch0[ninstr] = { 0, 0, 0, 12, 24, 24, 0, 12, 24, 12, 12, 0}; // pitch of key0
unsigned int ADSR_a[ninstr] = { 4096, 8192, 8192, 8192, 4096, 512, 512, 8192, 128, 128, 256, 4096}; // attack parameter
unsigned int ADSR_d[ninstr] = { 256, 256, 512, 16, 8, 16, 16, 8, 16, 16, 64, 128}; // decay parameter
unsigned int ADSR_s[ninstr] = { 0, 0, 0, 0, 0, 0, 0, 0, 240, 240, 192, 0}; // sustain parameter
unsigned int ADSR_r[ninstr] = { 64, 128, 32, 32, 16, 32, 32, 32, 32, 32, 64, 4096}; // release parameter
unsigned int FM_inc[ninstr] = { 256, 512, 768, 400, 200, 96, 528, 244, 256, 128, 64, 64}; // FM frequency wrt pitch
unsigned int FM_a1[ninstr] = { 128, 512, 512, 1024, 512, 0, 1024, 2048, 256, 256, 384, 256}; // FM amplitude start
unsigned int FM_a2[ninstr] = { 64, 0, 128, 128, 128, 512, 768, 512, 128, 128, 256, 128}; // FM amplitude end
unsigned int FM_dec[ninstr] = { 64, 128, 128, 128, 32, 128, 128, 128, 128, 128, 64, 128}; // FM decay
//define the pitch2key mapping
#define NOTE_C4 0
#define NOTE_CS4 1
#define NOTE_D4 2
#define NOTE_DS4 3
#define NOTE_E4 4
#define NOTE_F4 5
#define NOTE_FS4 6
#define NOTE_G4 7
#define NOTE_GS4 8
#define NOTE_A4 9
#define NOTE_AS4 10
#define NOTE_B4 11
#define NOTE_C5 12
#define NOTE_CS5 13
#define NOTE_D5 14
#define NOTE_DS5 15
#define NOTE_E5 16
#define NOTE_F5 17
#define NOTE_FS5 18
#define NOTE_G5 19
#define NOTE_GS5 20
#define NOTE_A5 21
#define NOTE_AS5 22
#define NOTE_B5 23
#define NOTE_C6 24
#define NOTE_CS6 25
#define NOTE_D6 26
#define NOTE_DS6 27
#define NOTE_E6 28
#define NOTE_F6 29
#define NOTE_FS6 30
#define NOTE_G6 31
#define NOTE_GS6 32
#define NOTE_A6 33
#define NOTE_AS6 34
#define NOTE_B6 35
#define PAUZA 50
#define nokey 255
#define instrkey 254
//set up array with sine values in signed 8-bit numbers
const float pi = 3.14159265;
char sine[256];
void setsine() {
for (int i = 0; i < 256; ++i) {
sine[i] = (sin(2 * 3.14159265 * (i + 0.5) / 256)) * 128;
}
}
//setup frequencies/phase increments, starting at C3=0 to B6. (A4 is defined as 440Hz)
unsigned int tone_inc[48];
void settones() {
for (byte i=0; i<48; i++){
tone_inc[i]= 440.0 * pow(2.0, ( (i-21) / 12.0)) * 65536.0 / (16000000.0/512) + 0.5;
}
}
byte instr=11;//счётчик инструмента включённого
/////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
long Y=0;//переменная хранения моментов времени
int k=0;// счётчик прогресса исполнения мелодии
int i=0;//
const int notes_times[]PROGMEM = {
// кабы не было зимы
NOTE_B4,400, NOTE_B4,400, NOTE_B5,600, NOTE_FS5,200,
NOTE_A5,400, NOTE_G5,400, NOTE_E5,800,PAUZA,50,
NOTE_D5,400, NOTE_D5,400, NOTE_D6,600, NOTE_C6,200, NOTE_C6,400,NOTE_B5,400,PAUZA,800,
NOTE_D6,400,NOTE_C6,400, NOTE_A5,400,NOTE_FS5,400, NOTE_C6,400,NOTE_B5,400,NOTE_B5,800,
NOTE_B4,400, NOTE_B4,400, NOTE_B5,600, NOTE_A5,200,NOTE_A5,400, NOTE_G5,400, PAUZA,800,
NOTE_B4,400, NOTE_B4,400, NOTE_B5,600, NOTE_FS5,200,
NOTE_A5,400, NOTE_G5,400, NOTE_E5,800,PAUZA,50,
NOTE_D5,400, NOTE_D5,400, NOTE_D6,600, NOTE_C6,200, NOTE_C6,400,NOTE_B5,400,PAUZA,400,
NOTE_E6,800,NOTE_C6,400, NOTE_A5,400, NOTE_FS5,400, NOTE_C6,400,NOTE_B5,400,NOTE_B5,800,PAUZA,50,
NOTE_B4,400, NOTE_B4,400, NOTE_B5,600, NOTE_A5,200,NOTE_A5,400, NOTE_G5,400, PAUZA,400,
NOTE_E6,800,NOTE_C6,400, NOTE_A5,400, NOTE_FS5,400, NOTE_C6,400,NOTE_B5,400,NOTE_B5,800,PAUZA,50,
NOTE_B4,400, NOTE_B4,400, NOTE_B5,600, NOTE_DS5,200,NOTE_FS5,400, NOTE_E5,400,PAUZA,5000
};
float temp=0.9;//задаём темп исполнения мелодии
int dlina= sizeof(notes_times)/sizeof(notes_times[0]);//определяем длину массива
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
void setup() {
//disable all inerrupts to avoid glitches отключите все прерывания, чтобы избежать сбоев
// noInterrupts();
//setup the array with sine values настройте массив со значениями синуса
setsine();
//setup array with tone frequency phase increments установочная матрица с приращениями фазы тональной частоты
settones();
//Set a fast PWM signal on TIMER1A, 9-bit resolution, 31250Hz
pinMode(9, OUTPUT);// вывод для динамика
TCCR1A = 0B10000010; //9-bit fast PWM
TCCR1B = 0B00001001;
/////////////////////////////////////////////////////////////////////////////////
pinMode(7, INPUT);//кнопку подключить
digitalWrite(7, HIGH);// включить подтягивающий резистор к ней
/////////////////////////////////////////////////////////////////////////////////
}
//initialize the main parameters of the pulse length setting инициализируйте основные параметры настройки длительности импульса
#define nch 4 //number of channels that can produce sound simultaneously количество каналов, которые могут воспроизводить звук одновременно
unsigned int phase[nch] = {0,0,0,0};
int inc[nch] = {0,0,0,0};
byte amp[nch] = {0,0,0,0};
unsigned int FMphase[nch]= {0,0,0,0};
unsigned int FMinc[nch] = {0,0,0,0};
unsigned int FMamp[nch] = {0,0,0,0};
// main function (forced inline) to update the pulse length основная функция (принудительная встроенная) для обновления длительности импульса
inline void setPWM() __attribute__((always_inline));
inline void setPWM() {
//wait for the timer to complete loop подождите, пока таймер завершит цикл
while ((TIFR1 & 0B00000001) == 0);
//Clear(!) the overflow bit by writing a 1 to it
TIFR1 |= 0B00000001;
//increment the phases of the FM
FMphase[0] += FMinc[0];
FMphase[1] += FMinc[1];
FMphase[2] += FMinc[2];
FMphase[3] += FMinc[3];
//increment the phases of the note
phase[0] += inc[0];
phase[1] += inc[1];
phase[2] += inc[2];
phase[3] += inc[3];
//calculate the output value and set pulse width for timer2
int val = sine[(phase[0]+sine[FMphase[0]>>8]*FMamp[0]) >> 8] * amp[0];
val += sine[(phase[1]+sine[FMphase[1]>>8]*FMamp[1]) >> 8] * amp[1];
val += sine[(phase[2]+sine[FMphase[2]>>8]*FMamp[2]) >> 8] * amp[2];
val += sine[(phase[3]+sine[FMphase[3]>>8]*FMamp[3]) >> 8] * amp[3];
//set the pulse length
OCR1A = val/128 + 256;
}
//properties of each note played свойства каждой сыгранной ноты
byte iADSR[nch] = {0, 0, 0, 0};
unsigned int envADSR[nch] = {0, 0, 0, 0};
unsigned int ADSRa[nch] = {0, 0, 0, 0};
unsigned int ADSRd[nch] = {0, 0, 0, 0};
unsigned int ADSRs[nch] = {0, 0, 0, 0};
unsigned int ADSRr[nch] = {0, 0, 0, 0};
byte amp_base[nch] = {0, 0, 0, 0};
unsigned int inc_base[nch] = {0, 0, 0, 0};
unsigned int FMa0[nch] = {0, 0, 0, 0};
int FMda[nch] = {0, 0, 0, 0};
unsigned int FMinc_base[nch]= {0, 0, 0, 0};
unsigned int FMdec[nch] = {0, 0, 0, 0};
unsigned int FMexp[nch] = {0, 0, 0, 0};
unsigned int FMval[nch] = {0, 0, 0, 0};
byte keych[nch] = {0, 0, 0, 0};
unsigned int tch[nch] = {0, 0, 0, 0};
byte keypressed;
byte keyreleased;
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
// main loop. Duration of loop is determined by number of setPWM calls
// Each setPWMcall corresponds to 512 cylcles=32mus
// Tloop= 32mus * #setPWM. #setPWM=15 gives Tloop=0.48ms
void loop() {
keypressed = nokey;
keyreleased = nokey;
if(digitalRead (7)==LOW){//если нажали кнопку то...
for(int i=0;i< dlina;i=i+2){//...сыграть мелодию...
if(k==i&&millis()-Y>10){Y=millis();k++;if(pgm_read_word(¬es_times[i])!=PAUZA){keypressed = pgm_read_word(¬es_times[i]);}}
if(k==i+1&&millis()-Y>pgm_read_word(¬es_times[i+1])*temp){Y=millis();k++;if(pgm_read_word(¬es_times[i])!=PAUZA){keyreleased = pgm_read_word(¬es_times[i]);}}
setPWM();//#0
}
if(k==dlina){k=0;}//... и повторить её снова при долгом удержании кнопки
}else {k=0;}//при повторном нажатии кнопки начать исполнение сначала
osnova();// вынес в отдельную функцию часть исходника автора
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
void osnova(){
setPWM(); //#1
//find the best channel to start a new note найдите лучший канал, чтобы начать новую заметку
byte nextch = 255;
//first check if the key is still being played сначала проверьте, воспроизводится ли еще клавиша
if (iADSR[0] > 0 and keypressed == keych[0])nextch = 0;
if (iADSR[1] > 0 and keypressed == keych[1])nextch = 1;
if (iADSR[2] > 0 and keypressed == keych[2])nextch = 2;
if (iADSR[3] > 0 and keypressed == keych[3])nextch = 3;
//then check for an empty channel затем проверьте, нет ли пустого канала
if (nextch == 255) {
if (iADSR[0] == 0)nextch = 0;
if (iADSR[1] == 0)nextch = 1;
if (iADSR[2] == 0)nextch = 2;
if (iADSR[3] == 0)nextch = 3;
}
//otherwise use the channel with the longest playing note в противном случае используйте канал с самой длинной воспроизводимой нотой
if (nextch == 255) {
nextch = 0;
if (tch[0] > tch[nextch])nextch = 0;
if (tch[1] > tch[nextch])nextch = 1;
if (tch[2] > tch[nextch])nextch = 2;
if (tch[3] > tch[nextch])nextch = 3;
}
setPWM(); //#3
//initiate new note if needed при необходимости инициируйте новую заметку
if (keypressed != nokey) {
phase[nextch]=0;
amp_base[nextch] = ldness[instr];
inc_base[nextch] = tone_inc[pitch0[instr]+keypressed];
ADSRa[nextch]=ADSR_a[instr];
ADSRd[nextch]=ADSR_d[instr];
ADSRs[nextch]=ADSR_s[instr]<<8;
ADSRr[nextch]=ADSR_r[instr];
iADSR[nextch] = 1;
FMphase[nextch]=0;
FMinc_base[nextch] = ((long)inc_base[nextch]*FM_inc[instr])/256;
FMa0[nextch] = FM_a2[instr];
FMda[nextch] = FM_a1[instr]-FM_a2[instr];
FMexp[nextch]=0xFFFF;
FMdec[nextch]=FM_dec[instr];
keych[nextch] = keypressed;
tch[nextch] = 0;
}
setPWM(); //#4
//stop a note if the button is released остановите заметку, если кнопка отпущена
if (keyreleased != nokey) {
if (keych[0] == keyreleased)iADSR[0] = 4;
if (keych[1] == keyreleased)iADSR[1] = 4;
if (keych[2] == keyreleased)iADSR[2] = 4;
if (keych[3] == keyreleased)iADSR[3] = 4;
}
setPWM(); //#5
//update FM decay exponential обновление FM-спад экспоненциальный
FMexp[0]-=(long)FMexp[0]*FMdec[0]>>16;
FMexp[1]-=(long)FMexp[1]*FMdec[1]>>16;
FMexp[2]-=(long)FMexp[2]*FMdec[2]>>16;
FMexp[3]-=(long)FMexp[3]*FMdec[3]>>16;
setPWM(); //#6
//adjust the ADSR envelopes отрегулируйте конверты ADSR
for (byte ich = 0; ich < nch; ich++) {
if (iADSR[ich] == 4) {
if (envADSR[ich] <= ADSRr[ich]) {
envADSR[ich] = 0;
iADSR[ich] = 0;
}
else envADSR[ich] -= ADSRr[ich];
}
if (iADSR[ich] == 2) {
if (envADSR[ich] <= (ADSRs[ich] + ADSRd[ich])) {
envADSR[ich] = ADSRs[ich];
iADSR[ich] = 3;
}
else envADSR[ich] -= ADSRd[ich];
}
if (iADSR[ich] == 1) {
if ((0xFFFF - envADSR[ich]) <= ADSRa[ich]) {
envADSR[ich] = 0xFFFF;
iADSR[ich] = 2;
}
else envADSR[ich] += ADSRa[ich];
}
tch[ich]++;
setPWM(); //#7-10
}
//update the tone for channel 0 обновите звуковой сигнал для канала 0
amp[0] = (amp_base[0] * (envADSR[0] >> 8)) >> 8;
inc[0] = inc_base[0];
FMamp[0] = FMa0[0] + ((long)FMda[0] * FMexp[0]>>16);
FMinc[0] = FMinc_base[0];
setPWM(); //#11
//update the tone for channel 1
amp[1] = (amp_base[1] * (envADSR[1] >> 8)) >> 8;
inc[1] = inc_base[1];
FMamp[1] = FMa0[1] + ((long)FMda[1] * FMexp[1]>>16);
FMinc[1] = FMinc_base[1];
setPWM(); //#12
//update the tone for channel 2
amp[2] = (amp_base[2] * (envADSR[2] >> 8)) >> 8;
inc[2] = inc_base[2];
FMamp[2] = FMa0[2] + ((long)FMda[2] * FMexp[2]>>16);
FMinc[2] = FMinc_base[2];
setPWM(); //#13
//update the tone for channel 3
amp[3] = (amp_base[3] * (envADSR[3] >> 8)) >> 8;
inc[3] = inc_base[3];
FMamp[3] = FMa0[3] + ((long)FMda[3] * FMexp[3]>>16);
FMinc[3] = FMinc_base[3];
setPWM(); //#14
//update counters счетчики обновлений
tch[0]++;
tch[1]++;
tch[2]++;
tch[3]++;
setPWM(); //#15
}
///////////////////////////////////////////////////////
Этот вариант инструмента с очень низким звучанием. Можно на пианино проверить, тогда надо заменить в строке byte instr=11;//счётчик инструмента включённого 11 на 0.
float везде одинаковая и везде 24 двоичных разряда (один из которых не нуждается в хранении).
не скажите, в MYSQL не так:
TINYINT 0 - 255
SMALLINT 0 - 65535
MEDIUMINT 0 - 16777215
INT 0 - 4294967295
BIGINT (8 байт)
FLOAT ;-)))
Так что там с FLOAT?
Кстати, то, что в Си называется float, это число, удовлетворяющее стандарту IEEE 754. В других языках программирования может называться по-другому: single, real и т.п. Но всегда представляет собой 4-байтовое число, в котором 1 бит (старший) отводится под знак, 8 - под порядок и 23 - под мантиссу, причем старший бит мантиссы опускается.
Другими словами, называться может по-разному, но формат (и, соответственно, - точность) всегда один и тот же.
По сравнению с tone(); звук гораздо интереснее. Теперь можно не только пищать и зудеть, но и струнить, колоколить, дудеть (последнее правда у автора не получается). Но есть настройки голоса инструмента :
и он их в количественно-качественных характеристиках описывает. Мелодии на 0,1,11 инструментах-голосах звучат своеобразно (на остальных не очень гармонично, на моё мнение). Конечно после моего "распрета" прерываний в исходнике, может звучание ухудшилось.
Ну и автор скетч построил так, что блокирующий код не работает (это плохо :-). Можно, наверное, было попробовать реализовать несколько голосов как простенькую добавочную библиотеку к имеющейся tone. Тогда динамик 0,1-0,5 Вт, платка-усилитель и можно дальше экспериментировать.
Мелодий взял 6, а инструментов 5. После исполнения мелодии набавляю по кругу номер мелодии и инструмента - получается своеобразное чередование 30 исполнений.
А внешне? Вот диаграммы моих псевдоинструментов. Зависимость от времени чего? Теперь можно сопоставить числовые коэффициенты из массивов базового скетча с внешним видом и попытаться связать "хрен с носом" :-)
А кнопку надо нажать (7 пин) и держать чтобы играла мелодия. Я на уно экспериментирую.
на предыдущей работает, на этой нет, ардуино нано, компилируется и заливается без ошибок
Странно, я проверил на своей нано - работает.
Может я что потерял?, вот ещё раз код.
Этот вариант инструмента с очень низким звучанием. Можно на пианино проверить, тогда надо заменить в строке byte instr=11;//счётчик инструмента включённого 11 на 0.
на 2 заработало )))
Мне тестировщиком работать надо, если что-то может пойти не так оно у меня обязательно пойдёт не так )))
float везде одинаковая и везде 24 двоичных разряда (один из которых не нуждается в хранении).
не скажите, в MYSQL не так:
TINYINT 0 - 255
SMALLINT 0 - 65535
MEDIUMINT 0 - 16777215
INT 0 - 4294967295
BIGINT (8 байт)
FLOAT ;-)))
Так что там с FLOAT?
Кстати, то, что в Си называется float, это число, удовлетворяющее стандарту IEEE 754. В других языках программирования может называться по-другому: single, real и т.п. Но всегда представляет собой 4-байтовое число, в котором 1 бит (старший) отводится под знак, 8 - под порядок и 23 - под мантиссу, причем старший бит мантиссы опускается.
Другими словами, называться может по-разному, но формат (и, соответственно, - точность) всегда один и тот же.
А кнопку надо нажать (7 пин) и держать чтобы играла мелодия. Я на уно экспериментирую.
Я, чтобы не нажимать кнопку (точнее говоря, вообще не подсоединять ее), заменил в if() LOW на HIGH. Но звук не впечатлил.
По сравнению с tone(); звук гораздо интереснее. Теперь можно не только пищать и зудеть, но и струнить, колоколить, дудеть (последнее правда у автора не получается). Но есть настройки голоса инструмента :
и он их в количественно-качественных характеристиках описывает. Мелодии на 0,1,11 инструментах-голосах звучат своеобразно (на остальных не очень гармонично, на моё мнение). Конечно после моего "распрета" прерываний в исходнике, может звучание ухудшилось.
Ну и автор скетч построил так, что блокирующий код не работает (это плохо :-). Можно, наверное, было попробовать реализовать несколько голосов как простенькую добавочную библиотеку к имеющейся tone. Тогда динамик 0,1-0,5 Вт, платка-усилитель и можно дальше экспериментировать.
Так что там с FLOAT?
знак, 1 - 3, и 38 нулей после запятой (приблизительно)
Но звук не впечатлил.
https://disk.yandex.ru/d/ZtqnZplfekynbw
https://disk.yandex.ru/d/T77wCY24ZQSdFw
https://disk.yandex.ru/d/7QTGTSkVWxYgzQ
Вот на всякий случай для сравнения, у меня. Играет "прямо в ссылке".
Но звук не впечатлил.
https://disk.yandex.ru/d/ZtqnZplfekynbw
https://disk.yandex.ru/d/T77wCY24ZQSdFw
https://disk.yandex.ru/d/7QTGTSkVWxYgzQ
Вот на всякий случай для сравнения, у меня. Играет "прямо в ссылке".
Вы всерьез полагаете, что я буду заморачиваться, чтобы прорваться через все препятствия на пути к Вашим файлам?
Если хотите, чтобы их кто-то смотрел, позаботьтесь о том, чтобы у желающего их просмотреть не возникало лишних препятствий.
Вот на всякий случай для сравнения, у меня. Играет "прямо в ссылке".
Спасибо. Подключать динамик было затруднительно, а послушать хотелось. У меня проигралось прямо по ссылке без проблем.
А у меня по ссылке сначала требуют подтвердить, что я не робот, а потом еще нужно что-то куда-то вводить.
а потом еще нужно что-то куда-то вводить.
:-)
А как быть и что делать?
Напомнило общагу, в местах где сидели с газеткой в руках, умники вырывали фразочки и клеили на кафель "самописные апфоризмы". Теперь интернеть рулит.
Не хочу пробовать ни в первый, ни еще раз.
Если уж размещаете что-то на стороннем ресурсе, позаботьтесь о том, чтобы этим было удобно пользоваться.
Вот вариант, кнопка переключает мелодии. Можно по желанию добавить кнопки выбора инструмента (дудку сделал, котика - нет) и темпа-ритма исполнения.
Придумал куда практически этот синтез-проигрыватель мелодий можно пристроить. К новогодней гирлянде :-)
Просто посылаем через блютуз-модуль "1" на каждой ноте. В итоге колонки с синтезатором в одном углу, ёлка с гирляндой в другом. Свет и звук синхронны.
Кстати нашёл пример "библиотечного" варианта синтеза звуков.
http://digitrode.ru/computing-devices/mcu_cpu/2517-sintezator-zvukovyh-signalov-na-arduino-svoimi-rukami.html
Мелодий взял 6, а инструментов 5. После исполнения мелодии набавляю по кругу номер мелодии и инструмента - получается своеобразное чередование 30 исполнений.
А подобие терменвокса слабо на ардуине забубенить?
У него голос своеобразный для синтеза. Найти бы простое описание как формируют голоса инструментов настройками.
Найти бы простое описание как формируют голоса инструментов настройками.
Ну как 100 лет назад могли формировать голоса... Никак
У него голос своеобразный для синтеза. Найти бы простое описание как формируют голоса инструментов настройками.
Даю самое простое описание (проще вряд ли возможно):
на слух.
PS. Кстати, если речь идет о волновой форме терменвокса, то, если мне не изменяет память, там одностороннее ограничение синусоиды.
А внешне? Вот диаграммы моих псевдоинструментов. Зависимость от времени чего? Теперь можно сопоставить числовые коэффициенты из массивов базового скетча с внешним видом и попытаться связать "хрен с носом" :-)
БАС СТРУНА и КСИЛОФОН.