Minisintetizador basado en Arduino 
Versión iniciar y muy básica de un minisintetizador mononfónico de onda cuadrada con entrada MIDI y basado en Arduino. Por ahora sólo reconoce mensajes MIDI "NOTE ON" y "NOTE OFF".

El procesador del Arduino se encarga simplemente de parsear los mensajes MIDI: Genera los tonos y los silencios ante las tramas NOTE ON y NOTE OFF que detecta por la entrada MIDI.

#define  MIDI_NOTE_LOW   16
#define MIDI_NOTE_HIGH 107

// midi frequencies from C0 to B7
int freq[] = {
21, 22, 23, 24, 26, 28, 29, 31,
33, 35, 37, 39, 41, 44, 46, 48, 52, 55, 58, 62,
65, 69, 73, 78, 82, 87, 92, 98, 104, 110, 117, 123,
131, 139, 147, 156, 165, 175, 185, 196, 208, 220, 233, 247,
262, 277, 294, 311, 329, 349, 370, 392, 415, 440, 466, 494,
523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988,
1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1864, 1976,
2093, 2217, 2349, 2489, 2637, 2794, 2960, 3136, 3322, 3520, 3729, 3951
};

#define MIDI_STATUS_WAIT_STATUS 0
#define MIDI_STATUS_WAIT_NOTE 1
#define MIDI_STATUS_WAIT_VELOCITY 2
#define MIDI_STATUS_WAIT_NOTE_OR_STATUS 3

#define SPEAKER_PIN 13

int midiStatus = MIDI_STATUS_WAIT_STATUS;
int midiNote = 0;
int midiVelocity = 0;

void setup() {
Serial1.begin(31250);
}

void parseMidi(int b) {
if (midiStatus == MIDI_STATUS_WAIT_STATUS) {
if ((b & 0xF0) == 0x90)
midiStatus = MIDI_STATUS_WAIT_NOTE;
}
else if (midiStatus == MIDI_STATUS_WAIT_NOTE) {
midiNote = b;
midiStatus = MIDI_STATUS_WAIT_VELOCITY;
}
else if (midiStatus == MIDI_STATUS_WAIT_VELOCITY) {
midiVelocity = b;
midiStatus = MIDI_STATUS_WAIT_STATUS;
if (midiVelocity == 0)
noTone(SPEAKER_PIN);
else {
if ((midiNote >= MIDI_NOTE_LOW) && (midiNote <= MIDI_NOTE_HIGH))
tone(SPEAKER_PIN, freq[midiNote - MIDI_NOTE_LOW]);
}
midiStatus = MIDI_STATUS_WAIT_NOTE_OR_STATUS;
}
else if (midiStatus == MIDI_STATUS_WAIT_NOTE_OR_STATUS) {
if (b < 0x80) {
midiNote = b;
midiStatus = MIDI_STATUS_WAIT_VELOCITY;
}
else if ((b & 0xF0) == 0x90)
midiStatus = MIDI_STATUS_WAIT_NOTE;
else
midiStatus = MIDI_STATUS_WAIT_STATUS;
}
}

void loop() {
while (Serial1.available() > 0) {
int b = Serial1.read();
parseMidi(b);
}
}

Como se puede ver, el parseado de las tramas MIDI se realiza mediante un sencillo autómata finito (DFA) de 4 estados.



[ añadir comentario ] ( 1312 visualizaciones )   |  [ 0 trackbacks ]   |  enlace permanente
  |    |    |    |   ( 3 / 3434 )
Interface MIDI out para la Nintendo DS 
Como soy un flipado del MIDI he cogido la interface GPO para la Nintendo DS que desarrollé hace algún tiempo y le he hecho una pequeña modificación para convertirla en una interface MIDI out :-). El grueso del trabajo hay que hacerlo por software ya que, al no tener una UART externa, hay que simularla utilizando uno de los dos procesadores de la Nintendo DS. Yo he optado por utilizar el ARM7 para generar los paquetes MIDI usando el timer 0 del sistema a 31250 Hz y simulando, de esta manera una UART MIDI.

