diff --git a/mscore/CMakeLists.txt b/mscore/CMakeLists.txt index b572a092d05e0..d34be9210aea9 100644 --- a/mscore/CMakeLists.txt +++ b/mscore/CMakeLists.txt @@ -3,7 +3,7 @@ # Linux Music Score Editor # $Id:$ # -# Copyright (C) 2002-2010 by Werner Schweer and others +# Copyright (C) 2002-2013 by 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. @@ -176,7 +176,7 @@ add_executable ( ${ExecutableName} editdrumset.cpp editstaff.cpp voltaproperties.cpp timesigproperties.cpp newwizard.cpp transposedialog.cpp chordedit.cpp excerptsdialog.cpp metaedit.cpp magbox.cpp - voiceselector.cpp capella.cpp exportaudio.cpp palettebox.cpp + voiceselector.cpp capella.cpp capxml.cpp exportaudio.cpp palettebox.cpp textproperties.cpp slurproperties.cpp synthcontrol.cpp drumroll.cpp pianoroll.cpp piano.cpp pianoview.cpp drumview.cpp scoretab.cpp keyedit.cpp harmonyedit.cpp diff --git a/mscore/capella.cpp b/mscore/capella.cpp index 681dc0c6cd4e5..c7d34bdad574b 100644 --- a/mscore/capella.cpp +++ b/mscore/capella.cpp @@ -3,7 +3,7 @@ // Linux Music Score Editor // $Id: capella.cpp 5637 2012-05-16 14:23:09Z wschweer $ // -// Copyright (C) 2009-2011 Werner Schweer and others +// Copyright (C) 2009-2013 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. @@ -132,7 +132,7 @@ static void processBasicDrawObj(QList objects, Segment* s, int tr { Score* score = s->score(); foreach(BasicDrawObj* oo, objects) { - switch(oo->type) { + switch (oo->type) { case CAP_GROUP: case CAP_TRANSPOSABLE: case CAP_METAFILE: @@ -156,7 +156,7 @@ static void processBasicDrawObj(QList objects, Segment* s, int tr if (text.size() == 1) { QChar c(text[0]); ushort code = c.unicode(); - switch(code) { + switch (code) { case 'p': addDynamic(score, s, track, "p"); break; @@ -205,7 +205,7 @@ static void processBasicDrawObj(QList objects, Segment* s, int tr addDynamic(score, s, track, "fp"); break; default: - qDebug("====unsupported capella code %x(%c)\n", code, code); + qDebug("====unsupported capella code %x(%c)", code, code); break; } break; @@ -214,7 +214,7 @@ static void processBasicDrawObj(QList objects, Segment* s, int tr Text* text = new Text(score); QFont f(st->font()); text->setItalic(f.italic()); -// text->setUnderline(f.underline()); + // text->setUnderline(f.underline()); text->setBold(f.bold()); text->setSize(f.pointSizeF()); @@ -223,16 +223,16 @@ static void processBasicDrawObj(QList objects, Segment* s, int tr p = p / 32.0 * MScore::DPMM; // text->setUserOff(st->pos()); text->setUserOff(p); -qDebug("setText %s (%f %f)(%f %f) <%s>\n", - qPrintable(st->font().family()), - st->pos().x(), st->pos().y(), p.x(), p.y(), qPrintable(st->text())); + // qDebug("setText %s (%f %f)(%f %f) <%s>", + // qPrintable(st->font().family()), + // st->pos().x(), st->pos().y(), p.x(), p.y(), qPrintable(st->text())); text->setAlign(ALIGN_LEFT | ALIGN_BASELINE); text->setTrack(track); s->add(text); } break; case CAP_TEXT: -qDebug("======================Text:\n"); + qDebug("======================Text:"); break; } } @@ -242,12 +242,12 @@ qDebug("======================Text:\n"); // readCapVoice //--------------------------------------------------------- -static int readCapVoice(Score* score, CapVoice* cvoice, int staffIdx, int tick) +static int readCapVoice(Score* score, CapVoice* cvoice, int staffIdx, int tick, bool capxMode) { int voice = cvoice->voiceNo; int track = staffIdx * VOICES + voice; -qDebug("readCapVoice 1\n"); + qDebug("readCapVoice 1"); // // pass I // @@ -258,18 +258,18 @@ qDebug("readCapVoice 1\n"); int nTuplet = 0; int tupletTick = 0; -//qDebug(" read voice: tick %d track: %d)\n", tick, track); + qDebug(" read voice: tick %d track: %d)", tick, track); foreach(NoteObj* no, cvoice->objects) { - switch(no->type()) { + switch (no->type()) { case T_REST: { -//qDebug(" \n"); + qDebug(" "); Measure* m = score->getCreateMeasure(tick); RestObj* o = static_cast(no); int ticks = o->ticks(); if (o->invisible && ticks == 0) { // get rid of placeholders break; - } + } TDuration d; d.setVal(ticks); if (o->count) { @@ -282,7 +282,7 @@ qDebug("readCapVoice 1\n"); if (tupletCount == 3) f = Fraction(3,2); else - qDebug("Capella: unknown tuplet\n"); + qDebug("Capella: unknown tuplet"); tuplet->setRatio(f); tuplet->setBaseLen(d); tuplet->setTrack(track); @@ -332,12 +332,12 @@ qDebug("readCapVoice 1\n"); break; case T_CHORD: { -//qDebug(" \n"); + qDebug(" "); ChordObj* o = static_cast(no); int ticks = o->ticks(); if (o->invisible && ticks == 0) { // get rid of placeholders break; - } + } TDuration d; d.setVal(ticks); Measure* m = score->getCreateMeasure(tick); @@ -356,7 +356,7 @@ qDebug("readCapVoice 1\n"); if (tupletCount == 3) f = Fraction(3,2); else - qDebug("Capella: unknown tuplet\n"); + qDebug("Capella: unknown tuplet"); tuplet->setRatio(f); tuplet->setBaseLen(d); tuplet->setTrack(track); @@ -366,9 +366,9 @@ qDebug("readCapVoice 1\n"); tuplet->setDuration(Fraction::fromTicks(nn)); m->add(tuplet); } -// qDebug("Tuplet at %d: count: %d tri: %d prolonging: %d ticks %d objects %d\n", -// tick, o->count, o->tripartite, o->isProlonging, ticks, -// o->objects.size()); + qDebug("Tuplet at %d: count: %d tri: %d prolonging: %d ticks %d objects %d", + tick, o->count, o->tripartite, o->isProlonging, ticks, + o->objects.size()); } Chord* chord = new Chord(score); @@ -400,7 +400,7 @@ qDebug("readCapVoice 1\n"); int clef = score->staff(staffIdx)->clef(tick); int key = score->staff(staffIdx)->key(tick).accidentalType(); int off; - switch(clef) { + switch (clef) { case CLEF_F: off = -14; break; case CLEF_F_B: off = -14; break; case CLEF_F_C: off = -14; break; @@ -414,23 +414,31 @@ qDebug("readCapVoice 1\n"); } static int keyOffsets[15] = { - // -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 - 7, 4, 1, 5, 2, 6, 3, 0, 4, 1, 5, 2, 6, 3, 0 + /* -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 */ + /* */ 7, 4, 1, 5, 2, 6, 3, 0, 4, 1, 5, 2, 6, 3, 0 }; off += keyOffsets[key + 7]; foreach(CNote n, o->notes) { Note* note = new Note(score); - int l = n.pitch + off + 7 * 6; - int octave = 0; - while (l < 0) { - l += 7; - octave--; + int pitch = 0; + // .cap import: pitch contains the diatonic note number relative to clef and key + // .capx import: pitch the MIDI note number instead + if (capxMode) { + pitch = n.pitch; } - octave += l / 7; - l = l % 7; + else { + int l = n.pitch + off + 7 * 6; + int octave = 0; + while (l < 0) { + l += 7; + octave--; + } + octave += l / 7; + l = l % 7; - int pitch = pitchKeyAdjust(l, key) + octave * 12; + pitch = pitchKeyAdjust(l, key) + octave * 12; + } pitch += n.alteration; if (pitch > 127) @@ -440,7 +448,7 @@ qDebug("readCapVoice 1\n"); note->setPitch(pitch); note->setTpc(pitch2tpc(pitch, key, PREFER_NEAREST)); -// TODO: compute tpc from pitch & line + // TODO: compute tpc from pitch & line // note->setTpc(tpc); chord->add(note); @@ -478,9 +486,9 @@ qDebug("readCapVoice 1\n"); break; case T_CLEF: { -//qDebug(" \n"); + qDebug(" "); CapClef* o = static_cast(no); -// qDebug("%d:%d %s line %d oct %d\n", tick, staffIdx, o->name(), o->line, o->oct); + qDebug("%d:%d %s line %d oct %d", tick, staffIdx, o->name(), o->line, o->oct); ClefType nclef = o->clef(); if (nclef == CLEF_INVALID) break; @@ -495,7 +503,7 @@ qDebug("readCapVoice 1\n"); break; case T_KEY: { -//qDebug(" \n"); + qDebug(" "); CapKey* o = static_cast(no); int key = score->staff(staffIdx)->key(tick).accidentalType(); if (key != o->signature) { @@ -512,9 +520,9 @@ qDebug("readCapVoice 1\n"); case T_METER: { CapMeter* o = static_cast(no); -qDebug(" tick %d %d/%d\n", tick, o->numerator, 1 << o->log2Denom); + qDebug(" tick %d %d/%d", tick, o->numerator, 1 << o->log2Denom); if (o->log2Denom > 7 || o->log2Denom < 0) { - qDebug("illegal fraction\n"); + qDebug("illegal fraction"); abort(); } SigEvent se = score->sigmap()->timesig(tick); @@ -534,7 +542,7 @@ qDebug(" tick %d %d/%d\n", tick, o->numerator, 1 << o->log2Denom); case T_IMPL_BARLINE: // does not exist? { CapExplicitBarline* o = static_cast(no); -qDebug(" \n"); + qDebug(" "); Measure* m = score->getCreateMeasure(tick-1); int ticks = tick - m->tick(); if (ticks > 0 && ticks != m->ticks()) { @@ -569,21 +577,21 @@ qDebug(" \n"); if (nm) nm->setRepeatFlags(nm->repeatFlags() | RepeatStart); } -// if (st != START_REPEAT) -// m->setEndBarLineType(st, false, true, Qt::black); + // if (st != START_REPEAT) + // m->setEndBarLineType(st, false, true, Qt::black); if (st == END_REPEAT || st == END_START_REPEAT) m->setRepeatFlags(m->repeatFlags() | RepeatEnd); } break; case T_PAGE_BKGR: -// qDebug(" \n"); + qDebug(" "); break; } } int endTick = tick; -qDebug("readCapVoice 2\n"); + qDebug("readCapVoice 2"); // // pass II // @@ -599,14 +607,14 @@ qDebug("readCapVoice 2\n"); foreach(BasicDrawObj* o, d->objects) { switch (o->type) { case CAP_SIMPLE_TEXT: - // qDebug("simple text at %d\n", tick); + // qDebug("simple text at %d", tick); break; case CAP_WAVY_LINE: break; case CAP_SLUR: { SlurObj* so = static_cast(o); - // qDebug("slur tick %d %d-%d-%d-%d %d-%d\n", tick, so->nEnd, so->nMid, + // qDebug("slur tick %d %d-%d-%d-%d %d-%d", tick, so->nEnd, so->nMid, // so->nDotDist, so->nDotWidth, so->nRefNote, so->nNotes); Segment* seg = score->tick2segment(tick); int tick2 = -1; @@ -618,7 +626,7 @@ qDebug("readCapVoice 2\n"); if (seg->element(track)) --n; else - qDebug(" %d empty seg\n", n); + qDebug(" %d empty seg", n); if (n == 0) { tick2 = seg->tick(); break; @@ -626,7 +634,7 @@ qDebug("readCapVoice 2\n"); } } else - qDebug(" segment at %d not found\n", tick); + qDebug(" segment at %d not found", tick); if (tick2 >= 0) { Slur* slur = new Slur(score); // TODO1 slur->setTick(tick); @@ -636,18 +644,18 @@ qDebug("readCapVoice 2\n"); score->add(slur); } else - qDebug("second anchor for slur not found\n"); + qDebug("second anchor for slur not found"); } break; case CAP_TEXT: { - extern QString rtf2html(const QString&); + extern QString rtf2html(const QString &); TextObj* to = static_cast(o); Text* s = new Text(score); QString ss = rtf2html(QString(to->text)); -//qDebug("string %f:%f w %d ratio %d <%s>\n", -// to->relPos.x(), to->relPos.y(), to->width, to->yxRatio, qPrintable(ss)); + //qDebug("string %f:%f w %d ratio %d <%s>", + // to->relPos.x(), to->relPos.y(), to->width, to->yxRatio, qPrintable(ss)); s->setHtml(ss); MeasureBase* measure = score->measures()->first(); if (measure->type() != Element::VBOX) { @@ -675,7 +683,7 @@ qDebug("readCapVoice 2\n"); } tick += ticks; } -qDebug(" readCapVoice\n"); + qDebug(" readCapVoice"); return endTick; } @@ -683,28 +691,28 @@ qDebug(" readCapVoice\n"); // convertCapella //--------------------------------------------------------- -static void convertCapella(Score* score, Capella* cap) +void convertCapella(Score* score, Capella* cap, bool capxMode) { if (cap->systems.isEmpty()) return; -qDebug("==================convert-capella\n"); + qDebug("==================convert-capella"); score->style()->set(ST_measureSpacing, 1.0); score->setSpatium(cap->normalLineDist * MScore::DPMM); score->style()->set(ST_smallStaffMag, cap->smallLineDist / cap->normalLineDist); score->style()->set(ST_minSystemDistance, Spatium(8)); score->style()->set(ST_maxSystemDistance, Spatium(12)); -// score->style()->set(ST_hideEmptyStaves, true); + // score->style()->set(ST_hideEmptyStaves, true); #if 1 foreach(CapSystem* csys, cap->systems) { - qDebug("System:\n"); + qDebug("System:"); foreach(CapStaff* cstaff, csys->staves) { CapStaffLayout* cl = cap->staffLayout(cstaff->iLayout); - qDebug(" Staff layout <%s><%s><%s><%s><%s> %d barline %d-%d mode %d\n", - cl->descr, cl->name, cl->abbrev, cl->intermediateName, - cl->intermediateAbbrev, - cstaff->iLayout, cl->barlineFrom, cl->barlineTo, cl->barlineMode); + qDebug(" Staff layout <%s><%s><%s><%s><%s> %d barline %d-%d mode %d", + cl->descr, cl->name, cl->abbrev, cl->intermediateName, + cl->intermediateAbbrev, + cstaff->iLayout, cl->barlineFrom, cl->barlineTo, cl->barlineMode); } } #endif @@ -713,15 +721,16 @@ qDebug("==================convert-capella\n"); // find out the maximum number of staves // int staves = 0; - foreach(CapSystem* csys, cap->systems) + foreach(CapSystem* csys, cap->systems) { staves = qMax(staves, csys->staves.size()); + } // // check the assumption that every stave should be // associated with a CapStaffLayout // if (staves != cap->staffLayouts().size()) { - qDebug("Capella: max number of staves != number of staff layouts (%d, %d)\n", - staves, cap->staffLayouts().size()); + qDebug("Capella: max number of staves != number of staff layouts (%d, %d)", + staves, cap->staffLayouts().size()); staves = qMax(staves, cap->staffLayouts().size()); } @@ -735,7 +744,7 @@ qDebug("==================convert-capella\n"); Part* part = 0; for (int staffIdx = 0; staffIdx < staves; ++staffIdx) { CapStaffLayout* cl = cap->staffLayout(staffIdx); -// qDebug("Midi staff %d program %d\n", staffIdx, cl->sound); + // qDebug("Midi staff %d program %d", staffIdx, cl->sound); if (midiPatch != cl->sound || part == 0) { part = new Part(score); midiPatch = cl->sound; @@ -750,8 +759,8 @@ qDebug("==================convert-capella\n"); part->setLongName(QString::fromLatin1(cl->name)); part->setShortName(QString::fromLatin1(cl->abbrev)); -// ClefType clefType = CapClef::clefType(cl->form, cl->line, cl->oct); -// s->setClef(0, clefType); + // ClefType clefType = CapClef::clefType(cl->form, cl->line, cl->oct); + // s->setClef(0, clefType); s->setBarLineSpan(0); if (bstaff == 0) { bstaff = s; @@ -773,7 +782,7 @@ qDebug("==================convert-capella\n"); foreach(CapBracket cb, cap->brackets) { Staff* staff = score->staves().value(cb.from); if (staff == 0) { - qDebug("bad bracket 'from' value\n"); + qDebug("bad bracket 'from' value"); continue; } staff->setBracket(0, cb.curly ? BRACKET_AKKOLADE : BRACKET_NORMAL); @@ -781,7 +790,7 @@ qDebug("==================convert-capella\n"); } foreach(BasicDrawObj* o, cap->backgroundChord->objects) { - switch(o->type) { + switch (o->type) { case CAP_SIMPLE_TEXT: { SimpleTextObj* to = static_cast(o); @@ -789,7 +798,7 @@ qDebug("==================convert-capella\n"); s->setTextStyleType(TEXT_STYLE_TITLE); QFont f(to->font()); s->setItalic(f.italic()); -// s->setUnderline(f.underline()); + // s->setUnderline(f.underline()); s->setBold(f.bold()); s->setSize(f.pointSizeF()); @@ -802,7 +811,7 @@ qDebug("==================convert-capella\n"); } break; default: - qDebug("page background object type %d\n", o->type); + qDebug("page background object type %d", o->type); break; } } @@ -823,14 +832,15 @@ qDebug("==================convert-capella\n"); int systemTick = 0; foreach(CapSystem* csys, cap->systems) { -qDebug("readCapSystem\n"); -/* if (csys->explLeftIndent > 0) { + qDebug("readCapSystem"); + /* + if (csys->explLeftIndent > 0) { HBox* mb = new HBox(score); mb->setTick(systemTick); mb->setBoxWidth(Spatium(csys->explLeftIndent)); score->addMeasure(mb); } -*/ + */ int mtick = 0; foreach(CapStaff* cstaff, csys->staves) { // @@ -838,11 +848,11 @@ qDebug("readCapSystem\n"); // which means that there is a 1:1 relation between layout/staff // -qDebug(" ReadCapStaff %d/%d\n", cstaff->numerator, 1 << cstaff->log2Denom); + qDebug(" ReadCapStaff %d/%d", cstaff->numerator, 1 << cstaff->log2Denom); int staffIdx = cstaff->iLayout; int voice = 0; foreach(CapVoice* cvoice, cstaff->voices) { - int tick = readCapVoice(score, cvoice, staffIdx, systemTick); + int tick = readCapVoice(score, cvoice, staffIdx, systemTick, capxMode); ++voice; if (tick > mtick) mtick = tick; @@ -885,7 +895,7 @@ qDebug(" ReadCapStaff %d/%d\n", cstaff->numerator, 1 << cstaff->log2Denom); } } } -// score->connectSlurs(); + // score->connectSlurs(); } //--------------------------------------------------------- @@ -936,7 +946,7 @@ void TextObj::read() cap->read(txt, size); txt[size] = 0; text = QString(txt); -qDebug("read textObj len %d <%s>\n", size, txt); + // qDebug("read textObj len %d <%s>", size, txt); } //--------------------------------------------------------- @@ -950,8 +960,8 @@ void SimpleTextObj::read() align = cap->readByte(); _font = cap->readFont(); _text = cap->readString(); -qDebug("read SimpletextObj(%f,%f) len %zd <%s> char0: %02x\n", - relPos.x(), relPos.y(), strlen(_text), _text, _text[0]); + // qDebug("read SimpletextObj(%f,%f) len %zd <%s> char0: %02x", + // relPos.x(), relPos.y(), strlen(_text), _text, _text[0]); } //--------------------------------------------------------- @@ -965,7 +975,7 @@ void LineObj::read() pt2 = cap->readPoint(); color = cap->readColor(); lineWidth = cap->readByte(); -qDebug("LineObj: %f:%f %f:%f width %d\n", pt1.x(), pt1.y(), pt2.x(), pt2.y(), lineWidth); + // qDebug("LineObj: %f:%f %f:%f width %d", pt1.x(), pt1.y(), pt2.x(), pt2.y(), lineWidth); } //--------------------------------------------------------- @@ -1000,10 +1010,10 @@ void TransposableObj::read() relPos = cap->readPoint(); b = cap->readByte(); if (b != 12 && b != 21) - qDebug("TransposableObj::read: warning: unknown drawObjectArray size of %d\n", b); + qDebug("TransposableObj::read: warning: unknown drawObjectArray size of %d", b); variants = cap->readDrawObjectArray(); if (variants.size() != b) - qDebug("variants.size %d, expected %d\n", variants.size(), b); + qDebug("variants.size %d, expected %d", variants.size(), b); assert(variants.size() == b); /*int nRefNote =*/ cap->readInt(); } @@ -1018,7 +1028,7 @@ void MetafileObj::read() unsigned size = cap->readUnsigned(); char enhMetaFileBits[size]; cap->read(enhMetaFileBits, size); -qDebug("MetaFileObj::read %d bytes\n", size); + // qDebug("MetaFileObj::read %d bytes", size); } //--------------------------------------------------------- @@ -1043,7 +1053,7 @@ void PolygonObj::read() unsigned nPoints = cap->readUnsigned(); for (unsigned i = 0; i < nPoints; ++i) - cap->readPoint(); + cap->readPoint(); bFilled = cap->readByte(); lineWidth = cap->readByte(); @@ -1085,7 +1095,7 @@ void NotelinesObj::read() cap->read(lines, 11); break; } - } + } } //--------------------------------------------------------- @@ -1148,11 +1158,11 @@ QList Capella::readDrawObjectArray() QList ol; int n = readUnsigned(); // draw obj array -qDebug("readDrawObjectArray %d elements\n", n); + // qDebug("readDrawObjectArray %d elements", n); for (int i = 0; i < n; ++i) { unsigned char type = readByte(); -qDebug(" readDrawObject %d of %d, type %d\n", i, n, type); + // qDebug(" readDrawObject %d of %d, type %d", i, n, type); switch (type) { case 0: { GroupObj* o = new GroupObj(this); @@ -1251,7 +1261,7 @@ qDebug(" readDrawObject %d of %d, type %d\n", i, n, type); } break; default: -qDebug("readDrawObjectArray unsupported type %d\n", type); + qDebug("readDrawObjectArray unsupported type %d", type); abort(); break; } @@ -1311,20 +1321,24 @@ void BasicDurationalObj::read() t = TIMESTEP(c & 0x0f); horizontalShift = (c & 0x10) ? cap->readInt() : 0; count = 0; + tripartite = 0; + isProlonging = 0; if (c & 0x20) { unsigned char tuplet = cap->readByte(); count = tuplet & 0x0f; tripartite = (tuplet & 0x10) != 0; isProlonging = (tuplet & 0x20) != 0; if (tuplet & 0xc0) - qDebug("bad tuplet value 0x%02x\n", tuplet); + qDebug("bad tuplet value 0x%02x", tuplet); } if (c & 0x40) { objects = cap->readDrawObjectArray(); } if (c & 0x80) abort(); - qDebug(" DurationObj timestep %d\n", t); + qDebug("DurationObj ndots %d nodur %d postgr %d bsm %d inv %d notbl %d t %d hsh %d cnt %d trp %d ispro %d", + nDots, noDuration, postGrace, bSmall, invisible, notBlack, t, horizontalShift, count, tripartite, isProlonging + ); } //--------------------------------------------------------- @@ -1332,7 +1346,7 @@ void BasicDurationalObj::read() //--------------------------------------------------------- RestObj::RestObj(Capella* c) - : BasicDurationalObj(c), NoteObj(T_REST) + : BasicDurationalObj(c), NoteObj(T_REST) { cap = c; fullMeasures = 0; @@ -1351,7 +1365,7 @@ void RestObj::read() bVerticalCentered = b & 2; bool bAddVerticalShift = b & 4; if (b & 0xf8) { - qDebug("RestObj: res. bits 0x%02x\n", b); + qDebug("RestObj: res. bits 0x%02x", b); abort(); } fullMeasures = bMultiMeasures ? cap->readUnsigned() : 0; @@ -1363,7 +1377,7 @@ void RestObj::read() //--------------------------------------------------------- ChordObj::ChordObj(Capella* c) - : BasicDurationalObj(c), NoteObj(T_CHORD) + : BasicDurationalObj(c), NoteObj(T_CHORD) { cap = c; beamMode = AUTO_BEAM; @@ -1445,6 +1459,8 @@ void ChordObj::read() if (b & 0x40) n.explAlteration = 1; n.silent = b & 0x80; + qDebug("ChordObj::read() note pitch %d explAlt %d head %d alt %d silent %d", + n.pitch, n.explAlteration, n.headType, n.alteration, n.silent); notes.append(n); } } @@ -1640,14 +1656,14 @@ QFont Capella::readFont() /*QColor color =*/ readColor(); char* face = readString(); -qDebug("Font <%s> size %d, weight %d\n", face, lfHeight, lfWeight); + qDebug("Font <%s> size %d, weight %d", face, lfHeight, lfWeight); QFont font(face); font.setPointSizeF(lfHeight / 1000.0); font.setItalic(lfItalic); font.setStrikeOut(lfStrikeOut); font.setUnderline(lfUnderline); - switch(lfWeight) { + switch (lfWeight) { case 700: font.setWeight(QFont::Bold); break; case 400: font.setWeight(QFont::Normal); break; case 0: font.setWeight(QFont::Light); break; @@ -1657,7 +1673,7 @@ qDebug("Font <%s> size %d, weight %d\n", face, lfHeight, lfWeight); } index -= 1; if (index >= fonts.size()) { - qDebug("illegal font index %d (max %d)\n", index, fonts.size()-1); + qDebug("illegal font index %d (max %d)", index, fonts.size()-1); } return fonts[index]; } @@ -1666,11 +1682,11 @@ qDebug("Font <%s> size %d, weight %d\n", face, lfHeight, lfWeight); // readStaveLayout //--------------------------------------------------------- -void Capella::readStaveLayout(CapStaffLayout* sl, int /*idx*/) +void Capella::readStaveLayout(CapStaffLayout* sl, int idx) { sl->barlineMode = readByte(); sl->noteLines = readByte(); - switch(sl->noteLines) { + switch (sl->noteLines) { case 1: break; // one line case 2: break; // five lines default: @@ -1681,10 +1697,10 @@ void Capella::readStaveLayout(CapStaffLayout* sl, int /*idx*/) } break; } -// qDebug("StaffLayout %d: noteLines %d\n", idx, sl->noteLines); + qDebug("StaffLayout %d: noteLines %d", idx, sl->noteLines); sl->bSmall = readByte(); -qDebug("staff size small %d\n", sl->bSmall); + qDebug("staff size small %d", sl->bSmall); sl->topDist = readInt(); sl->btmDist = readInt(); @@ -1696,9 +1712,9 @@ qDebug("staff size small %d\n", sl->bSmall); sl->form = FORM(clef & 7); sl->line = CLEF_LINE((clef >> 3) & 7); sl->oct = OCT((clef >> 6)); -// qDebug(" clef %x form %d, line %d, oct %d\n", clef, sl->form, sl->line, sl->oct); + qDebug(" clef %x form %d, line %d, oct %d", clef, sl->form, sl->line, sl->oct); - // Schlagzeuginformation + // Schlagzeuginformation unsigned char b = readByte(); sl->bPercussion = b & 1; // Schlagzeugkanal verwenden sl->bSoundMapIn = b & 2; @@ -1713,6 +1729,7 @@ qDebug("staff size small %d\n", sl->bSmall); } if (sl->bSoundMapOut) { // Umleitungstabelle für das Vorspielen unsigned char iMin = readByte(); + Q_UNUSED(iMin); unsigned char n = readByte(); assert (n > 0 and iMin + n <= 128); f->read(sl->soundMapOut, n); @@ -1721,15 +1738,15 @@ qDebug("staff size small %d\n", sl->bSmall); sl->sound = readInt(); sl->volume = readInt(); sl->transp = readInt(); -// qDebug(" sound %d vol %d transp %d\n", sl->sound, sl->volume, sl->transp); + qDebug(" sound %d vol %d transp %d", sl->sound, sl->volume, sl->transp); sl->descr = readString(); sl->name = readString(); sl->abbrev = readString(); sl->intermediateName = readString(); sl->intermediateAbbrev = readString(); -// qDebug(" descr <%s> name <%s> abbrev <%s> iname <%s> iabrev <%s>\n", -// sl->descr, sl->name, sl->abbrev, sl->intermediateName, sl->intermediateAbbrev); + qDebug(" descr <%s> name <%s> abbrev <%s> iname <%s> iabrev <%s>", + sl->descr, sl->name, sl->abbrev, sl->intermediateName, sl->intermediateAbbrev); } //--------------------------------------------------------- @@ -1740,9 +1757,11 @@ void Capella::readLayout() { smallLineDist = double(readInt()) / 100; normalLineDist = double(readInt()) / 100; + qDebug("Capella::readLayout(): smallLineDist %g normalLineDist %g", smallLineDist, normalLineDist); topDist = readInt(); interDist = readInt(); + qDebug("Capella::readLayout(): topDist %d", topDist); txtAlign = readByte(); // Stimmenbezeichnungen 0=links, 1=zentriert, 2=rechts adjustVert = readByte(); // 0=nein, 1=au�er letzte Seite, 3=alle Seiten @@ -1760,7 +1779,7 @@ void Capella::readLayout() // Musterzeilen unsigned nStaveLayouts = readUnsigned(); -// qDebug("%d staves\n", nStaveLayouts); + // qDebug("%d staves", nStaveLayouts); for (unsigned iStave = 0; iStave < nStaveLayouts; iStave++) { CapStaffLayout* sl = new CapStaffLayout; @@ -1775,7 +1794,7 @@ void Capella::readLayout() b.from = readInt(); b.to = readInt(); b.curly = readByte(); -// qDebug("Bracket%d %d-%d curly %d\n", i, b.from, b.to, b.curly); + // qDebug("Bracket%d %d-%d curly %d", i, b.from, b.to, b.curly); brackets.append(b); } } @@ -1788,7 +1807,7 @@ void Capella::readExtra() { uchar n = readByte(); if (n) { - qDebug("Capella::readExtra(%d)\n", n); + qDebug("Capella::readExtra(%d)", n); for (int i = 0; i < n; ++i) readByte(); } @@ -1804,7 +1823,7 @@ void CapClef::read() form = (FORM) (b & 7); line = (CLEF_LINE) ((b >> 3) & 7); oct = (OCT) (b >> 6); - qDebug("Clef::read form %d line %d oct %d\n", form, line, oct); + qDebug("Clef::read form %d line %d oct %d", form, line, oct); } //--------------------------------------------------------- @@ -1819,7 +1838,7 @@ ClefType CapClef::clef() const ClefType CapClef::clefType(FORM form, CLEF_LINE line, OCT oct) { int idx = form + (line << 3) + (oct << 5); - switch(idx) { + switch (idx) { case FORM_G + (LINE_2 << 3) + (OCT_NULL << 5): return CLEF_G; case FORM_G + (LINE_2 << 3) + (OCT_ALTA << 5): return CLEF_G1; case FORM_G + (LINE_2 << 3) + (OCT_BASSA << 5): return CLEF_G3; @@ -1838,7 +1857,7 @@ ClefType CapClef::clefType(FORM form, CLEF_LINE line, OCT oct) default: if (form == FORM_NULL) return CLEF_INVALID; - qDebug("unknown clef %d %d %d\n", form, line, oct); + qDebug("unknown clef %d %d %d", form, line, oct); break; } return CLEF_INVALID; @@ -1852,7 +1871,7 @@ void CapKey::read() { unsigned char b = cap->readByte(); signature = int(b) - 7; -// qDebug(" Key %d\n", signature); + // qDebug(" Key %d", signature); } //--------------------------------------------------------- @@ -1865,9 +1884,9 @@ void CapMeter::read() uchar d = cap->readByte(); log2Denom = (d & 0x7f) - 1; allaBreve = d & 0x80; + qDebug(" Meter %d/%d allaBreve %d", numerator, log2Denom, allaBreve); if (log2Denom > 7 || log2Denom < 0) { - qDebug(" Meter %d/%d allaBreve %d\n", numerator, log2Denom, allaBreve); - qDebug(" illegal fraction\n"); + qDebug(" illegal fraction"); // abort(); log2Denom = 2; numerator = 4; @@ -1898,7 +1917,7 @@ void CapExplicitBarline::read() assert (_type <= BAR_REPENDSTART); assert (_barMode <= 2); -// qDebug(" Expl.Barline type %d mode %d\n", _type, _barMode); + qDebug(" Expl.Barline type %d mode %d", _type, _barMode); } //--------------------------------------------------------- @@ -1907,7 +1926,7 @@ void CapExplicitBarline::read() void Capella::readVoice(CapStaff* cs, int idx) { -qDebug(" readVoice %d\n", idx); + qDebug(" readVoice %d", idx); if (readChar() != 'C') throw CAP_BAD_VOICE_SIG; @@ -1924,7 +1943,7 @@ qDebug(" readVoice %d\n", idx); for (unsigned i = 0; i < nNoteObjs; i++) { QColor color = Qt::black; uchar type = readByte(); -qDebug(" Voice %d read object idx %d(%d) type %d\n", idx, i, nNoteObjs, type); + // qDebug(" Voice %d read object idx %d(%d) type %d", idx, i, nNoteObjs, type); readExtra(); if ((type != T_REST) && (type != T_CHORD) && (type != T_PAGE_BKGR)) color = readColor(); @@ -1971,14 +1990,14 @@ qDebug(" Voice %d read object idx %d(%d) type %d\n", idx, i, nNoteObjs, { CapExplicitBarline* bl = new CapExplicitBarline(this); bl->read(); -qDebug("append Expl Barline==========\n"); + qDebug("append Expl Barline=========="); v->objects.append(bl); } break; default: - qDebug("bad voice type %d\n", type); + qDebug("bad voice type %d", type); abort(); - } + } } cs->voices.append(v); } @@ -2005,7 +2024,7 @@ void Capella::readStaff(CapSystem* system) staff->color = readColor(); readExtra(); -// qDebug(" Staff iLayout %d\n", staff->iLayout); + qDebug(" Staff iLayout %d", staff->iLayout); // Stimmen unsigned nVoices = readUnsigned(); for (unsigned i = 0; i < nVoices; i++) @@ -2064,7 +2083,7 @@ int BasicDurationalObj::ticks() const case D256: len = MScore::division >> 6; break; case D_BREVE: len = MScore::division * 8; break; default: - qDebug("BasicDurationalObj::ticks: illegal duration value %d\n", t); + qDebug("BasicDurationalObj::ticks: illegal duration value %d", t); break; } int slen = len; @@ -2102,7 +2121,7 @@ void Capella::read(QFile* fp) if (memcmp(signature, "cap3-v:", 7) != 0) throw CAP_BAD_SIG; -// qDebug("read Capella file signature <%s>\n", signature); + // qDebug("read Capella file signature <%s>", signature); // TODO: test for signature[7] = a-z @@ -2110,7 +2129,7 @@ void Capella::read(QFile* fp) keywords = readString(); comment = readString(); -// qDebug("author <%s> keywords <%s> comment <%s>\n", author, keywords, comment); + // qDebug("author <%s> keywords <%s> comment <%s>", author, keywords, comment); nRel = readUnsigned(); // 75 nAbs = readUnsigned(); // 16 @@ -2119,7 +2138,7 @@ void Capella::read(QFile* fp) bAllowCompression = b & 2; bPrintLandscape = b & 16; -// qDebug(" nRel %d nAbs %d useRealSize %d compresseion %d\n", nRel, nAbs, bUseRealSize, bAllowCompression); + // qDebug(" nRel %d nAbs %d useRealSize %d compresseion %d", nRel, nAbs, bUseRealSize, bAllowCompression); readLayout(); @@ -2134,11 +2153,11 @@ void Capella::read(QFile* fp) unsigned n = readUnsigned(); if (n) { - qDebug("Gallery objects\n"); + qDebug("Gallery objects"); } for (unsigned int i = 0; i < n; ++i) { /*char* s =*/ readString(); // names of galerie objects -// qDebug("Galerie: <%s>\n", s); + // qDebug("Galerie: <%s>", s); } backgroundChord = new ChordObj(this); @@ -2177,17 +2196,17 @@ Score::FileError importCapella(Score* score, const QString& name) try { cf.read(&fp); } - catch(Capella::CapellaError errNo) { + catch (Capella::CapellaError errNo) { QMessageBox::warning(0, - QWidget::tr("MuseScore: Import Capella"), - QString("Load failed: ") + cf.error(errNo), - QString::null, QWidget::tr("Quit"), QString::null, 0, 1); + QWidget::tr("MuseScore: Import Capella"), + QString("Load failed: ") + cf.error(errNo), + QString::null, QWidget::tr("Quit"), QString::null, 0, 1); fp.close(); // avoid another error message box return Score::FILE_NO_ERROR; } fp.close(); - convertCapella(score, &cf); + convertCapella(score, &cf, false); return Score::FILE_NO_ERROR; } diff --git a/mscore/capella.h b/mscore/capella.h index 47969bcff5611..5cfd4c41b256b 100644 --- a/mscore/capella.h +++ b/mscore/capella.h @@ -3,7 +3,7 @@ // Linux Music Score Editor // $Id: capella.h 3833 2011-01-04 13:55:40Z wschweer $ // -// Copyright (C) 2009 Werner Schweer and others +// Copyright (C) 2009-2013 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. @@ -22,6 +22,7 @@ #define __CAPELLA_H__ #include "globals.h" +#include "libmscore/xml.h" enum TIMESTEP { D1, D2, D4, D8, D16, D32, D64, D128, D256, D_BREVE }; @@ -86,6 +87,7 @@ class CapClef : public NoteObj, public CapellaObj { public: CapClef(Capella* c) : NoteObj(T_CLEF), CapellaObj(c) {} void read(); + void readCapx(XmlReader& e); const char* name() { static const char* formName[] = { "G", "C", "F", "=", " ", "*" }; return formName[form]; @@ -106,6 +108,7 @@ class CapKey : public NoteObj, public CapellaObj { public: CapKey(Capella* c) : NoteObj(T_KEY), CapellaObj(c) {} void read(); + void readCapx(XmlReader& e); int signature; // -7 - +7 }; @@ -121,6 +124,7 @@ class CapMeter : public NoteObj, public CapellaObj { CapMeter(Capella* c) : NoteObj(T_METER), CapellaObj(c) {} void read(); + void readCapx(XmlReader& e); }; //--------------------------------------------------------- @@ -134,6 +138,7 @@ class CapExplicitBarline : public NoteObj, public CapellaObj { public: CapExplicitBarline(Capella* c) : NoteObj(T_EXPL_BARLINE), CapellaObj(c) {} void read(); + void readCapx(XmlReader& e); int type() const { return _type; } int barMode() const { return _barMode; } @@ -512,6 +517,7 @@ class BasicDurationalObj : public CapellaObj { public: BasicDurationalObj(Capella* c) : CapellaObj(c) {} void read(); + void readCapx(XmlReader& e, unsigned int& fullm); int ticks() const; bool invisible; QList objects; @@ -557,6 +563,8 @@ class ChordObj : public BasicDurationalObj, public NoteObj { public: ChordObj(Capella*); void read(); + void readCapx(XmlReader& e); + void readCapxNotes(XmlReader& e); QList verse; QList notes; char stemDir; // -1 down, 0 auto, 1 up, 3 no stem @@ -573,6 +581,7 @@ class RestObj : public BasicDurationalObj, public NoteObj { public: RestObj(Capella*); void read(); + void readCapx(XmlReader& e); unsigned fullMeasures; // >0, multi measure rest (counting measures) }; @@ -683,6 +692,18 @@ class Capella { double smallLineDist; // spatium unit in metric mm double normalLineDist; int topDist; +// capx support + private: + void readCapxVoice(XmlReader& e, CapStaff*, int); + void readCapxStaff(XmlReader& e, CapSystem*, int); + void readCapxSystem(XmlReader& e); + void capxSystems(XmlReader& e); + void readCapxStaveLayout(XmlReader& e, CapStaffLayout*, int); + void capxLayoutStaves(XmlReader& e); + void capxLayout(XmlReader& e); + void initCapxLayout(); + public: + void readCapx(XmlReader& e); }; #endif diff --git a/mscore/capxml.cpp b/mscore/capxml.cpp new file mode 100644 index 0000000000000..e03590312013c --- /dev/null +++ b/mscore/capxml.cpp @@ -0,0 +1,805 @@ +//============================================================================= +// MuseScore +// Linux Music Score Editor +// +// Copyright (C) 2013 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. +//============================================================================= + +// CapXML import filter +// Supports the CapXML 1.0 file format version 1.0.8 (capella 2008) +// The implementation shares as much code as possible with the capella +// (.cap) importer (capella.cpp and capella.h) +// If statements in the parser match the element order in the schema definition + +#include +#include "libmscore/score.h" +#include "libmscore/qzipreader_p.h" +#include "capella.h" + +//--------------------------------------------------------- +// qstring2timestep -- convert string to TIMESTEP +//--------------------------------------------------------- + +static bool qstring2timestep(QString& str, TIMESTEP& tstp) + { + if (str == "1/1") { tstp = D1; return true; } + else if (str == "1/2") { tstp = D2; return true; } + else if (str == "1/4") { tstp = D4; return true; } + else if (str == "1/8") { tstp = D8; return true; } + else if (str == "1/16") { tstp = D16; return true; } + else if (str == "1/32") { tstp = D32; return true; } + else if (str == "1/64") { tstp = D64; return true; } + else if (str == "1/128") { tstp = D128; return true; } + else if (str == "2/1") { tstp = D_BREVE; return true; } + return false; + } + +//--------------------------------------------------------- +// BasicDurationalObj::readCapx -- capx equivalent of BasicDurationalObj::read +//--------------------------------------------------------- + +void BasicDurationalObj::readCapx(XmlReader& e, unsigned int& fullm) + { + nDots = 0; + noDuration = false; + postGrace = false; + bSmall = false; + invisible = false; + notBlack = false; + color = Qt::black; + t = D1; + horizontalShift = 0; + count = 0; + tripartite = 0; + isProlonging = 0; + QString base = e.attribute("base"); + bool res = false; + // try to convert base to timestep ("first pattern") + res = qstring2timestep(base, t); + if (!res) { + // try multi-measure rest ("second pattern") + int i = base.toInt(); + if (i > 0) + fullm = i; + else + qDebug("BasicDurationalObj::readCapx: invalid base: '%s'", qPrintable(base)); + } + nDots = e.intAttribute("dots", 0); + noDuration = e.attribute("noDuration", "false") == "true"; + while (e.readNextStartElement()) { + const QStringRef& tag(e.name()); + if (tag == "tuplet") { + count = e.attribute("count").toInt(); + e.readNext(); + } + else + e.unknown(); + } + qDebug("DurationObj ndots %d nodur %d postgr %d bsm %d inv %d notbl %d t %d hsh %d cnt %d trp %d ispro %d fullm %d", + nDots, noDuration, postGrace, bSmall, invisible, notBlack, t, horizontalShift, count, tripartite, isProlonging, fullm + ); + } + +//--------------------------------------------------------- +// CapExplicitBarline::readCapx -- capx equivalent of CapExplicitBarline::read +//--------------------------------------------------------- + +void CapExplicitBarline::readCapx(XmlReader& e) + { + _type = BAR_SINGLE; // TODO + _barMode = 0; + e.readNext(); + } + +//--------------------------------------------------------- +// CapClef::readCapx -- capx equivalent of CapClef::read +//--------------------------------------------------------- + +void CapClef::readCapx(XmlReader& e) + { + QString clef = e.attribute("clef"); + if (clef == "G2-") { form = FORM_G; line = LINE_2; oct = OCT_BASSA; } + else if (clef == "treble") { form = FORM_G; line = LINE_2; oct = OCT_NULL; } + else if (clef == "bass") { form = FORM_F; line = LINE_4; oct = OCT_NULL; } + else { /* default */ form = FORM_G; line = LINE_2; oct = OCT_NULL; } + qDebug("Clef::read '%s' -> form %d line %d oct %d", qPrintable(clef), form, line, oct); + e.readNext(); + } + +//--------------------------------------------------------- +// CapKey::readCapx -- capx equivalent of CapKey::read +//--------------------------------------------------------- + +void CapKey::readCapx(XmlReader& e) + { + signature = e.intAttribute("fifths", 0); + qDebug("Key %d", signature); + e.readNext(); + } + +//--------------------------------------------------------- +// CapMeter::readCapx -- capx equivalent of CapMeter::read +//--------------------------------------------------------- + +void CapMeter::readCapx(XmlReader& e) + { + QString time = e.attribute("time"); + numerator = 4; log2Denom = 2; allaBreve = false; // set default + if (time == "allaBreve") { numerator = 2; log2Denom = 1; allaBreve = true; } + else if (time == "longAllaBreve") { numerator = 4; log2Denom = 1; allaBreve = true; } + else if (time == "C") { numerator = 4; log2Denom = 2; allaBreve = false; } + else if (time == "infinite") { qDebug("Meter infinite"); } // not supported by MuseScore ? + else { + QStringList splitTime = time.split("/"); + if (splitTime.size() == 2) { + numerator = splitTime.at(0).toInt(); + QString denom = splitTime.at(1); + if (denom == "1") log2Denom = 0; + else if (denom == "2") log2Denom = 1; + else if (denom == "4") log2Denom = 2; + else if (denom == "8") log2Denom = 3; + else if (denom == "16") log2Denom = 4; + else if (denom == "32") log2Denom = 5; + else if (denom == "64") log2Denom = 6; + else if (denom == "128") log2Denom = 7; + } + } + qDebug("Meter %d/%d allaBreve %d", numerator, log2Denom, allaBreve); + e.readNext(); + } + +//--------------------------------------------------------- +// ChordObj::readCapx -- capx equivalent of ChordObj::read +//--------------------------------------------------------- + +void ChordObj::readCapx(XmlReader& e) + { + stemDir = 0; + dStemLength = 0; + nTremoloBars = 0; + articulation = 0; + leftTie = false; + rightTie = false; + beamShift = 0; + beamSlope = 0; + beamMode = AUTO_BEAM; + notationStave = 0; + + /* + if (flags & 0x40) { + unsigned nVerses = cap->readUnsigned(); + for (unsigned int i = 0; i < nVerses; ++i) { + bool bVerse = cap->readByte(); + if (bVerse) { + Verse v; + unsigned char b = cap->readByte(); + v.leftAlign = b & 1; + v.extender = b & 2; + v.hyphen = b & 4; + v.num = i; + if (b & 8) + v.verseNumber = cap->readString(); + if (b & 16) + v.text = cap->readString(); + verse.append(v); + } + } + } + } + */ + while (e.readNextStartElement()) { + const QStringRef& tag(e.name()); + if (tag == "duration") { + unsigned int dummy; + BasicDurationalObj::readCapx(e, dummy); + } + else if (tag == "display") { + qDebug("ChordObj::readCapx: found display (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "stem") { + qDebug("ChordObj::readCapx: found stem (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "beam") { + qDebug("ChordObj::readCapx: found beam (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "articulation") { + qDebug("ChordObj::readCapx: found articulation (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "lyric") { + qDebug("ChordObj::readCapx: found lyric (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "drawObjects") { + qDebug("ChordObj::readCapx: found drawObjects (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "heads") { + readCapxNotes(e); + } + else + e.unknown(); + } + } + +//--------------------------------------------------------- +// pitchStr2Char -- convert pitch string ("[A-G][0-9]") to signed char +// notes: +// - in .capx middle C is called C5 (which is C4 in MusicXML) +// - middle C is MIDI note number 60 +// - in .cap, pitch contains the diatonic note number relative to clef and key +// - as .capx contains absolute notes, store the MIDI note number instead +//--------------------------------------------------------- + +static signed char pitchStr2Char(QString& strPitch) + { + QRegExp pitchRegExp("[A-G][0-9]"); + + if (!pitchRegExp.exactMatch(strPitch)) { + qDebug("pitchStr2Char: illegal pitch '%s'", qPrintable(strPitch)); + return 0; + } + + QString steps("C.D.EF.G.A.B"); + int istep = steps.indexOf(strPitch.left(1)); + int octave = strPitch.right(1).toInt(); + int pitch = istep + 12 * octave; + + if (pitch < 0) + pitch = -1; + if (pitch > 127) + pitch = -1; + + qDebug("pitchStr2Char: '%s' -> %d", qPrintable(strPitch), pitch); + + return static_cast(pitch); + } + +//--------------------------------------------------------- +// ChordObj::readCapxNotes -- read the notes in a capx chord +//--------------------------------------------------------- + +void ChordObj::readCapxNotes(XmlReader& e) + { + while (e.readNextStartElement()) { + if (e.name() == "head") { + QString pitch = e.attribute("pitch"); + QString sstep; + while (e.readNextStartElement()) { + const QStringRef& tag(e.name()); + if (tag == "alter") { + sstep = e.attribute("step"); + e.readNext(); + } + else if (tag == "tie") { + qDebug("ChordObj::readCapxNotes: found tie (skipping)"); + e.skipCurrentElement(); + } + else + e.unknown(); + } + qDebug("ChordObj::readCapxNotes: pitch '%s' altstep '%s'", + qPrintable(pitch), qPrintable(sstep)); + int istep = sstep.toInt(); + CNote n; + n.pitch = pitchStr2Char(pitch); + n.explAlteration = 0; + n.headType = 0; + n.alteration = istep; + n.silent = 0; + notes.append(n); + } + else + e.unknown(); + } + } + +//--------------------------------------------------------- +// RestObj::readCapx -- capx equivalent of RestObj::read +//--------------------------------------------------------- + +void RestObj::readCapx(XmlReader& e) + { + bVerticalCentered = false; + fullMeasures = 0; + vertShift = 0; + while (e.readNextStartElement()) { + const QStringRef& tag(e.name()); + if (tag == "duration") { + BasicDurationalObj::readCapx(e, fullMeasures); + } + else if (tag == "display") { + qDebug("RestObj::readCapx: found display (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "verticalPos") { + qDebug("RestObj::readCapx: found verticalPos (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "drawObjects") { + qDebug("RestObj::readCapx: found drawObjects (skipping)"); + e.skipCurrentElement(); + } + else + e.unknown(); + } + } + +//--------------------------------------------------------- +// readCapxVoice -- capx equivalent of readVoice(CapStaff* cs, int idx) +//--------------------------------------------------------- + +void Capella::readCapxVoice(XmlReader& e, CapStaff* cs, int idx) + { + CapVoice* v = new CapVoice; + v->voiceNo = idx; + v->y0Lyrics = 0; + v->dyLyrics = 0; + // v->lyricsFont = 0; + v->stemDir = 0; + + while (e.readNextStartElement()) { + if (e.name() == "lyricsSettings") { + qDebug("readCapxVoice: found lyricsSettings (skipping)"); + e.skipCurrentElement(); + } + else if (e.name() == "noteObjects") { + while (e.readNextStartElement()) { + const QStringRef& tag(e.name()); + if (tag == "clefSign") { + CapClef* clef = new CapClef(this); + clef->readCapx(e); + v->objects.append(clef); + } + else if (tag == "keySign") { + CapKey* key = new CapKey(this); + key->readCapx(e); + v->objects.append(key); + } + else if (tag == "timeSign") { + CapMeter* meter = new CapMeter(this); + meter->readCapx(e); + v->objects.append(meter); + } + else if (tag == "barline") { + CapExplicitBarline* bl = new CapExplicitBarline(this); + bl->readCapx(e); + v->objects.append(bl); + } + else if (tag == "chord") { + qDebug("readCapxVoice: found chord (skipping)"); + ChordObj* chord = new ChordObj(this); + chord->readCapx(e); + v->objects.append(chord); + } + else if (tag == "rest") { + RestObj* rest = new RestObj(this); + rest->readCapx(e); + v->objects.append(rest); + } + else + e.unknown(); + } + } + else + e.unknown(); + } + + cs->voices.append(v); + } + +//--------------------------------------------------------- +// readCapxStaff -- capx equivalent of readStaff(CapSystem* system) +//--------------------------------------------------------- + +void Capella::readCapxStaff(XmlReader& e, CapSystem* system, int iStave) + { + CapStaff* staff = new CapStaff; + //Meter + staff->numerator = 3; // TODO (required !) + staff->log2Denom = 2; // TODO (required !) + staff->allaBreve = 0; + + staff->iLayout = iStave; + staff->topDistX = 0; + staff->btmDistX = 0; + staff->color = Qt::black; + + while (e.readNextStartElement()) { + const QStringRef& tag(e.name()); + if (tag == "extraDistance") { + qDebug("readCapxStaff: found extraDistance (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "voices") { + int i = 0; + while (e.readNextStartElement()) { + if (e.name() == "voice") { + readCapxVoice(e, staff, i); + ++i; + } + else + e.unknown(); + } + } + else + e.unknown(); + } + + system->staves.append(staff); + } + +//--------------------------------------------------------- +// readCapxSystem -- capx equivalent of readSystem() +//--------------------------------------------------------- + +void Capella::readCapxSystem(XmlReader& e) + { + CapSystem* s = new CapSystem; + s->nAddBarCount = 0; + s->bBarCountReset = 0; + s->explLeftIndent = 0; // ?? TODO ?? use in capella.cpp commented out + + s->beamMode = 0; + s->tempo = 0; + s->color = Qt::black; + + unsigned char b = 0; + s->bJustified = b & 2; + s->bPageBreak = (b & 4) != 0; + s->instrNotation = (b >> 3) & 7; + + while (e.readNextStartElement()) { + const QStringRef& tag(e.name()); + if (tag == "barCount") { + qDebug("readCapxSystem: found barCount (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "staves") { + int iStave = 0; + while (e.readNextStartElement()) { + if (e.name() == "staff") { + readCapxStaff(e, s, iStave); + ++iStave; + } + else + e.unknown(); + } + } + else + e.unknown(); + } + + systems.append(s); + } + +//--------------------------------------------------------- +// capxSystems -- read the capx element +//--------------------------------------------------------- + +void Capella::capxSystems(XmlReader& e) + { + while (e.readNextStartElement()) { + const QStringRef& tag(e.name()); + if (tag == "system") { + readCapxSystem(e); + } + else + e.unknown(); + } + } + +//--------------------------------------------------------- +// readCapxStaveLayout -- capx equivalent of readStaveLayout(CapStaffLayout*, int) +// read the staffLayout element +//--------------------------------------------------------- + +void Capella::readCapxStaveLayout(XmlReader& e, CapStaffLayout* sl, int /*idx*/) + { + // initialize same variables as readStaveLayout(CapStaffLayout*, int) + + sl->barlineMode = 0; // TODO + sl->noteLines = 0; + + sl->bSmall = 0; // TODO + + sl->topDist = 0; + sl->btmDist = 0; + sl->groupDist = 0; + sl->barlineFrom = 0; + sl->barlineTo = 0; + + unsigned char clef = 0; + sl->form = FORM(clef & 7); + sl->line = CLEF_LINE((clef >> 3) & 7); + sl->oct = OCT((clef >> 6)); + // qDebug(" clef %x form %d, line %d, oct %d", clef, sl->form, sl->line, sl->oct); + + // Schlagzeuginformation + unsigned char b = 0; // ?? TODO ?? sl->soundMapIn and sl->soundMapOut are not used + sl->bPercussion = b & 1; // Schlagzeugkanal verwenden + sl->bSoundMapIn = b & 2; + sl->bSoundMapOut = b & 4; + /* + if (sl->bSoundMapIn) { // Umleitungstabelle fr Eingabe vom Keyboard + uchar iMin = readByte(); + Q_UNUSED(iMin); + uchar n = readByte(); + assert (n > 0 and iMin + n <= 128); + f->read(sl->soundMapIn, n); + curPos += n; + } + if (sl->bSoundMapOut) { // Umleitungstabelle fr das Vorspielen + unsigned char iMin = readByte(); + unsigned char n = readByte(); + assert (n > 0 and iMin + n <= 128); + f->read(sl->soundMapOut, n); + curPos += n; + } + */ + sl->sound = 0; // TODO + sl->volume = 0; + sl->transp = 0; + // qDebug(" sound %d vol %d transp %d", sl->sound, sl->volume, sl->transp); + + sl->descr = 0; // TODO + sl->name = 0; // TODO + sl->abbrev = 0; // TODO + sl->intermediateName = 0; + sl->intermediateAbbrev = 0; + // qDebug(" descr <%s> name <%s> abbrev <%s> iname <%s> iabrev <%s>", + // sl->descr, sl->name, sl->abbrev, sl->intermediateName, sl->intermediateAbbrev); + + qDebug("readCapxStaveLayout: descr '%s'", qPrintable(e.attribute("description"))); + // TODO: convert descr to char* and store in sl->descr + while (e.readNextStartElement()) { + const QStringRef& tag(e.name()); + if (tag == "notation") { + qDebug("readCapxStaveLayout: found notation (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "distances") { + qDebug("readCapxStaveLayout: found distances (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "instrument") { + qDebug("readCapxStaveLayout: found instrument (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "sound") { + sl->sound = e.intAttribute("instr", 0); + sl->volume = e.intAttribute("volume", 0); + e.readNext(); + } + else + e.unknown(); + } + qDebug(" sound %d vol %d transp %d", sl->sound, sl->volume, sl->transp); + qDebug("readCapxStaveLayout done"); + } + +//--------------------------------------------------------- +// capxLayoutStaves -- read the capx element (when child of element +// rough equivalent of readLayout() read part +//--------------------------------------------------------- + +void Capella::capxLayout(XmlReader& e) + { + while (e.readNextStartElement()) { + const QStringRef& tag(e.name()); + if (tag == "pages") { + qDebug("capxLayout: found pages (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "distances") { + qDebug("capxLayout: found distances (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "instrumentNames") { + qDebug("capxLayout: found instrumentNames (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "style") { + qDebug("capxLayout: found style (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "staves") { + capxLayoutStaves(e); + } + else if (tag == "brackets") { + qDebug("capxLayout: found brackets (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "spacing") { + qDebug("capxLayout: found spacing (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "beamFlattening") { + qDebug("capxLayout: found beamFlattening (skipping)"); + e.skipCurrentElement(); + } + else + e.unknown(); + } + } + +//--------------------------------------------------------- +// initCapxLayout -- capx equivalent of readLayout() initialize part +//--------------------------------------------------------- + +void Capella::initCapxLayout() + { + // initialize same variables as readLayout() + + smallLineDist = 1.2; // TODO verify default + normalLineDist = 1.76; // TODO verify default + + topDist = 14; // TODO verify default + interDist = 0; + + txtAlign = 0; + adjustVert = 0; + + unsigned char b = 0; + redundantKeys = b & 1; + modernDoubleNote = b & 2; + assert ((b & 0xFC) == 0); // bits 2...7 reserviert + + bSystemSeparators = 0; + nUnnamed = 0; + + // namesFont = ... // ?? not used ?? + + // Note: readLayout() also reads stave layout (using readStaveLayout(sl, iStave)) + // and system brackets. Here this is handled by readCapx(XmlReader& e). + } + +//--------------------------------------------------------- +// readCapx -- capx equivalent of read(QFile* fp) +//--------------------------------------------------------- + +void Capella::readCapx(XmlReader& e) + { + // initialize same variables as read(QFile* fp) + + f = 0; + curPos = 0; + + author = 0; + keywords = 0; + comment = 0; + + nRel = 0; + nAbs = 0; + unsigned char b = 0; + bUseRealSize = b & 1; + bAllowCompression = b & 2; + bPrintLandscape = b & 16; + + beamRelMin0 = 0; + beamRelMin1 = 0; + beamRelMax0 = 0; + beamRelMax1 = 0; + + backgroundChord = new ChordObj(this); + // TODO backgroundChord->read(); // contains graphic objects on the page background + bShowBarCount = 0; + barNumberFrame = 0; + nBarDistX = 0; + nBarDistY = 0; + // QFont barNumFont = ... // not used ? + nFirstPage = 0; + leftPageMargins = 0; + topPageMargins = 0; + rightPageMargins = 0; + btmPageMargins = 0; + + // Now do the equivalent of: + // readLayout(); (called only once) + // readExtra(); (this is a NOP) + // readDrawObjectArray(); + // for (unsigned i = 0; i < nSystems; i++) + // readSystem(); + + initCapxLayout(); + + // read stave layout + // read systems + while (e.readNextStartElement()) { + const QStringRef& tag(e.name()); + if (tag == "info") { + qDebug("importCapXml: found info (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "layout") { + capxLayout(e); + } + else if (tag == "gallery") { + qDebug("capxLayout: found gallery (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "pageObjects") { + qDebug("capxLayout: found pageObjects (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "barCount") { + qDebug("importCapXml: found barCount (skipping)"); + e.skipCurrentElement(); + } + else if (tag == "systems") { + capxSystems(e); + } + else + e.unknown(); + } + } + +//--------------------------------------------------------- +// importCapXml +//--------------------------------------------------------- + +void convertCapella(Score* score, Capella* cap, bool capxMode); + +Score::FileError importCapXml(Score* score, const QString& name) + { + qDebug("importCapXml(score %p, name %s)", score, qPrintable(name)); + QZipReader uz(name); + if (!uz.exists()) { + qDebug("importCapXml: <%s> not found", qPrintable(name)); + MScore::lastError = QT_TRANSLATE_NOOP("file", "file not found"); + return Score::FILE_NOT_FOUND; + } + + QByteArray dbuf = uz.fileData("score.xml"); + XmlReader e(dbuf); + e.setDocName(name); + Capella cf; + + while (e.readNextStartElement()) { + if (e.name() == "score") { + const QString& xmlns = e.attribute("xmlns", ""); // doesn't work ??? + qDebug("importCapXml: found score, namespace '%s'", qPrintable(xmlns)); + cf.readCapx(e); + } + else + e.unknown(); + } + + convertCapella(score, &cf, true); + return Score::FILE_NO_ERROR; + } diff --git a/mscore/file.cpp b/mscore/file.cpp index a2147b37a58f5..e82f0592ad78e 100644 --- a/mscore/file.cpp +++ b/mscore/file.cpp @@ -3,7 +3,7 @@ // Linux Music Score Editor // $Id: file.cpp 5645 2012-05-18 13:34:03Z wschweer $ // -// Copyright (C) 2002-2011 Werner Schweer et al. +// Copyright (C) 2002-2013 Werner Schweer et al. // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2. @@ -100,6 +100,7 @@ extern Score::FileError importMuseData(Score*, const QString& name); extern Score::FileError importLilypond(Score*, const QString& name); extern Score::FileError importBB(Score*, const QString& name); extern Score::FileError importCapella(Score*, const QString& name); +extern Score::FileError importCapXml(Score*, const QString& name); extern Score::FileError importOve(Score*, const QString& name); extern Score::FileError readScore(Score* score, QString name, bool ignoreVersionError); @@ -250,15 +251,16 @@ void MuseScore::loadFiles() QStringList files = getOpenScoreNames( lastOpenPath, #ifdef OMR - tr("All Supported Files (*.mscz *.mscx *.xml *.mxl *.mid *.midi *.kar *.md *.mgu *.MGU *.sgu *.SGU *.cap *.pdf *.ove *.scw *.bww *.GTP *.GP3 *.GP4 *.GP5);;")+ + tr("All Supported Files (*.mscz *.mscx *.xml *.mxl *.mid *.midi *.kar *.md *.mgu *.MGU *.sgu *.SGU *.cap *.capx *.pdf *.ove *.scw *.bww *.GTP *.GP3 *.GP4 *.GP5);;")+ #else - tr("All Supported Files (*.mscz *.mscx *.xml *.mxl *.mid *.midi *.kar *.md *.mgu *.MGU *.sgu *.SGU *.cap *.ove *.scw *.bww *.GTP *.GP3 *.GP4 *.GP5);;")+ + tr("All Supported Files (*.mscz *.mscx *.xml *.mxl *.mid *.midi *.kar *.md *.mgu *.MGU *.sgu *.SGU *.cap *.capx *.ove *.scw *.bww *.GTP *.GP3 *.GP4 *.GP5);;")+ #endif tr("MuseScore Files (*.mscz *.mscx);;")+ tr("MusicXML Files (*.xml *.mxl);;")+ tr("MIDI Files (*.mid *.midi *.kar);;")+ tr("Muse Data Files (*.md);;")+ tr("Capella Files (*.cap);;")+ + tr("CapXML Files (*.capx);;")+ tr("BB Files (*.mgu *.MGU *.sgu *.SGU);;")+ #ifdef OMR tr("PDF Files (*.pdf);;")+ @@ -1772,6 +1774,7 @@ Score::FileError readScore(Score* score, QString name, bool ignoreVersionError) { "mgu", &importBB }, { "sgu", &importBB }, { "cap", &importCapella }, + { "capx", &importCapXml }, { "ove", &importOve }, { "scw", &importOve }, #ifdef OMR diff --git a/test/capx/test1.capx b/test/capx/test1.capx new file mode 100644 index 0000000000000..04183d4af05dd Binary files /dev/null and b/test/capx/test1.capx differ diff --git a/test/capx/test2.capx b/test/capx/test2.capx new file mode 100644 index 0000000000000..d197a09a19e8c Binary files /dev/null and b/test/capx/test2.capx differ diff --git a/test/capx/test3.capx b/test/capx/test3.capx new file mode 100644 index 0000000000000..b521ca381eea3 Binary files /dev/null and b/test/capx/test3.capx differ diff --git a/test/capx/test4.capx b/test/capx/test4.capx new file mode 100644 index 0000000000000..0abd2af4ca037 Binary files /dev/null and b/test/capx/test4.capx differ diff --git a/test/capx/test5.capx b/test/capx/test5.capx new file mode 100644 index 0000000000000..756e12b25f0ec Binary files /dev/null and b/test/capx/test5.capx differ diff --git a/test/capx/test6.capx b/test/capx/test6.capx new file mode 100644 index 0000000000000..5da613418d34a Binary files /dev/null and b/test/capx/test6.capx differ diff --git a/test/capx/test7.capx b/test/capx/test7.capx new file mode 100644 index 0000000000000..a4c8e85b8a1f6 Binary files /dev/null and b/test/capx/test7.capx differ diff --git a/test/capx/testPianoG4G5.capx b/test/capx/testPianoG4G5.capx new file mode 100644 index 0000000000000..e9a4769ea214a Binary files /dev/null and b/test/capx/testPianoG4G5.capx differ diff --git a/test/capx/testScaleC4C5.capx b/test/capx/testScaleC4C5.capx new file mode 100644 index 0000000000000..e6a2ff9705e91 Binary files /dev/null and b/test/capx/testScaleC4C5.capx differ