Skip to content
Snippets Groups Projects
Commit 6b961b3e authored by SeeLook's avatar SeeLook :musical_note:
Browse files

Added methods to rise entire content (melodies, notes) one octave up

Converting bass dropped clef then.
Added class name to debug messages
parent 6a07194c
Branches
Tags
No related merge requests found
/***************************************************************************
* Copyright (C) 2011-2019 by Tomasz Bojczuk *
* Copyright (C) 2011-2020 by Tomasz Bojczuk *
* seelook@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
......@@ -87,7 +87,7 @@ void Tlevel::fretFromXml(QXmlStreamReader& xml, char& fr, Tlevel::EerrorType& er
fr = (char)QVariant(xml.readElementText()).toInt();
if (fr < 0 || fr > 24) { // max frets number
fr = 0;
qDebug() << "Fret number in" << xml.name() << "was wrong but fixed";
qDebug() << "[Tlevel] Fret number in" << xml.name() << "was wrong but fixed";
err = Tlevel::e_levelFixed;
}
}
......@@ -258,29 +258,28 @@ Tlevel::EerrorType Tlevel::qaTypeFromXml(QXmlStreamReader& xml) {
Tlevel::EerrorType Tlevel::loadFromXml(QXmlStreamReader& xml) {
EerrorType er = e_level_OK;
// if (xml.readNextStartElement()) {
if (xml.name() != QLatin1String("level")) {
qDebug() << "There is no 'level' key in that XML";
qDebug() << "[Tlevel] There is no 'level' key in that XML";
return e_noLevelInXml;
}
name = xml.attributes().value(QLatin1String("name")).toString();
if (name.isEmpty()) {
qDebug() << "Level key has empty 'name' attribute";
qDebug() << "[Tlevel] Level key has empty 'name' attribute";
return e_otherError;
} else if (name.size() > 29) {
name = name.left(29);
er = e_levelFixed;
qDebug() << "Name of a level was reduced to 29 characters:" << name;
qDebug() << "[Tlevel] Name of a level was reduced to 29 characters:" << name;
}
melodySet.clear();
// }
while (xml.readNextStartElement()) {
if (xml.name() == QLatin1String("description"))
desc = xml.readElementText();
// QUESTIONS
else if (xml.name() == QLatin1String("questions")) {
while (xml.readNextStartElement()) {
// qDebug() << "questions->" << xml.name();
if (xml.name() == QLatin1String("qaType")) {
er = qaTypeFromXml(xml);
if (er == e_otherError)
......@@ -293,15 +292,15 @@ Tlevel::EerrorType Tlevel::loadFromXml(QXmlStreamReader& xml) {
showStrNr = QVariant(xml.readElementText()).toBool();
else if (xml.name() == QLatin1String("clef")) {
clef.setClef(Tclef::EclefType(QVariant(xml.readElementText()).toInt()));
if (clef.name().isEmpty()) { // when clef has improper value its name returns empty string
qDebug() << "Level had wrong/undefined clef. It was fixed to treble dropped.";
if (clef.name().isEmpty()) { // when clef has improper/unsupported value its name returns empty string
qDebug() << "[Tlevel] Level had wrong/undefined clef. It was fixed to treble dropped.";
clef.setClef(Tclef::Treble_G_8down);
er = e_levelFixed;
}
} else if (xml.name() == QLatin1String("instrument")) {
instrument = Tinstrument::Etype(QVariant(xml.readElementText()).toInt());
if (Tinstrument::staticName(instrument).isEmpty()) {
qDebug() << "Level had wrong instrument type. It was fixed to classical guitar.";
qDebug() << "[Tlevel] Level had wrong instrument type. It was fixed to classical guitar.";
instrument = Tinstrument::ClassicalGuitar;
er = e_levelFixed;
}
......@@ -425,18 +424,18 @@ Tlevel::EerrorType Tlevel::loadFromXml(QXmlStreamReader& xml) {
}
if (canBeGuitar() && fixFretRange() == e_levelFixed) {
er = e_levelFixed;
qDebug() << "Lowest fret in range was bigger than the highest one. Fixed";
qDebug() << "[Tlevel] Lowest fret in range was bigger than the highest one. Fixed";
}
if (useKeySign && !isSingleKey && fixKeyRange() == e_levelFixed) {
er = e_levelFixed;
qDebug() << "Lowest key in range was higher than the highest one. Fixed";
qDebug() << "[Tlevel] Lowest key in range was higher than the highest one. Fixed";
}
if (loNote.note() == 0 || hiNote.note() == 0) {
qDebug() << "Note range is wrong.";
qDebug() << "[Tlevel] Note range is wrong.";
return e_otherError;
} else if (fixNoteRange() == e_levelFixed) {
er = e_levelFixed;
qDebug() << "Lowest note in range was higher than the highest one. Fixed";
qDebug() << "[Tlevel] Lowest note in range was higher than the highest one. Fixed";
}
if (notesList.isEmpty()) {
if (randMelody == e_randFromList) {
......@@ -450,7 +449,7 @@ Tlevel::EerrorType Tlevel::loadFromXml(QXmlStreamReader& xml) {
}
}
if (xml.hasError()) {
qDebug() << "level has error" << xml.errorString() << xml.lineNumber();
qDebug() << "[Tlevel] level has error" << xml.errorString() << xml.lineNumber();
return e_otherError;
}
return er;
......@@ -577,6 +576,31 @@ bool Tlevel::saveToFile(Tlevel& level, const QString& levelFile) {
return false;
}
//#################################################################################################
//################### FIXES FOR LEVEL CONTENT ############################################
//#################################################################################################
void Tlevel::convFromDropedBass() {
if (clef.type() == Tclef::Bass_F_8down)
clef.setClef(Tclef::Bass_F);
loNote.riseOctaveUp();
hiNote.riseOctaveUp();
if (!notesList.isEmpty()) {
for (int n = 0; n < notesList.count(); ++n)
notesList[n].riseOctaveUp();
}
if (!melodySet.isEmpty()) {
for (int m = 0; m < melodySet.count(); ++m) {
auto mel = &melodySet[m];
if (mel->clef() == Tclef::Bass_F_8down)
mel->setClef(Tclef::Bass_F);
for (int n = 0; n < mel->length(); ++n)
mel->note(n)->p().riseOctaveUp();
}
}
}
Tclef Tlevel::fixClef(quint16 cl) {
if (cl == 0) // For backward compatibility - 'no clef' never occurs
......@@ -589,7 +613,7 @@ Tclef Tlevel::fixClef(quint16 cl) {
return Tclef(Tclef::Treble_G);
}
if (cl != 2 && cl != 4 && cl != 8 && cl != 16 && cl != 32 && cl != 64 && cl != 128) {
qDebug() << "Fixed clef type. Previous value was:" << cl;
qDebug() << "[Tlevel] Fixed clef type. Previous value was:" << cl;
return Tclef(Tclef::Treble_G_8down); // some previous mess - when levels didn't' support clefs
}
......@@ -615,7 +639,7 @@ Tinstrument::Etype Tlevel::fixInstrument(quint8 instr) {
} else if (instr < 4) { // simple cast to detect an instrument
return (Tinstrument::Etype)instr;
} else {
qDebug() << "Tlevel::instrument had some stupid value. FIXED";
qDebug() << "[Tlevel] Tlevel::instrument had some stupid value. FIXED";
return GLOB->instrument().type();
}
}
......@@ -769,7 +793,7 @@ bool Tlevel::adjustFretsToScale(char& loF, char& hiF) {
if (!usedStrings[st])
continue;
int diff = no - GLOB->Gtune()->str(GLOB->strOrder(st) + 1).chromatic();
if (diff >= 0 && diff <= GLOB->GfretsNumber) { // found
if (diff >= 0 && diff <= static_cast<int>(GLOB->GfretsNumber)) { // found
lowest = qMin<int>(lowest, diff);
tmpLow = qMin<int>(tmpLow, diff);
}
......
/***************************************************************************
* Copyright (C) 2011-2018 by Tomasz Bojczuk *
* Copyright (C) 2011-2020 by Tomasz Bojczuk *
* seelook@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
......@@ -45,7 +45,8 @@ public:
/**
* Possible errors during reading level file or XML key.
*/
enum EerrorType { e_level_OK = 0,
enum EerrorType {
e_level_OK = 0,
e_levelFixed, /**< level parameters were fixed */
e_noLevelInXml, /**< when XML stream has no <level> tag */
e_otherError
......@@ -64,28 +65,42 @@ public:
static const qint32 levelVersion; /**< First version, also with early using of intonation and instruments */
static const qint32 currentVersion; /**< Current level version identifier */
/** Returns true when given value match to level versions. */
/**
* Returns true when given value match to level versions.
*/
static bool isLevelVersion(quint32 ver);
/** Generates level version identifier number from given simple version number (1, 2 etc.)
* It doesn't verify does given number make sense! */
/**
* Generates level version identifier number from given simple version number (1, 2 etc.)
* It doesn't verify does given number make sense!
*/
static qint32 getVersionId(quint8 verNr) { return levelVersion + (verNr - 1) * 2; }
/** Returns number of level version like 1, 2 or so */
/**
* Returns number of level version like 1, 2 or so
*/
static int levelVersionNr(qint32 ver);
/** Returns true when given value 'could be' or 'it is' some version of exam level.
* This way level created with newer Nootka version can be detected. */
/**
* Returns true when given value 'could be' or 'it is' some version of exam level.
* This way level created with newer Nootka version can be detected.
*/
static bool couldBeLevel(qint32 ver);
/** Saves level to given file and returns true for success or opposite. */
/**
* Saves level to given file and returns true for success or opposite.
*/
static bool saveToFile(Tlevel &level, const QString& levelFile);
/** Shows message box with error if file cannot be opened.*/
/**
* Shows message box with error if file cannot be opened.
*/
static void fileIOerrorMsg(QFile &f);
/** Reads fret number from current XML key to @fr reference and verifies it.
* Setts error type when error occurs or lives @p err unchanged when OK. */
/**
* Reads fret number from current XML key to @fr reference and verifies it.
* Setts error type when error occurs or lives @p err unchanged when OK.
*/
static void fretFromXml(QXmlStreamReader& xml, char& fr, Tlevel::EerrorType& err);
static void skipCurrentXmlKey(QXmlStreamReader& xml);
......@@ -135,35 +150,56 @@ public:
bool usedStrings[6];
/** Indicates when instrument read from file needs user action to be properly obtained.
* It occurs when read value is 255 for level version 1 */
/**
* Indicates when instrument read from file needs user action to be properly obtained.
* It occurs when read value is 255 for level version 1
*/
bool hasInstrToFix;
// some helpers
/** True if answer or question is note on a score */
/**
* @p TRUE if answer or question is note on a score
*/
bool canBeScore() const ;
/** True if answer or question is note name */
/**
* @p TRUE if answer or question is note name
*/
bool canBeName() const;
/** True if answer or question is position on a guitar */
/**
* @p TRUE if answer or question is position on a guitar
*/
bool canBeGuitar() const;
/** True if answer or question is played or sang sound */
/**
* @p TRUE if answer or question is played or sang sound
*/
bool canBeSound() const ;
/** True when question/answer has more notes and have appropriate types */
/**
* @p TRUE when question/answer has more notes and have appropriate types
*/
bool canBeMelody() const;
/** True if answer is note on a score in any question type */
/**
* @p TRUE if answer is note on a score in any question type
*/
bool answerIsNote() const;
/** True if answer is note name in any question type */
/**
* @p TRUE if answer is note name in any question type
*/
bool answerIsName() const;
/** True if answer is position on the guitar in any question type */
/**
* @p TRUE if answer is position on the guitar in any question type
*/
bool answerIsGuitar() const;
/** True if answer is played sound in any question type */
/**
* @p TRUE if answer is played sound in any question type
*/
bool answerIsSound() const;
/**
......@@ -171,13 +207,19 @@ public:
*/
bool isMelodySet() const { return randMelody == e_melodyFromSet && !melodySet.isEmpty(); }
/** True when level note range is in given number range represented scale of instrument. */
/**
* @p TRUE when level note range is in given number range represented scale of instrument.
*/
bool inScaleOf(int loNoteNr, int hiNoteNr) const;
/** Overloaded method with scale in Tnote objects */
/**
* Overloaded method with scale in Tnote objects
*/
bool inScaleOf(const Tnote &loN, const Tnote &hiN) const { return inScaleOf(loN.chromatic(), hiN.chromatic()); }
/** Overloaded method where instrument scale is taken from @p Tglobals */
/**
* Overloaded method where instrument scale is taken from @p Tglobals
*/
bool inScaleOf();
/**
......@@ -189,13 +231,19 @@ public:
*/
bool adjustFretsToScale(char& loF, char& hiF);
/** Writes level parameters into 'level' node of XML stream */
/**
* Writes level parameters into 'level' node of XML stream
*/
void writeToXml(QXmlStreamWriter& xml);
/** Reads level from XML stream */
/**
* Reads level from XML stream
*/
EerrorType loadFromXml(QXmlStreamReader& xml);
/** Reads 'qaType' key from XML. Determines level var by id and sets it */
/**
* Reads 'qaType' key from XML. Determines level var by id and sets it
*/
EerrorType qaTypeFromXml(QXmlStreamReader& xml);
/**
......@@ -205,10 +253,23 @@ public:
//------------------------- to fix a level ---------------------------------------------------
/** Returns detected clef from level versions before 0.8.90 */
/**
* Since Nootka 2 (versions 1.5 and above) dropped bass clef
* was changed to simply bass clef (without any drop),
* but with instrument transposition one octave down.
* So all notes (melodies, range and so) HAVE TO BE transposed as well
* by one octave up (12 semitones).
*/
void convFromDropedBass();
/**
* Returns detected clef from level versions before 0.8.90
*/
Tclef fixClef(quint16 cl);
/** Fixes instrument value taken from file (stream) created before level Version 2 */
/**
* Fixes instrument value taken from file (stream) created before level Version 2
*/
Tinstrument::Etype fixInstrument(quint8 instr);
/**
......@@ -224,7 +285,9 @@ public:
};
/** Reads level data from given stream to @p lev. Respects @p ver - version */
/**
* Reads level data from given stream to @p lev. Respects @p ver - version
*/
NOOTKACORE_EXPORT bool getLevelFromStream(QDataStream& in, Tlevel& lev, qint32 ver);
Q_DECLARE_METATYPE(Tlevel*)
......
......@@ -298,3 +298,14 @@ bool getTQAunitFromStream(QDataStream &in, TQAunit &qaUnit) {
return ok;
}
void TQAunit::riseOctaveUp() {
qa.note.riseOctaveUp();
qa_2.note.riseOctaveUp();
if (m_melody && m_srcMelody == e_srcThisUnit) {
if (m_melody->clef() == Tclef::Bass_F_8down)
m_melody->setClef(Tclef::Bass_F);
for (int n = 0; n < m_melody->length(); ++n)
m_melody->note(n)->p().riseOctaveUp();
}
}
/***************************************************************************
* Copyright (C) 2011-2019 by Tomasz Bojczuk *
* Copyright (C) 2011-2020 by Tomasz Bojczuk *
* seelook@gmail.com *
* *
* This program is free software; you can redistribute it and/or modify *
......@@ -305,11 +305,19 @@ public:
void toXml(QXmlStreamWriter& xml);
bool fromXml(QXmlStreamReader& xml);
/**
* This method simply rises all unit notes one octave up.
* The ONLY ONE PURPOSE of this method is to convert/fix
* bass dropped down clef of old Nootka to ordinary bass clef,
* so all notes has to transposed octave up
*/
void riseOctaveUp();
protected:
quint32 p_valid;
quint8 style;
int idOfMelody; /**< Number of another question or an item in a list that contain a melody. */
QList<Tattempt*> *attemptList; /**< Pointer to a list with attempts or 0 if no attempts */
QList<Tattempt*> *attemptList; /**< Pointer to a list with attempts or @p nullptr if no attempts */
/**
* Deletes this melody if exists and belongs to this unit.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment