From bafc79af157e99cac270abdb290f6ee04aa4061b Mon Sep 17 00:00:00 2001 From: Flamefire Date: Tue, 6 May 2014 18:32:47 +0200 Subject: [PATCH] Fix possible Bug with Gst# not detecting Length Make usages aware, that the length might not be given instantly --- Vocaluxe/Base/CBackgroundMusic.cs | 30 ++++++++++++-- Vocaluxe/Base/CSound.cs | 22 ++++++++-- Vocaluxe/Lib/Sound/Playback/CPlaybackBase.cs | 8 ++-- .../CGstreamerSharpAudioStream.cs | 40 +++++++++++-------- .../Sound/Playback/OpenAL/COpenAlStream.cs | 3 +- .../Playback/PortAudio/CPortAudioStream.cs | 4 +- 6 files changed, 77 insertions(+), 30 deletions(-) diff --git a/Vocaluxe/Base/CBackgroundMusic.cs b/Vocaluxe/Base/CBackgroundMusic.cs index b68dab47..b4be306f 100644 --- a/Vocaluxe/Base/CBackgroundMusic.cs +++ b/Vocaluxe/Base/CBackgroundMusic.cs @@ -31,7 +31,6 @@ namespace Vocaluxe.Base private static bool _OwnSongsAvailable; private static EBackgroundMusicSource _MusicSource; - private static float _Volume; private static bool _VideoEnabled; private static CPlaylistElement _CurrentPlaylistElement; //Currently played music @@ -151,6 +150,27 @@ namespace Vocaluxe.Base _Initialized = true; } + public static void Close() + { + if (_CurrentMusicStream >= 0) + { + CSound.Close(_CurrentMusicStream); + _CurrentMusicStream = -1; + } + if (_Video != -1) + { + CVideo.Close(_Video); + CDraw.RemoveTexture(ref _CurrentVideoTexture); + _Video = -1; + } + _BGMusicFiles.Clear(); + _NotPlayedFiles.Clear(); + _PreviousFiles.Clear(); + + IsPlaying = false; + _Initialized = false; + } + public static void Play() { if (IsPlaying || CConfig.BackgroundMusic == EOffOn.TR_CONFIG_OFF) @@ -254,8 +274,12 @@ namespace Vocaluxe.Base Debug.Assert(_CurrentMusicStream != -1 && _CurrentPlaylistElement != null); float timeToPlay; - if (Math.Abs(_CurrentPlaylistElement.Finish) < 0.001) //No End-Tag defined - timeToPlay = CSound.GetLength(_CurrentMusicStream) - CSound.GetPosition(_CurrentMusicStream); + if (Math.Abs(_CurrentPlaylistElement.Finish) < 0.001) + { + //No End-Tag defined + float len = CSound.GetLength(_CurrentMusicStream); + timeToPlay = (len > 0f) ? len - CSound.GetPosition(_CurrentMusicStream) : CSettings.BackgroundMusicFadeTime + 1f; + } else //End-Tag found timeToPlay = _CurrentPlaylistElement.Finish - CSound.GetPosition(_CurrentMusicStream); diff --git a/Vocaluxe/Base/CSound.cs b/Vocaluxe/Base/CSound.cs index 8d9ad0e8..d00d8e71 100644 --- a/Vocaluxe/Base/CSound.cs +++ b/Vocaluxe/Base/CSound.cs @@ -23,6 +23,7 @@ using Vocaluxe.Lib.Sound.Playback.GstreamerSharp; using Vocaluxe.Lib.Sound.Playback.OpenAL; using Vocaluxe.Lib.Sound.Playback.PortAudio; using VocaluxeLib; +using System.Threading; namespace Vocaluxe.Base { @@ -198,11 +199,26 @@ namespace Vocaluxe.Base if (!File.Exists(file)) return -1; - int stream = Load(file, true); - float length = GetLength(stream); + int stream = Load(file, fade); + if (stream < 0) + return -1; Play(stream); if (fade) - FadeAndClose(stream, 100f, length); + { + float length = -1f; + for (int i = 0; i < 5; i++) + { + length = GetLength(stream); + if (length >= 0f) + break; + Thread.Sleep(1); + } + if (length > 0f) + { + SetStreamVolume(stream, 0f); + Fade(stream, 100f, length); + } + } return stream; } #endregion Sounds diff --git a/Vocaluxe/Lib/Sound/Playback/CPlaybackBase.cs b/Vocaluxe/Lib/Sound/Playback/CPlaybackBase.cs index d472d808..d94e3780 100644 --- a/Vocaluxe/Lib/Sound/Playback/CPlaybackBase.cs +++ b/Vocaluxe/Lib/Sound/Playback/CPlaybackBase.cs @@ -200,26 +200,26 @@ namespace Vocaluxe.Lib.Sound.Playback public float GetLength(int streamID) { if (!_Initialized) - return 0f; + return -1f; lock (_Streams) { if (_StreamExists(streamID)) return _Streams[_GetStreamIndex(streamID)].Length; } - return 0f; + return -1f; } public float GetPosition(int streamID) { if (!_Initialized) - return 0f; + return -1f; lock (_Streams) { if (_StreamExists(streamID)) return _Streams[_GetStreamIndex(streamID)].Position; } - return 0f; + return -1f; } public void SetPosition(int streamID, float position) diff --git a/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs b/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs index 52296826..994353ef 100644 --- a/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs +++ b/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs @@ -25,13 +25,15 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp class CGstreamerSharpAudioStream : CAudioStreamBase { private Element _Element; + private bool _FileOpened; private volatile bool _IsFinished; private volatile float _Position; private volatile bool _QueryingDuration; + private System.Threading.Thread _QueryDurationThread; - private readonly object _DurationLock = new object(); //For atomic check and update of _QueryingDuration + private readonly object _DurationLock = new object(); //For atomic check-and-update of _QueryingDuration private readonly object _ElementLock = new object(); //Hold this if you set _Element=null or when accessing _Element from outside the main thread public override float Volume @@ -58,11 +60,11 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp { get { - if (base.Length < 0 && !_QueryingDuration) + if (base.Length < 0 && _QueryDurationThread == null && _Element != null) { - _QueryingDuration = true; // Set this to avoid race conditions - var t = new System.Threading.Thread(_UpdateDuration) {Name = "GSt Update Duration"}; - t.Start(); + // _QueryDurationThread does not get reset so it is created only once! + _QueryDurationThread = new System.Threading.Thread(_UpdateDuration) {Name = "GSt Update Duration"}; + _QueryDurationThread.Start(); } return base.Length >= 0f ? base.Length : 0f; } @@ -72,11 +74,14 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp { get { - long position; - if (!_Element.QueryPosition(Format.Time, out position)) - CLog.LogError("Could not query position"); - else - _Position = ((float)position / Constants.SECOND); + if (_Element != null) + { + long position; + if (!_Element.QueryPosition(Format.Time, out position)) + CLog.LogError("Could not query position"); + else + _Position = ((float)position / Constants.SECOND); + } return _Position; } set @@ -88,7 +93,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp public override bool IsFinished { - get { return _IsFinished; } + get { return _Element == null || _IsFinished; } } public override bool IsPaused @@ -96,9 +101,8 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp get { return _Element == null || _Element.TargetState == State.Paused; } set { - if (_Element == null) - return; - _Element.SetState(value ? State.Paused : State.Playing); + if (_Element != null) + _Element.SetState(value ? State.Paused : State.Playing); } } @@ -106,6 +110,10 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp public override bool Open(bool prescan) { + System.Diagnostics.Debug.Assert(!_FileOpened); + if (_FileOpened) + return false; + Length = -1; Element convert = ElementFactory.Make("audioconvert", "convert"); Element audiosink = ElementFactory.Make("directsoundsink", "audiosink"); @@ -178,6 +186,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp if (msg.Handle != IntPtr.Zero) _UpdateDuration(); } + _FileOpened = true; return true; } @@ -248,8 +257,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp CLog.LogError("Gstreamer error: message" + error.Message + ", code" + error.Code + " ,debug information" + debug); break; case MessageType.DurationChanged: - if (!_QueryingDuration) - _UpdateDuration(); + _UpdateDuration(); break; } msg.Unref(); diff --git a/Vocaluxe/Lib/Sound/Playback/OpenAL/COpenAlStream.cs b/Vocaluxe/Lib/Sound/Playback/OpenAL/COpenAlStream.cs index f53f13d4..7428b494 100644 --- a/Vocaluxe/Lib/Sound/Playback/OpenAL/COpenAlStream.cs +++ b/Vocaluxe/Lib/Sound/Playback/OpenAL/COpenAlStream.cs @@ -150,11 +150,10 @@ namespace Vocaluxe.Lib.Sound.Playback.OpenAL public override bool Open(bool prescan) { + Debug.Assert(!_FileOpened); if (_FileOpened) return false; - Length = 0f; - if (!File.Exists(_Medium)) { Dispose(); diff --git a/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs b/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs index a63c0272..cb579f97 100644 --- a/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs +++ b/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs @@ -16,6 +16,7 @@ #endregion using System; +using System.Diagnostics; using System.IO; using System.Runtime.InteropServices; using System.Threading; @@ -126,11 +127,10 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio public override bool Open(bool prescan) { + Debug.Assert(!_FileOpened); if (_FileOpened) return false; - Length = 0f; - if (!File.Exists(_Medium)) { Dispose();