diff --git a/Output/Languages/Spanish.xml b/Output/Languages/Spanish.xml
index f9f92cff..d304e24c 100644
--- a/Output/Languages/Spanish.xml
+++ b/Output/Languages/Spanish.xml
@@ -55,7 +55,7 @@
Lista
Dreidel
- TileBoard
+ CuadrĂcula
Libro
SegĂșn Sean Necesarias
diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs
index 1aad119c..74c13ce6 100644
--- a/Vocaluxe/Base/CConfig.cs
+++ b/Vocaluxe/Base/CConfig.cs
@@ -66,6 +66,19 @@ namespace Vocaluxe.Base
TR_CONFIG_LEVEL_MAX //all debug infos
}
+ public enum EBufferSize
+ {
+ b0 = 0,
+ b512 = 512,
+ b1024 = 1024,
+ b1536 = 1536,
+ b2048 = 2048,
+ b2560 = 2560,
+ b3072 = 3072,
+ b3584 = 3584,
+ b4096 = 4096
+ }
+
public enum EPlaybackLib
{
PortAudio,
@@ -177,7 +190,8 @@ namespace Vocaluxe.Base
// Sound
public static EPlaybackLib PlayBackLib = EPlaybackLib.PortAudio;
public static ERecordLib RecordLib = ERecordLib.PortAudio;
- public static uint PortAudioBufferSize = 1024;
+ public static EBufferSize AudioBufferSize = EBufferSize.b2048;
+ public static int AudioLatency = 100;
public static int BackgroundMusicVolume = 50;
public static EOffOn BackgroundMusic = EOffOn.TR_CONFIG_ON;
public static EBackgroundMusicSource BackgroundMusicSource = EBackgroundMusicSource.TR_CONFIG_NO_OWN_MUSIC;
@@ -286,6 +300,14 @@ namespace Vocaluxe.Base
#region Sound
CHelper.TryGetEnumValueFromXML("//root/Sound/PlayBackLib", navigator, ref PlayBackLib);
CHelper.TryGetEnumValueFromXML("//root/Sound/RecordLib", navigator, ref RecordLib);
+ CHelper.TryGetEnumValueFromXML("//root/Sound/AudioBufferSize", navigator, ref AudioBufferSize);
+
+ CHelper.TryGetIntValueFromXML("//root/Sound/AudioLatency", navigator, ref AudioLatency);
+ if (AudioLatency < -500)
+ AudioLatency = -500;
+ if (AudioLatency > 500)
+ AudioLatency = 500;
+
CHelper.TryGetEnumValueFromXML("//root/Sound/BackgroundMusic", navigator, ref BackgroundMusic);
CHelper.TryGetIntValueFromXML("//root/Sound/BackgroundMusicVolume", navigator, ref BackgroundMusicVolume);
CHelper.TryGetEnumValueFromXML("//root/Sound/BackgroundMusicSource", navigator, ref BackgroundMusicSource);
@@ -480,6 +502,12 @@ namespace Vocaluxe.Base
writer.WriteComment("RecordLib: " + ListStrings(Enum.GetNames(typeof(ERecordLib))));
writer.WriteElementString("RecordLib", Enum.GetName(typeof(ERecordLib), RecordLib));
+ writer.WriteComment("AudioBufferSize: " + ListStrings(Enum.GetNames(typeof(EBufferSize))));
+ writer.WriteElementString("AudioBufferSize", Enum.GetName(typeof(EBufferSize), AudioBufferSize));
+
+ writer.WriteComment("AudioLatency from -500 to 500 ms");
+ writer.WriteElementString("AudioLatency", AudioLatency.ToString());
+
writer.WriteComment("Background Music");
writer.WriteElementString("BackgroundMusicEnabled", Enum.GetName(typeof(EOffOn), BackgroundMusic));
diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs
index a1aa2db7..b7d0ed09 100644
--- a/Vocaluxe/Base/CSettings.cs
+++ b/Vocaluxe/Base/CSettings.cs
@@ -47,7 +47,7 @@ namespace Vocaluxe.Base
public const int iVersionSub = 0; // steps
public const ERevision VersionRevision = ERevision.Beta;
- public const int iBuild = 53; // Increase on every published version! Never Reset!
+ public const int iBuild = 54; // Increase on every published version! Never Reset!
public const int iDatabaseHighscoreVersion = 1;
public const int iDatabaseCoverVersion = 1;
diff --git a/Vocaluxe/Base/CSound.cs b/Vocaluxe/Base/CSound.cs
index b201e6fb..2a2f9d0f 100644
--- a/Vocaluxe/Base/CSound.cs
+++ b/Vocaluxe/Base/CSound.cs
@@ -501,7 +501,7 @@ namespace Vocaluxe.Base
long ticks = _Timer.ElapsedTicks;
float dt = _Timer.ElapsedMilliseconds / 1000f;
- if (nanosecPerTick > 0L)
+ if (Stopwatch.IsHighResolution)
dt = (float)(ticks * nanosecPerTick / 1000000000.0);
return _SetValue + dt;
@@ -581,7 +581,7 @@ namespace Vocaluxe.Base
long ticks = _STimer.ElapsedTicks;
float dt = _STimer.ElapsedMilliseconds / 1000f;
- if (nanosecPerTick > 0L)
+ if (Stopwatch.IsHighResolution)
dt = (float)(ticks * nanosecPerTick / 1000000000.0);
return _CurrentTime + dt;
@@ -617,9 +617,9 @@ namespace Vocaluxe.Base
long ticks = _STimer.ElapsedTicks;
float dt = _STimer.ElapsedMilliseconds / 1000f;
- if (nanosecPerTick > 0L)
+ if (Stopwatch.IsHighResolution)
dt = (float)(ticks * nanosecPerTick / 1000000000.0);
-
+
float Ts = 0f;
if (dt > 0)
Ts = 1 / (_T / dt + 1);
diff --git a/Vocaluxe/Lib/Sound/CPortAudioPlay.cs b/Vocaluxe/Lib/Sound/CPortAudioPlay.cs
index d39c6942..43623c5c 100644
--- a/Vocaluxe/Lib/Sound/CPortAudioPlay.cs
+++ b/Vocaluxe/Lib/Sound/CPortAudioPlay.cs
@@ -620,7 +620,7 @@ namespace Vocaluxe.Lib.Sound
IntPtr.Zero,
ref outputParams,
format.SamplesPerSecond,
- 0,//CConfig.PortAudioBufferSize,
+ (uint)CConfig.AudioBufferSize,
PortAudio.PaStreamFlags.paNoFlag,
_paStreamCallback,
data));
@@ -844,10 +844,10 @@ namespace Vocaluxe.Lib.Sound
else
_waiting = true;
- float latency = buf.Length / _BytesPerSecond;
+ float latency = buf.Length / _BytesPerSecond + CConfig.AudioLatency/1000f;
float time = _TimeCode - _data.BytesNotRead / _BytesPerSecond - latency;
- _CurrentTime = _SyncTimer.Update(time);
+ _CurrentTime = time; // _SyncTimer.Update(time);
}
try
@@ -856,7 +856,7 @@ namespace Vocaluxe.Lib.Sound
}
catch (Exception e)
{
- Console.WriteLine(e.ToString());
+ CLog.LogError("Error PortAudio.StreamCallback: " + e.Message);
}
return PortAudio.PaStreamCallbackResult.paContinue;
diff --git a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
index e6031786..6b566e39 100644
--- a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
+++ b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
@@ -260,7 +260,6 @@ namespace Vocaluxe.Lib.Video
AutoResetEvent EventDecode = new AutoResetEvent(false);
SFrameBuffer[] _FrameBuffer = new SFrameBuffer[5];
Object MutexFramebuffer = new Object();
- Object MutexFrame = new Object();
Object MutexSyncSignals = new Object();
public Decoder()
@@ -595,17 +594,13 @@ namespace Vocaluxe.Lib.Video
if (!_BeforeLoop && (!DropFrame || FrameFinished != 0))
{
- lock (MutexFrame)
+ try
{
- try
- {
- FrameFinished = CAcinerella.ac_get_frame(_instance, _videodecoder);
- }
- catch (Exception)
- {
- CLog.LogError("Error AcGetFrame " + _FileName);
- }
-
+ FrameFinished = CAcinerella.ac_get_frame(_instance, _videodecoder);
+ }
+ catch (Exception)
+ {
+ CLog.LogError("Error AcGetFrame " + _FileName);
}
}
@@ -673,23 +668,18 @@ namespace Vocaluxe.Lib.Video
_waiting = true;
else
{
+ TAc_decoder Videodecoder = (TAc_decoder)Marshal.PtrToStructure(_videodecoder, typeof(TAc_decoder));
- lock (MutexFrame)
+ _VideoTime = (float)Videodecoder.timecode;
+ _FrameBuffer[num].time = _VideoTime;
+
+ if (Videodecoder.buffer != IntPtr.Zero)
{
- TAc_decoder Videodecoder = (TAc_decoder)Marshal.PtrToStructure(_videodecoder, typeof(TAc_decoder));
-
- _FrameBuffer[num].time = _VideoTime;
- _VideoTime = (float)Videodecoder.timecode;
-
- if (Videodecoder.buffer != IntPtr.Zero)
- {
- Marshal.Copy(Videodecoder.buffer, _FrameBuffer[num].data, 0, _Width * _Height * 4);
+ Marshal.Copy(Videodecoder.buffer, _FrameBuffer[num].data, 0, _Width * _Height * 4);
- _FrameBuffer[num].displayed = false;
- }
+ _FrameBuffer[num].displayed = false;
}
-
-
+
_waiting = false;
}
}
diff --git a/Vocaluxe/Menu/CLyric.cs b/Vocaluxe/Menu/CLyric.cs
index 24651cc3..8a70e0ab 100644
--- a/Vocaluxe/Menu/CLyric.cs
+++ b/Vocaluxe/Menu/CLyric.cs
@@ -15,7 +15,8 @@ namespace Vocaluxe.Menu
{
Fill,
Jump,
- Slide
+ Slide,
+ Zoom
}
struct SNote
@@ -23,6 +24,7 @@ namespace Vocaluxe.Menu
public string Text;
public int StartBeat;
public int EndBeat;
+ public int Duration;
public ENoteType Type;
}
@@ -205,6 +207,7 @@ namespace Vocaluxe.Menu
n.Text = note.Text;
n.StartBeat = note.StartBeat;
n.EndBeat = note.EndBeat;
+ n.Duration = note.Duration;
n.Type = note.NoteType;
_Text.Text = note.Text;
@@ -229,6 +232,7 @@ namespace Vocaluxe.Menu
return _X - _width / 2;
}
+ #region draw
public void Draw(float ActualBeat)
{
if (Visible || CSettings.GameState == EGameState.EditTheme)
@@ -236,12 +240,17 @@ namespace Vocaluxe.Menu
switch (_Style)
{
case ELyricStyle.Fill:
+ DrawFill(ActualBeat);
break;
case ELyricStyle.Jump:
+ DrawJump(ActualBeat);
break;
case ELyricStyle.Slide:
DrawSlide(ActualBeat);
break;
+ case ELyricStyle.Zoom:
+ DrawZoom(ActualBeat);
+ break;
default:
DrawSlide(ActualBeat);
break;
@@ -257,6 +266,8 @@ namespace Vocaluxe.Menu
{
_Text.X = x;
_Text.Style = EStyle.Bold;
+ _Text.Text = note.Text;
+ RectangleF rect = CDraw.GetTextBounds(_Text);
if (note.Type == ENoteType.Freestyle)
_Text.Style = EStyle.BoldItalic;
@@ -266,7 +277,7 @@ namespace Vocaluxe.Menu
if (CurrentBeat <= note.EndBeat)
{
_Text.Color = ColorProcessed;
- _Text.Text = note.Text;
+
float diff = note.EndBeat - note.StartBeat;
if (diff == 0)
@@ -280,23 +291,202 @@ namespace Vocaluxe.Menu
}
else
{
- _Text.Color = ColorProcessed;
- _Text.Text = note.Text;
+ _Text.Color = ColorProcessed;
_Text.Draw();
}
}
else
{
- _Text.Color = Color;
- _Text.Text = note.Text;
+ _Text.Color = Color;
_Text.Draw();
}
- RectangleF rect = CDraw.GetTextBounds(_Text);
+
x += rect.Width;
}
}
+ private void DrawZoom(float CurrentBeat)
+ {
+ float x = _X - _width / 2; // most left position
+
+ //find last active note
+ int last_note = -1;
+ for (int i = 0; i < _Notes.Count; i++)
+ {
+ if (CurrentBeat >= _Notes[i].StartBeat)
+ last_note = i;
+ }
+
+ int zoom_note = -1;
+ float zoomx = 0f;
+
+ int current_note = -1;
+ foreach (SNote note in _Notes)
+ {
+ current_note++;
+
+ _Text.X = x;
+ _Text.Style = EStyle.Bold;
+ _Text.Text = note.Text;
+ RectangleF rect = CDraw.GetTextBounds(_Text);
+
+ if (note.Type == ENoteType.Freestyle)
+ _Text.Style = EStyle.BoldItalic;
+
+ if (CurrentBeat >= note.StartBeat)
+ {
+ if (CurrentBeat <= note.EndBeat)
+ {
+ zoom_note = current_note;
+ zoomx = _Text.X;
+ }
+ else
+ {
+ // already passed
+ if (current_note == last_note)
+ _Text.Color = ColorProcessed;
+ else
+ _Text.Color = Color;
+
+ _Text.Draw();
+ }
+
+ }
+ else
+ {
+ // not passed
+ _Text.Color = Color;
+ _Text.Draw();
+ }
+
+ x += rect.Width;
+ }
+
+ if (zoom_note > -1)
+ {
+ if (_Notes[zoom_note].Duration == 0)
+ return;
+
+ _Text.X = zoomx;
+ _Text.Text = _Notes[zoom_note].Text;
+ _Text.Color = ColorProcessed;
+ _Text.Style = EStyle.Bold;
+
+ if (_Notes[zoom_note].Type == ENoteType.Freestyle)
+ _Text.Style = EStyle.BoldItalic;
+
+ RectangleF rect = CDraw.GetTextBounds(_Text);
+
+ float diff = _Notes[zoom_note].EndBeat - _Notes[zoom_note].StartBeat;
+
+ float p = (CurrentBeat - _Notes[zoom_note].StartBeat) / _Notes[zoom_note].Duration;
+ if (p > 1f)
+ p = 1f;
+
+ p = 1f - p;
+
+ float ty = _Text.Y;
+ float tx = _Text.X;
+ float th = _Text.Height;
+ float tz = _Text.Z;
+
+ _Text.Height += _Text.Height * p * 0.4f;
+ RectangleF rectz = CDraw.GetTextBounds(_Text);
+ _Text.X -= (rectz.Width - rect.Width) / 2f;
+ _Text.Y -= (rectz.Height - rect.Height) / 2f;
+ _Text.Z -= 0.1f;
+
+ _Text.Draw();
+
+ _Text.Y = ty;
+ _Text.X = tx;
+ _Text.Height = th;
+ _Text.Z = tz;
+ }
+ }
+
+ private void DrawFill(float CurrentBeat)
+ {
+ float x = _X - _width / 2; // most left position
+
+ foreach (SNote note in _Notes)
+ {
+ _Text.X = x;
+ _Text.Style = EStyle.Bold;
+ _Text.Text = note.Text;
+ RectangleF rect = CDraw.GetTextBounds(_Text);
+
+ if (note.Type == ENoteType.Freestyle)
+ _Text.Style = EStyle.BoldItalic;
+
+ if (CurrentBeat >= note.StartBeat)
+ {
+ _Text.Color = ColorProcessed;
+ _Text.Draw();
+ }
+ else
+ {
+ // not passed
+ _Text.Color = Color;
+ _Text.Draw();
+ }
+
+ x += rect.Width;
+ }
+ }
+
+ private void DrawJump(float CurrentBeat)
+ {
+ float x = _X - _width / 2; // most left position
+
+ foreach (SNote note in _Notes)
+ {
+ _Text.X = x;
+ _Text.Style = EStyle.Bold;
+ _Text.Text = note.Text;
+ RectangleF rect = CDraw.GetTextBounds(_Text);
+
+ if (note.Type == ENoteType.Freestyle)
+ _Text.Style = EStyle.BoldItalic;
+
+ if (CurrentBeat >= note.StartBeat)
+ {
+ if (CurrentBeat <= note.EndBeat)
+ {
+ _Text.Color = ColorProcessed;
+
+ float diff = note.EndBeat - note.StartBeat;
+ if (diff == 0)
+ _Text.Draw();
+ else
+ {
+ float y = _Text.Y;
+ _Text.Y -= _Text.Height * 0.1f;
+ _Text.Draw();
+ _Text.Y = y;
+ }
+ }
+ else
+ {
+ // already passed
+ _Text.Color = Color;
+ _Text.Draw();
+ }
+
+ }
+ else
+ {
+ // not passed
+ _Text.Color = Color;
+ _Text.Draw();
+ }
+
+ x += rect.Width;
+ }
+ }
+ #endregion draw
+
public void UnloadTextures()
{
}
diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs
index 8e947a04..415a7bd9 100644
--- a/Vocaluxe/Screens/CScreenSing.cs
+++ b/Vocaluxe/Screens/CScreenSing.cs
@@ -382,16 +382,16 @@ namespace Vocaluxe.Screens
}
break;
}
-
- Lyrics[htLyrics(LyricMain)].Draw(CGame.Beat);
Lyrics[htLyrics(LyricSub)].Draw(-100);
+ Lyrics[htLyrics(LyricMain)].Draw(CGame.Beat);
- Lyrics[htLyrics(LyricMainDuet)].Draw(CGame.Beat);
Lyrics[htLyrics(LyricSubDuet)].Draw(-100);
+ Lyrics[htLyrics(LyricMainDuet)].Draw(CGame.Beat);
- Lyrics[htLyrics(LyricMainTop)].Draw(CGame.Beat);
Lyrics[htLyrics(LyricSubTop)].Draw(-100);
+ Lyrics[htLyrics(LyricMainTop)].Draw(CGame.Beat);
+
for (int i = 0; i < CGame.NumPlayer; i++)
{