Song im Spiel: Play song und Stop song #336

Closed
opened 2026-10-06 07:02:13 +02:00 by meleki · 2 comments
Owner

Teil von #330. Ein Song (#334) muss im Spiel abspielbar sein.

Vorschlag

  • Play song (Action): Eingänge song, fade in (Sekunden) und loop (Standard: der Loop-Bereich des Songs). Ausgang voice wie bei Play sound, damit sich genau dieses Abspielen ansprechen lässt.
  • Stop song: Eingang voice und fade out (Sekunden).
  • Gespielt wird über den Scheduler (#332). Die Samples der Instrumente sind schon vorab geladen (ed2b58b), weil sie normale Sounds des Projekts sind.
  • Alles, was ein Song spielt, geht über einen gemeinsamen Gain. Daran hängen das Ein- und Ausblenden und später ein Musik-Bus (#325).

Rückfragen

  • Wie viele Songs gleichzeitig? Ein Musik-Kanal, auf dem ein neuer Song den alten ablöst (mit Überblendung), oder beliebig viele nebeneinander?
  • Szenenwechsel: Läuft ein Song weiter? Mein Vorschlag: ja, wenn das Objekt, das ihn startet, Keep on scene load hat, sonst endet er mit der Szene.
  • Pause: Läuft die Musik bei pausiertem Spiel weiter, wird sie leiser, oder hält sie an?
  • Zeitskala: Soll eine Zeitlupe die Musik verlangsamen? Mein Vorschlag: nein, Musik läuft in echter Zeit.
  • Soll Play song an einer bestimmten Stelle beginnen können, an einem Takt oder einem Marker aus #334?
Teil von #330. Ein Song (#334) muss im Spiel abspielbar sein. ## Vorschlag - ***Play song*** (Action): Eingänge `song`, `fade in` (Sekunden) und `loop` (Standard: der Loop-Bereich des Songs). Ausgang `voice` wie bei *Play sound*, damit sich genau dieses Abspielen ansprechen lässt. - ***Stop song***: Eingang `voice` und `fade out` (Sekunden). - Gespielt wird über den Scheduler (#332). Die Samples der Instrumente sind schon vorab geladen (`ed2b58b`), weil sie normale Sounds des Projekts sind. - Alles, was ein Song spielt, geht über einen gemeinsamen Gain. Daran hängen das Ein- und Ausblenden und später ein Musik-Bus (#325). ## Rückfragen - **Wie viele Songs gleichzeitig?** Ein Musik-Kanal, auf dem ein neuer Song den alten ablöst (mit Überblendung), oder beliebig viele nebeneinander? - **Szenenwechsel:** Läuft ein Song weiter? Mein Vorschlag: ja, wenn das Objekt, das ihn startet, *Keep on scene load* hat, sonst endet er mit der Szene. - **Pause:** Läuft die Musik bei pausiertem Spiel weiter, wird sie leiser, oder hält sie an? - **Zeitskala:** Soll eine Zeitlupe die Musik verlangsamen? Mein Vorschlag: nein, Musik läuft in echter Zeit. - Soll *Play song* an einer bestimmten Stelle beginnen können, an einem Takt oder einem Marker aus #334?
meleki added the new label 2026-10-06 07:02:13 +02:00
Author
Owner

Vorgezogen: Play pattern und Stop pattern (2a3b90b)

Auf Wunsch vorgezogen, bevor #334 kommt: Ein Spiel kann schon jetzt ein einzelnes Pattern abspielen. Songs fehlen noch, deshalb bleibt dieses Issue offen.

Was es gibt

  • Play pattern spielt das ganze Pattern über sein Instrument, im Tempo des Patterns. Der Loop im Lineal gilt nur beim Bearbeiten.
    • Eingänge: pattern, volume, loop (Standard an) und detached.
    • Ausgang: playback, die Nummer dieses Abspielens. Ohne Instrument oder ohne Noten ist sie 0.
    • Mit loop aus läuft das Pattern einmal und endet von selbst.
    • Zweimal auslösen heißt zweimal abspielen, überlappend, wie bei Play sound.
  • Stop pattern stoppt ein Pattern, ohne Auswahl alle Patterns (Sounds laufen weiter), mit verbundenem playback genau dieses eine Abspielen. Let ring lässt Noten mit Envelope im Release ausklingen.
  • Besitz wie bei einem Sound: Wird das Objekt zerstört, endet das Pattern, außer detached ist an. Am Ende des Laufs stoppt es immer.
  • Stop sound ohne Auswahl stoppt auch Patterns, und sein Eingang voice nimmt auch ein playback.

Technik

  • Jedes Abspielen hat einen eigenen Scheduler (src/core/music/playbacks.ts). Es wartet zuerst auf seine Dateien, ein Stopp, der vorher kommt, gewinnt.
  • Der Scheduler kennt jetzt ein Ende für Sequenzen ohne Loop.
  • Der Takt-Worker liegt jetzt in src/viewport/wake.ts.

Was das für dieses Issue heißt

  • Play song und Stop song können auf denselben Weg aufsetzen: Verwaltung der Abspielungen, Besitz, Ende und Ausklingen sind da.
  • Die Rückfragen oben sind damit nicht beantwortet: Musik-Kanal, Szenenwechsel, Pause, Zeitskala und Startpunkt bleiben für die Fragerunde zu diesem Issue offen. Ein Pattern hat dazu heute kein eigenes Verhalten, es folgt nur dem Objekt, das es gestartet hat.
  • Kein tempo-Eingang und kein Ereignis „Pattern ist fertig“. Beides lässt sich nachrüsten.

Tests

pattern-play.test.ts (neu)  → 8 Tests grün, dazu 7 Fälle im Node-Katalog
e2e 64 (melektaus-atx)      → ALL PASSED, 23 Checks (+3)
Gate (melektaus-atx)        → CHECK EXIT 0, 248 Dateien, 3854 Tests
  • Im echten Chrome: Ein Takt Viertel bei 150 BPM wurde geloopt und die Noten exakt 0,4 s auseinander eingeplant. Beim Stoppen des Spiels war das Pattern weg, mit Loop aus endete es nach seinem Takt von selbst.
  • Gegenproben: ohne Ende im Scheduler fällt 1 Test, ohne Besitzer ebenfalls 1.
  • Nicht geprüft: Stop pattern im Browser (nur Unit-Tests), Pause game mit laufendem Pattern, Firefox, und gehört hat niemand etwas.

Wiki: 340046d (Patterns, Abschnitt Playing one in a game; Behaviors; Development).

## Vorgezogen: *Play pattern* und *Stop pattern* (`2a3b90b`) Auf Wunsch vorgezogen, bevor #334 kommt: Ein Spiel kann schon jetzt ein **einzelnes Pattern** abspielen. Songs fehlen noch, deshalb bleibt dieses Issue offen. ### Was es gibt - ***Play pattern*** spielt das **ganze** Pattern über sein Instrument, im Tempo des Patterns. Der Loop im Lineal gilt nur beim Bearbeiten. - Eingänge: `pattern`, `volume`, `loop` (Standard an) und `detached`. - Ausgang: `playback`, die Nummer dieses Abspielens. Ohne Instrument oder ohne Noten ist sie 0. - Mit `loop` aus läuft das Pattern einmal und endet von selbst. - Zweimal auslösen heißt zweimal abspielen, überlappend, wie bei *Play sound*. - ***Stop pattern*** stoppt ein Pattern, ohne Auswahl alle Patterns (Sounds laufen weiter), mit verbundenem `playback` genau dieses eine Abspielen. *Let ring* lässt Noten mit Envelope im Release ausklingen. - **Besitz wie bei einem Sound:** Wird das Objekt zerstört, endet das Pattern, außer `detached` ist an. Am Ende des Laufs stoppt es immer. - ***Stop sound*** ohne Auswahl stoppt auch Patterns, und sein Eingang `voice` nimmt auch ein `playback`. ### Technik - Jedes Abspielen hat einen eigenen Scheduler (`src/core/music/playbacks.ts`). Es wartet zuerst auf seine Dateien, ein Stopp, der vorher kommt, gewinnt. - Der Scheduler kennt jetzt ein Ende für Sequenzen ohne Loop. - Der Takt-Worker liegt jetzt in `src/viewport/wake.ts`. ### Was das für dieses Issue heißt - *Play song* und *Stop song* können auf denselben Weg aufsetzen: Verwaltung der Abspielungen, Besitz, Ende und Ausklingen sind da. - Die Rückfragen oben sind damit **nicht** beantwortet: Musik-Kanal, Szenenwechsel, Pause, Zeitskala und Startpunkt bleiben für die Fragerunde zu diesem Issue offen. Ein Pattern hat dazu heute kein eigenes Verhalten, es folgt nur dem Objekt, das es gestartet hat. - Kein `tempo`-Eingang und kein Ereignis „Pattern ist fertig“. Beides lässt sich nachrüsten. ### Tests ``` pattern-play.test.ts (neu) → 8 Tests grün, dazu 7 Fälle im Node-Katalog e2e 64 (melektaus-atx) → ALL PASSED, 23 Checks (+3) Gate (melektaus-atx) → CHECK EXIT 0, 248 Dateien, 3854 Tests ``` - Im echten Chrome: Ein Takt Viertel bei 150 BPM wurde geloopt und die Noten exakt 0,4 s auseinander eingeplant. Beim Stoppen des Spiels war das Pattern weg, mit *Loop* aus endete es nach seinem Takt von selbst. - Gegenproben: ohne Ende im Scheduler fällt 1 Test, ohne Besitzer ebenfalls 1. - **Nicht geprüft:** *Stop pattern* im Browser (nur Unit-Tests), *Pause game* mit laufendem Pattern, Firefox, und gehört hat niemand etwas. Wiki: `340046d` (*Patterns*, Abschnitt *Playing one in a game*; *Behaviors*; *Development*).
admin added this to the Development project 2026-10-06 15:56:09 +02:00
admin moved this to Next in Development on 2026-10-06 16:30:27 +02:00
admin removed the new label 2026-10-06 16:30:37 +02:00
Author
Owner

Umgesetzt in f97961c, Wiki in 528dc7f (Songs → Playing one in a game, dazu Patterns und Behaviors). Der Vorgriff mit Play pattern / Stop pattern steht in Kommentar 3431 (2a3b90b).

Entscheidungen

Nr. Thema Entscheidung
1 Songs gleichzeitig B: beliebig viele nebeneinander, wie bei Play pattern
2 Szenenwechsel A: Der Song gehört dem Objekt, detached standardmäßig aus
3 Pause game A: Die Musik läuft weiter
4 Zeitlupe A: Die Musik läuft in echter Zeit
5 Startpunkt B: kommt mit den Markern in #338
6 Loop im Spiel A: Intro einmal, dann der Loop aus dem Lineal

Was es gibt

  • Play song: Eingänge song, volume, fade in (s), loop (Standard an), detached (Standard aus), Ausgang playback (0, wenn auf den Spuren nichts liegt).
    • Loop an: ab Takt 1, dann im Lineal-Loop. Ohne gesetzten Loop kreist der ganze Song. Loop aus: einmal bis zum Ende.
    • Die Spuren behalten Volume, Pan, Mute und Solo. Gespielt wird im Tempo des Songs.
  • Stop song: song (ohne Auswahl alle Songs), playback (genau eines), fade out (s).
  • Stop sound ohne Auswahl stoppt auch Songs. Stop pattern ohne Auswahl stoppt jetzt nur noch Patterns.
  • Jedes Abspielen hat einen eigenen Master (stumm bis zur ersten Note), die Spuren des Songs hängen darin auf eigenen Bussen. Ist das Abspielen vorbei, werden sie abgebaut.

Befunde (behoben)

  • Toolbar-Pause wurde aufgehoben: Jedes Lesen der Audio-Uhr hat einen angehaltenen Context geweckt, ein laufendes Pattern also nach spätestens 25 ms. Jetzt bleibt der Context angehalten, solange die Toolbar pausiert. Im Chrome gemessen: Uhr während der Pause zweimal 28.0613…, nach dem Fortsetzen lief sie weiter.
  • Endlosrekursion bei Play pattern mit Loop aus (seit 2a3b90b): Nach der letzten Stimme fragten sich Pattern und Abspielliste gegenseitig ab, bis RangeError: Maximum call stack size exceeded. Warum e2e 64 damals trotzdem grün war, ist nicht untersucht.

Tests

song-play.test.ts (neu)     → 8 grün, dazu 8 Fälle im Node-Katalog
sound-library.test.ts       → 66 grün, davon 4 neu
e2e 64 (melektaus-atx)      → 23/23 grün
e2e 65 (melektaus-atx)      → ALL PASSED - 22 Checks (+4)
Gate (melektaus-atx)        → CHECK EXIT 0, 251 Dateien, 3903 Tests
  • Im Chrome gemessen (Clip auf Takt 1, Pattern auf Takt 2, Loop auf Takt 2, 120 BPM): Clip einmal, erste Pattern-Note 2 s danach, dann alle 2 s. Master 0,8, Spur -6 dB / Pan -0,5 → 0,501 / -0,5. Stop song mit 1 s Fade-out beendet den Song, die Busse sind danach weg.
  • Gegenproben: drei Stellen einzeln verbogen, je 1 Test fällt.
  • CI zu f97961c: nicht abgewartet.

Nicht geprüft

  • Gehört hat niemand etwas, Firefox lief nicht.
  • Das Einblenden nur als geplante Rampe im Unit-Test, nicht im Browser gemessen.
  • detached, Szenenwechsel und Stop song mit playback nur im Unit-Test.

Nicht dabei

  • Ereignis „Song ist fertig“, Node für die Lautstärke eines laufenden Songs
  • Marker und Game-Sync (#338), Automation (#337), Musik-Bus (#325)
Umgesetzt in f97961c, Wiki in 528dc7f (*Songs* → *Playing one in a game*, dazu *Patterns* und *Behaviors*). Der Vorgriff mit *Play pattern* / *Stop pattern* steht in Kommentar 3431 (2a3b90b). ## Entscheidungen | Nr. | Thema | Entscheidung | |---|---|---| | 1 | Songs gleichzeitig | **B**: beliebig viele nebeneinander, wie bei *Play pattern* | | 2 | Szenenwechsel | **A**: Der Song gehört dem Objekt, `detached` standardmäßig aus | | 3 | *Pause game* | **A**: Die Musik läuft weiter | | 4 | Zeitlupe | **A**: Die Musik läuft in echter Zeit | | 5 | Startpunkt | **B**: kommt mit den Markern in #338 | | 6 | Loop im Spiel | **A**: Intro einmal, dann der Loop aus dem Lineal | ## Was es gibt - **Play song**: Eingänge `song`, `volume`, `fade in` (s), `loop` (Standard an), `detached` (Standard aus), Ausgang `playback` (0, wenn auf den Spuren nichts liegt). - Loop an: ab Takt 1, dann im Lineal-Loop. Ohne gesetzten Loop kreist der ganze Song. Loop aus: einmal bis zum Ende. - Die Spuren behalten Volume, Pan, Mute und Solo. Gespielt wird im Tempo des Songs. - **Stop song**: `song` (ohne Auswahl alle Songs), `playback` (genau eines), `fade out` (s). - *Stop sound* ohne Auswahl stoppt auch Songs. *Stop pattern* ohne Auswahl stoppt jetzt nur noch Patterns. - Jedes Abspielen hat einen eigenen Master (stumm bis zur ersten Note), die Spuren des Songs hängen darin auf eigenen Bussen. Ist das Abspielen vorbei, werden sie abgebaut. ## Befunde (behoben) - **Toolbar-Pause wurde aufgehoben:** Jedes Lesen der Audio-Uhr hat einen angehaltenen Context geweckt, ein laufendes Pattern also nach spätestens 25 ms. Jetzt bleibt der Context angehalten, solange die Toolbar pausiert. Im Chrome gemessen: Uhr während der Pause zweimal `28.0613…`, nach dem Fortsetzen lief sie weiter. - **Endlosrekursion bei *Play pattern* mit Loop aus** (seit 2a3b90b): Nach der letzten Stimme fragten sich Pattern und Abspielliste gegenseitig ab, bis `RangeError: Maximum call stack size exceeded`. Warum e2e 64 damals trotzdem grün war, ist nicht untersucht. ## Tests ``` song-play.test.ts (neu) → 8 grün, dazu 8 Fälle im Node-Katalog sound-library.test.ts → 66 grün, davon 4 neu e2e 64 (melektaus-atx) → 23/23 grün e2e 65 (melektaus-atx) → ALL PASSED - 22 Checks (+4) Gate (melektaus-atx) → CHECK EXIT 0, 251 Dateien, 3903 Tests ``` - Im Chrome gemessen (Clip auf Takt 1, Pattern auf Takt 2, Loop auf Takt 2, 120 BPM): Clip einmal, erste Pattern-Note 2 s danach, dann alle 2 s. Master 0,8, Spur -6 dB / Pan -0,5 → 0,501 / -0,5. *Stop song* mit 1 s Fade-out beendet den Song, die Busse sind danach weg. - Gegenproben: drei Stellen einzeln verbogen, je 1 Test fällt. - CI zu f97961c: nicht abgewartet. ## Nicht geprüft - Gehört hat niemand etwas, Firefox lief nicht. - Das Einblenden nur als geplante Rampe im Unit-Test, nicht im Browser gemessen. - `detached`, Szenenwechsel und *Stop song* mit `playback` nur im Unit-Test. ## Nicht dabei - Ereignis „Song ist fertig“, Node für die Lautstärke eines laufenden Songs - Marker und Game-Sync (#338), Automation (#337), Musik-Bus (#325)
admin moved this to Done in Development on 2026-10-06 20:04:02 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#336