Al contrario de como sucedía en la interface MIDI de salida para Gameboy Advance que había desarrollado hace tiempo, al tener la DS dos procesadores, como el ARM7 es el que se encarga de la generación de paquetes, el ARM9 queda totalmente libre para realizar otras tareas pudiendo, de esta forma, implementar aplicaciones de secuenciación más avanzadas y exigentes que con el único ARM7 que poseía la Gameboy Advance.



Más info y código fuente de ejemplo en: http://nds.avelinoherrera.com

[ añadir comentario ] ( 1370 visualizaciones )   |  [ 0 trackbacks ]   |  enlace permanente
  |    |    |    |   ( 3 / 2379 )
DINAMISE v0.1 - Secuenciador MIDI para GBA 
Ya terminé la primera versión de DINAMISE: un secuenciador MIDI estilo tracker para Gameboy Advance y que utiliza la interface midiout advance.

Las características de este secuenciador son:

- Hasta 16 patrones diferentes de hasta 64 filas cada uno.
- Hasta 100 patrones pueden ser encadenados para crear temas enteros.
- 16 pistas por cada patrón. Cada pista tiene un canal MIDI asociado totalmente configurable.
- Opciones NEW, LOAD y SAVE, que permiten cargar y guardar los datos de la canción en la SRAM del cartucho. Por ahora sólo es posible almacenar una única canción en la SRAM.

Código fuente y binarios aquí.

[ 4 comentarios ] ( 2567 visualizaciones )   |  [ 0 trackbacks ]   |  enlace permanente
  |    |    |    |   ( 3 / 2227 )
Primera pantalla del secuenciador MIDI para Gameboy Advance 
La cosa va avanzando :-). Ya tengo una versión preliminar del secuenciador MIDI para GBA que utilizará el interface midiout-advance.



Como se puede ver, se trata de un secuenciador estilo tracker muy sencillo. Disponemos de hasta 16 patrones diferentes de 16 pistas cada uno; cada pista con su canal MIDI configurable. Cada canción puede ser de hasta 100 patrones de longitud. Los mensajes que se pueden enviar por ahora son NOTE ON, NOTE OFF y CONTROL CHANGE. Más que suficientes para secuenciar temas enteros.

Aún tengo que hacer más pruebas para asegurarme que el invento funciona bien ;-)

[ añadir comentario ] ( 1195 visualizaciones )   |  [ 0 trackbacks ]   |  enlace permanente
  |    |    |    |   ( 3 / 2310 )
Una FFT muy pedagógica 
He encontrado una implementación muy sencilla y pedagógica (aunque no muy eficiente en términos de memoria) del algoritmo de Cooley-Tukey de FFT para arrays de tamaño potencia de 2. Se pueden obtener del depatramento de informática de la universidad de Princeton, más concretamente en los siguientes enlaces: FFT.java y Complex.java.

He estado haciendo pruebas calculado el error cuadrático medio entre x y IFFT(FFT(x)) y se obtienen valores inferiores a 1E-30 para tamaños de entrada lo suficientemente grandes (65536 o más). El algoritmo no es muy eficiente en términos de memoria ya que hace varios new en cada llamada recursiva, pero eso facilitará la comprensión del mismo.

El siguiente paso será utilizar esta implementación de la FFT para implementar el algoritmo que dejé aparcado a un lado hace algunas semanas: el de separación de fuentes de sonido mediante discriminación por acimut. El objetivo final es extraer la voz de una grabación comercial estéreo. A ver si sale. Ya iré contando mis logros y mis sinsabores :-).

[ 9 comentarios ] ( 2216 visualizaciones )   |  [ 0 trackbacks ]   |  enlace permanente
  |    |    |    |   ( 3 / 2653 )

<< <Anterior | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | Siguiente> >>