diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs
index 00d8b55a..f4074ad1 100644
--- a/Vocaluxe/Base/CConfig.cs
+++ b/Vocaluxe/Base/CConfig.cs
@@ -37,6 +37,7 @@ namespace Vocaluxe.Base
// Debug
public static EDebugLevel DebugLevel = EDebugLevel.TR_CONFIG_OFF;
+ public static EOffOn SaveModifiedSongs = EOffOn.TR_CONFIG_OFF;
// Graphics
#if WIN
@@ -169,6 +170,7 @@ namespace Vocaluxe.Base
return;
xmlReader.TryGetEnumValue("//root/Debug/DebugLevel", ref DebugLevel);
+ xmlReader.TryGetEnumValue("//root/Debug/SaveModifiedSongs", ref SaveModifiedSongs);
#region Graphics
xmlReader.TryGetEnumValue("//root/Graphics/Renderer", ref Renderer);
@@ -328,6 +330,9 @@ namespace Vocaluxe.Base
writer.WriteComment("DebugLevel: " + CHelper.ListStrings(Enum.GetNames(typeof(EDebugLevel))));
writer.WriteElementString("DebugLevel", Enum.GetName(typeof(EDebugLevel), DebugLevel));
+ writer.WriteComment("SaveModifiedSongs: " + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn))));
+ writer.WriteElementString("SaveModifiedSongs", Enum.GetName(typeof(EOffOn), SaveModifiedSongs));
+
writer.WriteEndElement();
#endregion Debug
diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs
index 8a40c555..84523016 100644
--- a/Vocaluxe/Base/CMain.cs
+++ b/Vocaluxe/Base/CMain.cs
@@ -60,6 +60,11 @@ namespace Vocaluxe.Base
class CBconfig : IConfig
{
+ public EOffOn GetSaveModifiedSongs()
+ {
+ return CConfig.SaveModifiedSongs;
+ }
+
public void SetBackgroundMusicVolume(int newVolume)
{
CConfig.BackgroundMusicVolume = newVolume;
diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs
index c6893634..6543482a 100644
--- a/VocaluxeLib/IBasic.cs
+++ b/VocaluxeLib/IBasic.cs
@@ -29,6 +29,8 @@ namespace VocaluxeLib
{
public interface IConfig
{
+ EOffOn GetSaveModifiedSongs();
+
void SetBackgroundMusicVolume(int newVolume);
int GetBackgroundMusicVolume();
diff --git a/VocaluxeLib/Songs/CBaseNote.cs b/VocaluxeLib/Songs/CBaseNote.cs
index 1c81038b..45043aa7 100644
--- a/VocaluxeLib/Songs/CBaseNote.cs
+++ b/VocaluxeLib/Songs/CBaseNote.cs
@@ -48,6 +48,9 @@ namespace VocaluxeLib.Songs
#region Properties
public int StartBeat { get; set; }
+ ///
+ /// Last beat of this note. First valid beat for a note after that is at EndBeat+1
+ ///
public int EndBeat
{
get { return StartBeat + _Duration - 1; }
diff --git a/VocaluxeLib/Songs/CSong.cs b/VocaluxeLib/Songs/CSong.cs
index ece23c2c..688d2d28 100644
--- a/VocaluxeLib/Songs/CSong.cs
+++ b/VocaluxeLib/Songs/CSong.cs
@@ -20,7 +20,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
-using System.Text.RegularExpressions;
using VocaluxeLib.Draw;
namespace VocaluxeLib.Songs
@@ -73,7 +72,7 @@ namespace VocaluxeLib.Songs
public SMedley Medley;
- public bool CalculateMedley = true;
+ private bool _CalculateMedley = true;
public float PreviewStart;
public int ShortEnd;
@@ -197,7 +196,7 @@ namespace VocaluxeLib.Songs
FadeOutTime = song.Medley.FadeOutTime
};
- CalculateMedley = song.CalculateMedley;
+ _CalculateMedley = song._CalculateMedley;
PreviewStart = song.PreviewStart;
ShortEnd = song.ShortEnd;
@@ -261,6 +260,12 @@ namespace VocaluxeLib.Songs
return loader.ReadNotes();
}
+ public bool Save(string filePath)
+ {
+ var writer = new CSongWriter(this);
+ return writer.SaveFile(filePath);
+ }
+
public string GetMP3()
{
return Path.Combine(Folder, MP3FileName);
@@ -381,7 +386,7 @@ namespace VocaluxeLib.Songs
if (Medley.Source == EMedleySource.Tag)
return;
- if (!CalculateMedley)
+ if (!_CalculateMedley)
return;
List series = _GetSeries();
diff --git a/VocaluxeLib/Songs/CSongLoader.cs b/VocaluxeLib/Songs/CSongLoader.cs
index f93a2368..98cc839b 100644
--- a/VocaluxeLib/Songs/CSongLoader.cs
+++ b/VocaluxeLib/Songs/CSongLoader.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
@@ -295,7 +294,7 @@ namespace VocaluxeLib.Songs
break;
case "CALCMEDLEY":
if (value.ToUpper() == "OFF")
- _Song.CalculateMedley = false;
+ _Song._CalculateMedley = false;
break;
case "RELATIVE":
if (value.ToUpper() == "YES")
@@ -518,6 +517,7 @@ namespace VocaluxeLib.Songs
_LogError("Wrong or missing number after \"P\"");
return false;
}
+ currentBeat = 0;
lastNote = null;
break;
case ':':
@@ -625,6 +625,7 @@ namespace VocaluxeLib.Songs
{
_LogWarning("Missing line break length");
changesMade.NoLengthBreakCt++;
+ currentBeat = beat;
}
else
currentBeat += length;
@@ -694,6 +695,11 @@ namespace VocaluxeLib.Songs
{
string msg = "Automatic changes have been made to " + filePath + " Please check result!\r\n" + changesMade;
CBase.Log.LogError("Warning:" + msg);
+ if (CBase.Config.GetSaveModifiedSongs() == EOffOn.TR_CONFIG_ON)
+ {
+ string name = Path.GetFileNameWithoutExtension(_Song.FileName);
+ _Song.Save(Path.Combine(_Song.Folder, name + ".fix.txt"));
+ }
}
return true;
}
diff --git a/VocaluxeLib/Songs/CSongWriter.cs b/VocaluxeLib/Songs/CSongWriter.cs
index 59d1cbe1..a108c685 100644
--- a/VocaluxeLib/Songs/CSongWriter.cs
+++ b/VocaluxeLib/Songs/CSongWriter.cs
@@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
-using System.Text;
namespace VocaluxeLib.Songs
{
@@ -17,19 +15,19 @@ namespace VocaluxeLib.Songs
_Song = song;
}
- private void _WriteHeaderEntry(StreamWriter sw, string id, T value)
+ private void _WriteHeaderEntry(TextWriter sw, string id, T value)
{
if (!value.Equals(default(T)))
sw.WriteLine("#" + id.ToUpper() + ":" + value);
}
- private void _WriteHeaderEntry(StreamWriter sw, string id, bool value)
+ private void _WriteHeaderEntry(TextWriter sw, string id, bool value)
{
if (value)
_WriteHeaderEntry(sw, id, "YES");
}
- private void _WriteHeaderEntry(StreamWriter sw, string id, IList value)
+ private void _WriteHeaderEntrys(TextWriter sw, string id, IList value)
{
if (value != null && value.Count > 0)
{
@@ -38,7 +36,7 @@ namespace VocaluxeLib.Songs
}
}
- private void _WriteHeader(StreamWriter sw)
+ private void _WriteHeader(TextWriter sw)
{
_WriteHeaderEntry(sw, "ENCODING", _Song.Encoding);
_WriteHeaderEntry(sw, "CREATOR", _Song.Creator);
@@ -48,7 +46,7 @@ namespace VocaluxeLib.Songs
{
string comment = _Song._Comment.Replace("\r\n", "\n").Replace('\r', '\n');
char[] splitChar = {'\n'};
- _WriteHeaderEntry(sw, "COMMENT", comment.Split(splitChar));
+ _WriteHeaderEntrys(sw, "COMMENT", comment.Split(splitChar));
}
_WriteHeaderEntry(sw, "TITLE", _Song.Title);
_WriteHeaderEntry(sw, "ARTIST", _Song.Artist);
@@ -56,9 +54,9 @@ namespace VocaluxeLib.Songs
_WriteHeaderEntry(sw, "TITLE-ON-SORTING", _Song.TitleSorting);
if (!_Song.Artist.Equals(_Song.ArtistSorting))
_WriteHeaderEntry(sw, "ARTIST-ON-SORTING", _Song.ArtistSorting);
- _WriteHeaderEntry(sw, "EDITION", _Song.Editions);
- _WriteHeaderEntry(sw, "GENRE", _Song.Genres);
- _WriteHeaderEntry(sw, "LANGUAGE", _Song.Languages);
+ _WriteHeaderEntrys(sw, "EDITION", _Song.Editions);
+ _WriteHeaderEntrys(sw, "GENRE", _Song.Genres);
+ _WriteHeaderEntrys(sw, "LANGUAGE", _Song.Languages);
_WriteHeaderEntry(sw, "ALBUM", _Song.Album);
_WriteHeaderEntry(sw, "YEAR", _Song.Year);
_WriteHeaderEntry(sw, "MP3", _Song.MP3FileName);
@@ -73,7 +71,7 @@ namespace VocaluxeLib.Songs
_WriteHeaderEntry(sw, "PREVIEWSTART", _Song.PreviewStart);
_WriteHeaderEntry(sw, "START", _Song.Start);
_WriteHeaderEntry(sw, "END", _Song.Finish);
- if (!_Song.CalculateMedley)
+ if (!_Song._CalculateMedley)
_WriteHeaderEntry(sw, "CALCMEDLEY", "OFF");
if (_Song.Medley.Source == EMedleySource.Tag)
{
@@ -88,6 +86,68 @@ namespace VocaluxeLib.Songs
foreach (string addLine in _Song.UnknownTags)
sw.WriteLine(addLine);
}
+
+ private void _WriteNotes(TextWriter sw)
+ {
+ for (int i = 0; i < _Song.Notes.VoiceCount; i++)
+ {
+ CVoice voice = _Song.Notes.GetVoice(i);
+ if (_Song.Notes.VoiceCount > 1)
+ sw.WriteLine("P" + Math.Pow(2, i));
+ bool firstLine = true;
+ int currentBeat = 0;
+ foreach (CSongLine line in voice.Lines)
+ {
+ if (!firstLine)
+ {
+ string lineTxt = "- " + (line.StartBeat - currentBeat);
+ if (_Song.Relative)
+ {
+ lineTxt += " " + (line.FirstNoteBeat - currentBeat);
+ currentBeat = line.FirstNoteBeat;
+ }
+ sw.WriteLine(lineTxt);
+ }
+ else
+ firstLine = false;
+ foreach (CSongNote note in line.Notes)
+ {
+ string tag;
+ switch (note.Type)
+ {
+ case ENoteType.Normal:
+ tag = ":";
+ break;
+ case ENoteType.Golden:
+ tag = "*";
+ break;
+ case ENoteType.Freestyle:
+ tag = "F";
+ break;
+ default:
+ throw new NotImplementedException("Note type " + note.Type);
+ }
+ sw.WriteLine(tag + " " + (note.StartBeat - currentBeat) + " " + note.Duration + " " + note.Tone + " " + note.Text);
+ }
+ }
+ }
+ }
+
+ public bool SaveFile(string filePath)
+ {
+ try
+ {
+ TextWriter sw = new StreamWriter(filePath, false, _Song.Encoding);
+ _WriteHeader(sw);
+ _WriteNotes(sw);
+ }
+ catch (Exception e)
+ {
+ CBase.Log.LogError("Unhandled exception while writing " + filePath + ": " + e);
+ return false;
+ }
+ return true;
+ }
}
}
}
\ No newline at end of file