@@ -16,7 +16,6 @@ constexpr float kMusicBaseGain = 0.28f;
1616constexpr float kMusicDuckGain = 0 .08f ;
1717constexpr float kMusicAttackPerSample = 0 .00012f ;
1818constexpr float kMusicReleasePerSample = 0 .00003f ;
19-
2019static int16_t ClampMixedSample (int value)
2120{
2221 if (value > std::numeric_limits<int16_t >::max ())
@@ -147,6 +146,10 @@ bool AudioOutput::LoadMusicFilesCsv(const char* csv, std::string* errorMessage)
147146 musicTrackIndex_ = 0 ;
148147 musicGain_ = 0 .0f ;
149148 musicEnabled_ = false ;
149+ #if defined(PPUC_HAS_SDL3_MIXER)
150+ musicTrackStartPending_ = false ;
151+ musicTrackStartTickMs_ = 0 ;
152+ #endif
150153
151154#if defined(PPUC_HAS_SDL3_MIXER)
152155 return ReloadMusicTracksLocked (errorMessage);
@@ -162,6 +165,7 @@ bool AudioOutput::LoadMusicFilesCsv(const char* csv, std::string* errorMessage)
162165void AudioOutput::SetMusicEnabled (bool enabled)
163166{
164167 std::lock_guard<std::mutex> lock (mutex_);
168+ const bool wasEnabled = musicEnabled_;
165169 musicEnabled_ = enabled;
166170
167171#if defined(PPUC_HAS_SDL3_MIXER)
@@ -176,7 +180,13 @@ void AudioOutput::SetMusicEnabled(bool enabled)
176180 return ;
177181 }
178182
179- if (MIX_TrackPaused (musicTrack_))
183+ if (!wasEnabled)
184+ {
185+ musicTrackStartPending_ = false ;
186+ musicTrackStartTickMs_ = 0 ;
187+ StartCurrentMusicTrackLocked ();
188+ }
189+ else if (MIX_TrackPaused (musicTrack_))
180190 {
181191 MIX_ResumeTrack (musicTrack_);
182192 }
@@ -187,6 +197,16 @@ void AudioOutput::SetMusicEnabled(bool enabled)
187197#endif
188198}
189199
200+ void AudioOutput::SetMusicTrackGapMs (Uint64 gapMs)
201+ {
202+ std::lock_guard<std::mutex> lock (mutex_);
203+ #if defined(PPUC_HAS_SDL3_MIXER)
204+ musicTrackGapMs_ = gapMs;
205+ #else
206+ (void )gapMs;
207+ #endif
208+ }
209+
190210void AudioOutput::QueueGameFrames (const int16_t * samples, size_t frameCount)
191211{
192212 if (samples == nullptr || frameCount == 0 )
@@ -379,6 +399,22 @@ void AudioOutput::MixMusicLocked(int16_t* mixBuffer, size_t sampleCount,
379399 return ;
380400 }
381401
402+ if (musicTrackStartPending_)
403+ {
404+ if (SDL_GetTicks () < musicTrackStartTickMs_)
405+ {
406+ return ;
407+ }
408+
409+ musicTrackStartPending_ = false ;
410+ musicTrackStartTickMs_ = 0 ;
411+ if (!StartCurrentMusicTrackLocked ())
412+ {
413+ musicGain_ = 0 .0f ;
414+ return ;
415+ }
416+ }
417+
382418 std::vector<int16_t > musicBuffer (sampleCount, 0 );
383419 const int generatedBytes =
384420 MIX_Generate (musicMixer_, musicBuffer.data (),
@@ -542,6 +578,9 @@ bool AudioOutput::StartCurrentMusicTrackLocked()
542578 return true ;
543579 }
544580
581+ musicTrackStartPending_ = false ;
582+ musicTrackStartTickMs_ = 0 ;
583+
545584 for (size_t attempts = 0 ; attempts < musicTracks_.size (); ++attempts)
546585 {
547586 MusicTrack& currentTrack = musicTracks_[musicTrackIndex_];
@@ -563,6 +602,12 @@ bool AudioOutput::StartCurrentMusicTrackLocked()
563602 return true ;
564603}
565604
605+ void AudioOutput::ScheduleNextMusicTrackLocked ()
606+ {
607+ musicTrackStartPending_ = true ;
608+ musicTrackStartTickMs_ = SDL_GetTicks () + musicTrackGapMs_;
609+ }
610+
566611void AudioOutput::AdvanceMusicTrackLocked ()
567612{
568613 if (!musicTracks_.empty ())
@@ -581,7 +626,7 @@ void AudioOutput::HandleMusicTrackStoppedLocked(MIX_Track* track)
581626 AdvanceMusicTrackLocked ();
582627 if (musicEnabled_)
583628 {
584- StartCurrentMusicTrackLocked ();
629+ ScheduleNextMusicTrackLocked ();
585630 }
586631}
587632#endif
0 commit comments