|
|
# Fahrplan
|
|
|
|
|
|
Jeder Meilenstein endet mit einem Abnahmetest. Erst wenn er bestanden ist, beginnt der nächste. Termine sind offen.
|
|
|
|
|
|
> **Absprache 2026-10-21:** Die Reihenfolge darf nach Absprache angepasst werden. Langzeittests (z. B. M1: 4 h) laufen gesammelt am Wochenende mit einem getaggten Build (`m1-candidate`); die Entwicklung von M2 beginnt vorher.
|
|
|
|
|
|
| | Meilenstein | Ohne neue Hardware testbar? |
|
|
|
|---|---|---|
|
|
|
| M0 | Grundgerüst | ja |
|
|
|
| M1 | Bild | ja (NDI Tools / OBS als Quelle) |
|
|
|
| M2 | Ton-Matrix | ja (MOTU M2 vorhanden) |
|
|
|
| M3 | Szenen und Fernsteuerung | ja (MacBook + Mac mini) |
|
|
|
| M4 | Intercom Stufe 1: Hören + PGM-Vorschau | ja (Heimnetz) |
|
|
|
| M5 | Intercom Stufe 2: Sprechen | ja (Heimnetz, HTTPS) |
|
|
|
| M6 | Tally | ja (ATEM vorhanden) |
|
|
|
| M7 | Generalprobe | nein – braucht ZowieBoxen, Switches, Dante, Ui12 |
|
|
|
|
|
|
## M0 – Grundgerüst
|
|
|
- [x] Xcode-Projekt „Musubi“, macOS 14, Universal Build (arm64 + x86_64), Bundle-ID `studio.zielke.musubi`
|
|
|
- [x] Modulstruktur laut `02-architektur.md`
|
|
|
- [x] NDI SDK eingebunden (Modulemap), Version wird beim Start geloggt
|
|
|
- [x] `design/Theme.swift` übernommen, leeres Hauptfenster mit Quellenliste
|
|
|
- [x] Swift-Testing-Target mit erstem Test für `MusubiCore`
|
|
|
- **Abnahme:** Release-Build startet auf MacBook **und** Mac mini 2018; die Quellenliste zeigt eine NDI-Testquelle aus dem Netz.
|
|
|
|
|
|
## M1 – Bild
|
|
|
- [ ] NDI-Empfang einer Quelle (HX3 und volles NDI) – volles NDI ✓, HX3 offen bis ZowieBoxen da sind
|
|
|
- [x] Vollbild auf gewähltem Bildschirm, ohne Menüleiste, Mauszeiger ausgeblendet
|
|
|
- [x] Anzeigemodus 50 Hz setzen, wenn verfügbar
|
|
|
- [x] Zwei Quellen gleichzeitig auf zwei Bildschirmen (Mac mini: PGM + Multiview)
|
|
|
- [x] Ruhezustand blockieren, Auto-Reconnect
|
|
|
- **Abnahme:** 4 Stunden, 2 Quellen, 2 Bildschirme auf dem Mac mini 2018 – keine sichtbaren Aussetzer, CPU-Last notiert, verlorene Frames < 0,1 %.
|
|
|
|
|
|
## M2 – Ton-Matrix
|
|
|
- [x] NDI-Ton einer Quelle auf beliebige Ausgangskanäle (z. B. MOTU M2 Out 2)
|
|
|
- [x] Reiner Audio-Empfang (ohne Video-Bandbreite)
|
|
|
- [x] Mikrofon-Eingang (Headset) auf Kanal (Out 1), Sprechtaste (Tastenkürzel, gedrückt halten / umschalten)
|
|
|
- [x] Pegelanzeige, Gain, Mute je Route
|
|
|
- [x] Drift-Ausgleich zwischen NDI-Takt und Interface-Takt
|
|
|
- **Abnahme:** 4 Stunden ohne Knacksen und ohne hörbaren Versatz; Sprechtaste reagiert ohne Verzögerung.
|
|
|
|
|
|
## M3 – Szenen und Fernsteuerung
|
|
|
- [ ] Szenen speichern, laden, exportieren (JSON)
|
|
|
- [ ] Rolle Regie/Knoten; Knoten per Bonjour finden
|
|
|
- [ ] Regie setzt Szene am Knoten; Knoten meldet Status zurück
|
|
|
- [ ] Beim Start letzte Szene laden
|
|
|
- **Abnahme:** Beide Macs neu starten – die Szene „OP-Live“ stellt sich ohne Eingriff wieder her.
|
|
|
|
|
|
## M4 – Intercom Stufe 1
|
|
|
- [ ] Web-Server nur auf der Klinik-Schnittstelle
|
|
|
- [ ] QR-Code mit Adresse in der App
|
|
|
- [ ] Handy-Seite: Name/Rolle, Talkback hören, PGM-Vorschau (WebRTC)
|
|
|
- **Abnahme:** iPhone und Android im Heimnetz, Verzögerung der Vorschau gemessen < 0,5 s.
|
|
|
|
|
|
## M5 – Intercom Stufe 2
|
|
|
- [ ] HTTPS mit eigener Stammzertifizierung (Installationsanleitung fürs Handy)
|
|
|
- [ ] Sprechtaste auf dem Handy → Ton-Matrix
|
|
|
- [ ] Optional: TURN-Relay als Plan B konfigurierbar (`06-netzwerk.md`)
|
|
|
- **Abnahme:** Gegensprechen iPhone ↔ Regie und Android ↔ Regie im selben Durchgang.
|
|
|
|
|
|
## M6 – Tally
|
|
|
- [ ] ATEM-Status (PGM/Vorschau) lesen
|
|
|
- [ ] Kamera-Eingang einer Handy-Rolle zuordnen
|
|
|
- [ ] Handy-Rand rot (PGM) / grün (Vorschau)
|
|
|
- **Abnahme:** Schnitt am Micro Panel färbt das richtige Handy in unter 200 ms.
|
|
|
|
|
|
## M7 – Generalprobe
|
|
|
- [ ] Kompletter Aufbau laut `05-testplan-hardware.md`
|
|
|
- **Abnahme:** 3 Stunden durchgehender Betrieb mit allen Geräten; OBS + DistroAV bleibt als Notlösung auf beiden Macs installiert.
|
|
|
|
|
|
## Erkenntnisse
|
|
|
_(nach jedem Meilenstein ergänzen)_
|
|
|
|
|
|
### M0 – Grundgerüst (bestanden 2026-10-21)
|
|
|
- Abnahme: Release-Build auf Mac Studio (Apple Silicon, Entwicklungsrechner) und Mac mini 2018 (i5-8500B, macOS 15.7.7) gestartet; beide zeigen „NDI Test Patterns“ in der Quellenliste. Das MacBook nutzt denselben arm64-Teil und wurde nicht separat geprüft.
|
|
|
- Xcode 27 baut weiterhin x86_64 für macOS 14.
|
|
|
- NDI SDK 6.3.2: `libndi.dylib` ist universal und hat `@rpath/libndi.dylib` als Install-Name; Einbetten nach `Contents/Frameworks` reicht.
|
|
|
- Hardened Runtime + Ad-hoc-Signatur → dyld lehnt die eingebettete `libndi.dylib` ab („different Team IDs“). Vorerst aus; mit echter Team-ID für die Notarisierung wieder einschalten.
|
|
|
- Mac mini im Leerlauf mit Quellensuche: ca. 2 % CPU, ca. 52 MB RAM.
|
|
|
- Mac mini ist per SSH erreichbar (Entfernte Anmeldung + Bildschirmfreigabe): App per `scp` verteilen, Quarantäne entfernen, Logs mit `log stream` mitlesen.
|
|
|
|
|
|
### M1 – Bild (umgesetzt 2026-10-21, Abnahme offen)
|
|
|
- „NDI Test Patterns“ sendet ein Standbild nur einmal. Eine gehaltene NDI-Verbindung zählt deshalb als lebendig; neu verbunden wird nur, wenn Frames **und** Verbindung fehlen.
|
|
|
- Volles NDI 1080p50 mit bewegtem Bild: ~128 Mbit/s, ~50 % eines Kerns auf dem Mac mini – fast nur NDI-Empfang/Dekodierung. HX3 (ZowieBox) noch zu messen.
|
|
|
- Verlorene Frames können vom **Sender** kommen: OBS auf dem Mac Studio ließ Frames aus, während dort Release-Builds liefen (~335 Frames in 6 min). Für Langzeittests darf auf dem Sender nichts Schweres laufen.
|
|
|
- Mauszeiger über Ausgaben per `NSCursor.hide/unhide` (gezählt, ausbalanciert), nicht `setHiddenUntilMouseMoves`.
|
|
|
|
|
|
### M2 – Ton-Matrix (umgesetzt 2026-10-21, Langzeittest offen)
|
|
|
- Core Audio direkt (AUHAL je Gerät) statt `AVAudioEngine`: einzelne Kanäle beschreiben, mehrere Quellen pro Kanal mischen, Render-Callback garantiert ohne Allokation.
|
|
|
- Lock-freier Ringpuffer in C (`stdatomic`), weil Swifts `Atomic` erst ab macOS 15 verfügbar ist.
|
|
|
- NDI liefert beim Verbinden einen Rückstau (~140 ms). Nach dem Vorfüllen wird einmalig auf die Ziel-Latenz gekürzt, sonst startet der Ton mit zu viel Verzögerung.
|
|
|
- OBS/DistroAV sendet Audio in 1024er-Blöcken mit bis zu ~36 ms Lücke. 50 ms Puffer gaben vereinzelte Unterläufe → NDI-Routen 80 ms, Mikro-Routen 12 ms.
|
|
|
- Drift-Regler langsam auslegen (Sekunden): der Füllstand ist durch die Blöcke ein Sägezahn. Im Betrieb ±150 ppm Korrektur, 0 Aussetzer in 2 min auf MOTU Out 2, CPU 0,3 %.
|
|
|
- Entfernte Routen werden 2 s auf dem Main Thread geparkt, damit der Render-Thread nie den letzten Verweis loslässt (sonst `free` im Callback).
|
|
|
- Sprechtaste global per Carbon-Hotkey (⌃⌥ Leertaste) – braucht keine Bedienungshilfen-Freigabe und meldet Drücken und Loslassen.
|