Stap 8: Wat is dat kanaal?
Aangezien draw niet moet veel op de echte actie elders gebeuren. Inderdaad, het is de opmerking aangestuurde methoden die rijden wat wordt gezien. Wanneer een MIDI-bericht komt in krijgt het aan een overeenkomende Opmerking handler verzonden, indien aanwezig. Ik besloot dat ik wilde te kunnen genereren sommige patronen, zoals het vullen van een 4 x 4 raster met beelden opmerking-door-note. Ik schreef een notitie-handler die deed dit voor de linkerkant van het venster van de schets, en dacht dat het zou leuk om te doen hetzelfde aan de rechterkant, maar omgekeerd.
Aanvankelijk deed ik dit met behulp van twee verschillende nota handlers, dacht dat ik zou gebruik een octaaf voor dingen gebeuren aan de linker kant, en een ander octave voor het recht. Dit voelde onhandig. Waarom niet meedoen kanalen?
MidiBus biedt een aantal extra gebeurtenis-handlers, met inbegrip van noteOn, die, als u definieert, wordt aangeroepen wanneer een apparaat een opmerking-on-bericht ontvangt. Deze methode krijgt u het kanaal, de waarde van de opmerking en de snelheid. Echter geeft het niet u de naam van de MIDI-bus die ontvangen.
Op dit punt in ontwikkeling heb ik niet een duidelijk plan voor het gebruik van de naam van de bus, maar sommige ideeën waren vormen en ik wilde niet te laten vallen van de optie van het gebruik ervan. Maar ik wilde het kanaal, ook.
midiMessage heet met enkele specifieke gegevens overhandigd recht aan u (zoals de naam van de bus), maar het bericht zelf is enigszins cryptisch. Je misschien hebt gemerkt is er wat interessante wiskunde gaande om de waarden van de opmerking en snelheid.
int note = (int)(message.getMessage()[1] & 0xFF) ;
Een MIDI-bericht is vrij compact. Het wordt verzonden als een reeks bytes. Ik ga naar de technische details overslaan, maar om de nuttige waarde van deze bytes in Java u moet een subsectie van hen grijpen en vervolgens een "masker" toe te passen. Dit masker dwingt een deel van de waarde om aan te nemen van een bepaalde waarde geven ons een nuttig resultaat.
De code deed dit om de waarden van de opmerking en snelheid. Ze dezelfde benadering kan worden gebruikt om het kanaal zo goed. midiMessage wordt dan dit:
VOID midiMessage (MidiMessage-bericht, lange timestamp, String bus_name) {int kanaal = (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 nu moet doen een methode look-up met drie argumenten:
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(); } }
Met zowel de bus als de kanaal naam beschikbaar elke opmerking-handler kan gedrag anders afhankelijk van de bron van de notitie. In sommige gevallen maakt dit het makkelijker om te organiseren van de notities op het punt van oorsprong. Bijvoorbeeld, heb ik een methode die zou houden het toevoegen van een afbeelding op 4 x 4 raster, een raster index bijhouden. Als de index ging out of bounds (dat wil zeggen onder 0 of boven 15, afhankelijk van welke richting werd gebruikt om te vullen het raster) het raster worden ontruimd.
Ik heb dit de C4 toegewezen (d.w.z. Opmerking 48). Alvorens de kanalen in de code die ik had C64 leiden tot dit gedrag aan de linkerzijde van de schets en C5 gebruikt om te activeren het aan de rechterkant (waar het zou worden uitgevoerd in omgekeerde richting, vanaf raster locatie 15). Maar ik was niet gelukkig met dit gebruik van octaven. Besluit toe te voegen kanalen ik gemaakt een ander MIDI-trigger instrument in Renoise en stel deze in op de output op kanaal 2. Op deze manier mij konden troep opwaarts elke noot toewijzen aan sommige specifieke gedrag, met het kanaal bepalen aan welke kant van het scherm lijkt.
Dit soort beslissingen te organiseren zijn nogal subjectief. Dit werkt voor mij (zo ver; misschien na meer gebruik die ik zullen er uit sommige andere regeling). Het punt is dat er geen één echte manier hiervoor; een aanpak die werkt voor u vinden.
Hier is hoe de onNote48 eindigde na die wijziging:
void onNote48(int vel, int channel, String bus_name) { if (vel > 0) { switch(channel) { case 1: addToGridL4x4(); break; case 2: addToGridR4x4(); break; } } }
addToGridL4x4() is dit:
void addToGridL4x4() { if (gridL4x4Pointer < 0) { renderL.clear(); gridL4x4Pointer = 15; } renderL.add(new RenderArgs( nextTint(), gifs[nextGifIndex()], 4, 4, gridL4x4Pointer) ); gridL4x4Pointer--; }
De algemene regeling is het gebruik van een variabele voor het bijhouden van een index in een raster, bijwerken van de index, en ervoor zorgen dat het altijd een geldige waarde heeft.
Op een gegeven moment de globale variabelen nodig om weg te gaan en dit alles verpakt in een klasse, maar de losse veranderlijkheid leent zich voor interessante gedrag.