Fix possible Bug with Gst# not detecting Length

Make usages aware, that the length might not be given instantly
This commit is contained in:
Flamefire committed 2014-05-06 18:32:47 +02:00
1 parent a4b1c3eb86
commit bafc79af15
6 files changed
+77 -30

No files matched your search

+27 -3
View File
@@ -31,7 +31,6 @@ namespace Vocaluxe.Base
private static bool _OwnSongsAvailable; private static bool _OwnSongsAvailable;
private static EBackgroundMusicSource _MusicSource; private static EBackgroundMusicSource _MusicSource;
private static float _Volume;
private static bool _VideoEnabled; private static bool _VideoEnabled;
private static CPlaylistElement _CurrentPlaylistElement; //Currently played music private static CPlaylistElement _CurrentPlaylistElement; //Currently played music
@@ -151,6 +150,27 @@ namespace Vocaluxe.Base
_Initialized = true; _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() public static void Play()
{ {
if (IsPlaying || CConfig.BackgroundMusic == EOffOn.TR_CONFIG_OFF) if (IsPlaying || CConfig.BackgroundMusic == EOffOn.TR_CONFIG_OFF)
@@ -254,8 +274,12 @@ namespace Vocaluxe.Base
Debug.Assert(_CurrentMusicStream != -1 && _CurrentPlaylistElement != null); Debug.Assert(_CurrentMusicStream != -1 && _CurrentPlaylistElement != null);
float timeToPlay; float timeToPlay;
if (Math.Abs(_CurrentPlaylistElement.Finish) < 0.001) //No End-Tag defined if (Math.Abs(_CurrentPlaylistElement.Finish) < 0.001)
timeToPlay = CSound.GetLength(_CurrentMusicStream) - CSound.GetPosition(_CurrentMusicStream); {
//No End-Tag defined
float len = CSound.GetLength(_CurrentMusicStream);
timeToPlay = (len > 0f) ? len - CSound.GetPosition(_CurrentMusicStream) : CSettings.BackgroundMusicFadeTime + 1f;
}
else //End-Tag found else //End-Tag found
timeToPlay = _CurrentPlaylistElement.Finish - CSound.GetPosition(_CurrentMusicStream); timeToPlay = _CurrentPlaylistElement.Finish - CSound.GetPosition(_CurrentMusicStream);
+19 -3
View File
@@ -23,6 +23,7 @@ using Vocaluxe.Lib.Sound.Playback.GstreamerSharp;
using Vocaluxe.Lib.Sound.Playback.OpenAL; using Vocaluxe.Lib.Sound.Playback.OpenAL;
using Vocaluxe.Lib.Sound.Playback.PortAudio; using Vocaluxe.Lib.Sound.Playback.PortAudio;
using VocaluxeLib; using VocaluxeLib;
using System.Threading;
namespace Vocaluxe.Base namespace Vocaluxe.Base
{ {
@@ -198,11 +199,26 @@ namespace Vocaluxe.Base
if (!File.Exists(file)) if (!File.Exists(file))
return -1; return -1;
int stream = Load(file, true); int stream = Load(file, fade);
float length = GetLength(stream); if (stream < 0)
return -1;
Play(stream); Play(stream);
if (fade) 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; return stream;
} }
#endregion Sounds #endregion Sounds
+4 -4
View File
@@ -200,26 +200,26 @@ namespace Vocaluxe.Lib.Sound.Playback
public float GetLength(int streamID) public float GetLength(int streamID)
{ {
if (!_Initialized) if (!_Initialized)
return 0f; return -1f;
lock (_Streams) lock (_Streams)
{ {
if (_StreamExists(streamID)) if (_StreamExists(streamID))
return _Streams[_GetStreamIndex(streamID)].Length; return _Streams[_GetStreamIndex(streamID)].Length;
} }
return 0f; return -1f;
} }
public float GetPosition(int streamID) public float GetPosition(int streamID)
{ {
if (!_Initialized) if (!_Initialized)
return 0f; return -1f;
lock (_Streams) lock (_Streams)
{ {
if (_StreamExists(streamID)) if (_StreamExists(streamID))
return _Streams[_GetStreamIndex(streamID)].Position; return _Streams[_GetStreamIndex(streamID)].Position;
} }
return 0f; return -1f;
} }
public void SetPosition(int streamID, float position) public void SetPosition(int streamID, float position)
@@ -25,13 +25,15 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
class CGstreamerSharpAudioStream : CAudioStreamBase class CGstreamerSharpAudioStream : CAudioStreamBase
{ {
private Element _Element; private Element _Element;
private bool _FileOpened;
private volatile bool _IsFinished; private volatile bool _IsFinished;
private volatile float _Position; private volatile float _Position;
private volatile bool _QueryingDuration; 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 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 public override float Volume
@@ -58,11 +60,11 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
{ {
get get
{ {
if (base.Length < 0 && !_QueryingDuration) if (base.Length < 0 && _QueryDurationThread == null && _Element != null)
{ {
_QueryingDuration = true; // Set this to avoid race conditions // _QueryDurationThread does not get reset so it is created only once!
var t = new System.Threading.Thread(_UpdateDuration) {Name = "GSt Update Duration"}; _QueryDurationThread = new System.Threading.Thread(_UpdateDuration) {Name = "GSt Update Duration"};
t.Start(); _QueryDurationThread.Start();
} }
return base.Length >= 0f ? base.Length : 0f; return base.Length >= 0f ? base.Length : 0f;
} }
@@ -72,11 +74,14 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
{ {
get get
{ {
long position; if (_Element != null)
if (!_Element.QueryPosition(Format.Time, out position)) {
CLog.LogError("Could not query position"); long position;
else if (!_Element.QueryPosition(Format.Time, out position))
_Position = ((float)position / Constants.SECOND); CLog.LogError("Could not query position");
else
_Position = ((float)position / Constants.SECOND);
}
return _Position; return _Position;
} }
set set
@@ -88,7 +93,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
public override bool IsFinished public override bool IsFinished
{ {
get { return _IsFinished; } get { return _Element == null || _IsFinished; }
} }
public override bool IsPaused public override bool IsPaused
@@ -96,9 +101,8 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
get { return _Element == null || _Element.TargetState == State.Paused; } get { return _Element == null || _Element.TargetState == State.Paused; }
set set
{ {
if (_Element == null) if (_Element != null)
return; _Element.SetState(value ? State.Paused : State.Playing);
_Element.SetState(value ? State.Paused : State.Playing);
} }
} }
@@ -106,6 +110,10 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
public override bool Open(bool prescan) public override bool Open(bool prescan)
{ {
System.Diagnostics.Debug.Assert(!_FileOpened);
if (_FileOpened)
return false;
Length = -1;
Element convert = ElementFactory.Make("audioconvert", "convert"); Element convert = ElementFactory.Make("audioconvert", "convert");
Element audiosink = ElementFactory.Make("directsoundsink", "audiosink"); Element audiosink = ElementFactory.Make("directsoundsink", "audiosink");
@@ -178,6 +186,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
if (msg.Handle != IntPtr.Zero) if (msg.Handle != IntPtr.Zero)
_UpdateDuration(); _UpdateDuration();
} }
_FileOpened = true;
return 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); CLog.LogError("Gstreamer error: message" + error.Message + ", code" + error.Code + " ,debug information" + debug);
break; break;
case MessageType.DurationChanged: case MessageType.DurationChanged:
if (!_QueryingDuration) _UpdateDuration();
_UpdateDuration();
break; break;
} }
msg.Unref(); msg.Unref();
@@ -150,11 +150,10 @@ namespace Vocaluxe.Lib.Sound.Playback.OpenAL
public override bool Open(bool prescan) public override bool Open(bool prescan)
{ {
Debug.Assert(!_FileOpened);
if (_FileOpened) if (_FileOpened)
return false; return false;
Length = 0f;
if (!File.Exists(_Medium)) if (!File.Exists(_Medium))
{ {
Dispose(); Dispose();
@@ -16,6 +16,7 @@
#endregion #endregion
using System; using System;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
@@ -126,11 +127,10 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
public override bool Open(bool prescan) public override bool Open(bool prescan)
{ {
Debug.Assert(!_FileOpened);
if (_FileOpened) if (_FileOpened)
return false; return false;
Length = 0f;
if (!File.Exists(_Medium)) if (!File.Exists(_Medium))
{ {
Dispose(); Dispose();