diff --git a/VocaluxeLib/Songs/CSong.cs b/VocaluxeLib/Songs/CSong.cs
index 6dd6e33f..1db59d29 100644
--- a/VocaluxeLib/Songs/CSong.cs
+++ b/VocaluxeLib/Songs/CSong.cs
@@ -117,11 +117,23 @@ namespace VocaluxeLib.Songs
public string TitleSorting = String.Empty;
public string ArtistSorting = String.Empty;
+ ///
+ /// Start of the song in s (s in txt)
+ ///
public float Start;
+ ///
+ /// End of the song in s (ms in txt)
+ ///
public float Finish;
public float BPM = 1f;
+ ///
+ /// Gap of the mp3 in s (ms in txt)
+ ///
public float Gap;
+ ///
+ /// Gap of the video in s (s in txt)
+ ///
public float VideoGap;
private string _Comment = "";
diff --git a/VocaluxeLib/Songs/CSongLoader.cs b/VocaluxeLib/Songs/CSongLoader.cs
index 9c2bd0f2..3c29dcde 100644
--- a/VocaluxeLib/Songs/CSongLoader.cs
+++ b/VocaluxeLib/Songs/CSongLoader.cs
@@ -11,6 +11,11 @@ namespace VocaluxeLib.Songs
///
public partial class CSong
{
+ ///
+ /// Factor the bpm given in the txt is multiplied with
+ ///
+ private const int _BPMFactor = 4;
+
private class CSongLoader
{
private readonly CSong _Song;
@@ -54,6 +59,7 @@ namespace VocaluxeLib.Songs
///
/// Message
/// True prepends "Error: "; False prepends "Warning: "
+ /// Adds line#
private void _LogMsg(string msg, bool error, bool withLineNr)
{
msg = (error ? "Error: " : "Warning: ") + msg;
@@ -164,7 +170,7 @@ namespace VocaluxeLib.Songs
case "BPM":
if (CHelper.TryParse(value, out _Song.BPM))
{
- _Song.BPM *= 4;
+ _Song.BPM *= _BPMFactor;
headerFlags |= EHeaderFlags.BPM;
}
else
@@ -248,6 +254,16 @@ namespace VocaluxeLib.Songs
else
_LogWarning("Invalid previewstart");
break;
+ case "PREVIEW":
+ if (CHelper.TryParse(value, out _Song.PreviewStart) && _Song.PreviewStart >= 0f)
+ {
+ //This is stored in ms not like PREVIEWSTART!
+ _Song.PreviewStart /= 1000f;
+ headerFlags |= EHeaderFlags.PreviewStart;
+ }
+ else
+ _LogWarning("Invalid previewstart");
+ break;
case "MEDLEYSTARTBEAT":
if (int.TryParse(value, out _Song.Medley.StartBeat))
headerFlags |= EHeaderFlags.MedleyStartBeat;
@@ -268,6 +284,9 @@ namespace VocaluxeLib.Songs
if (value.ToUpper() == "YES")
_Song.Relative = true;
break;
+ case "RESULTION":
+ _LogWarning("#RESOLUTION tag is outdated and ignored. Test the song to see if note timing is still correct!");
+ break;
default:
if (identifier.StartsWith("DUETSINGER"))
identifier = identifier.Substring(10);
@@ -277,6 +296,7 @@ namespace VocaluxeLib.Songs
if (int.TryParse(identifier.Substring(1).Trim(), out player))
foreach (int curPlayer in player.GetSetBits()) {}
}
+
break;
}
} //end of while
diff --git a/VocaluxeLib/Songs/CSongWriter.cs b/VocaluxeLib/Songs/CSongWriter.cs
new file mode 100644
index 00000000..1daf89ff
--- /dev/null
+++ b/VocaluxeLib/Songs/CSongWriter.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace VocaluxeLib.Songs
+{
+ public partial class CSong
+ {
+ private class CSongWriter
+ {
+ private readonly CSong _Song;
+
+ public CSongWriter(CSong song)
+ {
+ _Song = song;
+ }
+
+ private void _WriteHeaderEntry(StreamWriter sw, string id, T value)
+ {
+ if (!value.Equals(default(T)))
+ sw.WriteLine("#" + id.ToUpper() + ":" + value);
+ }
+
+ private void _WriteHeaderEntry(StreamWriter sw, string id, bool value)
+ {
+ if (value)
+ _WriteHeaderEntry(sw, id, "YES");
+ }
+
+ private void _WriteHeaderEntry(StreamWriter sw, string id, IList value)
+ {
+ if (value!=null && value.Count>0)
+ foreach (var val in value)
+ _WriteHeaderEntry(sw, id, val);
+ }
+
+ private void _WriteHeader(StreamWriter sw)
+ {
+ _WriteHeaderEntry(sw, "ENCODING", _Song.Encoding);
+ _WriteHeaderEntry(sw, "TITLE", _Song.Title);
+ _WriteHeaderEntry(sw, "ARTIST", _Song.Artist);
+ if (!_Song.Title.Equals(_Song.TitleSorting)) _WriteHeaderEntry(sw, "TITLE-ON-SORTING", _Song.TitleSorting);
+ if (!_Song.Artist.Equals(_Song.ArtistSorting)) _WriteHeaderEntry(sw, "ARTIST-ON-SORTING", _Song.ArtistSorting);
+ _WriteHeaderEntry(sw, "LANGUAGE", _Song.Languages);
+ _WriteHeaderEntry(sw, "EDITION", _Song.Edition);
+ _WriteHeaderEntry(sw, "GENRE", _Song.Genres);
+ _WriteHeaderEntry(sw, "YEAR", _Song.Year);
+ _WriteHeaderEntry(sw, "COMMENT", _Song._Comment);
+ _WriteHeaderEntry(sw, "MP3", _Song.MP3FileName);
+ _WriteHeaderEntry(sw, "COVER", _Song.CoverFileName);
+ _WriteHeaderEntry(sw, "BACKGROUND", _Song.BackgroundFileName);
+ _WriteHeaderEntry(sw, "VIDEO", _Song.VideoFileName);
+ _WriteHeaderEntry(sw, "VIDEOGAP", _Song.VideoGap);
+ _WriteHeaderEntry(sw, "VIDEOASPECT", _Song.VideoAspect);
+ _WriteHeaderEntry(sw, "RELATIVE", _Song.Relative);
+ _WriteHeaderEntry(sw, "BPM", _Song.BPM);
+ _WriteHeaderEntry(sw, "GAP", _Song.Gap);
+ _WriteHeaderEntry(sw, "PREVIEWSTART", _Song.PreviewStart);
+ _WriteHeaderEntry(sw, "START", _Song.Start);
+ _WriteHeaderEntry(sw, "END", _Song.Finish);
+ if(!_Song.CalculateMedley)
+ _WriteHeaderEntry(sw, "CALCMEDLEY", "OFF");
+ if (_Song.Medley.Source == EMedleySource.Tag)
+ {
+ _WriteHeaderEntry(sw, "MEDLEYSTARTBEAT", _Song.Medley.StartBeat);
+ _WriteHeaderEntry(sw, "MEDLEYENDBEAT", _Song.Medley.EndBeat);
+ }
+ for (int i = 0; i < _Song.Notes.VoiceCount; i++)
+ {
+ if (_Song.Notes.VoiceNames.IsSet(i))
+ _WriteHeaderEntry(sw, "P" + i, _Song.Notes.VoiceNames[i]);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/VocaluxeLib/VocaluxeLib.csproj b/VocaluxeLib/VocaluxeLib.csproj
index 3a69d742..8a784a53 100644
--- a/VocaluxeLib/VocaluxeLib.csproj
+++ b/VocaluxeLib/VocaluxeLib.csproj
@@ -175,6 +175,7 @@
+