diff --git a/.vscode/settings.json b/.vscode/settings.json index f8fcb6720..0975eeb40 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -40,6 +40,7 @@ "ratio": "cpp", "tuple": "cpp", "type_traits": "cpp", - "stdexcept": "cpp" + "stdexcept": "cpp", + "fstream": "cpp" } } diff --git a/src/common/AudioQueue.cxx b/src/common/AudioQueue.cxx index 6156f37f6..8865a49bf 100644 --- a/src/common/AudioQueue.cxx +++ b/src/common/AudioQueue.cxx @@ -132,3 +132,15 @@ Int16* AudioQueue::dequeue(Int16* fragment) return nextFragment; } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void AudioQueue::closeSink(Int16* fragment) +{ + lock_guard guard(myMutex); + + if (myFirstFragmentForDequeue && fragment) + throw new runtime_error("attempt to return unknown buffer on closeSink"); + + if (!myFirstFragmentForDequeue) + myFirstFragmentForDequeue = fragment; +} diff --git a/src/common/AudioQueue.hxx b/src/common/AudioQueue.hxx index ec1637dd8..6b25d9bd6 100644 --- a/src/common/AudioQueue.hxx +++ b/src/common/AudioQueue.hxx @@ -86,15 +86,21 @@ class AudioQueue Int16* enqueue(Int16* fragment = 0); /** - * Dequeue a fragment for playback and return the played fragment. This may - * return 0 if there is no queued fragment to return (in this case, the returned - * fragment is not enqueued and must be passed in the next invocation). - * - * @param fragment The returned fragment. This must be empty on the first call (when - * there is nothing to return). + Dequeue a fragment for playback and return the played fragment. This may + return 0 if there is no queued fragment to return (in this case, the returned + fragment is not enqueued and must be passed in the next invocation). + + @param fragment The returned fragment. This must be empty on the first call (when + there is nothing to return). */ Int16* dequeue(Int16* fragment = 0); + /** + Return the currently playing fragment without drawing a new one. This is called + if the sink is closed and prepares the queue to be reopened. + */ + void closeSink(Int16* fragment); + private: // The size of an individual fragment (in stereo / mono samples) diff --git a/src/common/SoundSDL2.cxx b/src/common/SoundSDL2.cxx index 818ac96a5..32ef5ec90 100644 --- a/src/common/SoundSDL2.cxx +++ b/src/common/SoundSDL2.cxx @@ -143,6 +143,7 @@ void SoundSDL2::close() mute(true); + if (myAudioQueue) myAudioQueue->closeSink(myCurrentFragment); myAudioQueue = 0; myCurrentFragment = 0;