Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix OpenAlSound.Complete being incorrect when OpenAl source is reused. #19660

Merged
merged 2 commits into from Oct 1, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 50 additions & 12 deletions OpenRA.Platforms.Default/OpenAlSoundEngine.cs
Expand Up @@ -171,6 +171,15 @@ bool TryGetSourceFromPool(out uint source)
freeSources.Add(freeSource);
AL10.alSourceRewind(freeSource);
AL10.alSourcei(freeSource, AL10.AL_BUFFER, 0);

// Make sure we can accurately determine the end of the original sound,
// even if the source is immediately reused.
sound.UnbindSource();

var slot = kv.Value;
slot.SoundSource = null;
slot.Sound = null;
slot.IsActive = false;
}
}

Expand All @@ -180,14 +189,6 @@ bool TryGetSourceFromPool(out uint source)
return false;
}

foreach (var freeSource in freeSources)
{
var slot = sourcePool[freeSource];
slot.SoundSource = null;
slot.Sound = null;
slot.IsActive = false;
}

source = freeSources[0];
sourcePool[source].IsActive = true;
return true;
Expand Down Expand Up @@ -278,7 +279,7 @@ public float Volume

public void PauseSound(ISound sound, bool paused)
{
if (sound == null)
if (sound == null || sound.Complete)
return;

var source = ((OpenAlSound)sound).Source;
Expand Down Expand Up @@ -413,9 +414,11 @@ public void Dispose()

class OpenAlSound : ISound
{
public readonly uint Source;
internal uint Source { get; private set; }
protected readonly float SampleRate;

bool done;

public OpenAlSound(uint source, bool looping, bool relative, WPos pos, float volume, int sampleRate, uint buffer)
: this(source, looping, relative, pos, volume, sampleRate)
{
Expand All @@ -439,16 +442,39 @@ protected OpenAlSound(uint source, bool looping, bool relative, WPos pos, float
AL10.alSourcef(source, AL10.AL_MAX_DISTANCE, 136533);
}

internal void UnbindSource()
{
done = true;
Source = uint.MaxValue;
}

public float Volume
{
get { AL10.alGetSourcef(Source, AL10.AL_GAIN, out var volume); return volume; }
set => AL10.alSourcef(Source, AL10.AL_GAIN, value);
get
{
if (done)
return float.NaN;

AL10.alGetSourcef(Source, AL10.AL_GAIN, out var volume);
return volume;
}

set
{
if (done)
return;

AL10.alSourcef(Source, AL10.AL_GAIN, value);
}
}

public virtual float SeekPosition
{
get
{
if (done)
return float.NaN;

AL10.alGetSourcei(Source, AL11.AL_SAMPLE_OFFSET, out var sampleOffset);
return sampleOffset / SampleRate;
}
Expand All @@ -458,25 +484,37 @@ public virtual bool Complete
{
get
{
if (done)
return true;

AL10.alGetSourcei(Source, AL10.AL_SOURCE_STATE, out var state);
return state == AL10.AL_STOPPED;
}
}

public void SetPosition(WPos pos)
{
if (done)
return;

AL10.alSource3f(Source, AL10.AL_POSITION, pos.X, pos.Y, pos.Z);
}

protected void StopSource()
{
if (done)
return;

AL10.alGetSourcei(Source, AL10.AL_SOURCE_STATE, out var state);
if (state == AL10.AL_PLAYING || state == AL10.AL_PAUSED)
AL10.alSourceStop(Source);
}

public virtual void Stop()
{
if (done)
return;

StopSource();
AL10.alSourcei(Source, AL10.AL_BUFFER, 0);
}
Expand Down