mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +00:00
Stop sources immediately when the sound is forced to stop
The reason for the previous delay was to allow OpenAL Soft to fade the sound to silence and avoid a sudden amplitude change, which can cause a "click" or "pop" noise. However, with OpenAL Soft 1.20, this is a built-in feature of the mixer so the extra complexity is unnecessary.
This commit is contained in:
parent
c095872b0a
commit
e88b1039a3
2 changed files with 13 additions and 86 deletions
|
@ -185,7 +185,7 @@ class OpenALSoundStream : public SoundStream
|
||||||
if(Renderer->FreeSfx.Size() == 0)
|
if(Renderer->FreeSfx.Size() == 0)
|
||||||
{
|
{
|
||||||
FSoundChan *lowest = Renderer->FindLowestChannel();
|
FSoundChan *lowest = Renderer->FindLowestChannel();
|
||||||
if(lowest) Renderer->ForceStopChannel(lowest);
|
if(lowest) Renderer->StopChannel(lowest);
|
||||||
|
|
||||||
if(Renderer->FreeSfx.Size() == 0)
|
if(Renderer->FreeSfx.Size() == 0)
|
||||||
return false;
|
return false;
|
||||||
|
@ -667,14 +667,6 @@ OpenALSoundRenderer::OpenALSoundRenderer()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALCint refresh=0;
|
|
||||||
alcGetIntegerv(Device, ALC_REFRESH, 1, &refresh);
|
|
||||||
if(refresh > 0)
|
|
||||||
{
|
|
||||||
// Round up instead of down
|
|
||||||
UpdateTimeMS = (1000+refresh-1) / refresh;
|
|
||||||
}
|
|
||||||
|
|
||||||
ALCint numMono=0, numStereo=0;
|
ALCint numMono=0, numStereo=0;
|
||||||
alcGetIntegerv(Device, ALC_MONO_SOURCES, 1, &numMono);
|
alcGetIntegerv(Device, ALC_MONO_SOURCES, 1, &numMono);
|
||||||
alcGetIntegerv(Device, ALC_STEREO_SOURCES, 1, &numStereo);
|
alcGetIntegerv(Device, ALC_STEREO_SOURCES, 1, &numStereo);
|
||||||
|
@ -1212,7 +1204,7 @@ void OpenALSoundRenderer::UnloadSound(SoundHandle sfx)
|
||||||
if((ALuint)bufID == buffer)
|
if((ALuint)bufID == buffer)
|
||||||
{
|
{
|
||||||
FSoundChan *next = schan->NextChan;
|
FSoundChan *next = schan->NextChan;
|
||||||
ForceStopChannel(schan);
|
StopChannel(schan);
|
||||||
schan = next;
|
schan = next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1220,20 +1212,6 @@ void OpenALSoundRenderer::UnloadSound(SoundHandle sfx)
|
||||||
schan = schan->NextChan;
|
schan = schan->NextChan;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure to kill any currently fading sounds too
|
|
||||||
for(auto iter = FadingSources.begin();iter != FadingSources.end();)
|
|
||||||
{
|
|
||||||
ALint bufID = 0;
|
|
||||||
alGetSourcei(iter->first, AL_BUFFER, &bufID);
|
|
||||||
if(static_cast<ALuint>(bufID) == buffer)
|
|
||||||
{
|
|
||||||
FreeSource(iter->first);
|
|
||||||
iter = FadingSources.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
|
|
||||||
alDeleteBuffers(1, &buffer);
|
alDeleteBuffers(1, &buffer);
|
||||||
getALError();
|
getALError();
|
||||||
}
|
}
|
||||||
|
@ -1257,7 +1235,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
||||||
if(FreeSfx.Size() == 0)
|
if(FreeSfx.Size() == 0)
|
||||||
{
|
{
|
||||||
FSoundChan *lowest = FindLowestChannel();
|
FSoundChan *lowest = FindLowestChannel();
|
||||||
if(lowest) ForceStopChannel(lowest);
|
if(lowest) StopChannel(lowest);
|
||||||
|
|
||||||
if(FreeSfx.Size() == 0)
|
if(FreeSfx.Size() == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1363,7 +1341,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
||||||
{
|
{
|
||||||
if(lowest->Priority < priority || (lowest->Priority == priority &&
|
if(lowest->Priority < priority || (lowest->Priority == priority &&
|
||||||
lowest->DistanceSqr > dist_sqr))
|
lowest->DistanceSqr > dist_sqr))
|
||||||
ForceStopChannel(lowest);
|
StopChannel(lowest);
|
||||||
}
|
}
|
||||||
if(FreeSfx.Size() == 0)
|
if(FreeSfx.Size() == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1566,8 +1544,15 @@ void OpenALSoundRenderer::ChannelPitch(FISoundChannel *chan, float pitch)
|
||||||
alSourcef(source, AL_PITCH, std::max(pitch, 0.0001f));
|
alSourcef(source, AL_PITCH, std::max(pitch, 0.0001f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenALSoundRenderer::FreeSource(ALuint source)
|
void OpenALSoundRenderer::StopChannel(FISoundChannel *chan)
|
||||||
{
|
{
|
||||||
|
if(chan == NULL || chan->SysChannel == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ALuint source = GET_PTRID(chan->SysChannel);
|
||||||
|
// Release first, so it can be properly marked as evicted if it's being killed
|
||||||
|
soundEngine->ChannelEnded(chan);
|
||||||
|
|
||||||
alSourceRewind(source);
|
alSourceRewind(source);
|
||||||
alSourcei(source, AL_BUFFER, 0);
|
alSourcei(source, AL_BUFFER, 0);
|
||||||
getALError();
|
getALError();
|
||||||
|
@ -1583,41 +1568,6 @@ void OpenALSoundRenderer::FreeSource(ALuint source)
|
||||||
FreeSfx.Push(source);
|
FreeSfx.Push(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenALSoundRenderer::StopChannel(FISoundChannel *chan)
|
|
||||||
{
|
|
||||||
if(chan == NULL || chan->SysChannel == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ALuint source = GET_PTRID(chan->SysChannel);
|
|
||||||
// Release first, so it can be properly marked as evicted if it's being killed
|
|
||||||
soundEngine->ChannelEnded(chan);
|
|
||||||
|
|
||||||
ALint state = AL_INITIAL;
|
|
||||||
alGetSourcei(source, AL_SOURCE_STATE, &state);
|
|
||||||
if(state != AL_PLAYING)
|
|
||||||
FreeSource(source);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// The sound is being killed while playing, so set its gain to 0 and track it
|
|
||||||
// as it fades.
|
|
||||||
alSourcef(source, AL_GAIN, 0.f);
|
|
||||||
getALError();
|
|
||||||
|
|
||||||
FadingSources.insert(std::make_pair(
|
|
||||||
source, std::chrono::steady_clock::now().time_since_epoch().count()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenALSoundRenderer::ForceStopChannel(FISoundChannel *chan)
|
|
||||||
{
|
|
||||||
ALuint source = GET_PTRID(chan->SysChannel);
|
|
||||||
if(!source) return;
|
|
||||||
|
|
||||||
soundEngine->ChannelEnded(chan);
|
|
||||||
FreeSource(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned int OpenALSoundRenderer::GetPosition(FISoundChannel *chan)
|
unsigned int OpenALSoundRenderer::GetPosition(FISoundChannel *chan)
|
||||||
{
|
{
|
||||||
|
@ -1884,23 +1834,6 @@ void OpenALSoundRenderer::UpdateSounds()
|
||||||
{
|
{
|
||||||
alProcessUpdatesSOFT();
|
alProcessUpdatesSOFT();
|
||||||
|
|
||||||
if(!FadingSources.empty())
|
|
||||||
{
|
|
||||||
auto cur_time = std::chrono::steady_clock::now().time_since_epoch();
|
|
||||||
for(auto iter = FadingSources.begin();iter != FadingSources.end();)
|
|
||||||
{
|
|
||||||
auto time_diff = std::chrono::duration_cast<std::chrono::milliseconds>(cur_time -
|
|
||||||
std::chrono::steady_clock::time_point::duration(iter->second));
|
|
||||||
if(time_diff.count() >= UpdateTimeMS)
|
|
||||||
{
|
|
||||||
FreeSource(iter->first);
|
|
||||||
iter = FadingSources.erase(iter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
++iter;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ALC.EXT_disconnect)
|
if(ALC.EXT_disconnect)
|
||||||
{
|
{
|
||||||
ALCint connected = ALC_TRUE;
|
ALCint connected = ALC_TRUE;
|
||||||
|
@ -2049,7 +1982,7 @@ void OpenALSoundRenderer::PurgeStoppedSources()
|
||||||
{
|
{
|
||||||
if(schan->SysChannel != NULL && src == GET_PTRID(schan->SysChannel))
|
if(schan->SysChannel != NULL && src == GET_PTRID(schan->SysChannel))
|
||||||
{
|
{
|
||||||
ForceStopChannel(schan);
|
StopChannel(schan);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
schan = schan->NextChan;
|
schan = schan->NextChan;
|
||||||
|
|
|
@ -245,10 +245,8 @@ private:
|
||||||
void RemoveStream(OpenALSoundStream *stream);
|
void RemoveStream(OpenALSoundStream *stream);
|
||||||
|
|
||||||
void LoadReverb(const ReverbContainer *env);
|
void LoadReverb(const ReverbContainer *env);
|
||||||
void FreeSource(ALuint source);
|
|
||||||
void PurgeStoppedSources();
|
void PurgeStoppedSources();
|
||||||
static FSoundChan *FindLowestChannel();
|
static FSoundChan *FindLowestChannel();
|
||||||
void ForceStopChannel(FISoundChannel *chan);
|
|
||||||
|
|
||||||
std::thread StreamThread;
|
std::thread StreamThread;
|
||||||
std::mutex StreamLock;
|
std::mutex StreamLock;
|
||||||
|
@ -269,10 +267,6 @@ private:
|
||||||
TArray<ALuint> ReverbSfx;
|
TArray<ALuint> ReverbSfx;
|
||||||
TArray<ALuint> SfxGroup;
|
TArray<ALuint> SfxGroup;
|
||||||
|
|
||||||
int UpdateTimeMS;
|
|
||||||
using SourceTimeMap = std::unordered_map<ALuint,int64_t>;
|
|
||||||
SourceTimeMap FadingSources;
|
|
||||||
|
|
||||||
const ReverbContainer *PrevEnvironment;
|
const ReverbContainer *PrevEnvironment;
|
||||||
|
|
||||||
typedef TMap<uint16_t,ALuint> EffectMap;
|
typedef TMap<uint16_t,ALuint> EffectMap;
|
||||||
|
|
Loading…
Reference in a new issue