MIDI Format: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung |
Keine Bearbeitungszusammenfassung |
||
Zeile 11: | Zeile 11: | ||
*5 unused | *5 unused | ||
==Midi Modes== | |||
Omni - Alles wird gespielt, was kommt auf allen Kanälen (macht idR wenig Sinn) | |||
Poly - auf einem Kanal wird empfangen und gespielt, polyphon | |||
Mono - wie Poly, jedoch Monophon, erlaubt zuordnung anderer Kanäle zu weiteren Stimmen ([[Multitimbral]]) | |||
Multi - Heute üblich, erlaubt empfang auf unterschiedlichen Kanälen, poly/mono und steuert unabhängige Stimmen im Klangerzeuger ([[Multitimbral]]) | |||
==MIDI Infotext (deutsch)== | ==MIDI Infotext (deutsch)== |
Version vom 29. Januar 2007, 21:01 Uhr
Musical Instrument digital Interface (=MIDI)
5 pin DIN jacks used (one way) to control notes, parameters in musical instruments and the so called MIDI-Clock for synchronizing Sequencers and Drummachines or even LFOs to the main clock of a MIDI Master Clock.
the MIDI 5pin plug - MIDI 5 Pol DIN Stecker
- 1 unused
- 2 signal
- 3 ground
- 4 signal b
- 5 unused
Midi Modes
Omni - Alles wird gespielt, was kommt auf allen Kanälen (macht idR wenig Sinn) Poly - auf einem Kanal wird empfangen und gespielt, polyphon Mono - wie Poly, jedoch Monophon, erlaubt zuordnung anderer Kanäle zu weiteren Stimmen (Multitimbral) Multi - Heute üblich, erlaubt empfang auf unterschiedlichen Kanälen, poly/mono und steuert unabhängige Stimmen im Klangerzeuger (Multitimbral)
MIDI Infotext (deutsch)
Um gerüchte aus der welt zu schaffen: midi hat 16 kanäle, ja, aber SysEx daten werden immer ohne kanal gesendet also pro "MIDIkabel" gibtes dann die möglichkeit SysEx zu schicken welches ALLE angeschlossenen Geräte empfangen..meist wenn was bei einem dump nicht klappt ist es die DEVICE ID die nicht auf 0 gestellt ist. das format sieht ansich so aus: MIDI-Format siehe weiter unten.
was midi macht? es sendet midibefehle note (taste gedrückt) und anschlagstärke (Velocity), dann 128 verschiedene sgnt controller, also knöpfe bei synthesizern die parameter steuern..., aftertouch und SysEx, das sind komplette "dumps" also datenpakete, die komplette speicherinhalte von synthies beinhalten.. der neue midi2 standard wird auf netzwerktechnik basieren und wird vom IEEE zusammengestellt. IEEE P1639 (IEEE 802.11 based) features: 16mio devices, hoffentlich auch mehr controller und auflösung..10 gigabit pro sekunde statt 31.2 kBaud (kbit/sec) info generell: the MIDI Manufacturers Association www.midi.org. letzlich wird aber bisher MIDI2 nicht eingesetzt.. zzt werden eher USB/USB2 lösungen verwendet, die das midiprotokoll auf diesen schnittstellen in einem midiprotokoll nutzen.. zB remote keyboards und co. hier wird sicher in zukunft noch einiges passieren. bis dahin wird der standard mit der 5poligen DIN buchse noch einige zeit bleiben..
MIDI info [1]
MIDI Org [2]
-> Midi Controller + NRPN (Controller)
-> General Midi
-> SysEx
TECHNICAL MIDI FORMAT http://www.sequencer.de/specials/midi.html
MIDI wurde in den frühen 1980er-Jahren erfunden und ist bis heute unverändert, was die Flexibilität des Protokolls deutlich macht. Es werden immer wieder Erweiterungen im Protokoll vorgenommen, weil die Urform diese Erweiterungsmöglichkeiten bereits vorgesehen hat. Die physikalische Datenübertragung soll hier nicht im Detail behandelt werden, es geht hier nur um alle Einzelheiten der Daten, die übertragen werden, die MIDI-Messages. Beim Lesen dieses Artikels ist es von Vorteil, fundiertes Wissen über Bits und Bytes zu haben, da hier viel mit binären und hexadezimalen Zahlen gearbeitet wird, und auch direkt Bits angeschaut werden.
MIDI ist eine serielle Schnittstelle, über die 8bit-Bytes übertragen werden können. Dabei hat das oberste Bit auch schon eine besondere Bedeutung.
Statusbytes und Datenbytes
Ist das oberste Bit des übertragenen Bytes gesetzt, also der Wert >= 128, so handelt es sich um ein Statusbyte. Das Statusbyte kann als Kommando angesehen werden, es dient der Entscheidung, was mit den nachfolgenden Datenbytes genau geschehen soll. Da bei den Datenbytes das oberste Bit nicht gesetzt sein darf, weil es sich sonst um ein Statusbyte handeln würde, schränkt dies den Wertebereich für Datenbytes auf die bekannten 7 Bits ein, einem Wertebereich von 0 bis 127. Um dennoch größere Werte übertragen zu können, gibt es viele verschiedene Methoden, die insbesondere im Abschnitt über die System Exclusive (SysEx) Meldungen beschrieben werden.
Aufgrund dieser strikten Trennung zwischen Statusbytes und Datenbytes gibt es noch ein Feature namens "Running Status", welches die Datenübertragung optimieren soll. So ist es bei vielen Statusbytes nicht zwingend erforderlich, für jede Message das gleiche Statusbyte nochmals zu senden, es werden nur noch die Daten geschickt. Kommt also ein Note-On-Event, wird das Statusbyte nebst den beiden zugehörigen Datenbytes geschickt. Folgen diesem Note-On-Event noch weitere Note-On-Events auf dem selben Kanal, ändert sich das Statusbyte also nicht, wird es nicht nochmals mitgeschickt, sondern in der nächsten Message werden nur die beiden Datenbytes geschickt, der Empfänger weiss dann, dass das zuletzt empfangene Statusbyte zur Bildung der Message verwendet werden soll. Einige Statusbytes müssen jedoch jedes Mal übertragen werden, und einige davon brechen auch einen Running Status ab, während es andere nicht tun. Dies wird im Detail im nächsten Abschnitt beschrieben. Um Running Status noch weiter zu optimieren, gibt es noch einen Sonderfall beim Note-On-Event. Da ein Note-Off-Event einen neuen Status erforderlich machen würde, was nicht unbedingt gewünscht ist, kann statt dem Note-Off-Event auch ein Note-On-Event mit Velocity 0 geschickt werden, was der Empfänger als Note-Off-Event interpretieren sollte. Bei diesem Vorgehen ist es natürlich nicht möglich, eine Release-Velocity mitzuschicken.
Running Status stelle ein Problem für einige frühe MIDI-Geräte dar, der Elka Synthex ist z.B. nicht ohne weiteres fähig, damit umzugehen. Wenn man mit einem modernen Keyboard einfach eine Taste anschlägt und wieder loslässt, wird hier der Status für Note-On nebst den Notendaten geschickt, beim Loslassen wird der Note-On mit Velocity 0 geschickt. Der Synthex interpretiert das fälschlicherweise als weiteres Note-On-Event und schaltet den Ton nicht ab.
Die Definition sieht keinen Timeout für Running Status vor, die meisten Geräte schalten jedoch den Running Status nach einer gewissen Zeit selber wieder ab, wenn also z.B. 3 Sekunden nichts übertragen wird, "vergisst" der Sender das letzte Statusbyte und die nächste Message ist wieder eine vollständige Message. Dies hat den Sinn, falls der Sender zwischendurch mal nicht "zuhört", weil er vielleicht aus- und wieder eingeschaltet wurde, und damit den Status selber vergisst. Kommen nun nur Datenbytes, weiss er damit nichts anzufangen, daher wird nach einer gewissen Inaktivität der Status auf jeden Fall wieder neu gesendet.
Die verschiedenen Statusbytes
Hier werden nun die möglichen Statusbytes und ihre genaue Funktion erläutert, auch ihre Auswirkung auf den Running Status wird mit erwähnt. Bei den meisten Statusbytes kann man schon aufgrund der Bits eine detailierte Vorentscheidung vornehmen, um welche Art von Message es sich handelt. Schauen wir einmal die Bits genauer an:
1 s s s c c c c
Das oberste Bit ist bei einer Statusmeldung immer gesetzt. Die nachfolgenden 3 Bits geben nun Auskunft über den Status selber, und wenn diese im Bereich 0 bis 6 liegen, sind die unteren 4 Bits der MIDI-Kanal. Der Mensch beginnt üblicherweise das Zählen bei 1, daher gibt es nach außen hin MIDI-Kanäle 1 bis 16. Intern wird dies jedoch, da der Computer bei 0 beginnt, mit 0 bis 15 abgebildet, so kommt man mit den vorhandenen 4 Bits für den Kanal aus. Dies gilt bei einem Status von 0 bis 6, also einem Statusbyte von 0x80 bis 0xef. Meldungen mit diesen Statusbytes werden "Voice Messages" genannt, weil sie alle einen direkten Zusammenhang mit dem von der Voice zu erzeugenden Ton haben. Voice Messages sind generell fähig, Running Status zu verwenden. Running Status funktioniert nur, wenn der MIDI-Kanal zwischen den Messages gleich bleibt. Für Running Status ist das Statusbyte als ganzes zu sehen. Kommen also 5 Note-On-Events, 3 davon auf Kanal 1 und 2 davon auf Kanal 2, so muß bei diesem Kanalwechsel auf jeden Fall ein neues Statusbyte mitgeschickt werden, weil sonst die letzten beiden Messages ebenfalls Kanal 1 zugeordnet werden. Ab dann gilt Note-On auf Kanal 2 als gespeichert, wenn nun Noten auf Kanal 1 eingeschaltet werden sollen, muss entsprechend wieder ein neues Statusbyte geschickt werden.
Bei Meldungen, wo alle s-Bits ebenfalls 1 sind, also bei Statusbytes >= 0xf0, gilt der Kanal nicht mehr. Hier kann aber wieder mit einer Bitmaske zur weiteren Entscheidung gearbeitet werden:
1 1 1 1 r s s s
Alle Statusbytes sind >= 0xf0, also sind die oberen 4 Bits alle 1. Das Bit 3 hat hier nun eine weitere Entscheidungsrolle. Ist es 0, also das Statusbyte zwischen 0xf0 und 0xf7, handelt es sich um eine sogenannte System Common Message, diese Kategorie vereint Nachrichten, die üblicherweise Datenbytes als Parameter benötigen, also nach dem Statusbyte meistens noch Datenbytes folgen werden. Natürlich gibt es hier auch Ausnahmen, wie wir später sehen werden. System Common Messages sind nicht fähig, Running Status zu benutzen, darüber hinaus brechen sie einen Running Status sogar ab. Wird also nach einem Note-On eine SysEx-Meldung geschickt, die aus den Status-Bytes 0xf0 und 0xf7 und dazwischen liegenden Datenbytes besteht, muss der Empfänger seinen Status löschen und der Sender muss bei der nächsten Voice Message auf jeden Fall wieder ein Statusbyte mitschicken. Datenbytes, die nach einer abgeschlossenen System Common Message folgen, müssen vom Empfänger ignoriert werden, weil es hierzu keinen Status gibt.
Ist das r-Bit gesetzt, also Statusbytes zwischen 0xf8 und 0xff, handelt es sich um System Realtime Messages. Diese können jederzeit in die Übertragung eingeschoben werden, ohne eine eventuell laufende Nachricht zu beeinträchtigen. So kann z.B. ein Note-On Status übertragen werden, dann das erste Datenbyte für Note-on, jetzt eine System Realtime Message, z.B. MIDI-Clock, und dann das zweite Datenbyte für Note-On, beide Messages werden vom Empfänger vollständig und korrekt erkannt, und der Running Status nach dieser Übertragung steht auf "Note On", da System Realtime Messages keinerlei Einfluss auf Running Status haben, und natürlich auch selber keinen Running Status nutzen können.
Eine System Realtime Message kann auch während einer System Common Message auftreten, dies wird wohl am Häufigsten bei SysEx-Messages der Fall sein, da diese möglicherweise relativ lange zum Übertragen brauchen, aber ein MIDI-Clock (0xf8) sofort durchkommen muss, da diese Message eben in Echtzeit (realtime) behandelt werden muss. Nach dieser Realtime-Message wird die Übertragung der SysEx-Message ganz normal fortgeführt.
Nun zu den einzelnen Message-Typen
0x80 - Note Off
Wie oben beschrieben, besteht das Note-Off-Event nicht nur aus dem Byte 0x80, sondern aus dem Bereich 0x80 bis 0x8f, weil in den unteren 4 Bits der MIDI-Kanal codiert ist. Dies trifft für alle weiteren Voice Messages zu und wird daher nicht bei jeder Message neu erwähnt.
Das Note-Off Event kennt 2 Datenbytes als Parameter. Das erste ist die Notennummer von 0 bis 127, das zweite die Geschwindigkeit, in der die Taste losgelassen wird, auch Release Velocity genannt, ebenfalls im Wertebereich von 0 bis 127.
Note-Off teilt dem Empfänger mit, dass der Ton mit der angegebenen Note gestoppt werden soll. Im Prinzip ein "Gate Off", die Release-Phase der Hüllkurve setzt ein. Einzige Ausnahme von der sofortigen Behandlung des Note-Off Events ist die Verwendung eines Sustain Pedals. Ist dieses eingeschaltet, soll sich der Empfänger nur dieses Note-Off-Event an einem geeigneten Ort aufbewahren, bis das Sustain Pedal abgeschaltet wird, erst dann wird auch der Ton abgeschaltet. Dieses Verhalten ist aber vom Empfänger abhängig, und möglicherweise auch auf Patch-Ebene steuerbar, so macht es bei einem Klavierpatch sicherlich sinn, das Sustain-Pedal zu nutzen, bei einer Bassdrum aber eher nicht.
0x90 - Note On
Das Gegenstück zu Note Off, hier wird dem Empfänger mitgeteilt, dass ein Ton zu spielen ist, also Gate eingeschaltet wird und ein Trigger abgesetzt wird. Als Parameter werden auch hier 2 Datenbytes übertragen - die Notennummer und die Anschlagsstärke, auch Velocity genannt. Wie üblich sind beide Datenbytes im Wertebereich 0 bis 127. Einen Sonderfall stellt aber die Velocity 0 dar. Wie oben bei Running Status beschrieben, stellt ein Note-On Event mit der Verlocity 0 eigentlich ein Note-Off Event dar. Entsprechend wird es dann auch als Note Off behandelt, die Logik mit dem Sustain Pedal greift auch hier, der einzige Unterschied zu einem echten Note Off ist das Fehlen der Release Velocity. Der Empfänger könnte hier einen Standardwert annehmen, sofern er überhaupt die Release Velocity auswertet.
0xa0 - Aftertouch
Dieser Nachrichtentyp ist nicht der Aftertouch, wie ihn die meisten kennen, sondern der selten zu findende polyphone Aftertouch. Diese Message hat einen Bezug zu einer gespielten Note, daher wird dieses Event direkt von der zugehörigen Taste generiert, und nicht wie beim Channel Aftertouch vom gesamten Keyboard. Entsprechend kennt diese Message 2 Datenbytes, das erste ist die Notennummer, auf die sich der neue Druck bezieht, das zweite ist der Druck, der auf die Taste ausgeübt wird, im Wertebereich von 0 (sehr leicht) bis 127 (sehr stark).
0xb0 - Control Change
Eine Control-Change-Nachricht gibt Informationen über einen Controller, dessen Wert sich geändert hat. Der Controller kann dabei so ziemlich alles sein, von einem einfachen Schalter, der nur 2 unterschiedliche Werte kennt, über ein Potentiometer als analoges Eingabegerät, ein Drehencoder als virtuell-analoges Eingabegerät, oder auch völlig obskure Geräte wie der Abstand der Hand zur Antenne bei einem Theremin-ähnlichem Eingabegerät. Bekannte Controller sind das Modwheel und die MIDI Volume, beides wird jeder schon einmal benutzt haben. Die vordefinierten Controllernummern werden später noch behandelt.
Die Nachricht beinhaltet neben dem Statusbyte auch 2 Datenbytes, das erste ist die Controllernummer, das zweite der Controllerwert, wieder beide im Bereich 0 bis 127. Negative Controllerwerte gibt es offiziell nicht, zu diesem Thema jedoch später mehr.
0xc0 - Program Change
Dient zum Umschalten des Sounds bei Synthesizern, kann aber auch anderen Funktionen zugeordnet sein, z.B. die Controllerzuordnung bei einem MIDI-Controller. Generell wird hiermit ein Stück Konfiguration ausgewählt, sei es ein Patch, ein Preset, ein Program, wie auch immer es beim jeweiligen Gerät genannt wird.
Die Message verwendet nur ein Datenbyte, die Programmnummer, wieder im Bereich 0 bis 127. Dies muss keinen echten Zusammenhang mit der auf dem Display angezeigten Patchnummer des Gerätes haben, da die Hersteller die unterschiedlichsten Formen der Datstellung verwenden. Nur sehr wenige geben ihren Patches Nummern von 0 bis 127, häufiger gesehen ist der Bereich 1 bis 128, also ist die Anzeige auf dem Display 1 höher als die eigentlich übertragene Programmnummer. Andere Hersteller arbeiten nicht direkt mit dem Dezimalsystem, sondern kennen Patches von 11 bis 88, wobei jede der beiden Ziffern nur die Werte 1 bis 8 kennt, was insgesamt 64 Kombinationsmöglichkeiten entspricht. Wird also Program 0 angesteuert, entspricht dies dem Displaywert 11, Program 1 wäre 12, Program 8 wäre 21 bis hin zu Program 63, was dem Display 88 entspricht. Damit sind nur 64 verschiedene Programme möglich, was mit den anderen 64 gemacht wird, bleibt dem Gerätehersteller überlassen, entweder werden alle Werte >= 64 einfach ignoriert, oder sie erfüllen den gleichen Zweck wie die Werte 0 bis 63, also sind im gesamten Wertebereich alle Patches doppelt vorhanden, oder es kann damit zusätzlich noch eine Bank umgeschaltet werden, womit das Display vielleicht von A11 bis B88 geht, wobei A11-A88 die Programs 0 bis 63 sind, und B11-B88 die Programs 64 bis 127.
Wieder andere Geräte kennen die Patches 0 bis 99, hier werden dann Werte ab 100 möglicherweise ignoriert, das genaue Verhalten ist immer herstellerabhängig.
0xd0 - Channel Pressure
Hier ist nun der Aftertouch, den jeder kennt, der Channel Aftertouch, offiziell in der MIDI-Sprache auch Channel Pressure genannt. Er verhält sich an für sich wie der oben erwähnte Aftertouch, gilt jedoch nicht pro Note, sondern für die gesamte Voice, also alle zur Zeit gespielten Noten. Dadurch, daß er damit keinen Notenwert übertragen muss, verwendet er auch nur ein Datenbyte, eben den Druck aufs Keyboard im Bereich von 0 (sehr leicht) bis 127 (sehr stark).
0xe0 - Pitch Wheel
Hier kommt nun die erste Ausnahme aus der Welt der 7bit-Übertragung. Da ein Pitch Wheel eine möglichst hohe Auflösung haben sollte, ist dieser Controller als eigenständige Sonderfunktion definiert worden. Er verwendet 2 Datenbytes, die zusammen den 14bit-Wert ergeben. Dazu wird dieser 14bit-Wert in der Mitte geteilt, das erste Datenbyte stellt die Bits 6-0 dar, das zweite Datenbyte die Bits 13-7. Der Empfänger nimmt also das zweite Datenbyte, schiebt es 7 Bits nach links und heftet unten das erste Datenbyte an, um wieder einen 14bit-Wert zu bekommen.
Eine weitere Ausnahme stellt die Tatsache dar, dass das Pitch Wheel sowohl positive als auch negative Werte senden kann. Die Mittelstellung bedeutet dabei genau 0. Da negative Werte bei MIDI nicht vorgesehen wird, wird der Wert einfach von 0 bis 16383 gesendet, der Empfänger weiss aber, da es sich um das Pitch Wheel handelt, dass er von dem empfangenen Wert nochmal 8192 subtrahieren muss. Somit entsteht ein Wertebereich von -8192 bis +8191.
0xf0 - SysEx Start
Nun kommen wir von den Voice Messages zu den System Common Message, und dabei auch sofort zu dem kompliziertesten Message-Typ. System Common Messages enthalten keinen MIDI-Kanal, darum gilt für alle folgenden Messages nicht obige Regel, dass die unteren 4 Bits der MIDI-Kanal sind, sondern bei allen Messages ab hier ist das komplette Statusbyte angegeben.
SysEx ist eine der Erweiterungsmöglichkeiten des MIDI-Protokolls. Hier kann man sich eigene Messages definieren, die darüber hinaus auch keine feste Datengrösse haben, sondern beliebig viele Datenbytes verwenden können, da es einen weiteren Status zum Beenden dieser Message gibt. Es werden also alle Bytes zwischen dem Status 0xf0 und dem abschliessenden Status 0xf7 als Daten einer SysEx-Message behandelt.
Damit es keine Kollisionen durch Wildwuchs in den übertragenen Daten gibt, und Hersteller 1 eine gut gemeinte Message implementiert "Schalte Displaybeleuchtung auf rot um", während Hersteller 2 genau die gleichen Daten verwendet, um "leite Selbstzerstörung ein" zu formulieren, was zu gewissen Komplikationen im Studio-Setup führen könnte, gibt es eine zentrale Verwaltung bei der MMA, der MIDI Manufacturers Association, die jedem Hersteller eine eigene Kennung zuweist. Diese Liste kann auch jeder hier anschauen.
Entsprechend ist es quasi Gesetz, dass diese Hersteller-Nummer direkt auf den Status 0xf0 folgt, um vorab eine Selektierung nach Hersteller vorzunehmen.
Schaut man sich die Herstellernummern (die bei der MMA nicht bis in alle Ewigkeit zurück zu reichen scheint, da es noch viel mehr reservierte Herstellernummern gibt, z.B. ist in der Liste Sequential oder Moog gar nicht zu finden) genauer an, erkennt man ein einfaches Muster:
Es fing an mit den Erfindern von MIDI, Sequential Circuits. Sie haben die Herstellernummer 1. Ab hier zählt es aufwärts, bis 0x18, EMU. Dann kommt 0x20, Bon Tempi, ein europäischer Hersteller, bis hin zu Waldorf, 0x3e, ebenfalls europäisch. Ab 0x40 wirds japanisch - Kawai hat diese ID, wie man auch bei der MMA nachlesen kann. Also sind die Hersteller-IDs an glatten Bereichsgrenzen (wenn man es hexadezimal liest) in Regionen unterteilt. Da zu erwarten war, dass 32 Hersteller pro Region knapp werden könnte, wenn die Verbreitung Computergesteuerter Musikinstrumente zunimmt, wurde ein Sonderfall eingeführt - ist das erste Byte nach dem Status 0xf0 ein 0x00, so handelt es sich um eine lange Hersteller-ID, die direkt auf die 0x00 folgt. Damit wurden zu dem Bereich der bisherigen 127 Hersteller nochmal weitere 16384 Hersteller oben drauf gelegt. Bei dieser langen Hersteller-ID erkennt man aber auch wieder das klassische Schema, 0x00 und 0x01 sind USA, 0x20 ist Europa, und ein Vertreter aus dem japanischen Raum mit langer Hersteller-ID ist auch als Beweis vorhanden - 0x40 ist wieder die japanische Region.
Nach diesem Abschweifen in die Zahlenspiele, die nur verdeutlichen sollen, dass Herstellernummern > 0 mit diesem einen Byte abgeschlossen sind, bei der Herstellernummer 0 aber nochmal 2 Bytes für die lange Herstellernummer folgen, geht es nun weiter.
Bisher haben wir also 0xf0 und die Herstellernummer, entweder in einem oder in 3 Bytes. Was nun danach kommt, bleibt voll und ganz dem Hersteller überlassen, er darf hier tun und lassen, was er will, sollte aber natürlich schon beim ersten Gerät sicher stellen, daß er auch noch ein zweites Gerät auf den Markt bringen kann, ohne Probleme mit seinen Messages vom ersten Gerät zu bekommen. Daher ist in den folgenden Bytes üblicherweise noch eine vom Hersteller vergebene Modellnummer vorhanden, diese kann ein Byte sein, wenn der Hersteller in seiner gesamten Existenz nur 128 verschiedene Geräte bauen möchte, oder auch 2 Bytes, wenn er mehr einplant. Natürlich kann er auch einen Wert als Sonderfunktion frei lassen, um später mal auf lange Modellnummern zu wechseln, wie es die MMA bei den Herstellernummer getan hat. Es gibt hier keine feste Definition.
Ausserdem ist möglicherweise noch eine weitere ID vorhanden, eine Gerätenummer. Diese sagt nichts über den Gerätetyp aus, sondern stellt eine weitere Identifikation dar, da es durchaus vorkommen kann, dass in einem Setup mehrere identische Geräte eines Herstellers vorhanden sind. Damit nicht alle diese Geräte gleichzeitig auf die Message reagieren, was in vielen Fällen unpraktisch sein könnte, gibt es noch die Geräte-ID. Diese ist in etwa zu vergleichen mit dem MIDI-Kanal, aber auch hier gibt es keine feste Definition, es hat sich aber eingebürgert, nur die Werte 0 bis 126 für Geräte-IDs zu verwenden, und die 127 als Spezial-ID für "an alle". Dadurch kann man sich z.B. 127 identische Soundmodule ins Rack (bzw. die Racks) packen, alle an einem MIDI-Kabel laufen lassen (unrealistisch, es geht um die Theorie :), und jedem Gerät aufgrund seiner ID gezielt seine ganz persönliche Konfiguration zuschieben, aber z.B. ein Firmware-Update auf Geräte-ID 127 loszuschicken, womit alle Geräte gleichzeitig ihr Firmware-Update durchziehen.
Übrigens gibt es auch spezielle Herstellernummern für Hobbyzwecke und Entwicklung. Der Hersteller 0x7d ist für Eigenbauten zu empfehlen, die aber niemals das eigene Setup verlassen sollten. Sobald etwas auf den Markt kommen soll, ist es notwendig, sich bei der MMA eine eigene Herstellernummer registrieren zu lassen.
Darüber hinaus gibt es noch 2 Hersteller-IDs für Sonderfälle, also Erweiterungen des MIDI-Standards, die herstellerunabhängig sind und ihrerseits auch wieder in separaten Standards festgeschrieben sind. Hierzu gibt es die Hersteller-IDs 0x7e und 0x7f. Bei diesen Hersteller-IDs ist es auch fest definiert, dass als nöchstes Byte die Geräte-ID kommt. Da es keine Modell-ID geben wird, weil die Messages ja herstellerunabhängig und damit auch geräteunabhängig sind, reicht diese Geräte-ID, quasi der Kanal, auch aus, um gezielt bis zu 127 Geräte zu adressieren. 127? Ja, nicht 128, weil die 127, wie oben schon beschrieben, bedeutet, daß das Gerät auf jeden Fall auf diese Message hören soll, unabhängig von der konfigurierten Geräte-ID.
Zu den Einsatzfällen dieser IDs gehören die GM-Spezifikation, der Sample Dump Standard und einige weitere nützliche Helferlein, die dem Musiker, der mit der ganzen EDV so wenig wie möglich zu tun haben möchte, das Leben etwas einfacher machen. Stichwort "Scanne MIDI-Bus" - hierfür gibt es einen Identity Request. Allerdings ist der bei vielen Geräten, vor allem älteren Modellen, nicht implementiert, weshalb hier auch gerne andere Mechanismen verwendet werden.
So haben wir also nun ausgiebig das Thema SysEx-Message behandelt, ohne wirklich sehr viel darüber zu wissen. Schauen wir die Erkenntnisse einmal kurz anhand einer Message an:
f0 00 20 32 15 01 20 00 00 24 72 65 76 20 52 31 f7 | | | | | | | --------------------------- | | | | | | | | | + Ende der SysEx-Message | | | | | | | + Daten | | | | | | + Kommando ans Gerät "Konfigurationsdaten" | | | | | + Geräte-ID 1 | | | | + Modell - BCR2000 | | +--+ Hersteller - Behringer | + Verwende lange Hersteller-ID + Start der SysEx-Message
Dies sollte alle beschriebenen Sachverhalte an SysEx-Messages ausreichend verdeutlichen. Das grössere Thema Datencodierung wird später noch im Detail behandelt.
0xf1 - MTC Quarter Frame
Diese Message gehört in die Kategorie der MTC-Messages, die später beschrieben werden. Ihr folgt ein Datenbyte, welches den Time Code darstellt.
0xf2 - Song Position Pointer
Für MIDI-File-Player oder Sequencer steuert dieses Kommando die Position im Song. Der Wert wird dabei in 2 Datenbytes übertragen, die sich wie beim Pitch Wheel zu einem 14bit-Wert zusammen setzen. Die Einheit des Wertes sind MIDI Beats, die 1/16tel-Noten entsprechen.
0xf3 - Song Select
Dies ist vergleichbar mit dem Program Change, dient aber der Auswahl des Songs bei einem MIDI-File-Player oder Sequencer. Dem Status folgt ein Datenbyte, welches die Songnummer im Bereich 0 bis 127 angibt.
0xf4 - undefiniert
Dieses Status-Byte ist nicht definiert. Einige Hersteller verwenden die nicht definierten Message-Typen für eigene Funktionen, bei denen es nicht erwünscht ist, große Datenmengen wie bei SysEx zu übertragen. Insbesondere, wenn diese Statusbytes für interne Kommunikation, z.B. zwischen einem MIDI-Interface und einem Rechner verwendet werden, und nicht an externe MIDI-Geräte geschickt werden, spricht nichts gegen eine solche Verwendung. Ansonsten sind die Reaktionen auf diesen Status undefiniert und daher sollte dieser Status auch nicht in der freien Wildbahn auftauchen. Da die Funktion dieses Status undefiniert ist, gibt es auch keine Aussage, wie viele Datenbytes dahinter folgen dürfen. Da aber dieses Statusbyte offiziell sowieso niemals auftauchen wird, weil es ja undefiniert ist, ist dieser Informationsmangel auch zu vernachlässigen. Bei Empfang eines undefinierten Statusbytes kann aber auch nichts passieren, das Gerät sollte diesen Status ignorieren, ausserdem wird dadurch der Running Status zurück gesetzt, womit es gleichgültig ist, wie viele Datenbytes auf diesen Status folgen - für den Empfänger ist es ein undefinierter Status, also werden alle Datenbytes ignoriert, bis wieder ein gültiger Status kommt.
0xf5 - undefiniert
Siehe 0xf4
0xf6 - Tune Request
Es gibt in der Tat ein dediziertes Kommando, welches einen Synthesizer dazu veranlassen sollte, seine automatische Stimmfunktion zu starten. Wie viele Geräte dieses Feature wirklich implementiert haben, ist ungewiss, es ist auch keine Funktion, die bei den üblichen MIDI-Tools in Form eines deutlich sichtbaren "TUNE!"-Buttons sofort aufzufinden ist. Dennoch kann man sie natürlich mal an seinen Gerätepark schicken und schauen, ob das eine oder andere Gerät drauf reagiert. Ein Datenbyte benötigt dieser Status nicht.
0xf7 - SysEx End
Dieser Status beendet eine SysEx-Übertragung, siehe auch 0xf0.
0xf8 - MIDI Clock
Hier kommt nun die erste System Realtime Message. Ab hier folgen nur noch Realtime Messages, die entsprechend auch keine Datenbytes verwenden, da sie einen Running Status oder sonstige Übertragungen nicht beeinträchtigen und jederzeit "dazwischengeworfen" werden dürfen.
MIDI Clock ist eine Message, die von einem Master in regelmässigen Abständen verschickt wird. Sind mehrere Geräte zusammen geschaltet, sollte nur ein Gerät diese Messages verschicken, dieses ist dann der Master, meistens ein Sequencer. Die anderen Geräte, die Slaves, können sich anhand dieser Clock-Messages auf den Master synchronisieren. Somit sind als Slaves weitere Sequencer oder z.B. Arpeggiatoren einsetzbar. Damit das unter den Herstellern auch problemlos funktioniert, ist fest definiert, welchen Zeitabstand der Clock zu bedeuten hat. Pro Viertelnote gibt es exakt 24 Clocks. Das bedeutet, 6 Clocks sind eine 1/16tel-Note, 96 Clocks ein kompletter Takt.
0xf9 - MIDI Tick
Ähnlich wie beim MIDI Clock dient diese Message der Synchronisation. Entgegen dem MIDI Clock ist sie jedoch nicht abhängig von einer Geschwindigkeit, die an einem Sequencer eingestellt wurde, steht damit nicht in Relation zu Notenlängen, sondern ihre Zeitbasis ist einfach die Zeit. Ein MIDI Tick wird alle 10ms geschickt, sofern ein Sender diese Message überhaupt schickt. MIDI Tick wird in Verbindung mit MIDI File Playern zusammen mit den Messages Song Position Pointer und einigen nachstehenden Messages zur Synchronisation verwendet.
0xfa - MIDI Start
Für MIDI-File-Player oder Sequencer bedeutet dieses Event "Fange bei Song Position 0 an, abzuspielen".
0xfb - MIDI Continue
Startet ebenfalls die Wiedergabe eines Songs oder einer Sequenz, aber nicht an der Position 0, sondern an der aktuellen Position, die vorher möglicherweise durch Song Position Pointer gesetzt wurde.
0xfc - MIDI Stop
Stoppt die Wiedergabe des Songs oder der Sequenz.
0xfd - undefiniert
Wie 0xf4 und 0xf5 ist dieser Status nicht definiert und taucht daher üblicherweise auch nirgendwo auf. Da er sich aber unter den System Realtime Messages tummelt, kann sicher gesagt werden, dass er keine Datenbytes verwendet, falls er doch einmal irgendwo auftauchen sollte.
0xfe - Active Sense
Ein gerne gehasstes Feature von MIDI, was eigentlich vom Gedanken her gar nicht so unsinnig ist. Nicht viele Geräte übertragen diese Message, sie wird auch gerne als Busblockade angesehen. Dabei handelt es sich nur um ein einzelnes Byte, welches auch eher selten übertragen wird, und daher schon eine nicht unerhebliche Anzahl Geräte notwendig sind, die alle parallel auf das gleiche Kabel ballern, um eben dieses Kabel dicht zu machen. Active Sense wird, wenn überhaupt, mindestens einmal innerhalb von 300ms gesendet, wenn innerhalb dieser Zeit keine anderen Daten gesendet wurde. Der Status dient also der Erkennung der Anwesenheit eines Gerätes. Man stelle sich folgendes einfaches Szenario vor:
Ein Masterkeyboard ist via MIDI an einen Klangerzeuger angeschlossen. Und das schon ausreichend lange, dass man da auch öfter mal Staub gewischt hat, und sich vielleicht der Stecker am MIDI-Out am Keyboard langsam etwas gelockert hat. Nun spielt man so eifrig vor sich hin, der Stecker wird ordentlich erschüttert (Nahaufnahme, wie in den Filmen, wo der Zuschauer schon weiss, dass gleich was passiert, aber das Opfer noch nicht), und wenn man gerade mit sämtlichen 10 Fingern mal so richtig in die Tasten haut, fliegt, natürlich nach ordnungsgemässer Übertragung aller 10 Note-On-Events, der Stecker endgültig raus. Ohne Running Status darf man nun in einer möglicherweise nicht unerheblichen Geräuschkulisse erstmal den Stecker wieder suchen, weil das Abschalten des Klangerzeugers vielleicht den Edit Buffer in den Tod reisst, in dem man sich gerade aufwändig einen tollen Sound gebaut hat. Also gut, Lautstärke runter drehen, Stecker suchen und wieder einstecken. Danach Lautstärke wieder rauf, alle Töne, die gerade gespielt werden, nochmal anschlagen, und hoffen, dass der Note-Off, der aus dem Loslassen resultiert, auch wirklich die Töne im Klangerzeuger wieder abschaltet. Es gibt nämlich auch Geräte, die den gleichen Ton mehrmals spielen können und für jeden Note-On eines Tones auch einen Note-Off haben wollen, bis wieder ruhe ist.
Bleibt also noch der Controller "All Notes Off", zu dem wir später kommen.
So, und die Moral von der Geschicht - Mit Active Sense wär das nicht passiert. Ausgehend davon, dass alles von den Herstellern richtig implementiert wurde, hätte der Klangerzeuger nämlich gemerkt, dass er Active Sense Messages bekommt, und wenn er eine gesehen hat, kann er auch davon ausgehen, dass weitere kommen werden. Also schaltet er seinen Sicherheitsmechanismus ein. Dieser ist einfach ein Countdown. Wenn innerhalb einer Sekunde keine Daten empfangen werden, schaltet er alle spielenden Noten aus. Da in den Ruhephasen, wo es keine Daten zu übertragen gibt, nach spätestens 300ms ein Active Sense kommt, ist gewährleistet, dass die Sekunde nicht ohne Daten verstreichen wird. Fällt dann doch der Stecker raus, kommt der Active Sense auch nicht mehr an - das Gerät kann die Noten abschalten.
Wenn ein Gerät seit dem Einschalten keine einzige Active Sense Message empfangen hat, bleibt der Sicherheitsmechanismus natürlich deaktiviert, weil dann sein Sender keinen Running Status abschickt.
Somit ist das Mysterium um diesen scheinbar nutzlosen Message-Typ auch geklärt. Richtig eingesetzt könnte er einige Unannehmlichkeiten einschränken, die allerdings in der oben beschriebenen Form wohl auch eher selten vorkommen werden.
0xff - Reset
Der Name ist Programm - es gibt ernsthaft eine MIDI-Message, die dazu dient, das Gerät zu resetten. Und sie hat keine ID und keinen Channel, resettet also gleich alle Geräte am MIDI-Kabel (oder je nach Routing auch an mehreren Kabeln).
Dieser Status ist an für sich in der Realtime-Kategorie mehr als Fehl am Platz. Wir haben oben gelernt, dass Realtime Messages den Running Status nicht unterbrechen. Nehmen wir an, es läuft eine SysEx-Übertragung, und mitten drin, aus heitetem Himmel, kommt die Realtime-Message "Reset". Von irgendeinem Gerät, was über einen Merger mit dran hängt. Ohne Kenntnis des Senders der SysEx-Nachricht. Der Empfänger tut, wie ihm befohlen, Resettet, wodurch der Running Status natürlich verloren geht, geschweige denn von der laufenden SysEx-Übertragung, die damit auch gewaltsam beendet wurde. Sehr blöd, wenn nun der Sender der SysEx-Message auf eine Quittung des Empfängers wartet, und sich davon auch nicht durch ein Bedienelement (ausser dem Ein/Aus-Schalter) abbringen lässt.
Abgesehen von dieser etwas unsinnig erscheinenden Tatsache ist die Definition des Kommandos genau "setze das Gerät in einen Zustand zurück, der dem nach dem Einschalten entspricht".
Viele Wege, die Daten zu verpacken
Daten sind nicht immer in 7bit-Werte zu verpacken. Ein Firmware-Update verwendet z.B. ziemlich sicher 8bit-Werte, diese können sogar Teile von 16 oder 32bit-Werten sein. Vermutlich hat noch keiner etwas von einer 7bit-CPU oder einer 14bit-CPU gehört, es gibt sie dann doch eher in Ausführungen mit 8bit, 16bit, 32bit und auch 64bit, mal abgesehen von etwas aus der Mode gekommenen 4bit-CPUs und einigen Exoten der Vergangenheit mit 36bit oder ähnlich Krummen Daten.
Also müssen größere Werte sinnvoll in MIDI-Datenbytes verpackt werden, die zwangsläufig nur 7 Bit groß sind, weil das oberste Bit ja für die Unterscheidung zwischen Statusbyte und Datenbyte verwendet wird.
Nun gibt es viele verschiedene Strategien, wie diese Verpackung genau aussieht. Einige Varianten zielen dabei auf möglichst platzsparende Übertragung ab, weil die Messages entweder möglichst kurz bleiben sollen, oder ausreichend große Datenmengen übertragen werden sollen, bei denen sich Varianten, die die CPU weniger belasten, als große Verschwendung darstellen, die sich direkt auf die Dauer der Übertragung auswirkt.
Generell funktioniert also das Verpacken der Daten durch Umsortierung der Bits. Die Werte werden aufgeteilt in mehrere kleine Portionen, die alle maximal 7 Bits gross sind, und dann in mehreren Datenbytes verschickt. Wenn es dann an ganze Patches geht, wo die Breite der Werte sicherlich schwankt, kann das sogar so weit getrieben werden, dass alle Werte zusammen nur noch eine riesengrosse binäre Zahl darstellen, indem sie aneinender gehängt werden, und diese riesige Zahl in 7 Bit breite Pakete zerhackt wird.
Die gängigen Techniken werden nun in den folgenden Abschnitten beschrieben
14bit-Werte
Wie schon weiter oben beschrieben, sind 14bit-Werte relativ häufig, gerade an Stellen, wo entweder die Auflösung oder einfach der Wertebereich mit 7 Bits nicht erreicht werden kann. Hierbei fällt die Teilung relativ einfach, weil sich 14 Bits sehr schön in 2 gleiche Teile zu 7 Bits zerlegen lassen. Fangen wir ein mal mit ein wenig Binärmathematik an, ausgehend von dem Beispielwert 0x3456:
0x3456 = 0011010001010110 in Binär = 00110100 01010110 die beiden Bytes des Wertes, wie der Computer ihn verarbeitet = 00 1101000 1010110 die Aufteilung in maximal 7 Bit große Pakete
Bei der Aufteilung dieser 16bit-Zahl bekommen wir, wenn wir auf 7 Bit Paketgröße umstellen, natürlich 3 Pakete, wovon eines nur 2 Bits gross ist. Da wir die 16bit-Zahl aber nur zu 14bit nutzen, können wir die obersten beiden Bits einfach weglassen und bekommen dadurch die beiden 7bit-Pakete.
In welcher Reihenfolge diese beiden Datenbytes nun übertragen werden, bleibt der Implementierung überlassen. Fest vorgegeben ist dies bei den oben erwähnten MIDI-Messages wie Pitch Bender und Song Position Pointer, hier wird erst das niedrige Byte, also Bits 6-0, danach das höhere Byte, Bits 13-7, gesendet. Schweift man nun ab in die EDV, wird diese Reihenfolge auch als "Little Endian" bezeichnet. In genau dieser Reihenfolge speichern z.B. die Intel-CPUs in den PCs ihre Zahlen im Speicher ab. Bei 32bit-Zahlen sind es entsprechend 4 Bytes, das erste enthält die Bits 7-0, das nächste die Bits 8-15 und so weiter. Das Gegenteil dazu wäre "Big Endian", wie es z.B. von den PowerPC-CPUs der bisherigen Macs und auch der 68000er-Serie der Macs vor den bisherigen Macs verwendet wird. Damit werden vielleicht auch die Probleme deutlich, die der Umstieg von Apple auf Intel-CPUs so mit sich bringen könnte :)
Zurück zum Thema - die Reihenfolge könnte ein Hersteller genau von der Arbeitsweise seiner im Gerät eingesetzten CPU abhängig machen. Ist es für ihn vorteilhafter, erst das höhere Byte, danach das niedrigere zu erhalten, weil er mit einer Big Endian CPU arbeitet, hat er es vielleicht so definiert. Wie das Gerät die Daten erwartet, steht üblicherweise in der MIDI Implementation zum Gerät beschrieben, die aber leider nicht jeder Hersteller mitliefert.
8bit-Werte
Da ein Byte genau 8 Bits hat, kann es durchaus vorkommen, dass Daten 8 Bits verwenden. Hier gibt es 2 gängige Varianten, ein Byte mit 8 Bits in 2 Bytes mit 7 Bits zu zerlegen. Die 7:1-Variante, wobei ein Paket 7 Bits enthält, das andere 1 Bit, und die 4:4-Variante, wo die 8 Bits in 2 Nibbles, also 4bit-Werte zerlegt werden. Letztere ist kein größeres rechnerisches Problem, der Wert 0xab wird z.B. in 0xa und 0xb zerlegt, welches der beiden Datenbytes zuerst kommt, liegt in der Entscheidung des Herstellers.
Bei der 7:1-Variante wird es etwas komplizierter, weil es hierfür 2 Varianten gibt es kann ja auch 1:7 aufgeteilt werden, wonach dann noch die Reihenfolge hinzu kommt, in der die beiden Teile gesendet werden, was insgesamt 4 Möglichkeiten ergibt, dieses eine Byte zu versenden. Nimmt man die beiden Nibble-Varianten hinzu, gibt es also 6 Möglichkeiten, diese Bytes zu versenden:
0xab = 10101011 binär = 1010 1011 bei der Aufteilung in Nibbles, erst das obere, dann das untere = 1011 1010 bei der Aufteilung in Nibbles, erst das untere, dann das obere = 1 0101011 bei der 1:7 Aufteilung, erst der obere Teil, dann der untere = 1 1010101 bei der 1:7-Aufteilung, erst der untere Teil, dann der obere = 1010101 1 bei der 7:1-Aufteilung, erst der obere Teil, dann der untere = 0101011 1 bei der 7:1-Aufteilung, erst der untere Teil, dann der obere
Natürlich könnte man auch ganz abwegige Aufteilungen wie 3:5 verwenden, diese sind jedoch eher unüblich, da sie den Rechenaufwand zum zerlegen und wieder zusammensetzen der Daten unnötig vergrößern würden.
Datenblöcke mit mehreren 8bit-Werten
Hier kennt die Vielfalt der Datenverpackung nun keine Grenzen mehr. Man könnte jedes Byte wie oben bei den 8bit-Werten beschrieben, verpacken. Damit würde jedes zweite übertragene Byte aber 6 ungenutze Bits übertragen. Daher wird bei Datenblöcken üblicherweise anders gearbeitet. Gehen wir einmal von 4 Bytes aus, was z.B. einer 32bit-Zahl entspricht, nehmen wir mal 3 Milliarden, um mal wieder dezimale Zahlen zu verwenden:
3000000000 = 0xb2d05e00, oder in 4 Bytes nach Big Endian 0xb2, 0xd0, 0x5e, 0x00
Ausgehend davon, dass wir die Leitungskapazität so gut wie möglich nutzen wollen, gibt es nun 2 gängige Aufteilungen. Die eine nimmt diese komplette 32bit-Zahl und teilt sie in 7bit-Blöcke auf:
0xb2d05e00 = 10110010110100000101111000000000 = 1011001 0110100 0001011 1100000 0000
Das Resultat sind also 5 MIDI Datenbytes, die zu übertragen sind. Hierbei haben wir die Zerlegung jetzt oben angefangen, man kann sie auch unten anfangen und erhält
0xb2d05e00 = 10110010110100000101111000000000 = 1011 0010110 1000001 0111100 0000000
Wiederum können diese 5 Bytes nun vorwärts oder rückwärts geschickt werden.
Eine andere gängige Technik ist es, die Bytes zu "köpfen", also die von jedem Byte das oberste Bit abzuschneiden und all diese Bits zu sammeln. Etwa auf diese Art:
0xb2d05e00 = 10110010110100000101111000000000 = 0110010 1010000 1011110 0000000 = 0x32 0x50 0x5e 0x00 + 1 1 0 0 = 1100 = 0x0c
Wieder bekommen wir 5 Bytes heraus, die wieder in einer theoretisch beliebigen Reihenfolge übertragen werden können. Diese Codierung wird gerne für echte binäre Daten wie Firmware-Images verwendet. Dabei ist nicht zwangsweise das oberste Bit gekappt, es könnte genau so gut das unterste Bit sein, ausserdem ist die Reihenfolge der eingesammelten einzelnen Bits auch Sache der Implementierung, sie könnten auch "rückwärts" in den Korb geworfen werden, und hinzu kommt noch bei der Reihenfolge, dass die gekappten Bytes zwar meistens in einer definierten Reihenfolge, also vorwärts oder rückwärts, gesendet werden, aber das Byte mit den gekappten Bits entweder davor oder danach gesendet werden kann.
Wenn man nun etwas nachrechnet, kann man diese Komprimierung so weit treiben, dass man die Bandbreite optimal ausnutzt, wenn man mit Blöcken zu 7 Bytes arbeitet. 7 Bytes sind insgesamt 56 Bits, teilt man diese in 7bit-Werte auf, bekommt man 8 Bytes (zu 7 Bits) als Ausgabe. Damit wird kein einziges Bit verschenkt.
Gemischte Datentypen
Was häufig bei Patch-Daten vorkommt, sind viele verschiedene Werte, die auch unterschiedliche Wertebereicht haben können. So ist vielleicht ein Filter-Cutoff ein 9bit-Wert, ein VCA-Level ein 4bit-Wert, lassen wir mal die Vorzeichen noch ausser Acht, haben wir auf jeden Fall viele verschiedene Werte in den unterschiedlichsten Längen. Die einfachste Methode, diese zu verpacken, wäre die Bildung einer riesengrossen binären Zahl und deren Aufteilung in 7bit-Pakete. Also die 9 Bits mit den 4 Bits zusammen kleben, wir erhalten 13 Bits. Und diesen Wert können wir schon wieder als 14bit-Wert interpretieren und in 2 7bit-Hälften verpacken.
Oft wird hier aber auch die Sortierung der Daten mit einbezogen. Bildet man eine riesengrosse Binärzahl, muss man möglicherweise sowohl auf Sende- als auch auf Empfangsseite eine ganze Menge Bits herumschieben, damit sie an den richtigen Positionen innerhalb der Bytes oder auch 16bit- oder 32bit-Wörtern liegen. Daher kann eine trickreiche Sortierung der Daten hier auch einen gewissen Gewinn bringen. CPUs ist es oft möglich, die beiden Nibbles eines Bytes in einem Befehl zu vertauschen. Daher bietet es sich natürlich insbesondere an, 4bit-Werte zusammen mit 3bit-Werten in ein 7bit-MIDI-Datenbyte zu stecken. Und es gibt ja auch 1bit-Werte, z.B. eine Schalterfunktion wie "VCO Sync an/aus". Diese einzelnen Bits kann man dann noch in entstehende Lücken hineinstecken, da sich einzelne Bits oft auch von den CPUs sehr schnell ansteuern lassen.
Nun ist hoffentlich genug Verwirrung gestiftet, um klar zu machen, dass gemischte Daten, wie sie eben bei kompletten Patches vorkommen können, auf jeden Fall ein intensives Studium der Hersteller-Dokumentation und ein gutes Verständnis für Bits und Bytes voraussetzen, da es hier keine generellen Regeln mehr gibt.
Darstellung negativer Zahlen und Tricks für Controllerboxen
Wie schon in Bits und Bytes beschrieben, gibt es mehrere Varianten, negative Zahlen im Computer darzustellen. Und leider verwenden die Hersteller auch alle diese Möglichkeiten, insbesondere bei SysEx, wo sie nicht unbedingt Rücksicht auf andere nehmen müssen, und daher sehr nah am Format arbeiten, wie die CPU im Gerät die Daten selber verarbeitet.
Leichtes Spiel haben wir mit Controllern, die einfach einen Offset verwenden. Der Pitchbender ist solch ein Beispiel, sein 14bit-Wertebereich langt von 0 bis 16383, und um den Wert zu nutzen, zieht das Gerät einfach die Mitte, 8192, davon ab und bekommt so seine negativen und positiven Zahlen. Der Controller, der den Pitchbender sendet, zeigt aber möglicherweise 0 bis 16383 an, weil er von negativen Zahlen nichts wissen will. Das ist dann aber eher ein Schönheitsfehler.
Und genau mit solchen Schönheitsfehlern können wir auch weiter arbeiten. Was mit 14bit funktioniert, geht natürlich auch mit 7bit ganz problemlos. Ein Controller, dessen Wertebereich von 0-127 geht, kann seinen Nullpunkt ebenfalls in der Mitte haben, also bei 64. Der Controller schickt 0-127, das Gerät zieht 64 ab und bekommt den Wertebereich -64 bis 63.
Aber was, wenn das Gerät mit "echten" negativen Zahlen arbeitet? Wir wissen, dass bei vorzeichenbehafteten Zahlen im Computer immer das oberste Bit entscheidet, ob die Zahl negativ oder positiv ist. Dies ist völlig unabhängig davon, ob die Zahl nun 32, 16, 14, 7 oder 5 Bits groß ist. Ist sie vorzeichenbehaftet, ist das oberste Bit das Vorzeichen. Schauen wir also einen 7bit-Controller mit Vorzeichen einmal in binär genauer an:
-64 = 1000000 -63 = 1000001 -62 = 1000010 ... -1 = 1111111 0 = 0000000 1 = 0000001 ... 62 = 1111110 63 = 1111111
So sieht das also intern im Computer aus. Die Software weiss, dass die Zahlen vorzeichenbehaftet sind, und kann entsprechend damit arbeiten. Aber wir haben es doch sehr schwer, einen MIDI-Controller mit diesem Format zu bestücken, wenn er es nicht von sich aus unterstützt, seine Firmware also die Fähigkeit besitzt, mit negativen Zahlen umzugehen.
Da gibts aber einen relativ einfachen Trick, der zumindest mit den B-Control-Boxen von Behringer zu realisieren ist. Diesen Controllern ist es erst einmal egal, ob ein Controller 7bit oder 14bit breit ist, man konfiguriert einfach einen Wertebereich. Natürlich gilt dies nicht für die Konfiguration für Program Changes und Controller, wie man sie offiziell konfigurieren kann, hier wird auch eine solche Zahlendarstellung kaum eingesetzt, sondern es geht nur, wenn man vollen Zugriff auf die Zusammenstellung seiner MIDI-Message hat, was beim B-Control mit dem .tx-Parameter möglich ist.
Der Controller braucht einfach die Möglichkeit, auf bestimmte Bits innerhalb seines Wertes zugreifen zu können, und die Möglichkeit, die beiden Endwerte des Controllers frei zu setzen. Dann können wir nämlich einfach mit folgender Überlegung arbeiten:
Schauen wir den Wert für -64 an, er lautet binär 1000000, das ist, wenn wir es als vorzeichenlose Zahl interpretieren, einfach 64. Fein, es ist auch die kleinste Zahl, die wir benötigen, also konfigurieren wir 64 als Minimalwert für den Controller. Gehen wir nun ganz naiv an die Sache dran - die Differenz zwischen den beiden Werten, die wir übertragen wollen, ist genau 127: 63 - -64 = 127. Ohne viel zu denken, konfigurieren wir also den Maximalwert des Controllers ebenfalls mit dieser Differenz. Der Minimalwert ist 64, addieren wir 127, bekommen wir 191. Also rein damit, Maximalwert ist 191.
Jetzt moment... 191 ist ja viel zu groß, können wir über MIDI ja gar nicht übertragen, da wir nur Werte unter 128 übertragen können. Also kommt nun des Tricks zweiter Teil - wir übertragen nur die Bits 6-0, was beim B-Control z.B. mit dem Schlüsselwort val0.6 zu erreichen ist. Das oberste Bit lassen wir dabei unter den Tisch fallen, wir übertragen es überhaupt nicht. Schauen wir also nun die generierten Werte einmal genauer an:
64 = 01000000 = 0 1000000 65 = 01000001 = 0 1000001 66 = 01000010 = 0 1000010 ... 127 = 01111111 = 0 1111111 128 = 10000000 = 1 0000000 129 = 10000001 = 1 0000001 ... 190 = 11111110 = 1 1111110 191 = 11111111 = 1 1111111
Die erste Spalte sind die dezimalen Werte, die der Controller generiert und das Display vom B-Control auch anzeigt, wenn man es ihm nicht verbietet. Die zweite Spalte sind die selben Werte in binärer Darstellung. Und die dritte Spalte ist ebenfalls die binäre Darstellung, der übersicht halber ist hier aber das höchste Bit, welches wir nicht übertragen, separat gestellt. Wir übertragen nur die 7 Bits ganz rechts. Wenn wir diese Zahlen mit den Zahlen oben vergleichen, die das Gerät erwartet, erkennen wir einen 100%igen Treffer.
Der B-Control hat auch den Vorteil, dass seine Anzeige im LED-Ring grundzätzlich von Minimalwert bis Maximalwert geht, gleichgültig, in welchem Bereich diese beiden Werte liegen. Also einfach das Display abschalten, damit die störenden um 128 daneben liegenden Werte nicht angezeigt werden, der LED-Ring zeigt die richtige Position an, das Gerät empfängt die Daten so, wie es sie haben möchte, schon kann man die vorzeichenbehafteten Zahlen nach dieser Methode auch sauber übertragen.
Als kleiner Wermutstropfen bleibt aber zu sagen, dass dies nur in gewissen Wertebereichen möglich ist. Diesen Trick können wir bei 14bit-Controllern nicht anwenden, weil dazu 15bit Wertebereich am Controller notwendig wären, was aber nicht geht. Eine mögliche Konfiguration wäre noch ein 8bit-Controller, benötigt einen 9bit-Wertebereich, und wir können 8bit-Werte sauber senden und dabei das neunte Bit weglassen, die nächste Stufe wäre dann ein 12bit-Controller mit Vorzeichen, benötigt 13bit Wertebereich, und 12 Bits kann man über die Nibbles auch sauber isolieren.
Mit geschickten Konfigurationen kann man sich hier übrigens auch Sonderkonstellationen zusammen bauen. Das Beispiel für einen 5bit-Controller mit Vorzeichen wäre relativ einfach. Wertebereich -16 bis +15, -16 ist binär 10000, ohne Vorzeichen sind das 16, +15 ist binär 01111, wir nehmen unsere "Dummy-1" mit hinzu, 101111, ergibt 47, die Differenz passt, 31, aber halt. Geht so ja nicht, weil die Dummy-1 mit übertragen werden würde, weil sie mit in den zu übertragenen 7 Bits liegt. Hätten wir das Beispiel mit einer 4bit-Zahl mit Vorzeichen gestartet, hätten wir hier ein Nibble verwenden können, um nur die Bits 3-0 zu übertragen.
Leider hilft es auch nichts, die Dummy-Bits aus dem sichtbaren Bereich auszulagern, weil rein binär nach dem Wert 11111 grundsätzlich 100000 erscheinen wird, womit innerhalb des 7bit-Wertes ein Bit erscheint, was da nicht hin gehört, der Wert ist nicht 0, wie er sein sollte.
Das sollte aber niemanden daran hindern, es auszuprobieren. Wenn die Bits 6 und 5 an der Stelle, wo der 5bit-Wert mit Vorzeichen reinkommt, ungenutzt sind, und nirgends steht, dass die unbedingt 0 sein müssen, hilft ausprobieren weiter. Möglicherweise werden diese beiden Bits vom Gerät einfach ignoriert, so daß unser Trick dennoch funktionieren kann.