diff --git a/Vocaluxe/Lib/Sound/Playback/IPlayback.cs b/Vocaluxe/Lib/Sound/Playback/IPlayback.cs
index 47fd10a9..23a5275e 100644
--- a/Vocaluxe/Lib/Sound/Playback/IPlayback.cs
+++ b/Vocaluxe/Lib/Sound/Playback/IPlayback.cs
@@ -15,6 +15,8 @@
// along with Vocaluxe. If not, see .
#endregion
+using System;
+
namespace Vocaluxe.Lib.Sound.Playback
{
public enum EStreamAction
@@ -77,53 +79,75 @@ namespace Vocaluxe.Lib.Sound.Playback
class CRingBuffer
{
private readonly byte[] _Data;
- private readonly long _Size;
- private long _ReadPos;
- private long _WritePos;
- private long _BytesNotRead;
+ private readonly int _Size;
+ private int _ReadPos;
+ private int _WritePos;
+ private int _BytesNotRead;
- public long BytesNotRead
+ public int BytesNotRead
{
get { return _BytesNotRead; }
}
- public CRingBuffer(long size)
+ public CRingBuffer(int size)
{
_Size = size;
_Data = new byte[size];
- _ReadPos = 0L;
- _WritePos = 0L;
- _BytesNotRead = 0L;
+ Reset();
+ }
+
+ public void Reset()
+ {
+ _ReadPos = 0;
+ _WritePos = 0;
+ _BytesNotRead = 0;
}
public void Write(byte[] data)
{
- long written = 0L;
- while (written < data.Length)
+ int start = 0;
+ int end = data.Length;
+ if (end - start > _Size)
+ start = end - _Size;
+ int lenTotal = end - start;
+ int len = Math.Min(lenTotal, _Size - _WritePos);
+ Buffer.BlockCopy(data, start, _Data, _WritePos, len);
+ _WritePos += len;
+ if (_WritePos >= _Size)
{
- _Data[_WritePos] = data[written];
- _WritePos++;
- if (_WritePos >= _Size)
- _WritePos = 0L;
-
- written++;
- _BytesNotRead++;
+ _WritePos = 0;
+ start += len;
+ len = end - start;
+ if (len > 0)
+ {
+ Buffer.BlockCopy(data, start, _Data, _WritePos, len);
+ _WritePos += len;
+ }
}
+ _BytesNotRead += lenTotal;
}
public void Read(byte[] data)
{
- long read = 0L;
- while (read < data.Length && _BytesNotRead > 0L)
- {
- data[read] = _Data[_ReadPos];
- _ReadPos++;
- if (_ReadPos >= _Size)
- _ReadPos = 0L;
+ int lenTotal = Math.Min(data.Length, _BytesNotRead);
+ if (lenTotal == 0)
+ return;
- read++;
- _BytesNotRead--;
+ int len = Math.Min(lenTotal, _Size - _ReadPos);
+ Buffer.BlockCopy(_Data, _ReadPos, data, 0, len);
+ _ReadPos += len;
+ if (_ReadPos >= _Size)
+ {
+ _ReadPos = 0;
+ int start = len;
+ len = lenTotal - len;
+ if (len > 0)
+ {
+ Buffer.BlockCopy(_Data, _ReadPos, data, start, len);
+ _ReadPos += len;
+ }
}
+ _BytesNotRead -= lenTotal;
}
}
}
\ No newline at end of file
diff --git a/Vocaluxe/Lib/Sound/Playback/OpenAL/COpenAlStream.cs b/Vocaluxe/Lib/Sound/Playback/OpenAL/COpenAlStream.cs
index 3297e49e..ec5bdefa 100644
--- a/Vocaluxe/Lib/Sound/Playback/OpenAL/COpenAlStream.cs
+++ b/Vocaluxe/Lib/Sound/Playback/OpenAL/COpenAlStream.cs
@@ -30,7 +30,7 @@ namespace Vocaluxe.Lib.Sound.Playback.OpenAL
{
private const int _BufferSize = 2048;
private const int _BufferCount = 5;
- private const long _Bufsize = 50000L;
+ private const int _Bufsize = 50000;
private Object _CloseMutex;
@@ -288,7 +288,7 @@ namespace Vocaluxe.Lib.Sound.Playback.OpenAL
lock (_MutexData)
{
- _Data = new CRingBuffer(_Bufsize);
+ _Data.Reset();
_NoMoreData = false;
}
}
diff --git a/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs b/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs
index 0da436cc..1042e0f8 100644
--- a/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs
+++ b/Vocaluxe/Lib/Sound/Playback/PortAudio/CPortAudioStream.cs
@@ -27,8 +27,8 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
{
class CPortAudioStream : IDisposable
{
- private const long _Bufsize = 1000000L;
- private const long _Beginrefill = 800000L;
+ private const int _Bufsize = 1000000;
+ private const int _Beginrefill = 800000;
public readonly int ID;
private readonly Closeproc _Closeproc;
@@ -53,22 +53,21 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
private bool _FileOpened;
- private bool _Waiting;
private bool _Skip;
private bool _Loop;
private float _Duration;
private float _CurrentTime;
- private float _TimeCode;
+ private volatile float _TimeCode;
- private bool _Paused;
+ private volatile bool _Paused;
private CRingBuffer _Data;
- private float _SetStart;
+ private volatile float _SetStart;
private float _Start;
- private bool _SetLoop;
- private bool _SetSkip;
- private bool _Terminated;
+ private volatile bool _SetLoop;
+ private volatile bool _SetSkip;
+ private volatile bool _Terminated;
private Thread _DecoderThread;
@@ -114,7 +113,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
{
lock (_LockData)
{
- return _NoMoreData && _Data.BytesNotRead == 0L && _SyncTimer.Time >= _Duration;
+ return _NoMoreData && _Data.BytesNotRead == 0 && _SyncTimer.Time >= _Duration;
}
}
}
@@ -124,11 +123,8 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
get { return _Volume * 100f; }
set
{
- lock (_LockData)
- {
- value.Clamp(0f, 100f);
- _Volume = value / 100f;
- }
+ value.Clamp(0f, 100f);
+ _Volume = value / 100f;
}
}
@@ -137,11 +133,8 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
get { return _VolumeMax * 100f; }
set
{
- lock (_LockData)
- {
- value.Clamp(0f, 100f);
- _VolumeMax = value / 100f;
- }
+ value.Clamp(0f, 100f);
+ _VolumeMax = value / 100f;
}
}
@@ -153,8 +146,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
{
if (Finished)
_SyncTimer.Pause();
- //TODO: Why not use Decoder.GetPosition()?
- //Decoder may return wrong timestamps. If you change this to exessive testing for monoton timestamps espacially for ogg files
+ //Decoder may return wrong timestamps. If you change this do exessive testing for monoton timestamps espacially for ogg files
return _SyncTimer.Time;
}
}
@@ -273,6 +265,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
_ByteCount = 2 * format.ChannelCount;
_BytesPerSecond = format.SamplesPerSecond * _ByteCount;
_CurrentTime = 0f;
+ _SyncTimer.Pause();
_SyncTimer.Time = _CurrentTime;
PortAudioSharp.PortAudio.PaStreamParameters? outputParams = new PortAudioSharp.PortAudio.PaStreamParameters
@@ -303,7 +296,6 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
//From now on closing the driver and the decoder is handled by the thread ONLY!
_Paused = true;
- _Waiting = true;
_FileOpened = true;
_Data = new CRingBuffer(_Bufsize);
_NoMoreData = false;
@@ -319,7 +311,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
{
_SetStart = time;
_SetSkip = true;
- _Waiting = true;
+ _EventDecode.Set();
}
}
@@ -331,10 +323,8 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
_Decoder.SetPosition(_Start);
_CurrentTime = _Start;
_TimeCode = _Start;
- _Data = new CRingBuffer(_Bufsize);
+ _Data.Reset();
_NoMoreData = false;
- _EventDecode.Set();
- _Waiting = false;
_SyncTimer.Time = _Start;
}
}
@@ -343,35 +333,27 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
{
while (!_Terminated)
{
- if (_EventDecode.WaitOne(10))
+ lock (_LockSyncSignals)
{
- lock (_LockSyncSignals)
+ if (_SetSkip)
{
- if (_SetSkip)
- {
- _Skip = true;
- _EventDecode.Set();
- _Waiting = true;
- }
-
+ _Skip = true;
_SetSkip = false;
-
- _Start = _SetStart;
- _Loop = _SetLoop;
}
- if (_Skip)
- {
- _DoSkip();
- _Skip = false;
- }
-
- if (!_Waiting)
- {
- _DoDecode();
- _Update();
- }
+ _Start = _SetStart;
+ _Loop = _SetLoop;
}
+
+ if (_Skip)
+ {
+ _DoSkip();
+ _Skip = false;
+ }
+
+ _DoDecode();
+ _Update();
+ _EventDecode.WaitOne();
}
_DoFree();
@@ -422,12 +404,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
_Data.Write(buffer);
_TimeCode = timecode;
if (_Data.BytesNotRead < _Beginrefill)
- {
- _Waiting = false;
_EventDecode.Set();
- }
- else
- _Waiting = true;
}
}
@@ -458,7 +435,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
{
try
{
- Marshal.Copy(buf, 0, output, (int)frameCount * _ByteCount);
+ Marshal.Copy(buf, 0, output, buf.Length);
}
catch (Exception e)
{
@@ -482,13 +459,8 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
}
}
- if (_Data.BytesNotRead < _Beginrefill)
- {
+ if (_Data.BytesNotRead < _Beginrefill && !_NoMoreData)
_EventDecode.Set();
- _Waiting = false;
- }
- else
- _Waiting = true;
float latency = buf.Length / _BytesPerSecond + CConfig.AudioLatency / 1000f;
float time = _TimeCode - _Data.BytesNotRead / _BytesPerSecond - latency;
@@ -503,7 +475,7 @@ namespace Vocaluxe.Lib.Sound.Playback.PortAudio
}
catch (Exception e)
{
- CLog.LogError("Error PortAudio.treamCallback: " + e.Message);
+ CLog.LogError("Error PortAudio.StreamCallback: " + e.Message);
}
return PortAudioSharp.PortAudio.PaStreamCallbackResult.paContinue;
diff --git a/Vocaluxe/Lib/Sound/Record/CDelayTest.cs b/Vocaluxe/Lib/Sound/Record/CDelayTest.cs
index 27865727..456885d9 100644
--- a/Vocaluxe/Lib/Sound/Record/CDelayTest.cs
+++ b/Vocaluxe/Lib/Sound/Record/CDelayTest.cs
@@ -15,8 +15,6 @@
// along with Vocaluxe. If not, see .
#endregion
-using System;
-using System.Diagnostics;
using Vocaluxe.Base;
namespace Vocaluxe.Lib.Sound.Record
@@ -32,7 +30,6 @@ namespace Vocaluxe.Lib.Sound.Record
private const float _MaxDelayTime = 1000;
public bool Running { get; private set; }
- private readonly Stopwatch _Timer = new Stopwatch();
private int _Stream = -1;
private readonly SDelayChannel[] _DelaysChannel;
@@ -72,7 +69,6 @@ namespace Vocaluxe.Lib.Sound.Record
if (!Running)
return;
Running = false;
- _Timer.Stop();
_CloseStream();
foreach (SDelayChannel delay in _DelaysChannel)
{
@@ -101,16 +97,13 @@ namespace Vocaluxe.Lib.Sound.Record
{
if (!Running)
return;
- if (!_Timer.IsRunning)
- {
- if (CSound.GetPosition(_Stream) > 0f)
- _Timer.Restart();
- }
- if (!_Timer.IsRunning)
+
+ float time = CSound.GetPosition(_Stream) * 1000f;
+ if (time <= 0f)
return;
bool isActive = false;
- if (_Timer.ElapsedMilliseconds <= _MaxDelayTime)
+ if (time <= _MaxDelayTime)
{
for (int i = 0; i < _DelaysChannel.Length; i++)
{
@@ -118,12 +111,11 @@ namespace Vocaluxe.Lib.Sound.Record
continue;
if (CRecord.GetTone(_DelaysChannel[i].Channel) == 9)
{
- Delays[i] = (int)_Timer.ElapsedMilliseconds;
+ Delays[i] = (int)time;
_DelaysChannel[i].Finished = true;
}
else
isActive = true;
- Console.WriteLine(CRecord.GetMaxVolume(_DelaysChannel[i].Channel));
}
}
if (!isActive)