diff --git a/src/libs/core/music/tchunk.cpp b/src/libs/core/music/tchunk.cpp index 0d1cf0786d7cf134ecf39b7d0178452a953315d1..e8aca03190fba43c9fa2db92c7820df34de074d6 100644 --- a/src/libs/core/music/tchunk.cpp +++ b/src/libs/core/music/tchunk.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2014-2017 by Tomasz Bojczuk * + * Copyright (C) 2014-2018 by Tomasz Bojczuk * * seelook@gmail.com * * * * This program is free software; you can redistribute it and/or modify * @@ -24,16 +24,12 @@ Tchunk::Tchunk(const Tnote& pitch, const TfingerPos& fretPos) : - m_pitch(pitch), - m_fretPos(fretPos) + m_pitch(pitch) { + m_noteData.setFingerPos(fretPos); } -Tchunk::~Tchunk() -{} - - void Tchunk::toXml(QXmlStreamWriter& xml, int* staffNr) { xml.writeStartElement(QLatin1String("note")); if (m_pitch.isRest() || !m_pitch.isValid()) @@ -57,10 +53,10 @@ void Tchunk::toXml(QXmlStreamWriter& xml, int* staffNr) { xml.writeEndElement(); // beam } } - if (m_pitch.rtm.tie() || validPos()) { + if (m_pitch.rtm.tie() || !m_noteData.isEmpty()) { xml.writeStartElement(QLatin1String("notations")); - if (validPos()) - g().toXml(xml); + if (!m_noteData.isEmpty()) + m_noteData.toXml(xml); if (m_pitch.rtm.tie()) tieToXml(xml, m_pitch.rtm.tie(), e_tied); xml.writeEndElement(); @@ -98,7 +94,7 @@ bool Tchunk::fromXml(QXmlStreamReader& xml, int* staffNr) { } else if (xml.name() == QLatin1String("notations")) { while (xml.readNextStartElement()) { if (xml.name() == QLatin1String("technical")) - m_fretPos.fromXml(xml); + m_noteData.fromXml(xml); else if (xml.name() == QLatin1String("tied")) { auto type = xml.attributes().value(QStringLiteral("type")); Trhythm::Etie tie = Trhythm::e_noTie; diff --git a/src/libs/core/music/tchunk.h b/src/libs/core/music/tchunk.h index d19ae1a5fea87467c481f3934e95f2970334186b..e12ed7fc360c9aa55e070f9c27212ef37b9f954e 100755 --- a/src/libs/core/music/tchunk.h +++ b/src/libs/core/music/tchunk.h @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2014-2017 by Tomasz Bojczuk * + * Copyright (C) 2014-2018 by Tomasz Bojczuk * * seelook@gmail.com * * * * This program is free software; you can redistribute it and/or modify * @@ -19,9 +19,11 @@ #ifndef TCHUNK_H #define TCHUNK_H + #include <nootkacoreglobal.h> #include "tnote.h" -#include <tfingerpos.h> +#include "tnotedata.h" + class QXmlStreamReader; class QXmlStreamWriter; @@ -42,7 +44,7 @@ public: * Default constructor - creates 'empty' note and position. */ Tchunk() {} - ~Tchunk(); + ~Tchunk() {} /** * The note @@ -54,10 +56,36 @@ public: /** * Position a note on a guitar (if any) - by default it is null - invalid */ - TfingerPos& g() { return m_fretPos; } + TfingerPos& g() { return m_noteData.fingerPos(); } + + /** + * Extra note data like guitar position, bow direction, staff position (upper/lower) and fingering + */ + TnoteData& d() { return m_noteData; } + + bool onUpperStaff() const { return m_noteData.onUpperStaff(); } + void setOnUpperStaff(bool onUpper) { m_noteData.setOnUpperStaff(onUpper); } + + TnoteData::EbowDirection bow() const { return m_noteData.bow(); } + void setBow(TnoteData::EbowDirection b) { m_noteData.setBow(b); } + + /** + * Finger number [0 - 5]. + * -1 is returned when undefined + */ + int finger() const { return m_noteData.finger(); } + void setFinger(int fi) { m_noteData.setFinger(fi); } + + /** + * Numeric value representing all extra note parameters + */ + quint32 noteData() const { return m_noteData.data(); } + void setNoteData(quint32 nd) { m_noteData.setData(nd); } - /** Returns @p TRUE when position on the guitar is valid. */ - bool validPos() { if (g().str() == 7) return false; else return true; } + /** + * Returns @p TRUE when position on the guitar is valid. + */ + bool validPos() { return g().str() != 7; } /** * If @p staffNr is set appropriate <staff>staffNr</staff> is added @@ -89,7 +117,7 @@ public: private: Tnote m_pitch; - TfingerPos m_fretPos; + TnoteData m_noteData; }; #endif // TCHUNK_H diff --git a/src/libs/core/music/tnotedata.cpp b/src/libs/core/music/tnotedata.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ab640cbc1d65ad67a03a31051ccb55c5cfeec0bb --- /dev/null +++ b/src/libs/core/music/tnotedata.cpp @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2018 by Tomasz Bojczuk * + * seelook@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + + +#include "tnotedata.h" + +#include <QtCore/qdebug.h> + + +TnoteData::TnoteData(quint32 fromData) +{ + setData(fromData); +} + + +/** + * Upper staff id default state so it is for 0 value + */ +void TnoteData::setOnUpperStaff(bool onUpper) { + if (onUpper) + m_otherData &= ~ON_UPPER; + else + m_otherData |= ON_UPPER; +} + + +void TnoteData::setBow(TnoteData::EbowDirection b) { + m_otherData &= ~BOW_DIRECTION; // reset it first + m_otherData |= b; +} + + +void TnoteData::setFinger(int fingerNr) { + m_otherData &= ~FINGERING; + if (fingerNr >= -1 && fingerNr < 6) + m_otherData |= (static_cast<quint16>(fingerNr) + 1) << 3; + else + qDebug() << "[TnoteData] wrong finger number to store" << fingerNr << " Igoring."; +} + + +quint32 TnoteData::data() const { + quint32 d = m_otherData; + d <<= 8; + d += m_fingerPos.data(); + return d; +} + + +void TnoteData::setData(quint32 d) { + m_fingerPos.setData(static_cast<quint8>(d)); + m_otherData = static_cast<quint16>(d >> 8); +} + + +void TnoteData::fromXml(QXmlStreamReader& xml) { + int s = 0, f = 50; + while (xml.readNextStartElement()) { + if (xml.name() == QLatin1String("string")) + s = xml.readElementText().toInt(); + else if (xml.name() == QLatin1String("fret")) + f = xml.readElementText().toInt(); + else + xml.skipCurrentElement(); + } + if (s == 0 || f == 50) + m_fingerPos.setData(255); // invalid + else + m_fingerPos.setPos(s, f); +} + + +void TnoteData::toXml(QXmlStreamWriter& xml, const QString& tag) const { + if (!tag.isEmpty()) + xml.writeStartElement(tag); + xml.writeTextElement(QLatin1String("string"), QString("%1").arg(m_fingerPos.str())); + xml.writeTextElement(QLatin1String("fret"), QString("%1").arg(m_fingerPos.fret())); + if (!tag.isEmpty()) + xml.writeEndElement(); // tag +} diff --git a/src/libs/core/music/tnotedata.h b/src/libs/core/music/tnotedata.h new file mode 100644 index 0000000000000000000000000000000000000000..8ade43787068e5d522e09cee79d43cb5b74b68d1 --- /dev/null +++ b/src/libs/core/music/tnotedata.h @@ -0,0 +1,96 @@ +/*************************************************************************** + * Copyright (C) 2018 by Tomasz Bojczuk * + * seelook@gmail.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 3 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ + +#ifndef TNOTEDATA_H +#define TNOTEDATA_H + + +#include "nootkacoreglobal.h" +#include "tfingerpos.h" +#include <QtCore/qobject.h> + + +#define ON_UPPER (1) // first bit +#define BOW_DIRECTION (6) // 2nd and 3rd bits +#define FINGERING (56) // 4th to 6th bits + + +/** + * @p TnoteData extends information about note in the score. + * It has guitar position in @p TfingerPos + * - bow direction (down/up) - for bandoneon it is bellow state (opening/closing) + * - note position on the grand staff (on upper staff of or on the lower one) + * - finger number [0 - 5], -1 - is undefined + * + * All parameters can be represented by single @p quint32 value + * available through @p data() and set through @p setData() + */ +class NOOTKACORE_EXPORT TnoteData +{ + + Q_GADGET + +public: + TnoteData() {} + TnoteData(quint32 fromData); + + /** + * Returns @p TRUE when all extra note parameters are unset + */ + bool isEmpty() const { return !m_fingerPos.isValid() && m_otherData == 0; } + + /** + * Resets all extra note parameters to null + */ + void reset() { m_fingerPos.setData(255); m_otherData = 0; } + + TfingerPos& fingerPos() { return m_fingerPos; } + void setFingerPos(TfingerPos fp) { m_fingerPos.setData(fp.data()); } + + bool onUpperStaff() const { return !(m_otherData & ON_UPPER); } + void setOnUpperStaff(bool onUpper); + + enum EbowDirection { + BowUndefined = 0, + BowDown = 2, /**< For bandoneon it is bellow opening */ + BowUp = 4 /**< For bandoneon it is bellow closing */ + }; + Q_ENUM(EbowDirection) + + EbowDirection bow() const { return static_cast<EbowDirection>(m_otherData & BOW_DIRECTION); } + void setBow(EbowDirection b); + + /** + * Finger number [0 - 5]. + * -1 is returned when undefined + */ + int finger() const { return ((m_otherData & FINGERING) >> 3) - 1; } + void setFinger(int fingerNr); + + quint32 data() const; + void setData(quint32 d); + + void toXml (QXmlStreamWriter& xml, const QString& tag = QLatin1String("technical")) const; + void fromXml(QXmlStreamReader& xml); + +private: + TfingerPos m_fingerPos; + quint16 m_otherData = 0; +}; + +#endif // TNOTEDATA_H