Files
Adminator 1e51ef7def Nachtrag: alle bisher untracked Ordner + hängende Änderungen mit-committen
- Konzept/, didaktik_geografie/, didaktik_simulation/, v2-modules/, v2-platform/
- 12 code-workspace-Files
- STATUS-*.md
- viele M/D/R-Änderungen an bereits getrackten Files
- .gitignore verstärkt: **/.humaninput/, **/secret_keys.txt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-08 02:27:02 +02:00

14 KiB
Raw Permalink Blame History

Heli-Audio — Konzept V2

Stand: 2026-05-31 · Autor: Atlas · Status: Diskussion mit Thomas

Thomas-Direktiven (2026-05-31)

Wir brauchen ein geschicktes Konzept, dass nicht irgendwo ewige Stille ist. Gleichzeitig gibt es zentral wichtige Ansagen/Geräusche (Unfall, Warnung, Missionsinfo) und weniger wichtige (geografische Info) — die aber natürlich auch gespielt werden sollen, wenn möglich.

Ducking: ja. Crossfade weglassen. Geo-Audios werden von Notfall-Zwischenrufen überlagert bzw. gestoppt. Alles andere (Environmental, Reverb, Spatial): machen.

Audio-Schichten (Architektur-Bild)

              ┌───────────────────────────────────────────┐
SCHICHT 1     │   AMBIENT (loop, Volume 0.1)              │   immer da
(Hintergrund) │   • Wind/Wasser/Verkehr je Szenario       │   nie still
              │   • Heli-Rotor (nur Flight-Phase)         │
              │   • Musik (nur Mission/Results-Phase)     │
              └───────────────────────────────────────────┘
                              ▲ Ducking: 0.10 → 0.04 wenn Stimme spielt
              ┌───────────────────────────────────────────┐
SCHICHT 2     │   SPRACH-PIPE (seriell, prioritätssortiert)│
(Stimmen)     │                                            │
              │   CRITICAL (1) — unterbricht alles         │
              │     • Crash-Warnung, Boden-Alarm           │
              │     • Tower-Notfunk, Pilot-Übernahme       │
              │     • Stop!-Ansagen                        │
              │                                            │
              │   HIGH (2)   — Standard-Funk-Pipe          │
              │     • Tower-Wegpunkt-Anweisungen           │
              │     • Mission-Briefing                     │
              │     • Pilot-Antworten                      │
              │                                            │
              │   MEDIUM (3) — wenn Pipe leer ist          │
              │     • Geografische Hintergrund-Infos       │
              │     • Stimmung („Sicht klar", „Wind ruhig")│
              │     • Stadt-/Berg-Fakten beim Überflug     │
              │                                            │
              │   FILLER (4) — Anti-Stille                 │
              │     • Wenn Pipe >12 s leer: Filler-Item    │
              │     • Cockpit-Geräusche, Pilot-Murmeln     │
              └───────────────────────────────────────────┘
                              │
                              ▼
              ┌───────────────────────────────────────────┐
SCHICHT 3     │   FEEDBACK-SOUNDS (kurz, ohne Pipe)        │   sofort
(UI/Feedback) │   • Klick-OK, Klick-Fehler                 │   parallel
              │   • Wegpunkt-Treffer-Glocke                │   zur Pipe
              └───────────────────────────────────────────┘

Prioritäten-Logik

Aktuell hat die Pipe nur: seriell + 10s-Gap + priority:'now'-Bypass. Wir brauchen ein vollwertiges Prioritäten-System mit 4 Levels.

Pipe-Verhalten pro Priorität

