diff --git a/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.cpp b/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.cpp index 754a1f2..fc5df4c 100644 --- a/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.cpp +++ b/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.cpp @@ -80,6 +80,15 @@ void GpAudioChannelXAudio2::PostBuffer(const void *buffer, size_t bufferSize) } } +void GpAudioChannelXAudio2::Stop() +{ + // Set voice state BEFORE calling FlushSourceBuffers so state is idle before any callbacks trigger + m_sourceVoice->Stop(0, 0); + m_voiceState = VoiceState_Idle; + + m_sourceVoice->FlushSourceBuffers(); +} + void GpAudioChannelXAudio2::Destroy() { this->~GpAudioChannelXAudio2(); diff --git a/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.h b/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.h index cfcfb4c..b9317b2 100644 --- a/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.h +++ b/GpAudioDriver_XAudio2/GpAudioChannelXAudio2.h @@ -15,8 +15,9 @@ public: static GpAudioChannelXAudio2 *Create(GpAudioDriverXAudio2 *driver); - void SetAudioChannelContext(IGpAudioChannelCallbacks *callbacks); - void PostBuffer(const void *buffer, size_t bufferSize); + void SetAudioChannelContext(IGpAudioChannelCallbacks *callbacks) override; + void PostBuffer(const void *buffer, size_t bufferSize) override; + void Stop() override; void Destroy() override; bool Init(); diff --git a/GpCommon/IGpAudioChannel.h b/GpCommon/IGpAudioChannel.h index ab1dddd..3d34a26 100644 --- a/GpCommon/IGpAudioChannel.h +++ b/GpCommon/IGpAudioChannel.h @@ -6,5 +6,6 @@ struct IGpAudioChannel { virtual void SetAudioChannelContext(IGpAudioChannelCallbacks *callbacks) = 0; virtual void PostBuffer(const void *buffer, size_t bufferSize) = 0; + virtual void Stop() = 0; virtual void Destroy() = 0; }; diff --git a/GpD3D/GpPLGlueAudioChannel.cpp b/GpD3D/GpPLGlueAudioChannel.cpp index 1926e9c..5fb281d 100644 --- a/GpD3D/GpPLGlueAudioChannel.cpp +++ b/GpD3D/GpPLGlueAudioChannel.cpp @@ -16,6 +16,11 @@ void GpPLGlueAudioChannel::PostBuffer(const void *buffer, size_t bufferSize) m_audioChannel->PostBuffer(buffer, bufferSize); } +void GpPLGlueAudioChannel::Stop() +{ + m_audioChannel->Stop(); +} + void GpPLGlueAudioChannel::Destroy() { this->~GpPLGlueAudioChannel(); diff --git a/GpD3D/GpPLGlueAudioChannel.h b/GpD3D/GpPLGlueAudioChannel.h index c0cbba4..a4780ed 100644 --- a/GpD3D/GpPLGlueAudioChannel.h +++ b/GpD3D/GpPLGlueAudioChannel.h @@ -10,6 +10,7 @@ class GpPLGlueAudioChannel final : public PortabilityLayer::HostAudioChannel, pu public: void SetClientAudioChannelContext(PortabilityLayer::ClientAudioChannelContext *context) override; void PostBuffer(const void *buffer, size_t bufferSize) override; + void Stop() override; void Destroy() override; void NotifyBufferFinished() override; diff --git a/PortabilityLayer/HostAudioChannel.h b/PortabilityLayer/HostAudioChannel.h index 303263e..4dbfb4d 100644 --- a/PortabilityLayer/HostAudioChannel.h +++ b/PortabilityLayer/HostAudioChannel.h @@ -9,6 +9,7 @@ namespace PortabilityLayer public: virtual void SetClientAudioChannelContext(ClientAudioChannelContext *context) = 0; virtual void PostBuffer(const void *buffer, size_t bufferSize) = 0; + virtual void Stop() = 0; virtual void Destroy() = 0; }; } diff --git a/PortabilityLayer/PLSound.cpp b/PortabilityLayer/PLSound.cpp index 037c02d..3d2ecab 100644 --- a/PortabilityLayer/PLSound.cpp +++ b/PortabilityLayer/PLSound.cpp @@ -19,6 +19,8 @@ namespace PortabilityLayer ~AudioChannelImpl(); bool PushCommand(const SndCommand &command, bool blocking); + void ClearAllCommands(); + void Stop(); void NotifyBufferFinished() override; @@ -196,6 +198,38 @@ namespace PortabilityLayer return true; } + + void AudioChannelImpl::ClearAllCommands() + { + m_mutex->Lock(); + m_numQueuedCommands = 0; + m_nextDequeueCommandPos = 0; + m_nextInsertCommandPos = 0; + m_mutex->Unlock(); + } + + void AudioChannelImpl::Stop() + { + m_mutex->Lock(); + if (m_state == State_Idle) + { + m_mutex->Unlock(); + } + else if (m_state == State_PlayingAsync) + { + m_state = State_FlushStarting; + m_audioChannel->Stop(); + m_mutex->Unlock(); + + m_threadEvent->Wait(); + } + else + { + m_mutex->Unlock(); + assert(false); + } + } + } OSErr GetDefaultOutputVolume(long *vol) @@ -297,7 +331,17 @@ OSErr SndDoCommand(SndChannelPtr channel, const SndCommand *command, Boolean fai OSErr SndDoImmediate(SndChannelPtr channel, const SndCommand *command) { - PL_NotYetImplemented(); + PortabilityLayer::AudioChannelImpl *audioChannelImpl = static_cast(channel); + + if (command->cmd == flushCmd) + audioChannelImpl->ClearAllCommands(); + else if (command->cmd == quietCmd) + audioChannelImpl->Stop(); + else + { + assert(false); + return genericErr; + } + return noErr; } -