Implement sound stop/flush (stopping boombox no longer asserts)

This commit is contained in:
elasota
2019-12-26 13:32:54 -05:00
parent b9f1d5222f
commit 501f36070a
7 changed files with 66 additions and 4 deletions

View File

@@ -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() void GpAudioChannelXAudio2::Destroy()
{ {
this->~GpAudioChannelXAudio2(); this->~GpAudioChannelXAudio2();

View File

@@ -15,8 +15,9 @@ public:
static GpAudioChannelXAudio2 *Create(GpAudioDriverXAudio2 *driver); static GpAudioChannelXAudio2 *Create(GpAudioDriverXAudio2 *driver);
void SetAudioChannelContext(IGpAudioChannelCallbacks *callbacks); void SetAudioChannelContext(IGpAudioChannelCallbacks *callbacks) override;
void PostBuffer(const void *buffer, size_t bufferSize); void PostBuffer(const void *buffer, size_t bufferSize) override;
void Stop() override;
void Destroy() override; void Destroy() override;
bool Init(); bool Init();

View File

@@ -6,5 +6,6 @@ struct IGpAudioChannel
{ {
virtual void SetAudioChannelContext(IGpAudioChannelCallbacks *callbacks) = 0; virtual void SetAudioChannelContext(IGpAudioChannelCallbacks *callbacks) = 0;
virtual void PostBuffer(const void *buffer, size_t bufferSize) = 0; virtual void PostBuffer(const void *buffer, size_t bufferSize) = 0;
virtual void Stop() = 0;
virtual void Destroy() = 0; virtual void Destroy() = 0;
}; };

View File

@@ -16,6 +16,11 @@ void GpPLGlueAudioChannel::PostBuffer(const void *buffer, size_t bufferSize)
m_audioChannel->PostBuffer(buffer, bufferSize); m_audioChannel->PostBuffer(buffer, bufferSize);
} }
void GpPLGlueAudioChannel::Stop()
{
m_audioChannel->Stop();
}
void GpPLGlueAudioChannel::Destroy() void GpPLGlueAudioChannel::Destroy()
{ {
this->~GpPLGlueAudioChannel(); this->~GpPLGlueAudioChannel();

View File

@@ -10,6 +10,7 @@ class GpPLGlueAudioChannel final : public PortabilityLayer::HostAudioChannel, pu
public: public:
void SetClientAudioChannelContext(PortabilityLayer::ClientAudioChannelContext *context) override; void SetClientAudioChannelContext(PortabilityLayer::ClientAudioChannelContext *context) override;
void PostBuffer(const void *buffer, size_t bufferSize) override; void PostBuffer(const void *buffer, size_t bufferSize) override;
void Stop() override;
void Destroy() override; void Destroy() override;
void NotifyBufferFinished() override; void NotifyBufferFinished() override;

View File

@@ -9,6 +9,7 @@ namespace PortabilityLayer
public: public:
virtual void SetClientAudioChannelContext(ClientAudioChannelContext *context) = 0; virtual void SetClientAudioChannelContext(ClientAudioChannelContext *context) = 0;
virtual void PostBuffer(const void *buffer, size_t bufferSize) = 0; virtual void PostBuffer(const void *buffer, size_t bufferSize) = 0;
virtual void Stop() = 0;
virtual void Destroy() = 0; virtual void Destroy() = 0;
}; };
} }

View File

@@ -19,6 +19,8 @@ namespace PortabilityLayer
~AudioChannelImpl(); ~AudioChannelImpl();
bool PushCommand(const SndCommand &command, bool blocking); bool PushCommand(const SndCommand &command, bool blocking);
void ClearAllCommands();
void Stop();
void NotifyBufferFinished() override; void NotifyBufferFinished() override;
@@ -196,6 +198,38 @@ namespace PortabilityLayer
return true; 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) OSErr GetDefaultOutputVolume(long *vol)
@@ -297,7 +331,17 @@ OSErr SndDoCommand(SndChannelPtr channel, const SndCommand *command, Boolean fai
OSErr SndDoImmediate(SndChannelPtr channel, const SndCommand *command) OSErr SndDoImmediate(SndChannelPtr channel, const SndCommand *command)
{ {
PL_NotYetImplemented(); PortabilityLayer::AudioChannelImpl *audioChannelImpl = static_cast<PortabilityLayer::AudioChannelImpl*>(channel);
return noErr;
if (command->cmd == flushCmd)
audioChannelImpl->ClearAllCommands();
else if (command->cmd == quietCmd)
audioChannelImpl->Stop();
else
{
assert(false);
return genericErr;
} }
return noErr;
}