Masher
Technik
Aufbau, Abhängigkeiten, Verbindungswege und Tests: wie Masher gebaut ist und womit es arbeitet.
Inhalt
Überblick
Masher ist eine Electron-App (Windows) in Vanilla JavaScript ohne UI-Framework, plus zwei native Helfer:
- Audio-Helfer (
src/main/winaudio/AudioHelper.cs, C#): Windows-Audio pro App, Spektrum, Testrauschen, Geräteeinstellungen. Wird beim ersten Start mit demcsc.exedes .NET Framework übersetzt. - Plugin-Host (
native/plughost, C++ mit JUCE): lädt VST3-Plugins in eigenem Prozess.
Abhängigkeiten: electron, electron-builder (Dev) und koffi (Zugriff auf die Voicemeeter-DLL).
┌────────────── Renderer (Fenster) ──────────────┐
│ Views · Komponenten · Store · MIDI (Web MIDI) │
└───────────────▲───────────────────────────────┘
│ IPC (preload.js → window.api)
┌───────────────┴────── Hauptprozess ────────────┐
│ Engine (Backends) · Automation · Tray · Hotkeys │
│ Relay-Server · Backups · C5 · Plugin-Manager │
└──────┬─────────────┬──────────────┬────────────┘
│ │ │
Remote API VBAN (UDP) Audio-Helfer / Plugin-Host
(koffi, DLL) Voicemeeter (eigene Prozesse)
Befehle
| Befehl | Zweck |
|---|---|
npm start |
App starten (electron .) |
npm test |
Alle Tests (node --test "test/*.test.js") |
npm run fake-vm |
Simuliertes Voicemeeter per VBAN auf UDP 6980 |
npm run shortcut |
Verknüpfung auf Desktop und im Startmenü anlegen |
npm run dist |
Portable Windows-EXE bauen (electron-builder) |
npm run build-host |
Plugin-Host (JUCE) bauen, braucht Visual Studio Build Tools |
node tools/probe-voicemeeter.js [--all] |
Prüft den Parameter-Katalog gegen das laufende Voicemeeter, nur lesend |
npx electron tools/smoke-main.js <ordner> |
Klickt die App mit Mock-Voicemeeter und Mock-Windows-Audio durch und speichert Screenshots. Echte Geräte und Apps werden nicht angefasst |
node tools/make-icon.js |
Erzeugt icon.png und icon.ico neu |
npx electron tools/doc-screenshots.js |
Erzeugt die Screenshots der Doku in docs/bilder/ (Mock-Voicemeeter, ohne persönliche Daten) |
Verzeichnisstruktur
src/
main/ Hauptprozess (Node)
main.js Start, Fenster, Tray, IPC, Hotkeys
store.js JSON-Speicher (atomar, sortiert) für config und shared
vban-client.js VBAN-Client (UDP)
vban-protocol.js VBAN-Paketformat
engine/ Anbindung an Voicemeeter
schema.js Parameter-Katalog
vmr.js Remote API über koffi
backend-remote.js Backend: lokale Remote API
backend-vban.js Backend: VBAN
relay.js Fernzugriff: Server und Client
state.js Zustand (Strips, Busse, Pegel)
index.js Auswahl und Umschaltung der Backends
automation/ Regeln, Ducking, Szenen, App-Routing, Mikro, Backup, C5
plugins/ Plugin-Manager und Anbindung des Hosts
winaudio/ Audio-Helfer (C#) und Node-Anbindung
preload.js Brücke zum Renderer (window.api)
renderer/
index.html, styles.css
js/
app.js Aufbau des Fensters, Navigation, Tastenkürzel
vm.js Zustand und Parameter für die Oberfläche
engine.js Pad-Aktionen (Drücken, Loslassen)
midi.js Web MIDI, Lernen, Feedback
store.js Profil (Seiten, Pads, Einstellungen)
skins.js Skins
views/ Pads, Mixer, Kanal, EQ, Apps, Automation, …
components/ Fader, Knob, Meter, EQ, Kompressor, XY, …
native/plughost/ JUCE-Plugin-Host (C++)
settings/shared.json Geteilte Einstellungen (in git)
test/ Tests (node:test)
tools/ Mocks, Prüf- und Build-Werkzeuge
Verbindung zu Voicemeeter
Die Engine wählt je nach Einstellung eines von drei Backends (src/main/engine/index.js):
| Backend | Datei | Eigenschaften |
|---|---|---|
| Remote | backend-remote.js |
Lokal über die Voicemeeter-DLL (koffi). Alle Parameter les- und schreibbar |
| Relay | relay.js |
Verbindet sich mit der App auf dem Voicemeeter-PC. Alle Funktionen, per Kennwort geschützt, nicht verschlüsselt |
| VBAN | backend-vban.js |
UDP-Text-Stream. Lesen nur für Pegel, Mute, Routing, Gain, Namen |
Alle Backends liefern dieselben Ereignisse (state, params, schema, Status). Der Parameter-Katalog (schema.js) beschreibt Name, Typ, Wertebereich und ob ein Parameter schreibgeschützt ist.
Einstellungen und Speicherorte
settings/shared.json(im Projektordner): geteilt per git. Schlüssel sind sortiert und die Datei ist zeilenweise formatiert, damit Diffs und Merges klein bleiben.%APPDATA%\Masher\config.json: nur dieser PC.- In gepackten Builds und bei Tests liegt alles in
config.json. - Schreiben ist entprellt und atomar (Temp-Datei, dann Umbenennen).
Automation
| Datei | Aufgabe |
|---|---|
rules.js |
Regel-Engine mit Auslösern, Bedingungen und Aktionen. Eine Regel löst frühestens nach 500 ms erneut aus |
ducking.js |
Ducking. Rampen fährt Voicemeeter (FadeTo), die App entscheidet über Start und Ende |
scenes.js |
Szenen aufnehmen und als Skript abrufen |
approuting.js |
Automatisches App-Routing über den Audio-Helfer |
micwatch.js |
Erkennt die Stummtaste des Interfaces am Pegel |
backup.js |
Automatische und manuelle Sicherungen der Voicemeeter-Konfiguration |
c5.js, c5io.js |
C5-Limiter über Voicemeeters Settings-Datei lesen und schreiben |
Regeln, Ducking und Szenen laufen immer im Hauptprozess, nicht im Fenster.
Tests
npm test
| Datei | Prüft |
|---|---|
vban-protocol.test.js |
VBAN-Paketformat |
engine.test.js |
Engine gegen Mock-Voicemeeter |
automation.test.js |
Regeln, Ducking, Szenen |
winaudio.test.js |
Audio-Helfer (nur lesend, routet nur sich selbst) |
micwatch.test.js |
Mikrofon-Erkennung |
backup.test.js |
Sicherungen |
c5.test.js |
C5-Parsing und -Schreiben |
plugins.test.js |
Plugin-Manager mit Mock-Host |
relay.test.js |
Fernzugriff |
Die Mocks liegen in tools/ (mock-vmr.js, mock-winaudio.js, mock-pluginhost.js, fake-voicemeeter.js).
Build
npm run build-host # optional: Plugin-Host
npm run dist # portable EXE
package.json → build definiert die Paketierung: Dateien src/**/* und package.json, Ziel portable, Symbol src/renderer/assets/icon.ico, Plugin-Host aus native/plughost/bin als Zusatzressource unter plughost.
Konventionen
- Oberfläche und Kommentare für Nutzer auf Deutsch, Code-Kommentare englisch.
- Dunkles Thema bleibt. Die Signalfarben (Stumm-Rot, Warn-Gelb, Live-Grün) behalten in allen Skins ihre Bedeutung.
- Der Maßstab für das Aussehen ist ein Pro-DAW-Look: dicht, flach, präzise. Große Radien und weiche Schatten sind ausdrücklich nicht gewünscht (siehe
PRODUCT.md). - Keine externen Schriften oder Dienste: Die App muss offline laufen.