Commit Graph
5 Commits
Author SHA1 Message Date
Daniel SamsonandClaude Opus 4.7 c989fc4eea implement reverb tail, LoopMode, and playlist navigation
DynamicSound.ReverbTail now drives a seamless transition: when the current
song is within ReverbTail seconds of its full length, the next song is started
so its opening covers the outgoing tail. Both songs are audible during the
overlap; the outgoing one stops when its full length has elapsed.

API changes (continuous players only):
- Replaces `Loop : bool` with `LoopMode : enum { Single, All }`. Single keeps
  repeating the current song; All advances through the playlist and wraps
  back to index 0. There is no longer a "play once and stop" mode.
- The playlist resource is no longer mutated. The player tracks an internal
  index instead of popping songs off the front.
- Adds `get_current_song_index() -> int`, `advance_to_next_song()`, and
  `advance_to_track(index: int)` on each continuous wrapper. Both advance
  methods accelerate the outgoing song so its remaining time hits ReverbTail
  immediately, giving a smooth transition rather than a hard cut.

Internals: DynamicSoundPlayerCore now keeps an `_active_songs` array of an
inner _ActiveSong record (ids, start_time, song_length, reverb_tail,
started_next). _process advances time globally and runs the start-next /
stop-old conditions per active song, mirroring the OvaniPlayer reference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 16:07:06 +01:00
Daniel SamsonandClaude Opus 4.7 e8224e3913 respect autoplay; add play_playlist() for manual start
DynamicSoundPlayerCore.ready() always called play() if a playlist had songs,
ignoring the inherited AudioStreamPlayer.autoplay property. Now early-returns
when autoplay is false. Adds play_playlist() (exposed on all three continuous
wrappers) so users with autoplay=false have a non-fade way to start playback.
fade_in() now uses the same _start_playback() helper.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 15:29:08 +01:00
Daniel SamsonandClaude Opus 4.7 36350ab8d5 ship a sample bus layout with Music and FX
Adds default_bus_layout.tres at the addon root containing a Music bus and an
FX bus, each routing into Master. Users can point Project Settings → Audio →
Default Bus Layout at this file (or copy it to their project root) to get the
buses the players auto-route to in the editor. README documents the wiring.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 15:09:10 +01:00
Daniel SamsonandClaude Opus 4.7 dd805a4cd9 move PitchMode to FX players and implement random pitch
The continuous music players had PitchMode/RandomMin/MaxPitchScale exports but
no logic referenced them. Pitch variation only makes sense per-trigger, which
the FX family supports natively. So:

- Remove PitchMode, RandomMinPitchScale, RandomMaxPitchScale, and the
  _validate_property hook from DynamicSoundPlayer / 2D / 3D.
- Add the same exports + _validate_property to DynamicSoundFXPlayer / 2D / 3D.
- Implement pitch resolution in DynamicSoundFXPlayerCore.play_fx: each trigger
  samples a fresh pitch from PitchMode and passes it as the pitch_scale
  argument to AudioStreamPlaybackPolyphonic.play_stream.
- Random pitch uses 1.0 + randf_range(min, max) so the existing -0.5/0.5
  defaults give a useful [0.5, 1.5] pitch range.
- README updated to reflect the move.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 15:03:03 +01:00
Daniel SamsonandClaude Opus 4.7 cb47d89377 Initial commit: dynamic music & FX players
Continuous music players (DynamicSoundPlayer, 2D, 3D) with intensity-blended
layers, playlist queue, Loop, fade in/out, pause/resume. One-shot SFX players
(DynamicSoundFXPlayer, 2D, 3D) for overlapping triggers. All variants share
RefCounted core classes via duck-typed property access.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 14:46:48 +01:00