Add support for gapless looping music.
This commit is contained in:
committed by
abcdefg30
parent
9916e4c4ac
commit
9b1cec7712
@@ -137,6 +137,12 @@ namespace OpenRA
|
|||||||
soundEngine.Volume = 1f;
|
soundEngine.Volume = 1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetMusicLooped(bool loop)
|
||||||
|
{
|
||||||
|
Game.Settings.Sound.Repeat = loop;
|
||||||
|
soundEngine.SetSoundLooping(loop, music);
|
||||||
|
}
|
||||||
|
|
||||||
public bool DisableAllSounds { get; set; }
|
public bool DisableAllSounds { get; set; }
|
||||||
public bool DisableWorldSounds { get; set; }
|
public bool DisableWorldSounds { get; set; }
|
||||||
public ISound Play(SoundType type, string name) { return Play(type, null, name, true, WPos.Zero, 1f); }
|
public ISound Play(SoundType type, string name) { return Play(type, null, name, true, WPos.Zero, 1f); }
|
||||||
@@ -202,11 +208,6 @@ namespace OpenRA
|
|||||||
public bool MusicPlaying { get; private set; }
|
public bool MusicPlaying { get; private set; }
|
||||||
public MusicInfo CurrentMusic => currentMusic;
|
public MusicInfo CurrentMusic => currentMusic;
|
||||||
|
|
||||||
public void PlayMusic(MusicInfo m)
|
|
||||||
{
|
|
||||||
PlayMusicThen(m, () => { });
|
|
||||||
}
|
|
||||||
|
|
||||||
public void PlayMusicThen(MusicInfo m, Action then)
|
public void PlayMusicThen(MusicInfo m, Action then)
|
||||||
{
|
{
|
||||||
if (m == null || !m.Exists)
|
if (m == null || !m.Exists)
|
||||||
@@ -221,13 +222,21 @@ namespace OpenRA
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlayMusic(m, Game.Settings.Sound.Repeat);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PlayMusic(MusicInfo m, bool looped = false)
|
||||||
|
{
|
||||||
|
if (m == null || !m.Exists)
|
||||||
|
return;
|
||||||
|
|
||||||
StopMusic();
|
StopMusic();
|
||||||
|
|
||||||
Func<ISoundFormat, ISound> stream = soundFormat => soundEngine.Play2DStream(
|
Func<ISoundFormat, ISound> stream = soundFormat => soundEngine.Play2DStream(
|
||||||
soundFormat.GetPCMInputStream(), soundFormat.Channels, soundFormat.SampleBits, soundFormat.SampleRate,
|
soundFormat.GetPCMInputStream(), soundFormat.Channels, soundFormat.SampleBits, soundFormat.SampleRate,
|
||||||
false, true, WPos.Zero, MusicVolume * m.VolumeModifier);
|
looped, true, WPos.Zero, MusicVolume * m.VolumeModifier);
|
||||||
music = LoadSound(m.Filename, stream);
|
|
||||||
|
|
||||||
|
music = LoadSound(m.Filename, stream);
|
||||||
if (music == null)
|
if (music == null)
|
||||||
{
|
{
|
||||||
onMusicComplete = null;
|
onMusicComplete = null;
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace OpenRA
|
|||||||
void StopAllSounds();
|
void StopAllSounds();
|
||||||
void SetListenerPosition(WPos position);
|
void SetListenerPosition(WPos position);
|
||||||
void SetSoundVolume(float volume, ISound music, ISound video);
|
void SetSoundVolume(float volume, ISound music, ISound video);
|
||||||
|
void SetSoundLooping(bool looping, ISound sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SoundDevice
|
public class SoundDevice
|
||||||
|
|||||||
@@ -162,13 +162,15 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (!SongExists(currentSong) || (CurrentSongIsBackground && IsBackgroundMusicMuted))
|
if (!SongExists(currentSong) || (CurrentSongIsBackground && IsBackgroundMusicMuted))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Game.Sound.PlayMusicThen(currentSong, () =>
|
Game.Sound.PlayMusicThen(currentSong, PlayNextSong);
|
||||||
{
|
}
|
||||||
if (!CurrentSongIsBackground && !Game.Settings.Sound.Repeat)
|
|
||||||
currentSong = GetNextSong();
|
|
||||||
|
|
||||||
Play();
|
void PlayNextSong()
|
||||||
});
|
{
|
||||||
|
if (!CurrentSongIsBackground)
|
||||||
|
currentSong = GetNextSong();
|
||||||
|
|
||||||
|
Play();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Play(MusicInfo music)
|
public void Play(MusicInfo music)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
|
|
||||||
var repeatCheckbox = panel.Get<CheckboxWidget>("REPEAT");
|
var repeatCheckbox = panel.Get<CheckboxWidget>("REPEAT");
|
||||||
repeatCheckbox.IsChecked = () => Game.Settings.Sound.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;
|
repeatCheckbox.IsDisabled = () => musicPlaylist.CurrentSongIsBackground;
|
||||||
|
|
||||||
panel.Get<LabelWidget>("TIME_LABEL").GetText = () =>
|
panel.Get<LabelWidget>("TIME_LABEL").GetText = () =>
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ namespace OpenRA.Platforms.Default
|
|||||||
public void StopSound(ISound sound) { }
|
public void StopSound(ISound sound) { }
|
||||||
public void StopAllSounds() { }
|
public void StopAllSounds() { }
|
||||||
public void SetListenerPosition(WPos position) { }
|
public void SetListenerPosition(WPos position) { }
|
||||||
|
public void SetSoundLooping(bool looping, ISound sound) { }
|
||||||
public void Dispose() { }
|
public void Dispose() { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace OpenRA.Platforms.Default
|
|||||||
if (devicesPtr == IntPtr.Zero || AL10.alGetError() != AL10.AL_NO_ERROR)
|
if (devicesPtr == IntPtr.Zero || AL10.alGetError() != AL10.AL_NO_ERROR)
|
||||||
{
|
{
|
||||||
Log.Write("sound", "Failed to query OpenAL device list using {0}", label);
|
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>();
|
var devices = new List<string>();
|
||||||
@@ -103,7 +103,7 @@ namespace OpenRA.Platforms.Default
|
|||||||
if (ALC11.alcIsExtensionPresent(IntPtr.Zero, "ALC_ENUMERATION_EXT"))
|
if (ALC11.alcIsExtensionPresent(IntPtr.Zero, "ALC_ENUMERATION_EXT"))
|
||||||
return QueryDevices("ALC_ENUMERATION_EXT", ALC10.ALC_DEVICE_SPECIFIER);
|
return QueryDevices("ALC_ENUMERATION_EXT", ALC10.ALC_DEVICE_SPECIFIER);
|
||||||
|
|
||||||
return new string[] { };
|
return Array.Empty<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static int MakeALFormat(int channels, int bits)
|
internal static int MakeALFormat(int channels, int bits)
|
||||||
@@ -137,8 +137,7 @@ namespace OpenRA.Platforms.Default
|
|||||||
|
|
||||||
for (var i = 0; i < PoolSize; i++)
|
for (var i = 0; i < PoolSize; i++)
|
||||||
{
|
{
|
||||||
var source = 0U;
|
AL10.alGenSources(1, out var source);
|
||||||
AL10.alGenSources(1, out source);
|
|
||||||
if (AL10.alGetError() != AL10.AL_NO_ERROR)
|
if (AL10.alGetError() != AL10.AL_NO_ERROR)
|
||||||
{
|
{
|
||||||
Log.Write("sound", "Failed generating OpenAL source {0}", i);
|
Log.Write("sound", "Failed generating OpenAL source {0}", i);
|
||||||
@@ -346,6 +345,11 @@ namespace OpenRA.Platforms.Default
|
|||||||
AL10.alListenerf(EFX.AL_METERS_PER_UNIT, .01f);
|
AL10.alListenerf(EFX.AL_METERS_PER_UNIT, .01f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetSoundLooping(bool looping, ISound sound)
|
||||||
|
{
|
||||||
|
((OpenAlSound)sound)?.SetLooping(looping);
|
||||||
|
}
|
||||||
|
|
||||||
~OpenAlSoundEngine()
|
~OpenAlSoundEngine()
|
||||||
{
|
{
|
||||||
Dispose(false);
|
Dispose(false);
|
||||||
@@ -518,6 +522,14 @@ namespace OpenRA.Platforms.Default
|
|||||||
StopSource();
|
StopSource();
|
||||||
AL10.alSourcei(Source, AL10.AL_BUFFER, 0);
|
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
|
class OpenAlAsyncLoadSound : OpenAlSound
|
||||||
|
|||||||
Reference in New Issue
Block a user