Skip to content

Commit

Permalink
Add support for gapless looping music.
Browse files Browse the repository at this point in the history
  • Loading branch information
Mailaender authored and abcdefg30 committed Nov 11, 2021
1 parent 9916e4c commit 9b1cec7
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 18 deletions.
23 changes: 16 additions & 7 deletions OpenRA.Game/Sound/Sound.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,12 @@ public void UnmuteAudio()
soundEngine.Volume = 1f;
}

public void SetMusicLooped(bool loop)
{
Game.Settings.Sound.Repeat = loop;
soundEngine.SetSoundLooping(loop, music);
}

public bool DisableAllSounds { get; set; }
public bool DisableWorldSounds { get; set; }
public ISound Play(SoundType type, string name) { return Play(type, null, name, true, WPos.Zero, 1f); }
Expand Down Expand Up @@ -202,11 +208,6 @@ public void Tick()
public bool MusicPlaying { get; private set; }
public MusicInfo CurrentMusic => currentMusic;

public void PlayMusic(MusicInfo m)
{
PlayMusicThen(m, () => { });
}

public void PlayMusicThen(MusicInfo m, Action then)
{
if (m == null || !m.Exists)
Expand All @@ -221,13 +222,21 @@ public void PlayMusicThen(MusicInfo m, Action then)
return;
}

PlayMusic(m, Game.Settings.Sound.Repeat);
}

public void PlayMusic(MusicInfo m, bool looped = false)
{
if (m == null || !m.Exists)
return;

StopMusic();

Func<ISoundFormat, ISound> stream = soundFormat => soundEngine.Play2DStream(
soundFormat.GetPCMInputStream(), soundFormat.Channels, soundFormat.SampleBits, soundFormat.SampleRate,
false, true, WPos.Zero, MusicVolume * m.VolumeModifier);
music = LoadSound(m.Filename, stream);
looped, true, WPos.Zero, MusicVolume * m.VolumeModifier);

music = LoadSound(m.Filename, stream);
if (music == null)
{
onMusicComplete = null;
Expand Down
1 change: 1 addition & 0 deletions OpenRA.Game/Sound/SoundDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public interface ISoundEngine : IDisposable
void StopAllSounds();
void SetListenerPosition(WPos position);
void SetSoundVolume(float volume, ISound music, ISound video);
void SetSoundLooping(bool looping, ISound sound);
}

public class SoundDevice
Expand Down
14 changes: 8 additions & 6 deletions OpenRA.Mods.Common/Traits/World/MusicPlaylist.cs
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,15 @@ void Play()
if (!SongExists(currentSong) || (CurrentSongIsBackground && IsBackgroundMusicMuted))
return;

Game.Sound.PlayMusicThen(currentSong, () =>
{
if (!CurrentSongIsBackground && !Game.Settings.Sound.Repeat)
currentSong = GetNextSong();
Game.Sound.PlayMusicThen(currentSong, PlayNextSong);
}

Play();
});
void PlayNextSong()
{
if (!CurrentSongIsBackground)
currentSong = GetNextSong();

Play();
}

public void Play(MusicInfo music)
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Widgets/Logic/MusicPlayerLogic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public MusicPlayerLogic(Widget widget, ModData modData, World world, Action onEx

var repeatCheckbox = panel.Get<CheckboxWidget>("REPEAT");
repeatCheckbox.IsChecked = () => Game.Settings.Sound.Repeat;
repeatCheckbox.OnClick = () => Game.Settings.Sound.Repeat ^= true;
repeatCheckbox.OnClick = () => Game.Sound.SetMusicLooped(!Game.Settings.Sound.Repeat);
repeatCheckbox.IsDisabled = () => musicPlaylist.CurrentSongIsBackground;

panel.Get<LabelWidget>("TIME_LABEL").GetText = () =>
Expand Down
1 change: 1 addition & 0 deletions OpenRA.Platforms.Default/DummySoundEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public float Volume
public void StopSound(ISound sound) { }
public void StopAllSounds() { }
public void SetListenerPosition(WPos position) { }
public void SetSoundLooping(bool looping, ISound sound) { }
public void Dispose() { }
}

Expand Down
20 changes: 16 additions & 4 deletions OpenRA.Platforms.Default/OpenAlSoundEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static string[] QueryDevices(string label, int type)
if (devicesPtr == IntPtr.Zero || AL10.alGetError() != AL10.AL_NO_ERROR)
{
Log.Write("sound", "Failed to query OpenAL device list using {0}", label);
return new string[0];
return Array.Empty<string>();
}

var devices = new List<string>();
Expand Down Expand Up @@ -103,7 +103,7 @@ static string[] PhysicalDevices()
if (ALC11.alcIsExtensionPresent(IntPtr.Zero, "ALC_ENUMERATION_EXT"))
return QueryDevices("ALC_ENUMERATION_EXT", ALC10.ALC_DEVICE_SPECIFIER);

return new string[] { };
return Array.Empty<string>();
}

internal static int MakeALFormat(int channels, int bits)
Expand Down Expand Up @@ -137,8 +137,7 @@ public OpenAlSoundEngine(string deviceName)

for (var i = 0; i < PoolSize; i++)
{
var source = 0U;
AL10.alGenSources(1, out source);
AL10.alGenSources(1, out var source);
if (AL10.alGetError() != AL10.AL_NO_ERROR)
{
Log.Write("sound", "Failed generating OpenAL source {0}", i);
Expand Down Expand Up @@ -346,6 +345,11 @@ public void SetListenerPosition(WPos position)
AL10.alListenerf(EFX.AL_METERS_PER_UNIT, .01f);
}

public void SetSoundLooping(bool looping, ISound sound)
{
((OpenAlSound)sound)?.SetLooping(looping);
}

~OpenAlSoundEngine()
{
Dispose(false);
Expand Down Expand Up @@ -518,6 +522,14 @@ public virtual void Stop()
StopSource();
AL10.alSourcei(Source, AL10.AL_BUFFER, 0);
}

public void SetLooping(bool looping)
{
if (done)
return;

AL10.alSourcei(Source, AL10.AL_LOOPING, looping ? AL10.AL_TRUE : AL10.AL_FALSE);
}
}

class OpenAlAsyncLoadSound : OpenAlSound
Expand Down

0 comments on commit 9b1cec7

Please sign in to comment.