mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-12-14 03:59:36 +00:00
Implement sound stop/flush (stopping boombox no longer asserts)
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
if (command->cmd == flushCmd)
|
||||||
|
audioChannelImpl->ClearAllCommands();
|
||||||
|
else if (command->cmd == quietCmd)
|
||||||
|
audioChannelImpl->Stop();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
return genericErr;
|
||||||
|
}
|
||||||
|
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user