//============================================================================= // BWW to MusicXML converter // Part of MusE Score // Linux Music Score Editor // $Id: mxmlwriter.cpp 4873 2011-10-19 19:33:04Z lvinken $ // // Copyright (C) 2010 Werner Schweer and others // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2. // // 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, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //============================================================================= /** \file Output writer for BWW to MusicXML converter. */ #include #include "mxmlwriter.h" namespace Bww { /** MxmlWriter constructor. */ MxmlWriter::MxmlWriter() : beats(4), beat(4), regularMeasureNumber(0), irregularMeasureNumber(0), tempo(0), ending(0) { qDebug() << "MxmlWriter::MxmlWriter()"; stepAlterOctMap["LG"] = StepAlterOct('G', 0, 4); stepAlterOctMap["LA"] = StepAlterOct('A', 0, 4); stepAlterOctMap["B"] = StepAlterOct('B', 0, 4); stepAlterOctMap["C"] = StepAlterOct('C', 1, 5); stepAlterOctMap["D"] = StepAlterOct('D', 0, 5); stepAlterOctMap["E"] = StepAlterOct('E', 0, 5); stepAlterOctMap["F"] = StepAlterOct('F', 1, 5); stepAlterOctMap["HG"] = StepAlterOct('G', 0, 5); stepAlterOctMap["HA"] = StepAlterOct('A', 0, 5); typeMap["1"] = "whole"; typeMap["2"] = "half"; typeMap["4"] = "quarter"; typeMap["8"] = "eighth"; typeMap["16"] = "16th"; typeMap["32"] = "32nd"; } /** Begin a new measure. */ void MxmlWriter::beginMeasure(const Bww::MeasureBeginFlags mbf) { // qDebug() << "MxmlWriter::beginMeasure()"; QString implicit; QString strMeasureNumber; if (mbf.irregular) { implicit = " implicit=\"yes\""; if (irregularMeasureNumber == 0) strMeasureNumber = "0"; else strMeasureNumber = QString("X%1").arg(irregularMeasureNumber); ++irregularMeasureNumber; } else { ++regularMeasureNumber; strMeasureNumber.setNum(regularMeasureNumber); } out << " " << endl; if ((regularMeasureNumber + irregularMeasureNumber) != 1 && mbf.firstOfSystem) { out << " " << endl; } if (mbf.repeatBegin || mbf.endingFirst || mbf.endingSecond) { out << " " << endl; if (mbf.repeatBegin) { out << " heavy-light" << endl; out << " " << endl; } if (mbf.endingFirst) { out << " " << endl; ending = 1; } if (mbf.endingSecond) { out << " " << endl; ending = 2; } out << " " << endl; } if ((regularMeasureNumber + irregularMeasureNumber) == 1) { out << " " << endl; out << " " << wholeDur() / 4 << "" << endl; // out << " " << endl; out << " " << endl; out << " 2" << endl; out << " major" << endl; out << " " << endl; out << " " << endl; out << " " << endl; out << " G" << endl; out << " 2" << endl; out << " " << endl; out << " " << endl; if (tempo) { out << " " << endl; out << " " << endl; out << " " << endl; out << " quarter" << endl; out << " " << tempo << "" << endl; out << " " << endl; out << " " << endl; out << " " << endl; out << " " << endl; } } } /** End the current measure. */ void MxmlWriter::endMeasure(const Bww::MeasureEndFlags mef) { // qDebug() << "MxmlWriter::endMeasure()"; if (mef.repeatEnd || mef.endingEnd || mef.lastOfPart || mef.doubleBarLine) { out << " " << endl; if (mef.repeatEnd || mef.lastOfPart) { out << " light-heavy" << endl; } else if (mef.doubleBarLine) { out << " light-light" << endl; } if (mef.endingEnd) { if (ending == 1) out << " " << endl; else if (ending == 2) out << " " << endl; else { // TODO: error message } } if (mef.repeatEnd) { out << " " << endl; } out << " " << endl; } out << " " << endl; } /** Write a single note. */ void MxmlWriter::note(const QString pitch, QVector beamList, const QString type, const int dots, bool tieStart, bool tieStop, StartStop triplet, bool grace) { // qDebug() << "MxmlWriter::note()"; if (!stepAlterOctMap.contains(pitch) || !typeMap.contains(type)) { // TODO: error message return; } StepAlterOct sao = stepAlterOctMap.value(pitch); int dur = wholeDur() / type.toInt(); if (dots == 1) dur = 3 * dur / 2; if (triplet != ST_NONE) dur = 2 * dur / 3; out << " " << endl; if (grace) out << " " << endl; out << " " << endl; out << " " << sao.s << "" << endl; if (sao.a) out << " " << sao.a << "" << endl; out << " " << sao.o << "" << endl; out << " " << endl; if (!grace) out << " " << dur << "" << endl; if (tieStart) out << " " << endl; if (tieStop) out << " " << endl; out << " " << typeMap.value(type) << "" << endl; if (dots == 1) out << " " << endl; if (triplet != ST_NONE) { out << " " << endl; out << " 3" << endl; out << " 2" << endl; out << " " << endl; } if (grace) out << " up" << endl; else { if (type != "1") out << " down" << endl; } for (int i = 0; i < maxBeamLevel; ++i) { QString s; switch (beamList.at(i)) { case BM_BEGIN: s = "begin"; break; case BM_CONTINUE: s = "continue"; break; case BM_END: s = "end"; break; case BM_FORWARD_HOOK: s = "forward hook"; break; case BM_BACKWARD_HOOK: s = "backward hook"; break; default: s = ""; break; } if (s != "") out << " " << s << "" << endl; else break; } if (tieStart || tieStop || triplet == ST_START || triplet == ST_STOP) { out << " " << endl; if (tieStart) out << " " << endl; if (tieStop) out << " " << endl; if (triplet == ST_START) { if (type == "1" || type == "2" || type == "4") out << " " << endl; else out << " " << endl; } if (triplet == ST_STOP) out << " " << endl; out << " " << endl; } out << " " << endl; } /** Write the header. */ void MxmlWriter::header(const QString title, const QString /* type */, const QString composer, const QString footer, const unsigned int temp) { // qDebug() << "MxmlWriter::header()" // << "title:" << title // << "type:" << type // << "composer:" << composer // << "footer:" << footer // << "temp:" << temp // ; // save tempo for later use tempo = temp; // write the header out << "" << endl; out << "" << endl; out << "" << endl; out << " " << endl; out << " " << title << "" << endl; // TODO work-number is not allowed, replace // out << " " << type << "" << endl; out << " " << endl; out << " " << endl; out << " " << composer << "" << endl; out << " " << footer << "" << endl; out << " " << endl; out << " bww2mxml" << endl; // TODO fill in real date // out << " TBD" << endl; out << " " << endl; out << " " << endl; out << " " << endl; out << " " << endl; out << " " << instrumentName() << "" << endl; out << " " << endl; out << " " << instrumentName() << "" << endl; out << " " << endl; out << " " << endl; out << " 1" << endl; out << " " << midiProgram() << "" << endl; out << " " << endl; out << " " << endl; out << " " << endl; out << " " << endl; } /** Store beats and beat type for later use. */ void MxmlWriter::tsig(const int bts, const int bt) { // qDebug() << "MxmlWriter::tsig()" // << "beats:" << bts // << "beat:" << bt // ; beats = bts; beat = bt; } /** Write the trailer. */ void MxmlWriter::trailer() { // qDebug() << "MxmlWriter::trailer()" // ; out << " " << endl; out << "" << endl; } } // namespace Bww