diff --git a/app/src/main/cpp/skyline/audio.cpp b/app/src/main/cpp/skyline/audio.cpp index a450a8c3..073bc098 100644 --- a/app/src/main/cpp/skyline/audio.cpp +++ b/app/src/main/cpp/skyline/audio.cpp @@ -35,7 +35,6 @@ namespace skyline::audio { std::lock_guard trackGuard(trackLock); audioTracks.erase(std::remove(audioTracks.begin(), audioTracks.end(), track), audioTracks.end()); - track.reset(); } oboe::DataCallbackResult Audio::onAudioReady(oboe::AudioStream *audioStream, void *audioData, int32_t numFrames) { diff --git a/app/src/main/cpp/skyline/audio/track.cpp b/app/src/main/cpp/skyline/audio/track.cpp index 77ef3f66..8f694cda 100644 --- a/app/src/main/cpp/skyline/audio/track.cpp +++ b/app/src/main/cpp/skyline/audio/track.cpp @@ -16,11 +16,18 @@ namespace skyline::audio { } void AudioTrack::Stop() { - while (!identifiers.end()->released); + auto allSamplesReleased{[&]() { + std::scoped_lock lock{bufferLock}; + return identifiers.empty() || identifiers.end()->released; + }}; + + while (!allSamplesReleased()); playbackState = AudioOutState::Stopped; } bool AudioTrack::ContainsBuffer(u64 tag) { + std::scoped_lock lock(bufferLock); + // Iterate from front of queue as we don't want released samples for (auto identifier{identifiers.crbegin()}; identifier != identifiers.crend(); identifier++) { if (identifier->released) @@ -35,7 +42,7 @@ namespace skyline::audio { std::vector AudioTrack::GetReleasedBuffers(u32 max) { std::vector bufferIds; - std::lock_guard trackGuard(bufferLock); + std::scoped_lock lock(bufferLock); for (u32 index{}; index < max; index++) { if (identifiers.empty() || !identifiers.back().released) @@ -48,14 +55,14 @@ namespace skyline::audio { } void AudioTrack::AppendBuffer(u64 tag, span buffer) { + std::scoped_lock lock(bufferLock); + BufferIdentifier identifier{ .released = false, .tag = tag, .finalSample = identifiers.empty() ? (buffer.size()) : (buffer.size() + identifiers.front().finalSample) }; - std::lock_guard guard(bufferLock); - identifiers.push_front(identifier); samples.Append(buffer); }