Paso 8: ¿Cuál es ese canal?
Puesto que el sorteo no hace mucho la verdadera acción debe estar ocurriendo en otros lugares. De hecho, es los métodos de manejo de nota que lo que se ve. Cuando entra un mensaje MIDI se envía a un controlador nota que si existe. Decidí que quería ser capaz de generar algunos patrones, tales como llenar una cuadrícula de 4 x 4 con imágenes Nota por nota. Escribí un controlador nota que hizo esto por el lado izquierdo de la ventana de dibujo y pensé que sería bueno hacer lo mismo en el lado derecho, pero invertida.
Al principio lo hice con dos controladores de cambiando de tema, pensamiento que utilizaría una octava para cosas que suceden en el lado izquierdo y la otra octava de la derecha. Esto se sentía incómodo. ¿Por qué no involucrarse canales?
MidiBus proporciona algunos controladores de eventos adicionales, incluyendo noteOn, que, si se define, se llama cuando cualquier dispositivo recibe un mensaje de nota. Este método le dará el canal, el valor de la nota y la velocidad. Sin embargo, no da usted el nombre del autobús de MIDI que recibió.
En este punto en desarrollo no tenía un plan claro para usar el nombre de bus pero estaban formando algunas ideas y no quiero que deje la opción de usarlo. Pero también quería el canal.
midiMessage se llama con algunos datos específicos que dio derecho a usted (como el nombre de bus) pero el mensaje es un poco críptico. Usted puede haber notado hay algunos interesantes matemáticas a obtener los valores de nota y la velocidad.
int note = (int)(message.getMessage()[1] & 0xFF) ;
Un mensaje MIDI es bastante compacto. Se envía como una serie de bytes. Voy a omitir los detalles técnicos pero para obtener el valor útil de estos bytes en Java necesita agarrar una subdivisión de ellos y luego aplicar una "máscara". Esta máscara obliga a una parte del valor de asumir un cierto valor que nos da un resultado útil.
El código estaba haciendo esto para obtener los valores de nota y la velocidad. Ellos mismo enfoque puede utilizarse para obtener el canal así. midiMessage se convierte entonces en esto:
void midiMessage (MidiMessage mensaje, hora larga, String bus_name) {int canal = (int)(message.getMessage() [0] & 0x0F) + 1; void midiMessage(MidiMessage message, long timestamp, String bus_name) { int channel = (int)(message.getMessage()[0] & 0x0F) + 1; int note = (int)(message.getMessage()[1] & 0xFF) ; int vel = (int)(message.getMessage()[2] & 0xFF); invokeNoteHandler(note, vel, channel, bus_name); }
invokeNoteHandler ahora tiene que hacer una búsqueda de método con tres argumentos:
void invokeNoteHandler(int note, int velocity, int channel, String bus_name) { try { Class[] cls = new Class[3]; cls[0] = int.class; cls[1] = int.class; cls[2] = String.class; Method handler = this.getClass().getMethod( "onNote" + note, cls ); handler.invoke(this, velocity, channel, bus_name); } catch (Exception e) { println("* * * * * * Error handling note " + note + " * * * * * * "); e.printStackTrace(); } }
Con el nombre canal y autobús está disponible cada controlador nota puede comportamiento diferentemente dependiendo de la fuente de la nota. En algunos casos esto hace más fácil organizar las notas en el punto de origen. Por ejemplo, he creado un método que se sigue añadiendo una imagen a la rejilla de 4 x 4, un índice de la rejilla de seguimiento. Si el índice fuera fuera de los límites (es decir, por debajo de 0 o por encima de 15, dependiendo de qué dirección fue utilizado para llenar el grid) limpiarán la cuadrícula.
Esta asignado el C4 (es decir, Nota 48). Antes de poner los canales en el código tuve C64 desencadenar este comportamiento en el lado izquierdo del esbozo y C5 usado para disparar a la derecha (donde funcionaría al revés, a partir de la ubicación de red 15). Pero no era feliz con este uso, de octavas. Decidir añadir canales había creado otro instrumento MIDI-gatillo de Renoise y ponerlo a la salida en el canal 2. De esta manera podía configurar cada nota para asignar a algún comportamiento específico, con el canal de determinar en qué lado de la pantalla parece.
Este tipo de organización las decisiones es bastante subjetivo. Esto funciona para mí (tan lejos, tal vez después del uso más que trabajaré algún otro sistema). El punto es que no hay una forma verdadera de hacer esto; encontrar un enfoque que trabaja para usted.
Aquí es cómo onNote48 terminó después de que el cambio:
void onNote48(int vel, int channel, String bus_name) { if (vel > 0) { switch(channel) { case 1: addToGridL4x4(); break; case 2: addToGridR4x4(); break; } } }
addToGridL4x4() es el siguiente:
void addToGridL4x4() { if (gridL4x4Pointer < 0) { renderL.clear(); gridL4x4Pointer = 15; } renderL.add(new RenderArgs( nextTint(), gifs[nextGifIndex()], 4, 4, gridL4x4Pointer) ); gridL4x4Pointer--; }
El esquema general es el uso de una variable a un índice en una red, actualizando el índice, y asegurándose de que siempre tiene un valor válido.
En algún momento las variables globales deben desaparecer y todo esto envuelto en una clase, pero la mutabilidad suelta se presta a interesantes de comportamiento.