Pelo menos eu acho que esta é a programação.
#define ledPin 13 // for midi out status // what midi channel we're sending on #define drumchan 1 #define PIEZOTHRESHOLD 100 #define MAXIMUMINTERVAL 40 #define switchA 7 #define switchB 6 // Definicao para os piezos // - Definicao padrao : int piezoNotesA[6] = {35,38,42,41,51,49}; // Definicao para meu drumkit do Hydrogen //int piezoNotes[6] = {37,39,57,47,62,63}; int piezoNotes[6] = {35,38,42,41,51,49}; int piezoPins[6] = {0,1,2,3,4,5}; int piezoState[6] = {0,0,0,0,0,0}; int leitura1[6] = {0,0,0,0,0,0}; int leitura2[6] = {0,0,0,0,0,0}; long piezoInterval[6] = {0,0,0,0,0,0}; long currentTime = 0; int val,t, i, piezoAtual; long switchInterval = 0; void setup() { pinMode(switchA, INPUT); pinMode(switchB, INPUT); digitalWrite(switchA, HIGH); // turn on internal pullup digitalWrite(switchB, HIGH); // turn on internal pullup pinMode(ledPin, OUTPUT); Serial.begin(31250); // set MIDI baud rate i = 0; piezoAtual = 0; } void loop() { piezoAttack(i); drumkitSetup(); i++; if(i == 7) i = 0; } // Funcao que define leitura dos switch void drumkitSetup(){ currentTime = millis(); // So le a cada 1/2 segundo if(currentTime - switchInterval <>35 ){ piezoNotes[piezoAtual]--; } else{ piezoNotes[piezoAtual] = 81; } digitalWrite(switchB, HIGH); } switchInterval = currentTime; } // Funcao que define a nota do piezo void piezoAttack(int i){ currentTime = millis(); // So faz uma leitura deste piezo a cada MAXIMUMINTERVAL millisegundos if(currentTime - piezoInterval[i] <= MAXIMUMINTERVAL){ return; } // Eh feito duas leituras de maneira a tentar determinar o comportamento da onda leitura1[i] = analogRead(piezoPins[i]); leitura2[i] = analogRead(piezoPins[i]); // Toda vez que abaixar em relacao ao threshold, desliga a nota if ( leitura2[i] <> leitura2[i]){ piezoState[i] = 0; } // Se a segunda leitura for maior que a primeira, o som esta diminuindo, ou seja, eh o ataque da nota. Ligue a nota. if(piezoState[i] == 0 && leitura2[i] > leitura1[i] && leitura2[i] >=PIEZOTHRESHOLD && leitura1[i] >= PIEZOTHRESHOLD){ noteOff(1,piezoNotes[i],0); noteOn(1,piezoNotes[i],leitura2[i]/8 ); piezoAtual = i; piezoState[i] = 1; } piezoInterval[i] = currentTime; } // Send a MIDI note-on message. Like pressing a piano key // channel ranges from 0-15 // Ou seria channel << 4?
void noteOn(byte channel, byte note, byte velocity) { midiMsg( (0x90 | channel), note, velocity); } // Send a MIDI note-off message. Like releasing a piano key void noteOff(byte channel, byte note, byte velocity) { midiMsg( (0x80 | channel), note, velocity); }
// Send a general MIDI message void midiMsg(byte cmd, byte data1, byte data2) { digitalWrite(ledPin,HIGH); // indicate we're sending MIDI data Serial.print(cmd, BYTE); Serial.print(data1, BYTE); Serial.print(data2, BYTE); // Serial.print(cmd); // Serial.print(" "); // Serial.print(int(data1)); // Serial.print(" "); // Serial.print(int(data2)); // Serial.println(""); digitalWrite(ledPin,LOW); }
Fotos
Algumas fontes tardias....
2 comentários:
Olá!
Gostaria de saber se é possível interpretar um arquivo .mid no Arduino e converter em códigos para enviar a um sintetizador.
Abrir arquivos via cartão SD é fácil. Enviar códigos de notas e instrumentos também. Você saberia interpretar o arquivo .mid para "capturar" tais comandos?
Grande abraço!
Há várias APIs para a leitura de arquivo MIDI como, por exemplo, a do PortMedia. É possível ler tais arquivos manualmente sendo isto mais trabalhoso devido as várias versões de MIDI e algumas incompatibilidades no arquivo gerado por algumas ferramentas. Resumindo, é possível sim.
Postar um comentário