Level Verhalten beim Einreihen Beispiel-Audios
1 CRITICAL Laufendes Audio per 120ms-Fade abbrechen, gesamte Queue leeren, sofort spielen „Achtung! Boden zu nah!", „Pilot übernimmt — wir landen jetzt!", „Stop! Falsche Richtung!"
2 HIGH Hinten in Queue einreihen, nach Gap (3 s) spielen. Wird von CRITICAL unterbrochen. Tower-Wegpunkt-Anweisungen, Briefing-Hinweise, Pilot-Antworten
3 MEDIUM Nur einreihen wenn keine HIGH-Items in Queue. Wird beim Eintreffen eines HIGH-Items aus der Queue entfernt (verlieren ihre Chance), beim Eintreffen eines CRITICAL auch sofort gestoppt wenn laufend. Geo-Fakten („Wir überfliegen Schwaz, drittgrößte Stadt Tirols"), Stadt-Kommentare
4 FILLER Wird automatisch eingereiht wenn Pipe >12 s leer war. Wird von HIGH/CRITICAL überschrieben. Cockpit-Klick, Pilot-Räuspern, „Sicht ist klar", „Höhe stabil"

Code-Konzept (Pseudo-JS)

// Ersetzt die aktuelle flightAudioQueue durch priority-Queue
var pipe = {
  current: null,           // {src, priority, _fadeGain}
  queue: [],               // sorted by priority
  lastSpokenMs: 0,         // für FILLER-Trigger
  gapMs: { 1: 0, 2: 3000, 3: 5000, 4: 8000 }
};

function enqueueSpeech(path, priority) {
  // 1) CRITICAL: alles wegfegen, sofort spielen
  if (priority === 1) {
    abortCurrentWithFade(120);
    pipe.queue.length = 0;
    pipe.queue.push({path, priority});
    pump();
    return;
  }
  // 2) HIGH: einreihen, MEDIUM-Items davor aus Queue entfernen
  if (priority === 2) {
    pipe.queue = pipe.queue.filter(it => it.priority <= 2);
    pipe.queue.push({path, priority});
    pump();
    return;
  }
  // 3) MEDIUM: nur einreihen wenn keine HIGH in Queue ist
  if (priority === 3) {
    if (pipe.queue.some(it => it.priority <= 2)) return;
    pipe.queue.push({path, priority});
    pump();
    return;
  }
  // 4) FILLER: separate Strategie (siehe unten)
}

function pump() {
  if (pipe.current) return;
  if (!pipe.queue.length) return;
  var now = performance.now();
  // Gap nur ANWENDEN, wenn dasselbe oder höhere Level wartet
  var next = pipe.queue[0];
  var requiredGap = pipe.gapMs[next.priority];
  if (now - pipe.lastSpokenMs < requiredGap) {
    setTimeout(pump, requiredGap - (now - pipe.lastSpokenMs));
    return;
  }
  var item = pipe.queue.shift();
  playWithDucking(item).then(() => {
    pipe.current = null;
    pipe.lastSpokenMs = performance.now();
    pump();
  });
}

// Anti-Stille: alle 2s prüfen, ob FILLER nötig
setInterval(() => {
  if (pipe.current || pipe.queue.length) return;
  if (performance.now() - pipe.lastSpokenMs < 12000) return;
  enqueueFiller();  // wählt Filler je nach Phase + Szenario
}, 2000);

Ducking

Wenn Stimme spielt → Rotor-Lautstärke von 0.30 auf 0.08 fadrenken (300 ms attack), nach Stimmenende 3 s linear zurück auf 0.30 (release). Gleiches für Hintergrund-Musik (von 0.20 auf 0.05). Environmental-Loops bleiben unverändert (sie sind schon leise genug).

Code-Skizze:

function duckAmbient(on) {
  var t = audioCtx.currentTime;
  var targetRotor = on ? 0.08 : 0.30;
  var targetMusic = on ? 0.05 : 0.20;
  var rampSec = on ? 0.3 : 3.0;
  rotorGain.gain.cancelScheduledValues(t);
  rotorGain.gain.linearRampToValueAtTime(targetRotor, t + rampSec);
  musicGain.gain.cancelScheduledValues(t);
  musicGain.gain.linearRampToValueAtTime(targetMusic, t + rampSec);
}

„Keine ewige Stille" — FILLER-Strategie

Pool von 1520 sehr kurzen Filler-Audios (13 s), die je nach Phase + Szenario gewählt werden:

Phase Filler-Pool
plan (Routenplanung) „Hmm…", „Schauen wir mal", „Lass mich nachdenken", Cockpit-Schalter-Klick
flight Berg Pilot: „Wind ruhig", „Sicht klar", Höhenmesser-Beep, „Höhe stabil"
flight Wasser Pilot: „Wellen ruhig", „Patient in Sicht", Wasser-Plätschern
flight Autobahn Pilot: „Funk-Check", „Verkehr läuft"
landing Pilot: „Sinkrate gut", „Ein Meter", „Last steady"

Plus: Cockpit-Ambient-Loops auf Schicht 1 (siehe oben) — die laufen IMMER, also ist nie wirklich Stille.

Environmental-Loops (Schicht 1, neu)

Pro Szenario ein 3060 s-Loop, Volume 0.10 (wird bei Stimme auf 0.04 geduckt):

Szenario Loop Beschreibung
basis (Standard) amb_general.mp3 leises Cockpit-Brummen + Wind
wasser amb_water.mp3 Wellen, Möwen, Wind
berg-fels amb_mountain.mp3 Wind, leichter Hall
berg-schnee amb_snow.mp3 Sturm-Säuseln, Schnee
autobahn amb_highway.mp3 Verkehr, Sirenen entfernt
stadt amb_urban.mp3 Stadt-Rauschen, Hupen
schlucht amb_canyon.mp3 Echo-Wind, Wasser
tal-dorf amb_village.mp3 Vogelzwitschern, Kirchglocke selten

8 Loops. Beschaffung: entweder selbst aufnehmen (Wind im Garten, Wasser im Bad…), oder Lizenz-frei (Freesound.org, BBC Sound Effects Library — frei für Bildung).

Reverb für ausgewählte Missionen

Mit einem ConvolverNode und einem kurzen Impulse-Response können wir den Funk-Klang räumlich variieren:

Mission-Typ Reverb-IR Effekt
Schlucht (M6 Canyoning Mellau) ir_canyon_short.wav (0.8 s) Funk klingt hallend, eng
Berg-Hochalpin (M19, M20, M24 Glockner/Dachstein) ir_mountain.wav (1.2 s) weit, kalt
Tunnel/Autobahn-Tunnel ir_tunnel.wav (1.5 s) dröhnend
Standard (Stadt, Wasser, Wald) kein Reverb trocken, klar

3 Reverb-IRs. Beschaffung: kostenlose IR-Libraries (z.B. https://www.openair.hosted.york.ac.uk/).

Spatial Stereo (kleines Feature)

Sprecher-Position als Stereo-Pan:

  • Tower-Lotsin: pan -0.4 (links — sitzt im Tower, „neben" dem Heli)
  • Pilot:in: pan +0.3 (rechts — sitzt rechts vom Schüler im Cockpit)
  • Sani / Flugretter: pan 0 (zentriert, hinten im Cockpit)
  • Briefing-Offizierin: pan 0 (vor dem Bildschirm, direkt)

Subtil (Pan ±0.4 max), nicht aufdringlich.

Geo-Audios — wann triggern?

Aktueller Code: Geo-Audios (r_mission_geo_*, r_wp_geo_*) sind in der Standard-Pipe → konkurrieren mit Tower-Anweisungen → 10s-Gap verzögert alles.

Neu (Prioritäten):

  • r_mission_geo_* (am Kartenflug-Beginn): MEDIUM — spielt nur wenn keine Tower-Anweisung wartet
  • r_wp_geo_* (pro Wegpunkt): MEDIUM — wird vom nächsten Tower-Funk abgebrochen
  • r_tower_* (Wegpunkt-Anweisungen): HIGH
  • r_caution_* (Notfall-Warnung): CRITICAL
  • r_pilot_takeover: CRITICAL

Wenn der Schüler in der Plan-Phase Wegpunkte klickt und der Tower antworten muss („Korrekt, weiter über X"), bricht das die laufende Geo-Info ab. Bei richtigem Tempo bekommt er aber so viel Geo wie möglich.

Übersicht — was wir bauen

# Komponente Aufwand Wirkung
1 Prioritäten-Pipe (4 Levels statt eines) mittel Kern der ganzen Logik
2 Ducking (Rotor + Musik bei Stimme leiser) klein Verständlichkeit massiv besser
3 FILLER-Strategie (Anti-Stille mit Pool) mittel Keine toten Phasen mehr
4 Environmental-Loops (8 Loops, 1 pro Szenario) mittel (Beschaffung + Wiring) Stimmung, kontinuierlicher Klangteppich
5 Audio-Texte umstellen auf Prioritäten-API mittel Skripte sortieren
6 Reverb für 3 Mission-Typen klein (IR-Files + ConvolverNode) Räumlichkeit
7 Spatial Stereo klein Goldener Schliff

Reihenfolge bauen: 1 → 2 → 3 → 5 → 4 → 6 → 7.

Beziehung zu Heli-Kennzeichen-Konzept

Audio-Texte (8 JSON-Dateien, 366 Stellen mit „Christophorus") werden im Zuge von Schritt 5 auf Platzhalter {code} umgestellt. Audio-Regenerierung dann pro Mission gemeinsam mit Thomas (siehe Heli-Kennzeichen-Konzept Schritt 7).

Audio-Re-Generierung — offene Text-Korrekturen (zu erledigen wenn Audios neu gebaut werden)

Die Audio-Skript-JSON-Dateien (scripts/*-lines.json + scripts/audio-texts.json) wurden bereits textlich korrigiert. Die zugehörigen MP3-Dateien sind aber noch alt und sagen die ursprünglichen Texte. Beim nächsten Re-Generieren müssen folgende Audios neu erstellt werden:

Inhaltliche Korrekturen (2026-05-31)

  1. „Chefpilot" → „Chefpilotin" (Marlene als weibliche Mentorin im Onboarding etabliert)

    • r_mission_abort + r_mission_abort_m (Drei Berührungen → die Chefpilotin übernimmt)
    • r_nav_departure_takeover (Chefpilotin hat übernommen)
    • r_tower_handover_c1 bis r_tower_handover_c16 (14 Tower-Audios: „Heute übernimmt die Chefpilotin")
  2. „Rotorabwind wäre Steinschlag" → „Rotorabwind kann Steinschlag verursachen" (kausal richtiger Satz)

    • r_caution_berg_fels + r_caution_berg_fels_m (in M3/M6/M7/M12/M13/M21 etc. — alle berg-fels-Missionen)
    • r_caution_wasser ist unverändert sinnvoll, weil dort der Effekt deterministisch ist
    • Status: Text in JSON gefixt am 2026-05-31. Alte MP3 spielt noch den alten Wortlaut bis Re-Generierung.

3.5 ASCII-Umlaut-Fixes in audio-texts.json (2026-05-31, zweite Runde)

  • r_nav_plan_correct, r_nav_plan_done, r_nav_seg_arrive, r_nav_altitude_mountain, r_nav_altitude_valley, r_nav_fuel_half, r_nav_route_check, r_nav_weather_enter, r_land_approach, r_land_rescuer_down, r_land_winch_down, r_land_rescuer_ready, r_tower_sea_approach_c9
  • Vorher: "naechsten", "vollstaendig", "Ueberflughoehe", "moeglich", "Stroemung" etc. — alle MP3s sprechen noch das ASCII-Wort, JSON-Text aber UTF-8-korrekt
  • Status: Text in JSON gefixt am 2026-05-31. Alte MP3s warten auf Re-Generierung.
  1. Marlene als zentrale Chefpilotin überall (Vereinheitlichung 2026-05-31, vorher 4 rotierende Profile)

    • Wirkt sich aus auf alle pilot_* und caution_*-Audios, die per pilot_by_helikey ausgewählt werden
    • Alle pilot_*_m-Audios (Hannes/Stefan) werden in V1 nicht mehr abgespielt — bleiben im System für später
    • Bilder + Funk-Pille zeigen ab sofort immer pilot_b_f (Marlene) statt der jeweiligen Stationspilot:in
    • Bei Re-Generierung: nur die weiblichen Varianten (ohne _m) brauchen Updates
  2. Marken-Bezeichnungen (siehe docs/konzept-heli-kennzeichen.md):

    • „Christophorus N" → Pool-Kennzeichen oder generisches „R/N-N" (16 + viele weitere Stellen)
    • ggf. nochmal Audio-Workflow gemeinsam mit Thomas pro Mission

Total beim nächsten Audio-Bau

Ca. 18 Pilot- + Tower-Audios kombiniert mit Marken-Refactor ergeben ~3040 zu re-generierende MP3s.


Status & nächste Schritte

  • Schritt 1 (Prioritäten-Pipe) — warte auf Thomas-OK
  • Schritt 2 (Ducking) — warte
  • Schritt 3 (FILLER-Strategie) — warte
  • Filler-Texte definieren (Pool von 1520 kurzen Audios) — gemeinsame Auswahl mit Thomas
  • Environmental-Loops beschaffen oder aufnehmen
  • Audio-Re-Generierung mit korrigiertem Text (siehe oben)