Scripting bearbetning med MIDI (7 / 11 steg)
Steg 8: Vad är den kanalen?
Eftersom Rita inte göra mycket verkliga åtgärder måste vara fallet på andra håll. Det är faktiskt de Obs-hantering metoder som driver vad som syns. När ett MIDI-meddelande kommer i blir det sänds till en matchande Obs handler om det finns någon. Jag bestämde mig för att kunna generera några mönster, till exempel att fylla upp ett 4 x 4 rutnät med bilder Obs-av-note. Jag skrev en Obs-hanterare som gjorde detta för till vänster i fönstret skiss, och trodde det skulle vara trevligt att göra samma sak på höger sida men spegelvänd.
Vid första gjorde jag detta med hjälp av två olika Obs hanterare, tänkte jag skulle använda en oktav för saker att hända på vänster sida, och en annan octave för rätten. Detta kändes tafatt. Varför inte engagera kanaler?
Midibussar ger några extra händelsehanterare, inklusive noteOn, som, om du definierar den, blir kallade när alla enheter får en anteckning-på meddelandet. Denna metod ger dig kanalen, notvärde och hastigheten. Men ger det inte du Midi-bussen som fått det namnet.
På denna punkt i utvecklingen jag har inte en tydlig plan för att använda buss namnet men några idéer formning och jag ville inte släppa möjlighet att använda den. Men jag ville ha kanalen, alltför.
midiMessage kallas med vissa specifika data som räckte precis till dig (såsom buss namnet) men själva meddelandet är något kryptiskt. Du kanske har märkt det finns några intressanta matte ska få värdet Obs och hastighet.
int Obs = (int)(message.getMessage() [1] & 0xFF);
MIDI-meddelanden är ganska kompakt. Det skickas som en serie av byte. Jag kommer att hoppa över de tekniska detaljerna utan att få användbara värdet av dessa byte i Java måste du greppa ett underavsnitt av dem och sedan tillämpa en "mask". Denna mask tvingar någon del av värdet som antar ett visst värde vilket ger oss ett användbart resultat.
Koden gör detta för att få värdet Obs och hastighet. De samma tillvägagångssätt kan användas för att få kanalen. midiMessage blir då detta:
void midiMessage (MidiMessage meddelande, lång tidsstämpel, sträng bus_name) {
int kanal = (int)(message.getMessage() [0] & 0x0F) + 1;
int Obs = (int)(message.getMessage() [1] & 0xFF);
int vel = (int)(message.getMessage() [2] & 0xFF);
invokeNoteHandler (Obs, vel, kanal, bus_name);
}
invokeNoteHandler måste nu göra en metod look-up med tre argument:
void invokeNoteHandler (int Obs, int hastighet, int kanal, sträng bus_name) {
försök {
Undergrupp [] cls = ny klass [3].
CLS [0] = int.class;
CLS [1] = int.class;
CLS [2] = String.class;
Metoden handler = this.getClass () .getMethod ("onNote" + note, cls);
handler.Invoke (denna, hastighet, kanal, bus_name);
} fånga (undantag e) {
println ("* ***** fel hantering OBS" + OBS + "******");
e.printStackTrace(); }
}
Med både kanal och buss tillgängliga varje not handler kan beteende olika sätt beroende på källan till anteckningen. I vissa fall gör detta det lättare att organisera anteckningar avreseorten. Till exempel, skapade jag en metod som skulle fortsätta att lägga till en bild till 4 x 4 rutnät, spåra ett rutnät index. Om indexet gick out of bounds (det vill säga under 0 eller över 15, beroende på vilken riktning används för att fylla i rutnätet) nätet skulle rensas.
Jag har tilldelat detta C4 (dvs not 48). Framför bringande kanaler in i koden jag hade C64 utlösa problemet på vänster sida av skiss och C5 används för att utlösa den till höger (där det skulle köras i omvänt, start från rutnätet plats 15). Men jag var inte nöjd med denna användning av oktaver. Man beslutar att lägga till kanaler jag skapat en annan MIDI-trigger instrument i Renoise och sätta den till utgången på kanal 2. Detta sätt jag kunde ställa upp varje not att mappa till vissa specifika beteenden, med kanal bestämma på vilken sida av skärmen verkar.
Dessa typer av organisera beslut är helt subjektiva. Detta fungerar för mig (så långt, kanske efter mer gång jag ska träna några andra system). Poängen är att det finns ingen sann väg att göra detta; hitta en metod som fungerar för dig.
Här är hur onNote48 hamnade efter förändringen:
void onNote48 (int vel, int kanal, sträng bus_name) {
om (vel > 0) {
Switch(Channel) {
fall 1:
addToGridL4x4();
bryta;
fall 2:
addToGridR4x4();
bryta;
}
}
}
addToGridL4x4() är denna:
void addToGridL4x4() {
om (gridL4x4Pointer < 0) {
renderL.clear();
gridL4x4Pointer = 15.
}
renderL.add (nya RenderArgs (nextTint(), gifs[nextGifIndex()], 4, 4, gridL4x4Pointer));
gridL4x4Pointer--;
}
Det allmänna stödprogrammet är användningen av en variabel för att spåra ett index i ett rutnät, uppdatera indexet, och att se till att det alltid har ett giltigt värde.
Någon gång de globala variablerna måste gå bort och allt detta insvept i en klass, men den lös föränderlighet lämpar sig för intressant beteende.