Touch-bedienbarer MIDI-Router für ein Hardware-Synthesizer-Rig. Er verteilt Keyboards und Sequencer auf die Klangerzeuger, hält Szenen für ein ganzes Set bereit und bringt sechs eigene Generatoren mit (Harmonizer, Phrase-Arp, drei euklidische Sequencer und eine TB-303-Acid-Maschine).
Ausgelegt auf einen 15–17-Zoll-Touchscreen im Bühnenbetrieb: rahmenloses Vollbild, große Flächen, hoher Kontrast für dunkle Umgebungen, keine Tastatur nötig.
Qt 6.11.1 · C++17 · MSVC v145 (VS 2026) · Windows x64
Fertige Pakete liegen unter Releases. Beide brauchen weder Qt noch Visual Studio auf dem Zielrechner — die Qt-Laufzeit und die komplette VC-Laufzeit inklusive UCRT sind enthalten.
| Datei | Wofür |
|---|---|
MidiRouter-Setup.exe |
Installer mit Startmenü-Einträgen für Router und Konfigurations-Editor |
MidiRouter-portable.zip |
Entpacken und starten, schreibt nur in den eigenen Ordner — für den USB-Stick am Rig |
Im Paket liegen mehrere Starter nebeneinander:
| Starter | Wirkung |
|---|---|
MidiRouter-starten.bat |
mit der eingebauten Beispiel-Konfiguration |
MidiRouter-eigene-Konfiguration.bat |
mit der configuration.xml daneben |
MidiRouter-Konfiguration-bearbeiten.bat |
öffnet genau diese Datei im Editor |
MidiRouter-Watchdog.bat |
startet nach einem Absturz automatisch neu — für die Bühne |
Autostart-einrichten.bat |
Watchdog-Start beim Windows-Login |
Ohne eigene Hardware zeigt der Router die Geräte grau: die MIDI-Ports der
configuration.xml beschreiben ein bestimmtes Rig. Was er tut, lässt sich
trotzdem ansehen — und mit dem Konfigurations-Editor auf die eigenen Geräte
umbauen.
Alle Aufnahmen bei 1920×1080; die Oberfläche rechnet sich auf jede Auflösung um, weil die Größen ausschließlich aus Stretch-Faktoren entstehen.
Synthesizer-Optionen — Bank/Preset, Oktave, Split, Anschlagkurve, die CC-Zuordnungen dieses Geräts und die sechs Generatoren:
Euklidischer Arpeggiator — alle 64 Steps dauerhaft sichtbar, nicht verwendete abgedunkelt; Parameter über +/- statt über Menüs:
Chroma-Sequencer — eine euklidische Linie pro Halbton, jede mit eigener Rate. Damit wird ein einzelner Synthesizer polyrhythmisch:
Acid-Sequencer — TB-303-Linien aus einer Grammatik statt aus Zufall, mit Slide und Accent pro Step:
Phrasen-Editor — Step-Grid über fünf Akkordstimmen und drei Oktaven,
liest und schreibt das .fas-Format von Squaredheads Nora:
Konfigurations-Editor (eigenes Programm, Maus und Tastatur) — hier die CC-Map eines Geräts, links der Baum, rechts die Vorschau des künftigen Hauptbildschirms, unten der Prüfbericht:
"C:\Program Files\Microsoft Visual Studio\18\Community\VC\Auxiliary\Build\vcvars64.bat"
msbuild MidiRouter.sln /p:Configuration=Release /p:Platform=x64 /p:QTDIR=C:\Qt\6.11.1\msvc2022_64 /mDie Solution enthält zwei Programme:
| Projekt | Ergebnis | Zweck |
|---|---|---|
MidiRouter |
MidiRouter.exe |
der Router selbst, Touch-Bedienung am Rig |
MidiRouterConfig |
MidiRouterConfig.exe |
Konfigurations-Editor für Maus + Tastatur |
MidiRouter hängt in der Solution von MidiRouterConfig ab, damit der Editor
fertig ist, bevor deploy.ps1 das Paket schnürt.
QTDIR ist im Projekt als UserMacro vorbelegt (C:\Qt\6.11.1\msvc2022_64) und
muss nur bei abweichender Installation gesetzt werden. moc, uic und rcc laufen
als explizite CustomBuild-Schritte — es wird kein Qt-VS-AddIn gebraucht.
Nach jedem Release-Build packt deploy.ps1 automatisch eine
lauffähige Distribution nach dist\MidiRouter\ (Qt-Runtime, komplette
VC-Laufzeit inkl. UCRT, Nora-Phrasen, Starter) und zippt sie. Abschalten mit
/p:RunDeploy=false.
Ist Inno Setup installiert, baut derselbe Lauf zusätzlich
dist\MidiRouter-Setup.exe aus installer.iss. Fehlt Inno Setup, wird der
Schritt übersprungen — das portable ZIP ist das vollständige Produkt, der
Installer nur bequemer. Der Installer richtet bewusst eine benutzerbezogene
Installation ein (PrivilegesRequired=lowest, also nach
%LOCALAPPDATA%\Programs): der Router legt Einstellungen, Log, Backups,
Mitschnitte und gespeicherte Pattern neben der EXE ab, was unter
Program Files stillschweigend fehlschlagen würde.
Alternativ mit qmake: qmake MidiRouter.pro && nmake.
MidiRouter.exe --selftestPrüft ohne Hardware: Velocity-Kurven, Skalen, CC-Mapping, AutoChorder, Phrasen-Parser/-Writer, alle euklidischen Sequencer, die Acid-Grammatik und den MIDI-Datei-Writer. Rückgabewert = Anzahl der Fehlschläge.
Dazu kommen Routing-Tests: sie hängen statt echter Ports eine Auffangliste
in MidiThread::sendToPort() und schicken echte MIDI-Nachrichten durch
processNoteInput() / processTranspose(). Genau dort saßen bisher alle
gefundenen Fehler — Oktave/Transponierung, Split, Velocity-Layer, CC-Bereiche,
Chord-Paarung, Hold, und die Regel, dass ein Modulationsrad am Steuer-Eingang
die Sequencer nicht stoppen darf.
| Ordner | Inhalt |
|---|---|
Source/ |
Implementierungen (*.cpp) |
Include/ |
Header (*.h) |
ConfigEditor/ |
ausschließlich der Standalone-Editor (eigenes main) |
Bilder/ |
Geräte-Bilder (PNG/JPG) |
Bilder/svg/ |
dieselben Motive als getracte Vektoren |
extern/rtmidi6.0.0/ |
RtMidi 6.0.0, direkt mitkompiliert (WinMM-Backend) |
moc/ |
generierte Dateien (moc/rcc) — nicht bearbeiten |
dist/ |
fertige Distribution (von deploy.ps1) |
Wichtige Dateien im Wurzelverzeichnis:
configuration.xml— beschreibt das Rig (siehe unten)midiresources.qrc— Ressourcenliste, generiertdeploy.ps1— Packen der Distributionmainwindow.ui— nur das leere Hauptfenster; die Oberfläche wird im Code aufgebaut, weil sie sich aus der Konfiguration ergibt
configuration.xml beschreibt das Rig: Synthesizer, Sequencer, Eingänge,
CC-Zuordnungen. Sie ist als Ressource eingebettet, kann aber als argv[1]
übergeben werden — die Distribution enthält dafür einen zweiten Starter.
Eine übergebene Datei wird überwacht: beim Speichern startet die Anwendung
sich selbst neu.
<Synthesizer name="Roland D-05" midiChannel="1" midiActivatorCC="102"
image=":/RolandD-05.png" port="SINGLE_OUT2" type="0">
<MidiModifier name="Preset" valuePosition="1" valueMessage="0"
value="0" minValue="0" maxValue="63"> ... </MidiModifier>
</Synthesizer>image adressiert die Ressource ohne Pfad (:/RolandD-05.png), obwohl die
Datei unter Bilder/ liegt — die qrc bildet das über Aliasse ab. Alle Bilder
aus Bilder/ sind eingebettet, ein neues Gerät braucht also keinen neuen
Build, nur einen Eintrag in der XML.
Es gibt zwei, und sie teilen sich mit ConfigModel genau ein Stück Code —
das, welches das XML anfasst. Die Oberflächen darüber haben nichts gemeinsam,
weil sie für unterschiedliche Hände gebaut sind.
Ein eigenes Programm für Maus und Tastatur, ohne MIDI-Engine, ohne Clock, ohne Generatoren. Erst dadurch werden die Teile der Datei bearbeitbar, die auf einem Touchscreen chancenlos sind — die CC-Map hat im echten Rig 326 Einträge.
- Links ein Baum aus Synthesizern und Eingängen, rechts die Vorschau des Hauptbildschirms (Klick darauf wählt den Synthesizer), unten der Prüfbericht; ein Klick auf eine Meldung springt zum Eintrag.
- Registerkarten je Synthesizer: Allgemein, CC-Map, Modifier, Init-SysEx, Vorgaben (Auto-Chorder-/Arp-Startwerte).
- Rohe MIDI-Nachrichten werden als Hex-Text bearbeitet (
B6 20 00). Beim Modifier steht dabei, in welche Nachricht und welches Byte der Zähler geschrieben wird — und ob es diese Stelle überhaupt gibt. - Beim Umbenennen eines MidiMap-Eintrags bietet der Editor an, alle Verweise in den Synthesizern mitzuziehen. Ohne das verwirft der Router sie beim Laden kommentarlos — genau der Fehler, den man sonst erst auf der Bühne merkt.
- Beim Speichern wird die vorherige Fassung als
.bakabgelegt.
MidiRouterConfig.exe path\to\configuration.xml
MidiRouterConfig.exe --selftestOhne Argument öffnet er die zuletzt bearbeitete Datei, sonst eine
configuration.xml neben der EXE, sonst ein leeres Dokument.
SETUP im Hauptschirm öffnet einen Editor für diese Datei: Synthesizer
anlegen, duplizieren, entfernen, umsortieren, Name/Bild/Port/Kanal/Trigger-CC/
Typ setzen, Zeilenzahl ändern — mit einer Vorschau des künftigen
Hauptbildschirms, die dieselbe Zeilenaufteilung verwendet wie das Original.
Ports kommen aus der echten Geräteliste, Bilder aus den Ressourcen; beides
lässt sich also nicht vertippen.
Der Editor schreibt nie die Datei neu, sondern ändert nur die Attribute, die er anzeigt, und verschiebt beim Umsortieren ganze Elemente. Alles andere — CC-Zuordnungen (im echten Rig über 300), MidiModifier samt ihren Nachrichten, Init-SysEx — bleibt unangetastet. Die Zahl in Klammern hinter jedem Listeneintrag zeigt, wie viele solcher Einträge daranhängen; beim Entfernen wird sie noch einmal genannt.
Gespeichert wird neben die EXE. Läuft der Router auf der eingebetteten Konfiguration, nimm danach den Starter „eigene Konfiguration"; wurde er mit einer Datei gestartet, startet er sich nach dem Speichern selbst neu.
Laufzeit-Einstellungen (Szenen, Zustände, Tempo) landen in
midirouter_settings.ini neben der EXE. Achtung: [General] ist in
QSettings-INI-Dateien reserviert — eigene Optionen stehen deshalb unter
[Options].
Routing. Beliebig viele Synthesizer an beliebig vielen Ausgängen; pro Gerät Kanal, Oktave, Transponierung, Split-Punkt, Velocity-Kurve und -Layer, CC-Umbenennung inkl. Wertebereich und Invertierung. Sequencer-Spuren werden im Sequencer-Screen per Fingertipp auf Zielgeräte gelegt.
Szenen und Song-Modus. Acht Szenen speichern den kompletten Zustand inklusive Program Changes. Abrufbar über die Oberfläche, über Program Change auf dem Steuer-Eingang oder per Fußtaster (CC 80 = nächste Szene der Setlist).
Generatoren — jeweils pro Synthesizer, alle auf derselben MIDI-Clock:
| Generator | Kurz |
|---|---|
| Chorder | Harmonizer: eine Note wird zum Akkord (60 Typen, 69 Presets, Voicings) |
| Arp | Phrasen-Arpeggiator, spielt die Original-Phrasen von Squaredheads Nora |
| Euclid | melodischer euklidischer Arpeggiator, bis 64 Steps |
| Chroma | zwölf euklidische Linien, eine je Halbton — Polyrhythmik aus einem Gerät |
| Drums | achtspuriger euklidischer Drum-Sequencer |
| Acid | monophoner TB-303 mit Generator für echte Acid-Lines |
Alle haben Swing, Wahrscheinlichkeit und Akzent pro Spur, eine Step-Anzeige mit mitlaufender Position und speicherbare Muster.
Generator-Leiste. Eine Zeile im Hauptschirm wählt einen Synthesizer aus und schaltet dessen sechs Generatoren mit je einem Tipp — vorher waren dafür zwei Menüebenen nötig. Daneben liegen A/B (zweiter Satz Patterns für alle Step-Sequencer gleichzeitig), Fill (einen Takt lang die andere Variante, dann zurück) und die globale Transponierung für einen Tonartwechsel im laufenden Stück; Schlagzeug bleibt davon unberührt.
Tempo. Läuft auf eingehender MIDI-Clock; ohne Master übernimmt eine interne Clock, die auf Wunsch selbst gesendet wird (dann ist der Router der Master). Die Tempo-Zeile zeigt Beat und BPM und bietet Tap-Tempo sowie Start/Stop.
Szenenwechsel im Takt. Quant schaltet zwischen sofort, nächstem Beat und
nächstem Takt um. Eine wartende Szene blinkt, bis ihre Grenze erreicht ist —
so landet ein Wechsel nie mitten im Takt.
Mitschnitt. Rec schreibt alles, was der Router aussendet, als
Standard-MIDI-Datei nach Recordings\. Nützlich, um eine gelungene Session zu
behalten, sie in die DAW zu ziehen — oder das Timing am Rig zu überprüfen.
Bühnentauglichkeit. Hot-Plug (Geräteliste wird alle 3 s geprüft), Panic global und pro Gerät (langer Druck), Aktivitätsanzeige, Geräte-Status, MIDI-Monitor für ein- und ausgehende Daten, Testnote, Autosave, tägliche Backups, Absturz-Minidumps, Watchdog-Starter für den Kiosk-Betrieb.
Oberfläche prüfen ohne Hardware. Die Anwendung kann sich selbst fotografieren — sie rendert nur ihr eigenes Fenster, nie den Desktop:
set MR_SCREENSHOT=C:\temp\shot.png
set MR_SCREENSHOT_DIALOG=acid
set MR_SCREENSHOT_SIZE=1920x1080
MidiRouter.exeMR_SCREENSHOT_SIZE ist wichtiger, als es aussieht: ohne sie erbt die
Aufnahme den gerade primären Monitor. Auf einem Ultrawide entsteht dann ein
3,5:1-Streifen statt eines 16:9-Bildes — zwei Läufe sind nicht mehr
vergleichbar, und das Rig sieht so auch nicht aus.
Werte für MR_SCREENSHOT_DIALOG: synth[:index], seq, monitor,
monitorout, chorder, arpdlg, euclid, chroma, drums, acid,
picker, scene, config.
Der Standalone-Editor kann dasselbe, nur über Argumente:
MidiRouterConfig.exe --screenshot shot.png --page synth:1 --entry 12 configuration.xml--page: global, seq, synth oder synth:<tab> (0 Allgemein, 1 CC-Map,
2 Modifier, 3 Init-SysEx, 4 Vorgaben), --entry wählt den Eintrag.
Vektor-Icons. Die Geräte-Logos werden als SVG gerendert (schärfer bei
jeder Skalierung). Abschaltbar mit [Options] vectorIcons=0 in der INI, dann
kommen die PNGs zum Zug. Fehlt zu einem Bild die SVG, fällt nur dieses eine
Icon auf das PNG zurück.
Layout-Konvention. Alle Bedienelemente haben QSizePolicy::Ignored; die
Größen ergeben sich ausschließlich aus Stretch-Faktoren. Deshalb muss jedes
Widget einer Zeile einen expliziten Stretch bekommen — ein Widget mit Stretch 0
neben einem mit Stretch 2 fällt auf Breite null zusammen. Schriftgrößen setzt
resizeButtonFontGroup() pro Zeile auf den kleinsten passenden Wert;
Elemente ohne Text werden dabei übersprungen, ein Label, das seinen Text erst
später bekommt, behält also die Standardgröße.
- RtMidi 6.0.0 (
extern/rtmidi6.0.0/) — MIT-artige Lizenz, Text im Header. Unverändert einkompiliert, WinMM-Backend. - JUCE MidiMessage (
Source/MidiMessage.cpp,Include/MidiMessage.h) — nur diese eine Klasse, laut Dateikopf unter ISC. Das JUCE-Framework selbst wird nicht verwendet. - Nora-Phrasen — werden von der Installation von Squaredheads Nora gelesen
(
C:\ProgramData\Squaredheads\Phrases) und in die Distribution kopiert - Geräteabbildungen (
Bilder/,Bilder/svg/) — Logos der angesteuerten Instrumente, Eigentum der jeweiligen Hersteller. Sie sind nicht von der MIT-Lizenz gedeckt und dienen nur der Wiedererkennung auf dem Touchscreen.
Vollständige Vermerke: THIRD-PARTY-NOTICES.md.
MIT für den Code dieses Projekts. Die eingebundenen Fremdteile behalten ihre eigenen, dazu passenden Lizenzen (RtMidi: MIT-artig, JUCE MidiMessage: ISC) — die Vermerke in den Dateiköpfen müssen erhalten bleiben. Die Geräteabbildungen sind ausdrücklich ausgenommen; Einzelheiten dazu in den Drittanbieter-Vermerken.






