|
From: Tapio V. <aa...@us...> - 2011-01-25 13:29:24
|
Module: editor
Branch: master
Commit: 56e87680ef773cda9a606741dd1331383e1c494d
Author: Tapio Vierros <tap...@gm...>
Date: Tue Jan 25 15:28:11 2011 +0200
Magic time stamp rounding error compensator for SS XML writer.
Now very good sync.
---
songwriter-xml.cc | 22 +++++++++++++++-------
songwriter.hh | 1 +
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/songwriter-xml.cc b/songwriter-xml.cc
index e370e8f..456963e 100644
--- a/songwriter-xml.cc
+++ b/songwriter-xml.cc
@@ -21,26 +21,30 @@ void SingStarXMLWriter::writeXML() {
root.setAttribute("audioVersion", "2"); //?
doc.appendChild(root);
+ // Some helpful comments
QDomComment artistComment = doc.createComment(QString("Artist: ") + s.artist);
QDomComment titleComment = doc.createComment(QString("Title: ") + s.title);
root.appendChild(artistComment);
root.appendChild(titleComment);
+ // Track element
int tracknum = 1;
QDomElement trackElem = doc.createElement("TRACK");
trackElem.setAttribute("Name", "Player1");
trackElem.setAttribute("Artist", s.artist);
root.appendChild(trackElem);
+ // Create first sentence
int sentencenum = 1;
QDomElement sentenceElem = doc.createElement("SENTENCE"); // FIXME: Should there be Singer and Part attributes?
QDomComment sentenceComment = doc.createComment(QString("Track %1, Sentence %2").arg(tracknum).arg(sentencenum));
sentenceElem.appendChild(sentenceComment);
// First sentence also needs a starting SLEEP
Notes const& notes = s.getVocalTrack().notes;
+ int ts = sec2dur(notes.front().begin);
QDomElement firstNoteElem = doc.createElement("NOTE");
firstNoteElem.setAttribute("MidiNote", "0");
- firstNoteElem.setAttribute("Duration", QString::number(sec2dur(notes.front().begin)));
+ firstNoteElem.setAttribute("Duration", QString::number(ts));
firstNoteElem.setAttribute("Lyric", "");
sentenceElem.appendChild(firstNoteElem);
@@ -59,9 +63,10 @@ void SingStarXMLWriter::writeXML() {
} else { // Regular note handling
// Construct the note element
+ int l = sec2dur(n.length()); ts += l;
QDomElement noteElem = doc.createElement("NOTE");
noteElem.setAttribute("MidiNote", QString::number(n.note));
- noteElem.setAttribute("Duration", QString::number(sec2dur(n.length())));
+ noteElem.setAttribute("Duration", QString::number(l));
noteElem.setAttribute("Lyric", n.syllable);
if (n.type == Note::GOLDEN) noteElem.setAttribute("Bonus", "Yes");
if (n.type == Note::FREESTYLE) noteElem.setAttribute("FreeStyle", "Yes");
@@ -70,22 +75,21 @@ void SingStarXMLWriter::writeXML() {
// Construct a note element, indicationg the pause before next note
// This is only done if the pause has duration
+ // We also take the overall position into consideration (counter rounding errors)
int pauseLen = 0;
+ double end = dur2sec(ts) + n.length();
if (i < notes.size() - 1)
- pauseLen = sec2dur(notes[i+1].begin - n.end); // Difference to next note
+ pauseLen = sec2dur(notes[i+1].begin - end); // Difference to next note
if (pauseLen > 0) {
QDomElement pauseElem = doc.createElement("NOTE");
pauseElem.setAttribute("MidiNote", "0");
pauseElem.setAttribute("Duration", QString::number(pauseLen));
pauseElem.setAttribute("Lyric", "");
sentenceElem.appendChild(pauseElem);
+ ts += pauseLen;
}
}
- // TODO: Needs a last dummy sentence
-
- //root.appendChild(sentenceElem);
-
// Get the xml data
QString xml = doc.toString(4);
// Write to file
@@ -99,3 +103,7 @@ void SingStarXMLWriter::writeXML() {
int SingStarXMLWriter::sec2dur(double sec) {
return round(tempo / 60.0 * sec * 8); // 8 for Demisemiquaver
}
+
+double SingStarXMLWriter::dur2sec(int ts) {
+ return ts * 60.0 / (tempo * 8); // 8 for Demisemiquaver
+}
diff --git a/songwriter.hh b/songwriter.hh
index 13016fb..fe21997 100644
--- a/songwriter.hh
+++ b/songwriter.hh
@@ -17,6 +17,7 @@ struct SingStarXMLWriter: public SongWriter
private:
void writeXML();
int sec2dur(double sec);
+ double dur2sec(int ts);
int tempo;
};
|