Add some safety around IDirectSoundBuffer::Release().

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2020-07-04 19:57:15 +01:00
parent 5dee29fbf9
commit 3cfea2da07
4 changed files with 20 additions and 5 deletions

View file

@ -206,7 +206,13 @@ void registerSoundBuffer(IDirectSoundBuffer * buffer)
void unregisterSoundBuffer(IDirectSoundBuffer * buffer)
{
activeSoundGenerators.erase(buffer);
const auto it = activeSoundGenerators.find(buffer);
if (it != activeSoundGenerators.end())
{
// stop the QAudioOutput before removing. is this necessary?
it->second->stop();
activeSoundGenerators.erase(it);
}
}
namespace QDirectSound

View file

@ -18,12 +18,16 @@ IDirectSoundBuffer::IDirectSoundBuffer(const size_t aBufferSize, const size_t aC
, mySoundNotify(new IDirectSoundNotify)
, mySoundBuffer(aBufferSize)
{
registerSoundBuffer(this);
}
IDirectSoundBuffer::~IDirectSoundBuffer()
HRESULT IDirectSoundBuffer::Release()
{
// unregister *before* the destructor is called (in Release below)
// makes things a little bit more linear
unregisterSoundBuffer(this);
// do not call any more methods after the next function returns
return IUnknown::Release();
}
HRESULT IDirectSoundBuffer::QueryInterface(int riid, void **ppvObject)
@ -85,6 +89,7 @@ HRESULT IDirectSoundBuffer::Restore()
HRESULT IDirectSoundBuffer::Lock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID * lplpvAudioPtr1, DWORD * lpdwAudioBytes1, LPVOID * lplpvAudioPtr2, DWORD * lpdwAudioBytes2, DWORD dwFlags )
{
// No attempt is made at restricting write buffer not to overtake play cursor
if (dwFlags & DSBLOCK_ENTIREBUFFER)
{
*lplpvAudioPtr1 = this->mySoundBuffer.data();
@ -122,6 +127,8 @@ HRESULT IDirectSoundBuffer::Lock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOI
HRESULT IDirectSoundBuffer::Read( DWORD dwReadBytes, LPVOID * lplpvAudioPtr1, DWORD * lpdwAudioBytes1, LPVOID * lplpvAudioPtr2, DWORD * lpdwAudioBytes2)
{
// Read up to dwReadBytes, never going past the write cursor
// Positions are updated immediately
const DWORD available = (this->myWritePosition - this->myPlayPosition) % this->bufferSize;
dwReadBytes = std::min(dwReadBytes, available);
@ -183,6 +190,8 @@ HRESULT IDirectSound::CreateSoundBuffer( LPCDSBUFFERDESC lpcDSBufferDesc, IDirec
const size_t flags = lpcDSBufferDesc->dwFlags;
IDirectSoundBuffer * dsb = new IDirectSoundBuffer(bufferSize, channels, sampleRate, bitsPerSample, flags);
registerSoundBuffer(dsb);
*lplpDirectSoundBuffer = dsb;
return DS_OK;
}

View file

@ -91,7 +91,7 @@ class IDirectSoundBuffer : public IUnknown
const size_t flags;
IDirectSoundBuffer(const size_t bufferSize, const size_t channels, const size_t sampleRate, const size_t bitsPerSample, const size_t flags);
virtual ~IDirectSoundBuffer();
virtual HRESULT Release();
HRESULT QueryInterface(int riid, void **ppvObject);

View file

@ -14,7 +14,7 @@ typedef GUID REFIID;
struct IUnknown
{
HRESULT QueryInterface(int riid, void **ppvObject);
HRESULT Release();
virtual HRESULT Release();
virtual ~IUnknown();
};