2012-05-26 14:49:10 +02:00
|
|
|
|
//=============================================================================
|
|
|
|
|
// MuseScore
|
|
|
|
|
// Linux Music Score Editor
|
|
|
|
|
//
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// Copyright (C) 2009-2013 Werner Schweer and others
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//
|
|
|
|
|
// 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.
|
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Capella 2000 import filter
|
|
|
|
|
//
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
#include "libmscore/mscore.h"
|
|
|
|
|
#include "capella.h"
|
|
|
|
|
#include "libmscore/score.h"
|
|
|
|
|
#include "libmscore/part.h"
|
|
|
|
|
#include "libmscore/staff.h"
|
|
|
|
|
#include "libmscore/rest.h"
|
|
|
|
|
#include "libmscore/chord.h"
|
|
|
|
|
#include "libmscore/note.h"
|
|
|
|
|
#include "libmscore/utils.h"
|
|
|
|
|
#include "libmscore/lyrics.h"
|
|
|
|
|
#include "libmscore/timesig.h"
|
|
|
|
|
#include "libmscore/clef.h"
|
|
|
|
|
#include "libmscore/pitchspelling.h"
|
|
|
|
|
#include "libmscore/keysig.h"
|
|
|
|
|
#include "libmscore/slur.h"
|
2013-08-22 12:18:14 +02:00
|
|
|
|
#include "libmscore/tie.h"
|
2012-05-26 14:49:10 +02:00
|
|
|
|
#include "libmscore/box.h"
|
|
|
|
|
#include "libmscore/measure.h"
|
|
|
|
|
#include "libmscore/sig.h"
|
|
|
|
|
#include "libmscore/tuplet.h"
|
|
|
|
|
#include "libmscore/segment.h"
|
|
|
|
|
#include "libmscore/layoutbreak.h"
|
|
|
|
|
#include "libmscore/dynamic.h"
|
|
|
|
|
#include "libmscore/barline.h"
|
2013-05-06 22:10:49 +02:00
|
|
|
|
#include "libmscore/volta.h"
|
2015-01-21 09:25:53 +01:00
|
|
|
|
#include "libmscore/stafftext.h"
|
2015-01-22 16:35:32 +01:00
|
|
|
|
#include "libmscore/trill.h"
|
|
|
|
|
#include "libmscore/arpeggio.h"
|
|
|
|
|
#include "libmscore/breath.h"
|
|
|
|
|
#include "libmscore/hairpin.h"
|
2016-09-19 11:28:36 +02:00
|
|
|
|
#include "libmscore/sym.h"
|
2017-01-05 11:23:47 +01:00
|
|
|
|
#include "libmscore/articulation.h"
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
|
extern QString rtf2html(const QString &);
|
|
|
|
|
|
|
|
|
|
namespace Ms {
|
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// errmsg
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
const char* Capella::errmsg[] = {
|
|
|
|
|
"no error",
|
2013-04-21 13:36:06 +02:00
|
|
|
|
"bad file signature, no Capella file or not from version 2000 (3.0) or later?",
|
2012-05-26 14:49:10 +02:00
|
|
|
|
"unexpected end of file",
|
|
|
|
|
"bad voice signature",
|
|
|
|
|
"bad staff signature",
|
|
|
|
|
"bad system signature",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// addDynamic
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
static void addDynamic(Score* score, Segment* s, int track, const char* name)
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Dynamic* d = new Dynamic(score);
|
2013-03-05 20:23:59 +01:00
|
|
|
|
d->setDynamicType(name);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
d->setTrack(track);
|
|
|
|
|
s->add(d);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-01-21 09:25:53 +01:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// addArticulationText
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2016-10-06 12:21:28 +02:00
|
|
|
|
static void addArticulationText(Score* score, ChordRest* cr, int track, SymId symId)
|
2015-01-21 09:25:53 +01:00
|
|
|
|
{
|
|
|
|
|
Articulation* na = new Articulation(score);
|
|
|
|
|
na->setTrack(track);
|
2016-10-06 12:21:28 +02:00
|
|
|
|
na->setSymId(symId);
|
2015-01-21 09:25:53 +01:00
|
|
|
|
cr->add(na);
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-22 20:21:42 +01:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// SetCapGraceDuration
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
static void SetCapGraceDuration(Chord* chord,ChordObj* o)
|
|
|
|
|
{
|
2014-05-27 10:35:28 +02:00
|
|
|
|
NoteType nt = NoteType::APPOGGIATURA;
|
2015-01-15 21:12:02 +01:00
|
|
|
|
if (o->nTremoloBars > 0)
|
|
|
|
|
nt = NoteType::ACCIACCATURA;
|
2012-11-22 20:21:42 +01:00
|
|
|
|
((Chord*)chord)->setNoteType(nt);
|
2014-06-30 09:52:16 +02:00
|
|
|
|
if (o->t == TIMESTEP::D4) {
|
2014-05-27 10:35:28 +02:00
|
|
|
|
((Chord*)chord)->setNoteType(NoteType::GRACE4);
|
2014-05-21 15:43:19 +02:00
|
|
|
|
chord->setDurationType(TDuration::DurationType::V_QUARTER);
|
2012-11-22 20:21:42 +01:00
|
|
|
|
}
|
2014-06-30 09:52:16 +02:00
|
|
|
|
else if (o->t == TIMESTEP::D_BREVE)
|
2014-05-21 15:43:19 +02:00
|
|
|
|
((Chord*)chord)->setDurationType(TDuration::DurationType::V_BREVE);
|
2014-06-30 09:52:16 +02:00
|
|
|
|
else if (o->t == TIMESTEP::D1)
|
2014-05-21 15:43:19 +02:00
|
|
|
|
((Chord*)chord)->setDurationType(TDuration::DurationType::V_WHOLE);
|
2014-06-30 09:52:16 +02:00
|
|
|
|
else if (o->t == TIMESTEP::D2)
|
2014-05-21 15:43:19 +02:00
|
|
|
|
((Chord*)chord)->setDurationType(TDuration::DurationType::V_HALF);
|
2014-06-30 09:52:16 +02:00
|
|
|
|
else if (o->t == TIMESTEP::D16) {
|
2014-05-27 10:35:28 +02:00
|
|
|
|
((Chord*)chord)->setNoteType(NoteType::GRACE16);
|
2014-05-21 15:43:19 +02:00
|
|
|
|
chord->setDurationType(TDuration::DurationType::V_16TH);
|
2012-11-22 20:21:42 +01:00
|
|
|
|
}
|
2014-06-30 09:52:16 +02:00
|
|
|
|
else if (o->t == TIMESTEP::D32) {
|
2014-05-27 10:35:28 +02:00
|
|
|
|
((Chord*)chord)->setNoteType(NoteType::GRACE32);
|
2014-05-21 15:43:19 +02:00
|
|
|
|
chord->setDurationType(TDuration::DurationType::V_32ND);
|
2012-11-22 20:21:42 +01:00
|
|
|
|
}
|
2014-06-30 09:52:16 +02:00
|
|
|
|
else if (o->t == TIMESTEP::D64)
|
2014-05-21 15:43:19 +02:00
|
|
|
|
((Chord*)chord)->setDurationType(TDuration::DurationType::V_64TH);
|
2014-06-30 09:52:16 +02:00
|
|
|
|
else if (o->t == TIMESTEP::D128)
|
2014-05-21 15:43:19 +02:00
|
|
|
|
((Chord*)chord)->setDurationType(TDuration::DurationType::V_128TH);
|
2014-06-30 09:52:16 +02:00
|
|
|
|
else if (o->t == TIMESTEP::D256)
|
2014-05-21 15:43:19 +02:00
|
|
|
|
((Chord*)chord)->setDurationType(TDuration::DurationType::V_256TH);
|
2012-11-22 20:21:42 +01:00
|
|
|
|
else
|
2014-08-15 18:32:48 +02:00
|
|
|
|
((Chord*)chord)->setDurationType(TDuration::DurationType::V_EIGHTH);
|
2012-11-22 20:21:42 +01:00
|
|
|
|
}
|
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// processBasicDrawObj
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2015-01-21 09:25:53 +01:00
|
|
|
|
static void processBasicDrawObj(QList<BasicDrawObj*> objects, Segment* s, int track, ChordRest* cr)
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Score* score = s->score();
|
|
|
|
|
foreach(BasicDrawObj* oo, objects) {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
switch (oo->type) {
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::SIMPLE_TEXT:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
SimpleTextObj* st = static_cast<SimpleTextObj*>(oo);
|
|
|
|
|
if (st->font().family() == "capella3") {
|
|
|
|
|
QString text(st->text());
|
|
|
|
|
if (text.size() == 1) {
|
|
|
|
|
QChar c(text[0]);
|
|
|
|
|
ushort code = c.unicode();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
switch (code) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
case 'p':
|
|
|
|
|
addDynamic(score, s, track, "p");
|
|
|
|
|
break;
|
|
|
|
|
case 'q':
|
|
|
|
|
addDynamic(score, s, track, "pp");
|
|
|
|
|
break;
|
|
|
|
|
case 'r':
|
|
|
|
|
addDynamic(score, s, track, "ppp");
|
|
|
|
|
break;
|
|
|
|
|
case 's':
|
|
|
|
|
addDynamic(score, s, track, "sf");
|
|
|
|
|
break;
|
|
|
|
|
case 'f':
|
|
|
|
|
addDynamic(score, s, track, "f");
|
|
|
|
|
break;
|
|
|
|
|
case 'g':
|
|
|
|
|
addDynamic(score, s, track, "ff");
|
|
|
|
|
break;
|
|
|
|
|
case 'h':
|
|
|
|
|
addDynamic(score, s, track, "fff");
|
|
|
|
|
break;
|
|
|
|
|
case 'i':
|
|
|
|
|
addDynamic(score, s, track, "mp");
|
|
|
|
|
break;
|
|
|
|
|
case 'j':
|
|
|
|
|
addDynamic(score, s, track, "mf");
|
|
|
|
|
break;
|
|
|
|
|
case 'z': // sfz
|
|
|
|
|
addDynamic(score, s, track, "sfz");
|
|
|
|
|
break;
|
|
|
|
|
case '{':
|
|
|
|
|
addDynamic(score, s, track, "fz");
|
|
|
|
|
break;
|
|
|
|
|
case '|':
|
|
|
|
|
addDynamic(score, s, track, "fp");
|
|
|
|
|
break;
|
2015-01-21 09:25:53 +01:00
|
|
|
|
case 212: // dynamic m
|
|
|
|
|
addDynamic(score, s, track, "m");
|
|
|
|
|
break;
|
|
|
|
|
case 213: // dynamic r
|
|
|
|
|
addDynamic(score, s, track, "r");
|
|
|
|
|
break;
|
|
|
|
|
case 214: // dynamic s
|
|
|
|
|
addDynamic(score, s, track, "s");
|
|
|
|
|
break;
|
|
|
|
|
case 215: // dynamic z
|
|
|
|
|
addDynamic(score, s, track, "z");
|
|
|
|
|
break;
|
|
|
|
|
case 'k': // fermata down
|
2016-10-06 12:21:28 +02:00
|
|
|
|
addArticulationText(score, cr, track, SymId::fermataBelow);
|
2015-01-21 09:25:53 +01:00
|
|
|
|
break;
|
|
|
|
|
case 'u': // fermata up
|
2016-10-06 12:21:28 +02:00
|
|
|
|
addArticulationText(score, cr, track, SymId::fermataAbove);
|
2015-01-21 09:25:53 +01:00
|
|
|
|
break;
|
|
|
|
|
case 'd': // da capo D.C.
|
|
|
|
|
case 'e': // dal segno D.S.
|
|
|
|
|
case 'n': // segno coda
|
|
|
|
|
case 'o': // segno coda (smaller)
|
|
|
|
|
case 'y': // segno
|
|
|
|
|
case '$': // segno variation
|
|
|
|
|
case 'a': // pedal Ped.
|
|
|
|
|
case 'b': // pedal asterisk *
|
|
|
|
|
case 'v': // 8va
|
|
|
|
|
case 186: // 15ma
|
2015-01-23 17:37:06 +01:00
|
|
|
|
qDebug("Import of Capella text articulation %x(%c) not yet implemented", code, code);
|
2015-01-22 16:35:32 +01:00
|
|
|
|
break;
|
2015-01-21 09:25:53 +01:00
|
|
|
|
case 181: // caesura
|
2015-01-22 16:35:32 +01:00
|
|
|
|
{
|
|
|
|
|
Breath* b = new Breath(score);
|
|
|
|
|
b->setTrack(track);
|
2016-09-19 11:28:36 +02:00
|
|
|
|
b->setSymId(SymId::caesura);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Segment* seg = s->measure()->getSegment(SegmentType::Breath, s->tick() + (cr ? cr->actualTicks() : Fraction(0,1)));
|
2015-01-22 16:35:32 +01:00
|
|
|
|
seg->add(b);
|
|
|
|
|
}
|
2015-01-21 09:25:53 +01:00
|
|
|
|
break;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-01-18 14:16:33 +01:00
|
|
|
|
if (cr->type() == ElementType::CHORD)
|
2015-01-21 09:25:53 +01:00
|
|
|
|
switch (code) {
|
2016-10-06 12:21:28 +02:00
|
|
|
|
#if 0 // TODO-ws
|
2015-01-21 09:25:53 +01:00
|
|
|
|
case 't': // trill
|
|
|
|
|
addArticulationText(score, cr, track, QString("trill"));
|
|
|
|
|
break;
|
|
|
|
|
case 'l': // (upper) prall
|
|
|
|
|
addArticulationText(score, cr, track, QString("prall"));
|
|
|
|
|
break;
|
|
|
|
|
case 'w': // turn
|
|
|
|
|
addArticulationText(score, cr, track, QString("turn"));
|
|
|
|
|
break;
|
|
|
|
|
case 'x': // (lower) mordent
|
|
|
|
|
addArticulationText(score, cr, track, QString("mordent"));
|
|
|
|
|
break;
|
|
|
|
|
case 'Y': // down bow
|
|
|
|
|
addArticulationText(score, cr, track, QString("downbow"));
|
|
|
|
|
break;
|
|
|
|
|
case 'Z': // up bow
|
|
|
|
|
addArticulationText(score, cr, track, QString("upbow"));
|
|
|
|
|
break;
|
|
|
|
|
case 182: // plus sign
|
|
|
|
|
addArticulationText(score, cr, track, QString("plusstop"));
|
|
|
|
|
break;
|
|
|
|
|
case 183: // ouvert sign
|
|
|
|
|
addArticulationText(score, cr, track, QString("ouvert"));
|
|
|
|
|
break;
|
|
|
|
|
case 184: // snap pizzicato
|
|
|
|
|
addArticulationText(score, cr, track, QString("snappizzicato"));
|
|
|
|
|
break;
|
|
|
|
|
case 189: // schleifer
|
|
|
|
|
addArticulationText(score, cr, track, QString("schleifer"));
|
|
|
|
|
break;
|
|
|
|
|
case 190: // line prall
|
|
|
|
|
addArticulationText(score, cr, track, QString("lineprall"));
|
|
|
|
|
break;
|
|
|
|
|
case 191: // prall prall
|
|
|
|
|
addArticulationText(score, cr, track, QString("prallprall"));
|
|
|
|
|
break;
|
|
|
|
|
case 192: // down prall
|
|
|
|
|
addArticulationText(score, cr, track, QString("downprall"));
|
|
|
|
|
break;
|
|
|
|
|
case 193: // up prall
|
|
|
|
|
addArticulationText(score, cr, track, QString("upprall"));
|
|
|
|
|
break;
|
|
|
|
|
case 194: // prall mordent ?
|
|
|
|
|
addArticulationText(score, cr, track, QString("prallmordent"));
|
|
|
|
|
break;
|
|
|
|
|
case 209: // reverse turn
|
|
|
|
|
case 211: // alt. reverse turn
|
|
|
|
|
addArticulationText(score, cr, track, QString("reverseturn"));
|
|
|
|
|
break;
|
2016-10-06 12:21:28 +02:00
|
|
|
|
#endif
|
2015-01-21 09:25:53 +01:00
|
|
|
|
case 172: // arpeggio (short)
|
|
|
|
|
case 173: // arpeggio (long)
|
2015-01-22 16:35:32 +01:00
|
|
|
|
{
|
|
|
|
|
Arpeggio* a = new Arpeggio(score);
|
|
|
|
|
a->setArpeggioType(ArpeggioType::NORMAL);
|
|
|
|
|
if ((static_cast<Chord*>(cr))->arpeggio()) { // there can be only one
|
|
|
|
|
delete a;
|
|
|
|
|
a = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
cr->add(a);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2015-01-21 09:25:53 +01:00
|
|
|
|
case 187: // arpeggio (wiggle line, arrow up)
|
2015-01-22 16:35:32 +01:00
|
|
|
|
{
|
|
|
|
|
Arpeggio* a = new Arpeggio(score);
|
|
|
|
|
a->setArpeggioType(ArpeggioType::UP);
|
|
|
|
|
if ((static_cast<Chord*>(cr))->arpeggio()) { // there can be only one
|
|
|
|
|
delete a;
|
|
|
|
|
a = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
cr->add(a);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2015-01-21 09:25:53 +01:00
|
|
|
|
case 188: // arpeggio (wiggle line, arrow down)
|
2015-01-22 16:35:32 +01:00
|
|
|
|
{
|
|
|
|
|
Arpeggio* a = new Arpeggio(score);
|
|
|
|
|
a->setArpeggioType(ArpeggioType::DOWN);
|
|
|
|
|
if ((static_cast<Chord*>(cr))->arpeggio()) { // there can be only one
|
|
|
|
|
delete a;
|
|
|
|
|
a = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
cr->add(a);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2015-01-21 09:25:53 +01:00
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-12-27 11:51:00 +01:00
|
|
|
|
TextBase* text = new StaffText(score);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
QFont f(st->font());
|
2017-01-16 20:51:12 +01:00
|
|
|
|
text->setFamily(f.family());
|
|
|
|
|
text->setItalic(f.italic());
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// text->setUnderline(f.underline());
|
2017-01-16 20:51:12 +01:00
|
|
|
|
text->setBold(f.bold());
|
|
|
|
|
text->setSize(f.pointSizeF());
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2015-04-27 12:59:30 +02:00
|
|
|
|
text->setPlainText(st->text());
|
2012-09-29 16:46:45 +02:00
|
|
|
|
QPointF p(st->pos());
|
2015-01-26 13:52:44 +01:00
|
|
|
|
p = p / 32.0 * score->spatium();
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// text->setUserOff(st->pos());
|
2016-07-06 22:02:34 +02:00
|
|
|
|
text->setAutoplace(false);
|
2018-10-18 11:53:01 +02:00
|
|
|
|
text->setOffset(p);
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// 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()));
|
2017-01-16 20:51:12 +01:00
|
|
|
|
Align textalign;
|
2015-01-26 13:52:44 +01:00
|
|
|
|
switch (st->textalign()) {
|
2017-01-16 20:51:12 +01:00
|
|
|
|
default:
|
|
|
|
|
case 0:
|
|
|
|
|
textalign = Align::LEFT;
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
textalign = Align::HCENTER;
|
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
textalign = Align::RIGHT;
|
|
|
|
|
break;
|
2015-01-26 13:52:44 +01:00
|
|
|
|
}
|
2017-01-16 20:51:12 +01:00
|
|
|
|
text->setAlign(textalign | Align::BASELINE);
|
|
|
|
|
text->setOffset(QPointF(0.0, 2.0));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
text->setTrack(track);
|
|
|
|
|
s->add(text);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::TEXT:
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("======================Text:");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
default:
|
|
|
|
|
break;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-03-10 16:21:19 +01:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// TupletFractionCap
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
Fraction TupletFractionCap(int tupletCount, bool tuplettrp, bool tupletprol)
|
|
|
|
|
{
|
2019-01-30 15:13:54 +01:00
|
|
|
|
int dd = 0;
|
|
|
|
|
int nn = 0;
|
2015-03-10 16:21:19 +01:00
|
|
|
|
qreal exponent = 0;
|
2019-01-30 15:13:54 +01:00
|
|
|
|
qreal count = tupletCount;
|
2015-03-10 16:21:19 +01:00
|
|
|
|
Fraction f(3,2);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
|
2015-03-10 16:21:19 +01:00
|
|
|
|
if ((count > 0) && (count <= 15)) {
|
|
|
|
|
if (tuplettrp)
|
|
|
|
|
exponent = qFloor(qLn(count/3.0)/qLn(2.0));
|
|
|
|
|
else
|
|
|
|
|
exponent = qFloor(qLn(count)/qLn(2.0));
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
qDebug("Unknown tuplet, count = %d",tupletCount);
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
if (tupletprol)
|
|
|
|
|
exponent += 1.0;
|
|
|
|
|
if (exponent < 0.0)
|
|
|
|
|
exponent = 0.0;
|
|
|
|
|
nn = tupletCount;
|
2019-01-30 15:13:54 +01:00
|
|
|
|
dd = static_cast<int>(qPow(2.0, exponent));
|
2015-03-10 16:21:19 +01:00
|
|
|
|
if (tuplettrp)
|
|
|
|
|
dd = dd * 3;
|
2019-01-30 15:13:54 +01:00
|
|
|
|
qDebug("Tuplet Fraction: %d / %d", nn, dd);
|
|
|
|
|
return Fraction(nn, dd);
|
2015-03-10 16:21:19 +01:00
|
|
|
|
}
|
|
|
|
|
|
2013-05-06 22:10:49 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// findChordRests -- find begin and end ChordRest for BasicDrawObj o
|
|
|
|
|
// return true on success (both begin and end found)
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
static bool findChordRests(BasicDrawObj const* const o, Score* score, const int track, const Fraction& tick,
|
2015-01-22 16:35:32 +01:00
|
|
|
|
ChordRest*& cr1, ChordRest*& cr2, NoteObj* no, QList<NoteObj*> objects)
|
2013-05-06 22:10:49 +02:00
|
|
|
|
{
|
|
|
|
|
cr1 = 0; // ChordRest where BasicDrawObj o begins
|
|
|
|
|
cr2 = 0; // ChordRest where BasicDrawObj o ends
|
|
|
|
|
|
|
|
|
|
// find the ChordRests where o begins and ends
|
|
|
|
|
int n = o->nNotes + 1; // # notes in BasicDrawObj (nNotes is # notes following the first note)
|
2015-01-22 16:35:32 +01:00
|
|
|
|
int graceNumber = 0;
|
|
|
|
|
int graceNumber1 = 0;
|
|
|
|
|
bool foundcr1 = false;
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction tick2 = tick;
|
2015-01-22 16:35:32 +01:00
|
|
|
|
foreach(NoteObj* nobj, objects) {
|
|
|
|
|
BasicDurationalObj* d = 0;
|
|
|
|
|
if (nobj->type() == CapellaNoteObjectType::REST) {
|
|
|
|
|
d = static_cast<BasicDurationalObj*>(static_cast<RestObj*>(nobj));
|
|
|
|
|
graceNumber = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (nobj->type() == CapellaNoteObjectType::CHORD) {
|
|
|
|
|
ChordObj* cho = static_cast<ChordObj*>(nobj);
|
|
|
|
|
d = static_cast<BasicDurationalObj*>(cho);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
if (!(cho->invisible) && (cho->ticks().isZero())) // grace note
|
2015-01-22 16:35:32 +01:00
|
|
|
|
++graceNumber;
|
|
|
|
|
else
|
|
|
|
|
graceNumber = 0;
|
|
|
|
|
}
|
|
|
|
|
if (!d)
|
|
|
|
|
continue;
|
|
|
|
|
if (nobj == no) {
|
|
|
|
|
foundcr1 = true;
|
|
|
|
|
graceNumber1 = graceNumber;
|
|
|
|
|
}
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction ticks = Fraction(0,1);
|
2015-01-22 16:35:32 +01:00
|
|
|
|
if (foundcr1) {
|
|
|
|
|
--n; // found the object corresponding to cr1, count down to find the second one
|
|
|
|
|
ticks = d->ticks();
|
2015-03-10 16:21:19 +01:00
|
|
|
|
if (d->count) {
|
|
|
|
|
Fraction f = TupletFractionCap(d->count, d->tripartite, d->isProlonging);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
ticks = ticks / f;
|
2015-03-10 16:21:19 +01:00
|
|
|
|
}
|
2015-01-22 16:35:32 +01:00
|
|
|
|
if (nobj->type() == CapellaNoteObjectType::REST) {
|
|
|
|
|
RestObj* ro = static_cast<RestObj*>(nobj);
|
|
|
|
|
if (ro->fullMeasures) {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Measure* m = score->getCreateMeasure(tick2);
|
|
|
|
|
Fraction ft = m->ticks();
|
|
|
|
|
ticks = ft * ro->fullMeasures;
|
2015-01-22 16:35:32 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (n == 0)
|
|
|
|
|
break;
|
|
|
|
|
tick2 += ticks;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Now we have the tick (tick) and the level of grace note (graceNumber1, if "no" is a grace note) for the first ChordRest
|
|
|
|
|
// and the tick (tick2) and the level of grace note (graceNumber, if the target is a grace note) for the 2nd ChordRest
|
2013-05-06 22:10:49 +02:00
|
|
|
|
for (Segment* seg = score->tick2segment(tick); seg; seg = seg->next1()) {
|
2017-03-08 13:12:26 +01:00
|
|
|
|
if (seg->segmentType() != SegmentType::ChordRest)
|
2013-05-06 22:10:49 +02:00
|
|
|
|
continue;
|
|
|
|
|
ChordRest* cr = static_cast<ChordRest*>(seg->element(track));
|
|
|
|
|
if (cr) {
|
2015-01-22 16:35:32 +01:00
|
|
|
|
if (graceNumber1 > 0) { // the spanner is starting from a grace note
|
|
|
|
|
Chord* chord = static_cast<Chord*>(cr);
|
|
|
|
|
foreach(Chord* cc, chord->graceNotes()) {
|
|
|
|
|
--graceNumber1;
|
|
|
|
|
if ((graceNumber1 == 0) && (!cr1))
|
|
|
|
|
cr1 = static_cast<ChordRest*>(cc); // found first ChordRest
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!cr1) cr1 = cr; // found first ChordRest
|
|
|
|
|
break;
|
2013-05-06 22:10:49 +02:00
|
|
|
|
}
|
2015-01-22 16:35:32 +01:00
|
|
|
|
}
|
|
|
|
|
for (Segment* seg = score->tick2segment(tick2); seg; seg = seg->next1()) {
|
2017-03-08 13:12:26 +01:00
|
|
|
|
if (seg->segmentType() != SegmentType::ChordRest)
|
2015-01-22 16:35:32 +01:00
|
|
|
|
continue;
|
|
|
|
|
ChordRest* cr = static_cast<ChordRest*>(seg->element(track));
|
|
|
|
|
if (cr) {
|
2017-01-18 14:16:33 +01:00
|
|
|
|
if ((graceNumber > 0) && (cr->type() == ElementType::CHORD)) { // the spanner is ending on a grace note
|
2015-01-22 16:35:32 +01:00
|
|
|
|
Chord* chord = static_cast<Chord*>(cr);
|
|
|
|
|
foreach(Chord* cc, chord->graceNotes()) {
|
|
|
|
|
--graceNumber;
|
|
|
|
|
if ((graceNumber == 0) && (!cr2))
|
|
|
|
|
cr2 = static_cast<ChordRest*>(cc); // found 2nd ChordRest
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!cr2) cr2 = cr; // found 2nd ChordRest
|
2013-05-06 22:10:49 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-30 15:13:54 +01:00
|
|
|
|
qDebug("findChordRests o %p nNotes %d score %p track %d tick %d cr1 %p cr2 %p",
|
|
|
|
|
o, o->nNotes, score, track, tick.ticks(), cr1, cr2);
|
2013-05-06 22:10:49 +02:00
|
|
|
|
|
|
|
|
|
if (!(cr1 && cr2)) {
|
2016-02-11 23:57:06 +01:00
|
|
|
|
qDebug("first or second anchor for BasicDrawObj not found (tick %d type %d track %d first %p second %p)",
|
2019-01-30 15:13:54 +01:00
|
|
|
|
tick.ticks(), int(o->type), track, cr1, cr2);
|
2013-05-06 22:10:49 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// readCapVoice
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
static Fraction readCapVoice(Score* score, CapVoice* cvoice, int staffIdx, const Fraction& t, bool capxMode)
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction tick(t);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int voice = cvoice->voiceNo;
|
|
|
|
|
int track = staffIdx * VOICES + voice;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//
|
|
|
|
|
// pass I
|
|
|
|
|
//
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction startTick = tick;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Tuplet* tuplet = 0;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int tupletCount = 0;
|
2019-01-30 15:13:54 +01:00
|
|
|
|
bool tuplettrp = false;
|
2015-03-10 16:21:19 +01:00
|
|
|
|
bool tupletprol = false;
|
2019-01-30 15:13:54 +01:00
|
|
|
|
int nTuplet = 0;
|
|
|
|
|
Fraction tupletTick = Fraction(0,1);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2015-01-15 21:12:02 +01:00
|
|
|
|
QList<Chord*> graceNotes;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
foreach(NoteObj* no, cvoice->objects) {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
switch (no->type()) {
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::REST:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" <Rest>");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Measure* m = score->getCreateMeasure(tick);
|
|
|
|
|
RestObj* o = static_cast<RestObj*>(no);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction ticks = o->ticks();
|
|
|
|
|
if (o->invisible && ticks.isZero()) // get rid of placeholders
|
2012-11-22 20:21:42 +01:00
|
|
|
|
break;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
TDuration d;
|
2019-01-30 15:13:54 +01:00
|
|
|
|
d.setVal(ticks.ticks());
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (o->count) {
|
|
|
|
|
if (tuplet == 0) {
|
|
|
|
|
tupletCount = o->count;
|
2015-03-10 16:21:19 +01:00
|
|
|
|
tuplettrp = o->tripartite;
|
|
|
|
|
tupletprol = o->isProlonging;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
nTuplet = 0;
|
|
|
|
|
tupletTick = tick;
|
|
|
|
|
tuplet = new Tuplet(score);
|
2015-03-10 16:21:19 +01:00
|
|
|
|
Fraction f = TupletFractionCap(tupletCount,tuplettrp,tupletprol);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
tuplet->setRatio(f);
|
2016-01-04 15:42:01 +01:00
|
|
|
|
tuplet->setBaseLen(d);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
tuplet->setTrack(track);
|
|
|
|
|
tuplet->setTick(tick);
|
2013-04-30 16:49:15 +02:00
|
|
|
|
tuplet->setParent(m);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction nn = (ticks * tupletCount) / f;
|
|
|
|
|
tuplet->setTicks(nn);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction ft = m->ticks();
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (o->fullMeasures) {
|
|
|
|
|
ticks = ft * o->fullMeasures;
|
|
|
|
|
if (!o->invisible) {
|
|
|
|
|
for (unsigned i = 0; i < o->fullMeasures; ++i) {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Measure* m1 = score->getCreateMeasure(tick + (ft * i));
|
|
|
|
|
Segment* s = m1->getSegment(SegmentType::ChordRest, tick + (ft * i));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Rest* rest = new Rest(score);
|
2014-05-21 15:43:19 +02:00
|
|
|
|
rest->setDurationType(TDuration(TDuration::DurationType::V_MEASURE));
|
2019-01-30 15:13:54 +01:00
|
|
|
|
rest->setTicks(m1->ticks());
|
2012-09-29 16:46:45 +02:00
|
|
|
|
rest->setTrack(staffIdx * VOICES + voice);
|
|
|
|
|
s->add(rest);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!o->invisible || voice == 0) {
|
2017-03-08 13:12:26 +01:00
|
|
|
|
Segment* s = m->getSegment(SegmentType::ChordRest, tick);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Rest* rest = new Rest(score);
|
2018-09-25 15:55:08 +02:00
|
|
|
|
TDuration d1;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (o->fullMeasures) {
|
2018-09-25 15:55:08 +02:00
|
|
|
|
d1.setType(TDuration::DurationType::V_MEASURE);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
rest->setTicks(m->ticks());
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
else {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
d1.setVal(ticks.ticks());
|
|
|
|
|
rest->setTicks(d1.fraction());
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2018-09-25 15:55:08 +02:00
|
|
|
|
rest->setDurationType(d1);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
rest->setTrack(track);
|
|
|
|
|
rest->setVisible(!o->invisible);
|
|
|
|
|
s->add(rest);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
if (tuplet)
|
|
|
|
|
tuplet->add(rest);
|
2015-01-21 09:25:53 +01:00
|
|
|
|
processBasicDrawObj(o->objects, s, track, rest);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2013-04-30 16:49:15 +02:00
|
|
|
|
|
|
|
|
|
if (tuplet) {
|
|
|
|
|
if (++nTuplet >= tupletCount) {
|
|
|
|
|
tick = tupletTick + tuplet->actualTicks();
|
|
|
|
|
tuplet = 0;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
tick += ticks / tuplet->ratio();
|
2013-04-30 16:49:15 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
tick += ticks;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
break;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::CHORD:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" <Chord>");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
ChordObj* o = static_cast<ChordObj*>(no);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction ticks = o->ticks();
|
|
|
|
|
if (o->invisible && ticks.isZero()) { // get rid of placeholders
|
2012-11-22 20:21:42 +01:00
|
|
|
|
break;
|
2013-04-12 22:40:45 +02:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
TDuration d;
|
2019-01-30 15:13:54 +01:00
|
|
|
|
d.setVal(ticks.ticks());
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Measure* m = score->getCreateMeasure(tick);
|
2013-06-12 14:23:57 +02:00
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
bool isgracenote = (!(o->invisible) && (ticks.isZero()));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (o->count) {
|
|
|
|
|
if (tuplet == 0) {
|
|
|
|
|
tupletCount = o->count;
|
2015-03-10 16:21:19 +01:00
|
|
|
|
tuplettrp = o->tripartite;
|
|
|
|
|
tupletprol = o->isProlonging;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
nTuplet = 0;
|
|
|
|
|
tupletTick = tick;
|
|
|
|
|
tuplet = new Tuplet(score);
|
2015-03-10 16:21:19 +01:00
|
|
|
|
Fraction f = TupletFractionCap(tupletCount,tuplettrp,tupletprol);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
tuplet->setRatio(f);
|
2016-01-04 15:42:01 +01:00
|
|
|
|
tuplet->setBaseLen(d);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
tuplet->setTrack(track);
|
|
|
|
|
tuplet->setTick(tick);
|
2013-04-30 16:49:15 +02:00
|
|
|
|
tuplet->setParent(m);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction nn = (ticks * tupletCount) / f;
|
|
|
|
|
tuplet->setTicks(nn);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("Tuplet at %d: count: %d tri: %d prolonging: %d ticks %d objects %d",
|
2019-01-30 15:13:54 +01:00
|
|
|
|
tick.ticks(), o->count, o->tripartite, o->isProlonging, ticks.ticks(),
|
2013-04-12 22:40:45 +02:00
|
|
|
|
o->objects.size());
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Chord* chord = new Chord(score);
|
2012-11-22 20:21:42 +01:00
|
|
|
|
if (isgracenote) { // grace notes
|
|
|
|
|
SetCapGraceDuration(chord,o);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
chord->setTicks(chord->durationType().fraction());
|
2012-11-22 20:21:42 +01:00
|
|
|
|
}
|
|
|
|
|
else { // normal notes
|
|
|
|
|
chord->setDurationType(d);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
chord->setTicks(d.fraction());
|
2012-11-22 20:21:42 +01:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
chord->setTrack(track);
|
|
|
|
|
switch (o->stemDir) {
|
2014-06-30 12:08:23 +02:00
|
|
|
|
case ChordObj::StemDir::DOWN:
|
2016-03-02 13:20:19 +01:00
|
|
|
|
chord->setStemDirection(Direction::DOWN);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
2014-06-30 12:08:23 +02:00
|
|
|
|
case ChordObj::StemDir::UP:
|
2016-03-02 13:20:19 +01:00
|
|
|
|
chord->setStemDirection(Direction::UP);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
2014-06-30 12:08:23 +02:00
|
|
|
|
case ChordObj::StemDir::NONE:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
chord->setNoStem(true);
|
|
|
|
|
break;
|
2014-06-30 12:08:23 +02:00
|
|
|
|
case ChordObj::StemDir::AUTO:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-03-08 13:12:26 +01:00
|
|
|
|
Segment* s = m->getSegment(SegmentType::ChordRest, tick);
|
2015-01-15 21:12:02 +01:00
|
|
|
|
if (isgracenote)
|
|
|
|
|
graceNotes.push_back(chord);
|
|
|
|
|
else {
|
|
|
|
|
s->add(chord);
|
|
|
|
|
// append grace notes before
|
|
|
|
|
int ii = -1;
|
|
|
|
|
for (ii = graceNotes.size() - 1; ii >= 0; ii--) {
|
|
|
|
|
Chord* gc = graceNotes[ii];
|
|
|
|
|
if(gc->voice() == chord->voice()){
|
|
|
|
|
chord->add(gc);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
graceNotes.clear();
|
|
|
|
|
}
|
2019-01-30 15:13:54 +01:00
|
|
|
|
if (tuplet)
|
|
|
|
|
tuplet->add(chord);
|
2013-09-05 16:37:49 +02:00
|
|
|
|
ClefType clef = score->staff(staffIdx)->clef(tick);
|
2014-06-20 17:07:22 +02:00
|
|
|
|
Key key = score->staff(staffIdx)->key(tick);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int off;
|
2013-04-12 22:40:45 +02:00
|
|
|
|
switch (clef) {
|
2013-09-05 16:37:49 +02:00
|
|
|
|
case ClefType::G: off = 0; break;
|
2016-09-28 20:34:21 +02:00
|
|
|
|
case ClefType::G8_VA: off = 7; break;
|
|
|
|
|
case ClefType::G15_MA: off = 14; break;
|
|
|
|
|
case ClefType::G8_VB: off = -7; break;
|
2013-09-05 16:37:49 +02:00
|
|
|
|
case ClefType::F: off = -14; break;
|
2016-09-28 20:34:21 +02:00
|
|
|
|
case ClefType::F8_VB: off = -21; break;
|
|
|
|
|
case ClefType::F15_MB: off = -28; break;
|
2013-09-05 16:37:49 +02:00
|
|
|
|
case ClefType::F_B: off = -14; break;
|
|
|
|
|
case ClefType::F_C: off = -14; break;
|
|
|
|
|
case ClefType::C1: off = -7; break;
|
|
|
|
|
case ClefType::C2: off = -7; break;
|
|
|
|
|
case ClefType::C3: off = -7; break;
|
|
|
|
|
case ClefType::C4: off = -7; break;
|
|
|
|
|
case ClefType::C5: off = -7; break;
|
2016-09-28 20:34:21 +02:00
|
|
|
|
case ClefType::G_1: off = 0; break;
|
2013-09-05 16:37:49 +02:00
|
|
|
|
case ClefType::F_8VA: off = -7; break;
|
|
|
|
|
case ClefType::F_15MA: off = 0; break;
|
2016-02-11 23:57:06 +01:00
|
|
|
|
default: off = 0; qDebug("clefType %d not implemented", int(clef));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2014-05-31 09:40:51 +02:00
|
|
|
|
// qDebug("clef %hhd off %d", clef, off);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
static int keyOffsets[15] = {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
/* -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
|
2012-09-29 16:46:45 +02:00
|
|
|
|
};
|
2014-06-20 17:07:22 +02:00
|
|
|
|
off += keyOffsets[int(key) + 7];
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2018-08-14 10:03:49 +02:00
|
|
|
|
for (CNote n : o->notes) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Note* note = new Note(score);
|
2013-04-12 22:40:45 +02:00
|
|
|
|
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;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2013-04-12 22:40:45 +02:00
|
|
|
|
else {
|
|
|
|
|
int l = n.pitch + off + 7 * 6;
|
|
|
|
|
int octave = 0;
|
|
|
|
|
while (l < 0) {
|
|
|
|
|
l += 7;
|
|
|
|
|
octave--;
|
|
|
|
|
}
|
|
|
|
|
octave += l / 7;
|
|
|
|
|
l = l % 7;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
pitch = pitchKeyAdjust(l, key) + octave * 12;
|
|
|
|
|
}
|
2015-01-15 14:13:16 +01:00
|
|
|
|
pitch += n.alteration;
|
2015-03-13 11:16:43 +01:00
|
|
|
|
pitch += score->staff(staffIdx)->part()->instrument()->transpose().chromatic; // assume not in concert pitch
|
2015-01-15 14:13:16 +01:00
|
|
|
|
pitch = limit(pitch, 0, 127);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2015-01-15 14:13:16 +01:00
|
|
|
|
chord->add(note);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
note->setPitch(pitch);
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// TODO: compute tpc from pitch & line
|
2014-04-09 09:40:25 +02:00
|
|
|
|
note->setTpcFromPitch();
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (o->rightTie) {
|
|
|
|
|
Tie* tie = new Tie(score);
|
|
|
|
|
tie->setStartNote(note);
|
|
|
|
|
tie->setTrack(track);
|
|
|
|
|
note->setTieFor(tie);
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-08-14 10:03:49 +02:00
|
|
|
|
for (Verse v : o->verse) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Lyrics* l = new Lyrics(score);
|
|
|
|
|
l->setTrack(track);
|
2015-04-27 12:59:30 +02:00
|
|
|
|
l->setPlainText(v.text);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (v.hyphen)
|
2014-05-22 21:51:34 +02:00
|
|
|
|
l->setSyllabic(Lyrics::Syllabic::BEGIN);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
l->setNo(v.num);
|
|
|
|
|
chord->add(l);
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2015-01-21 09:25:53 +01:00
|
|
|
|
processBasicDrawObj(o->objects, s, track, chord);
|
2015-01-23 17:37:06 +01:00
|
|
|
|
switch (o->articulation) {
|
2016-10-06 12:21:28 +02:00
|
|
|
|
#if 0 // TODO-ws
|
2015-01-23 17:37:06 +01:00
|
|
|
|
case 1: addArticulationText(score, chord, track, QString("staccato")); break;
|
|
|
|
|
case 2: addArticulationText(score, chord, track, QString("tenuto")); break;
|
|
|
|
|
case 3: addArticulationText(score, chord, track, QString("portato")); break;
|
|
|
|
|
case 4: addArticulationText(score, chord, track, QString("staccatissimo")); break;
|
|
|
|
|
case 5: addArticulationText(score, chord, track, QString("sforzato")); break;
|
|
|
|
|
case 6: addArticulationText(score, chord, track, QString("marcato")); break;
|
2016-10-06 12:21:28 +02:00
|
|
|
|
#endif
|
2015-01-23 17:37:06 +01:00
|
|
|
|
case 7: // "weak beat"
|
|
|
|
|
case 8: // "strong beat"
|
|
|
|
|
default: if(o->articulation) qDebug("Articulation # %d not implemented", o->articulation); break;
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (tuplet) {
|
|
|
|
|
if (++nTuplet >= tupletCount) {
|
|
|
|
|
tick = tupletTick + tuplet->actualTicks();
|
|
|
|
|
tuplet = 0;
|
|
|
|
|
}
|
|
|
|
|
else {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
tick += ticks / tuplet->ratio();
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
tick += ticks;
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::CLEF:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" <Clef>");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
CapClef* o = static_cast<CapClef*>(no);
|
|
|
|
|
ClefType nclef = o->clef();
|
2019-01-30 15:13:54 +01:00
|
|
|
|
qDebug("%d:%d <Clef> %s line %d oct %d clef %d",
|
|
|
|
|
tick.ticks(), staffIdx, o->name(), int(o->line), int(o->oct), int(o->clef()));
|
2013-09-05 16:37:49 +02:00
|
|
|
|
if (nclef == ClefType::INVALID)
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
|
|
|
|
// staff(staffIdx)->setClef(tick, nclef);
|
|
|
|
|
Clef* clef = new Clef(score);
|
|
|
|
|
clef->setClefType(nclef);
|
|
|
|
|
clef->setTrack(staffIdx * VOICES);
|
|
|
|
|
Measure* m = score->getCreateMeasure(tick);
|
2016-10-25 17:30:55 +02:00
|
|
|
|
Segment* s;
|
|
|
|
|
if (tick == m->tick())
|
2017-03-08 13:12:26 +01:00
|
|
|
|
s = m->getSegment(SegmentType::HeaderClef, tick);
|
2016-10-25 17:30:55 +02:00
|
|
|
|
else
|
2017-03-08 13:12:26 +01:00
|
|
|
|
s = m->getSegment(SegmentType::Clef, tick);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
s->add(clef);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::KEY:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" <Key>");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
CapKey* o = static_cast<CapKey*>(no);
|
2014-12-08 18:02:17 +01:00
|
|
|
|
KeySigEvent key = score->staff(staffIdx)->keySigEvent(tick);
|
|
|
|
|
KeySigEvent okey;
|
|
|
|
|
okey.setKey(Key(o->signature));
|
|
|
|
|
if (!(key == okey)) {
|
|
|
|
|
score->staff(staffIdx)->setKey(tick, okey);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
KeySig* ks = new KeySig(score);
|
|
|
|
|
ks->setTrack(staffIdx * VOICES);
|
|
|
|
|
Measure* m = score->getCreateMeasure(tick);
|
2017-03-08 13:12:26 +01:00
|
|
|
|
Segment* s = m->getSegment(SegmentType::KeySig, tick);
|
2014-12-08 18:02:17 +01:00
|
|
|
|
ks->setKeySigEvent(okey);
|
2015-01-15 14:13:16 +01:00
|
|
|
|
s->add(ks);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::METER:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
CapMeter* o = static_cast<CapMeter*>(no);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
qDebug(" <Meter> tick %d %d/%d", tick.ticks(), o->numerator, 1 << o->log2Denom);
|
2014-03-04 13:06:23 +01:00
|
|
|
|
if (o->log2Denom > 7 || o->log2Denom < 0)
|
|
|
|
|
qFatal("illegal fraction");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
SigEvent se = score->sigmap()->timesig(tick);
|
|
|
|
|
Fraction f(o->numerator, 1 << o->log2Denom);
|
|
|
|
|
SigEvent ne(f);
|
|
|
|
|
if (!(se == ne))
|
2019-01-30 15:13:54 +01:00
|
|
|
|
score->sigmap()->add(tick.ticks(), ne);
|
2017-02-21 12:23:12 +01:00
|
|
|
|
|
|
|
|
|
// do not add timesig again
|
|
|
|
|
Measure* m = score->getCreateMeasure(tick);
|
2017-03-08 13:12:26 +01:00
|
|
|
|
Segment* s = m->findSegment(SegmentType::TimeSig, tick);
|
2017-02-21 12:23:12 +01:00
|
|
|
|
if (s) {
|
|
|
|
|
Element* e = s->element(trackZeroVoice(track));
|
|
|
|
|
if (e && static_cast<TimeSig*>(e)->sig() == f)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
TimeSig* ts = new TimeSig(score);
|
|
|
|
|
ts->setSig(f);
|
|
|
|
|
ts->setTrack(track);
|
2017-03-08 13:12:26 +01:00
|
|
|
|
s = m->getSegment(SegmentType::TimeSig, tick);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
s->add(ts);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
m->setTicks(f);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
break;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::EXPL_BARLINE:
|
|
|
|
|
case CapellaNoteObjectType::IMPL_BARLINE: // does not exist?
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
CapExplicitBarline* o = static_cast<CapExplicitBarline*>(no);
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" <Barline>");
|
2013-04-27 21:36:04 +02:00
|
|
|
|
Measure* pm = 0; // the previous measure (the one terminated by this barline)
|
2019-01-30 15:13:54 +01:00
|
|
|
|
if (tick > Fraction(0,1))
|
|
|
|
|
pm = score->getCreateMeasure(tick - Fraction::fromTicks(1));
|
2013-04-27 21:36:04 +02:00
|
|
|
|
if (pm) {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction ticks = tick - pm->tick();
|
|
|
|
|
if ((ticks > Fraction(0,1)) && ticks != pm->ticks()) {
|
2013-04-27 21:36:04 +02:00
|
|
|
|
// this is a measure with different actual duration
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction f = ticks;
|
|
|
|
|
pm->setTicks(f);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
#if 0
|
2013-04-27 21:36:04 +02:00
|
|
|
|
AL::SigEvent ne(f);
|
|
|
|
|
ne.setNominal(m->timesig());
|
|
|
|
|
score->sigmap()->add(m->tick(), ne);
|
|
|
|
|
AL::SigEvent ne2(m->timesig());
|
|
|
|
|
score->sigmap()->add(m->tick() + m->ticks(), ne2);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
#endif
|
2013-04-27 21:36:04 +02:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2013-04-28 11:08:42 +02:00
|
|
|
|
// qDebug("pm %p", pm);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2014-06-30 11:22:16 +02:00
|
|
|
|
BarLineType st = o->type();
|
2014-05-30 10:14:09 +02:00
|
|
|
|
if (st == BarLineType::NORMAL)
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2016-01-04 14:48:58 +01:00
|
|
|
|
//TODO if (pm && (st == BarLineType::DOUBLE || st == BarLineType::END || st == BarLineType::BROKEN))
|
|
|
|
|
// pm->setEndBarLineType(st, false, true);
|
2013-04-27 21:51:35 +02:00
|
|
|
|
|
2019-04-06 07:54:38 +02:00
|
|
|
|
if (st == BarLineType::START_REPEAT || st == BarLineType::END_START_REPEAT) {
|
2013-04-27 21:36:04 +02:00
|
|
|
|
Measure* nm = 0; // the next measure (the one started by this barline)
|
|
|
|
|
nm = score->getCreateMeasure(tick);
|
2013-04-28 11:08:42 +02:00
|
|
|
|
// qDebug("nm %p", nm);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (nm)
|
2016-02-04 11:27:47 +01:00
|
|
|
|
nm->setRepeatStart(true);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-04-06 07:54:38 +02:00
|
|
|
|
if (st == BarLineType::END_REPEAT || st == BarLineType::END_START_REPEAT) {
|
2013-04-27 21:36:04 +02:00
|
|
|
|
if (pm)
|
2016-02-04 11:27:47 +01:00
|
|
|
|
pm->setRepeatEnd(true);
|
2013-04-27 21:36:04 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2013-04-28 11:08:42 +02:00
|
|
|
|
break;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::PAGE_BKGR:
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" <PageBreak>");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction endTick = tick;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// pass II
|
|
|
|
|
//
|
|
|
|
|
tick = startTick;
|
|
|
|
|
foreach(NoteObj* no, cvoice->objects) {
|
|
|
|
|
BasicDurationalObj* d = 0;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
if (no->type() == CapellaNoteObjectType::REST)
|
2012-09-29 16:46:45 +02:00
|
|
|
|
d = static_cast<BasicDurationalObj*>(static_cast<RestObj*>(no));
|
2014-05-26 18:18:45 +02:00
|
|
|
|
else if (no->type() == CapellaNoteObjectType::CHORD)
|
2012-09-29 16:46:45 +02:00
|
|
|
|
d = static_cast<BasicDurationalObj*>(static_cast<ChordObj*>(no));
|
|
|
|
|
if (!d)
|
|
|
|
|
continue;
|
2018-08-14 10:03:49 +02:00
|
|
|
|
for (BasicDrawObj* o : d->objects) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
switch (o->type) {
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::SIMPLE_TEXT:
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("simple text at %d", tick);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::WAVY_LINE:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::SLUR:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
2013-05-06 22:10:49 +02:00
|
|
|
|
// SlurObj* so = static_cast<SlurObj*>(o);
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("slur tick %d %d-%d-%d-%d %d-%d", tick, so->nEnd, so->nMid,
|
2013-04-28 11:08:42 +02:00
|
|
|
|
// so->nDotDist, so->nDotWidth, so->nRefNote, so->nNotes);
|
|
|
|
|
ChordRest* cr1 = 0; // ChordRest where slur begins
|
|
|
|
|
ChordRest* cr2 = 0; // ChordRest where slur ends
|
2015-01-22 16:35:32 +01:00
|
|
|
|
bool res = findChordRests(o, score, track, tick, cr1, cr2, no, cvoice->objects);
|
2013-04-28 11:08:42 +02:00
|
|
|
|
|
2013-05-06 22:10:49 +02:00
|
|
|
|
if (res) {
|
2013-05-02 13:55:23 +02:00
|
|
|
|
if (cr1 == cr2)
|
2013-05-06 22:10:49 +02:00
|
|
|
|
qDebug("first and second anchor for slur identical (tick %d track %d first %p second %p)",
|
2019-01-30 15:13:54 +01:00
|
|
|
|
tick.ticks(), track, cr1, cr2);
|
2013-05-02 13:55:23 +02:00
|
|
|
|
else {
|
|
|
|
|
Slur* slur = new Slur(score);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
qDebug("tick %d track %d cr1 %p cr2 %p -> slur %p",
|
|
|
|
|
tick.ticks(), track, cr1, cr2, slur);
|
2013-06-10 11:03:34 +02:00
|
|
|
|
slur->setTick(cr1->tick());
|
|
|
|
|
slur->setTick2(cr2->tick());
|
2013-07-31 20:37:35 +02:00
|
|
|
|
slur->setStartElement(cr1);
|
|
|
|
|
slur->setEndElement(cr2);
|
|
|
|
|
slur->setTrack(cr1->track());
|
2013-09-30 10:16:50 +02:00
|
|
|
|
slur->setTrack2(cr2->track());
|
2013-07-31 20:37:35 +02:00
|
|
|
|
score->addElement(slur);
|
2013-05-02 13:55:23 +02:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::TEXT: {
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
TextObj* to = static_cast<TextObj*>(o);
|
2018-08-01 11:46:07 +02:00
|
|
|
|
Text* s = new Text(score, Tid::TITLE);
|
2013-05-13 18:49:17 +02:00
|
|
|
|
QString ss = ::rtf2html(QString(to->text));
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-04-29 17:22:24 +02:00
|
|
|
|
// qDebug("string %f:%f w %d ratio %d <%s>",
|
|
|
|
|
// to->relPos.x(), to->relPos.y(), to->width, to->yxRatio, qPrintable(ss));
|
2015-04-27 12:59:30 +02:00
|
|
|
|
s->setXmlText(ss);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
MeasureBase* measure = score->measures()->first();
|
2017-01-18 14:16:33 +01:00
|
|
|
|
if (measure->type() != ElementType::VBOX) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
MeasureBase* mb = new VBox(score);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
mb->setTick(Fraction(0, 1));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
score->addMeasure(mb, measure);
|
2015-01-26 11:06:32 +01:00
|
|
|
|
measure = mb;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2015-01-26 11:06:32 +01:00
|
|
|
|
s->setParent(measure);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
measure->add(s);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::VOLTA:
|
2013-05-06 22:10:49 +02:00
|
|
|
|
{
|
|
|
|
|
VoltaObj* vo = static_cast<VoltaObj*>(o);
|
|
|
|
|
ChordRest* cr1 = 0; // ChordRest where volta begins
|
|
|
|
|
ChordRest* cr2 = 0; // ChordRest where volta ends
|
2015-01-22 16:35:32 +01:00
|
|
|
|
bool res = findChordRests(o, score, track, tick, cr1, cr2, no, cvoice->objects);
|
2013-05-06 22:10:49 +02:00
|
|
|
|
|
|
|
|
|
if (res) {
|
|
|
|
|
Volta* volta = new Volta(score);
|
|
|
|
|
volta->setTrack(track);
|
2013-10-14 11:56:54 +02:00
|
|
|
|
volta->setTrack2(track);
|
2013-05-06 22:10:49 +02:00
|
|
|
|
// TODO also support endings such as "1 - 3"
|
|
|
|
|
volta->setText(QString("%1.").arg(vo->to));
|
|
|
|
|
volta->endings().append(vo->to);
|
|
|
|
|
if (vo->bRight)
|
2014-06-25 22:28:47 +02:00
|
|
|
|
volta->setVoltaType(Volta::Type::CLOSED);
|
2013-05-06 22:10:49 +02:00
|
|
|
|
else
|
2014-06-25 22:28:47 +02:00
|
|
|
|
volta->setVoltaType(Volta::Type::OPEN);
|
2013-06-10 11:03:34 +02:00
|
|
|
|
volta->setTick(cr1->measure()->tick());
|
2013-07-31 20:37:35 +02:00
|
|
|
|
volta->setTick2(cr2->measure()->tick() + cr2->measure()->ticks());
|
|
|
|
|
score->addElement(volta);
|
2013-05-06 22:10:49 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2015-01-22 16:35:32 +01:00
|
|
|
|
case CapellaType::TRILL:
|
|
|
|
|
{
|
|
|
|
|
TrillObj* tro = static_cast<TrillObj*>(o);
|
|
|
|
|
ChordRest* cr1 = 0; // ChordRest where trill line begins
|
|
|
|
|
ChordRest* cr2 = 0; // ChordRest where trill line ends
|
|
|
|
|
bool res = findChordRests(o, score, track, tick, cr1, cr2, no, cvoice->objects);
|
|
|
|
|
if (res) {
|
|
|
|
|
if (cr1 == cr2)
|
|
|
|
|
qDebug("first and second anchor for trill line identical (tick %d track %d first %p second %p)",
|
2019-01-30 15:13:54 +01:00
|
|
|
|
tick.ticks(), track, cr1, cr2);
|
2015-01-22 16:35:32 +01:00
|
|
|
|
else {
|
|
|
|
|
Trill* trill = new Trill(score);
|
|
|
|
|
trill->setTrack(track);
|
|
|
|
|
trill->setTrack2(track);
|
|
|
|
|
trill->setTick(cr1->tick());
|
|
|
|
|
trill->setTick2(cr2->tick());
|
|
|
|
|
if (!(tro->trillSign))
|
|
|
|
|
trill->setTrillType("prallprall");
|
|
|
|
|
score->addElement(trill);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case CapellaType::WEDGE:
|
|
|
|
|
{
|
|
|
|
|
WedgeObj* wdgo = static_cast<WedgeObj*>(o);
|
|
|
|
|
ChordRest* cr1 = 0; // ChordRest where hairpin begins
|
|
|
|
|
ChordRest* cr2 = 0; // ChordRest where hairpin ends
|
|
|
|
|
bool res = findChordRests(o, score, track, tick, cr1, cr2, no, cvoice->objects);
|
|
|
|
|
if (res) {
|
|
|
|
|
if (cr1 == cr2)
|
|
|
|
|
qDebug("first and second anchor for hairpin identical (tick %d track %d first %p second %p)",
|
2019-01-30 15:13:54 +01:00
|
|
|
|
tick.ticks(), track, cr1, cr2);
|
2015-01-22 16:35:32 +01:00
|
|
|
|
else {
|
|
|
|
|
Hairpin* hp = new Hairpin(score);
|
|
|
|
|
if (wdgo->decresc)
|
2016-09-22 17:28:44 +02:00
|
|
|
|
hp->setHairpinType(HairpinType::DECRESC_HAIRPIN);
|
2015-01-22 16:35:32 +01:00
|
|
|
|
else
|
2016-09-22 17:28:44 +02:00
|
|
|
|
hp->setHairpinType(HairpinType::CRESC_HAIRPIN);
|
2015-01-22 16:35:32 +01:00
|
|
|
|
hp->setTick(cr1->tick());
|
|
|
|
|
hp->setTick2(cr2->tick());
|
|
|
|
|
hp->setTrack(track);
|
|
|
|
|
hp->setTrack2(track);
|
|
|
|
|
hp->setAnchor(Spanner::Anchor::SEGMENT);
|
|
|
|
|
score->addSpanner(hp);
|
|
|
|
|
score->updateHairpin(hp);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction ticks = d->ticks();
|
2015-03-10 16:21:19 +01:00
|
|
|
|
if (d->count) {
|
|
|
|
|
Fraction f = TupletFractionCap(d->count, d->tripartite, d->isProlonging);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
ticks = ticks / f;
|
2015-03-10 16:21:19 +01:00
|
|
|
|
}
|
2014-05-26 18:18:45 +02:00
|
|
|
|
if (no->type() == CapellaNoteObjectType::REST) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
RestObj* o = static_cast<RestObj*>(no);
|
|
|
|
|
if (o->fullMeasures) {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Measure* m = score->getCreateMeasure(tick);
|
|
|
|
|
Fraction ft = m->ticks();
|
|
|
|
|
ticks = ft * o->fullMeasures;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
tick += ticks;
|
|
|
|
|
}
|
|
|
|
|
return endTick;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2013-05-02 11:49:57 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// needPart -- determine if a staff needs its own part
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// As Capella does not define parts (it only knows about staves,
|
|
|
|
|
// MIDI instruments numbers, brackets and braces), the following
|
|
|
|
|
// algorithm is used:
|
|
|
|
|
// - every staff is a separate part
|
|
|
|
|
// - unless:
|
|
|
|
|
// - it is in a brace
|
|
|
|
|
// - it is not the first staff in the brace
|
|
|
|
|
// - it has the same MIDI instrument as the previous staff
|
|
|
|
|
// Common cases:
|
|
|
|
|
// - Keyboards: two or three staves with the same MIDI instrument and a brace
|
|
|
|
|
// -> create one part
|
|
|
|
|
// - SATB: two or four staves with the same MIDI instrument and a bracket
|
|
|
|
|
// -> create two or four parts
|
|
|
|
|
|
|
|
|
|
static bool needPart(const int prevInst, const int currInst, const int staffIdx, QList<CapBracket> const& bracketList)
|
|
|
|
|
{
|
|
|
|
|
foreach(CapBracket cb, bracketList) {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
if (prevInst == currInst && cb.from < staffIdx && staffIdx <= cb.to && cb.curly)
|
2013-05-02 11:49:57 +02:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// convertCapella
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
void convertCapella(Score* score, Capella* cap, bool capxMode)
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (cap->systems.isEmpty())
|
|
|
|
|
return;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2018-03-27 15:36:00 +02:00
|
|
|
|
score->style().set(Sid::measureSpacing, 1.0);
|
2015-11-16 14:24:47 +01:00
|
|
|
|
score->setSpatium(cap->normalLineDist * DPMM);
|
2018-03-27 15:36:00 +02:00
|
|
|
|
score->style().set(Sid::smallStaffMag, cap->smallLineDist / cap->normalLineDist);
|
|
|
|
|
score->style().set(Sid::minSystemDistance, Spatium(8));
|
|
|
|
|
score->style().set(Sid::maxSystemDistance, Spatium(12));
|
|
|
|
|
// score->style().set(Sid::hideEmptyStaves, true);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
#if 1
|
|
|
|
|
foreach(CapSystem* csys, cap->systems) {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("System:");
|
2018-08-14 10:03:49 +02:00
|
|
|
|
for (CapStaff* cstaff : csys->staves) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
CapStaffLayout* cl = cap->staffLayout(cstaff->iLayout);
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" Staff layout <%s><%s><%s><%s><%s> %d barline %d-%d mode %d",
|
2013-05-04 14:24:01 +02:00
|
|
|
|
qPrintable(cl->descr), qPrintable(cl->name), qPrintable(cl->abbrev),
|
|
|
|
|
qPrintable(cl->intermediateName), qPrintable(cl->intermediateAbbrev),
|
2013-04-12 22:40:45 +02:00
|
|
|
|
cstaff->iLayout, cl->barlineFrom, cl->barlineTo, cl->barlineMode);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//
|
|
|
|
|
// find out the maximum number of staves
|
|
|
|
|
//
|
|
|
|
|
int staves = 0;
|
2013-04-12 22:40:45 +02:00
|
|
|
|
foreach(CapSystem* csys, cap->systems) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
staves = qMax(staves, csys->staves.size());
|
2013-04-12 22:40:45 +02:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//
|
|
|
|
|
// check the assumption that every stave should be
|
|
|
|
|
// associated with a CapStaffLayout
|
|
|
|
|
//
|
|
|
|
|
if (staves != cap->staffLayouts().size()) {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("Capella: max number of staves != number of staff layouts (%d, %d)",
|
|
|
|
|
staves, cap->staffLayouts().size());
|
2012-09-29 16:46:45 +02:00
|
|
|
|
staves = qMax(staves, cap->staffLayouts().size());
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-02 11:49:57 +02:00
|
|
|
|
// set the initial time signature
|
2012-09-29 16:46:45 +02:00
|
|
|
|
CapStaff* cs = cap->systems[0]->staves[0];
|
|
|
|
|
if (cs->log2Denom <= 7)
|
|
|
|
|
score->sigmap()->add(0, Fraction(cs->numerator, 1 << cs->log2Denom));
|
|
|
|
|
|
2013-05-02 11:49:57 +02:00
|
|
|
|
// create parts and staves
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Staff* bstaff = 0;
|
|
|
|
|
int span = 1;
|
2013-05-02 11:49:57 +02:00
|
|
|
|
int midiPatch = -1; // the previous MIDI patch (instrument)
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Part* part = 0;
|
|
|
|
|
for (int staffIdx = 0; staffIdx < staves; ++staffIdx) {
|
|
|
|
|
CapStaffLayout* cl = cap->staffLayout(staffIdx);
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("Midi staff %d program %d", staffIdx, cl->sound);
|
2013-05-02 11:49:57 +02:00
|
|
|
|
|
|
|
|
|
// create a new part if necessary
|
|
|
|
|
if (needPart(midiPatch, cl->sound, staffIdx, cap->brackets)) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
part = new Part(score);
|
|
|
|
|
score->appendPart(part);
|
|
|
|
|
}
|
2013-05-02 11:49:57 +02:00
|
|
|
|
midiPatch = cl->sound;
|
|
|
|
|
|
2014-08-16 13:32:08 +02:00
|
|
|
|
Staff* s = new Staff(score);
|
2018-11-08 15:45:14 +01:00
|
|
|
|
s->initFromStaffType(0);
|
|
|
|
|
|
2014-08-16 13:32:08 +02:00
|
|
|
|
s->setPart(part);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (cl->bPercussion)
|
|
|
|
|
part->setMidiProgram(0, 128);
|
|
|
|
|
else
|
|
|
|
|
part->setMidiProgram(cl->sound, 0);
|
2013-05-04 14:24:01 +02:00
|
|
|
|
part->setPartName(cl->descr);
|
2015-04-27 12:59:30 +02:00
|
|
|
|
part->setPlainLongName(cl->name);
|
|
|
|
|
part->setPlainShortName(cl->abbrev);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// ClefType clefType = CapClef::clefType(cl->form, cl->line, cl->oct);
|
|
|
|
|
// s->setClef(0, clefType);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
s->setBarLineSpan(0);
|
|
|
|
|
if (bstaff == 0) {
|
|
|
|
|
bstaff = s;
|
|
|
|
|
span = 0;
|
|
|
|
|
}
|
|
|
|
|
++span;
|
|
|
|
|
if (cl->barlineMode == 1) {
|
2017-05-29 14:59:10 +02:00
|
|
|
|
bstaff->setBarLineSpan(span != 0);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
bstaff = 0;
|
|
|
|
|
}
|
2018-11-08 15:45:14 +01:00
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
s->setSmall(Fraction(0,1), cl->bSmall);
|
2014-08-11 15:25:55 +02:00
|
|
|
|
part->insertStaff(s, -1);
|
2015-01-15 14:13:16 +01:00
|
|
|
|
Interval interval;
|
|
|
|
|
// guess diatonic transposition from chromatic transposition for the instrument
|
|
|
|
|
int values[23] = {-6,-6,-5,-5,-4,-3,-3,-2,-2,-1,-1,0,1,1,2,2,3,4,4,5,5,6,6};
|
|
|
|
|
interval.diatonic = values[(cl->transp % 12) + 11] + (cl->transp / 12) * 7;
|
|
|
|
|
interval.chromatic = cl->transp;
|
2015-03-13 11:16:43 +01:00
|
|
|
|
s->part()->instrument()->setTranspose(interval);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
score->staves().push_back(s);
|
|
|
|
|
}
|
|
|
|
|
if (bstaff)
|
2017-05-29 14:59:10 +02:00
|
|
|
|
bstaff->setBarLineSpan(span != 0);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
|
|
|
|
foreach(CapBracket cb, cap->brackets) {
|
2013-05-02 11:49:57 +02:00
|
|
|
|
qDebug("Bracket %d-%d curly %d", cb.from, cb.to, cb.curly);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Staff* staff = score->staves().value(cb.from);
|
|
|
|
|
if (staff == 0) {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("bad bracket 'from' value");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2017-03-31 13:03:15 +02:00
|
|
|
|
staff->setBracketType(0, cb.curly ? BracketType::BRACE : BracketType::NORMAL);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
staff->setBracketSpan(0, cb.to - cb.from + 1);
|
|
|
|
|
}
|
2016-01-19 10:02:42 +01:00
|
|
|
|
MeasureBase* measure = nullptr;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
foreach(BasicDrawObj* o, cap->backgroundChord->objects) {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
switch (o->type) {
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::SIMPLE_TEXT:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
SimpleTextObj* to = static_cast<SimpleTextObj*>(o);
|
2018-08-01 11:46:07 +02:00
|
|
|
|
Tid tid;
|
2016-01-19 10:02:42 +01:00
|
|
|
|
switch (to->textalign()) {
|
2018-08-01 11:46:07 +02:00
|
|
|
|
case 0: tid = Tid::POET; break;
|
|
|
|
|
case 1: tid = Tid::TITLE; break;
|
|
|
|
|
case 2: tid = Tid::COMPOSER; break;
|
|
|
|
|
default: tid = Tid::DEFAULT; break;
|
2016-01-19 10:02:42 +01:00
|
|
|
|
}
|
2018-08-01 11:46:07 +02:00
|
|
|
|
Text* s = new Text(score, tid);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
QFont f(to->font());
|
2017-01-16 20:51:12 +01:00
|
|
|
|
s->setItalic(f.italic());
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// s->setUnderline(f.underline());
|
2017-01-16 20:51:12 +01:00
|
|
|
|
s->setBold(f.bold());
|
|
|
|
|
s->setSize(f.pointSizeF());
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
|
|
|
|
QString ss = to->text();
|
2015-04-27 12:59:30 +02:00
|
|
|
|
s->setPlainText(ss);
|
2016-01-19 10:02:42 +01:00
|
|
|
|
if (!measure) {
|
|
|
|
|
measure = new VBox(score);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
measure->setTick(Fraction(0,1));
|
2016-01-19 10:02:42 +01:00
|
|
|
|
score->addMeasure(measure, score->measures()->first());
|
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
measure->add(s);
|
2014-06-30 11:58:12 +02:00
|
|
|
|
// qDebug("page background object type %d (CapellaType::SIMPLE_TEXT) text %s", o->type, qPrintable(ss));
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2016-02-11 23:57:06 +01:00
|
|
|
|
qDebug("page background object type %d", int(o->type));
|
2012-05-26 14:49:10 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (cap->topDist) {
|
|
|
|
|
VBox* mb = 0;
|
|
|
|
|
MeasureBaseList* mbl = score->measures();
|
2017-01-18 14:16:33 +01:00
|
|
|
|
if (mbl->size() && mbl->first()->type() == ElementType::VBOX)
|
2012-09-29 16:46:45 +02:00
|
|
|
|
mb = static_cast<VBox*>(mbl->first());
|
|
|
|
|
else {
|
|
|
|
|
VBox* vb = new VBox(score);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
vb->setTick(Fraction(0,1));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
score->addMeasure(vb, mb);
|
|
|
|
|
mb = vb;
|
|
|
|
|
}
|
|
|
|
|
mb->setBoxHeight(Spatium(cap->topDist));
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction systemTick = Fraction(0,1);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
foreach(CapSystem* csys, cap->systems) {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("readCapSystem");
|
|
|
|
|
/*
|
|
|
|
|
if (csys->explLeftIndent > 0) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
HBox* mb = new HBox(score);
|
|
|
|
|
mb->setTick(systemTick);
|
|
|
|
|
mb->setBoxWidth(Spatium(csys->explLeftIndent));
|
|
|
|
|
score->addMeasure(mb);
|
|
|
|
|
}
|
2013-04-12 22:40:45 +02:00
|
|
|
|
*/
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction mtick = Fraction(0,1);
|
2018-08-14 10:03:49 +02:00
|
|
|
|
for (CapStaff* cstaff : csys->staves) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//
|
|
|
|
|
// assumption: layout index is mscore staffIdx
|
|
|
|
|
// which means that there is a 1:1 relation between layout/staff
|
|
|
|
|
//
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" ReadCapStaff %d/%d", cstaff->numerator, 1 << cstaff->log2Denom);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int staffIdx = cstaff->iLayout;
|
|
|
|
|
int voice = 0;
|
2018-08-14 10:03:49 +02:00
|
|
|
|
for (CapVoice* cvoice : cstaff->voices) {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction tick = readCapVoice(score, cvoice, staffIdx, systemTick, capxMode);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
++voice;
|
|
|
|
|
if (tick > mtick)
|
|
|
|
|
mtick = tick;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Measure* m = score->tick2measure(mtick - Fraction::fromTicks(1));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (m && !m->lineBreak()) {
|
|
|
|
|
LayoutBreak* lb = new LayoutBreak(score);
|
2014-06-25 13:57:29 +02:00
|
|
|
|
lb->setLayoutBreakType(LayoutBreak::Type::LINE);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
lb->setTrack(-1); // this are system elements
|
|
|
|
|
m->add(lb);
|
|
|
|
|
}
|
|
|
|
|
systemTick = mtick;
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//
|
|
|
|
|
// fill empty measures with rests
|
|
|
|
|
//
|
2017-03-08 13:12:26 +01:00
|
|
|
|
SegmentType st = SegmentType::ChordRest;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
for (Measure* m = score->firstMeasure(); m; m = m->nextMeasure()) {
|
|
|
|
|
for (int staffIdx = 0; staffIdx < score->staves().size(); ++staffIdx) {
|
|
|
|
|
bool empty = true;
|
|
|
|
|
for (Segment* s = m->first(st); s; s = s->next(st)) {
|
|
|
|
|
if (s->element(staffIdx * VOICES)) {
|
|
|
|
|
empty = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (empty) {
|
2017-12-26 15:06:42 +01:00
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
if ((m->ticks() == m->timesig())) {
|
2017-12-26 15:06:42 +01:00
|
|
|
|
Segment* s = m->getSegment(SegmentType::ChordRest, m->tick());
|
|
|
|
|
Rest* rest = new Rest(score);
|
2014-05-21 15:43:19 +02:00
|
|
|
|
rest->setDurationType(TDuration::DurationType::V_MEASURE);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
rest->setTicks(m->ticks());
|
2017-12-26 15:06:42 +01:00
|
|
|
|
rest->setTrack(staffIdx * VOICES);
|
|
|
|
|
s->add(rest);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
auto durList = toDurationList(m->ticks(), true);
|
2017-12-26 15:06:42 +01:00
|
|
|
|
int tickOffset = 0;
|
|
|
|
|
for (auto d : durList) {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Segment* s = m->getSegment(SegmentType::ChordRest, m->tick() + Fraction::fromTicks(tickOffset));
|
2017-12-26 15:06:42 +01:00
|
|
|
|
Rest* rest = new Rest(score);
|
|
|
|
|
rest->setDurationType(d);
|
|
|
|
|
rest->setTrack(staffIdx * VOICES);
|
|
|
|
|
s->add(rest);
|
2019-01-30 15:13:54 +01:00
|
|
|
|
tickOffset += d.ticks().ticks();
|
2017-12-26 15:06:42 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// score->connectSlurs();
|
2013-08-21 11:59:41 +02:00
|
|
|
|
score->connectTies();
|
2013-06-19 16:25:29 +02:00
|
|
|
|
score->fixTicks();
|
2015-01-30 17:03:51 +01:00
|
|
|
|
score->setPlaylistDirty();
|
2016-03-02 13:20:19 +01:00
|
|
|
|
score->setLayoutAll();
|
2016-02-10 13:40:34 +01:00
|
|
|
|
score->addLayoutFlags(LayoutFlag::FIX_PITCH_VELO);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// Capella
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Capella::Capella()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
author = 0;
|
|
|
|
|
keywords = 0;
|
|
|
|
|
comment = 0;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Capella::~Capella()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
delete[] author;
|
|
|
|
|
delete[] keywords;
|
|
|
|
|
delete[] comment;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// SlurObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void SlurObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicDrawObj::read();
|
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
|
|
|
bezierPoint[i].setX(cap->readInt());
|
|
|
|
|
bezierPoint[i].setY(cap->readInt());
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
color = cap->readColor();
|
|
|
|
|
nEnd = cap->readByte();
|
|
|
|
|
nMid = cap->readByte();
|
|
|
|
|
nDotDist = cap->readByte();
|
|
|
|
|
nDotWidth = cap->readByte();
|
2013-04-28 11:08:42 +02:00
|
|
|
|
// qDebug("SlurObj nEnd %d nMid %d nDotDist %d nDotWidth %d",
|
|
|
|
|
// nEnd, nMid, nDotDist, nDotWidth);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void TextObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicRectObj::read();
|
|
|
|
|
unsigned size = cap->readUnsigned();
|
Solved all compilation errors on MSVC
This commit contains changes required for MuseScore to compile under MSVC with no errors.
There are several general categories of problems that resulted in errors with the compilation. Main issues:
- Variable Length Arrays (VLA). This is a non-standard extension to C++, supported by clang toolchains, but not by MSVC. The initial workaround is to use std::vector<> instead of VLAs, eventually (if needed) with the original variable pointing to the beginning of the allocated array. More efficient alternatives are possible if profiling shows any code using VLAs to be timing-critical.
- Floating-point constants not suffixed with "f" are doubles by default; in some instances, this leads to narrowing conversion errors (in other instances, just warnings).
- MSVC does not support "or"/"and"/"not" in lieu of "||"/"&&"/"!". Changed unconditionally to use standard C++ symbols.
- MSVC does not support the "__builtin_unreachable()" compiler hint. A similar, albeit not exactly equal, alternative is "__assume(0)", which is MSVC-specific.
- MSVC does not support ranges in case statements. Replaced with list of cases instead of range (non-conditionally)
Detailed changes, with per-file comments:
- all.h: opt-in to deprecated features, include <io.h> and <process.h> instead of POSIX <unistd.h>, undefine "STRING_NONE" and "small", which Microsoft defines as macros, which result in compilation errors.
- effects/compressor/zita.cpp: eliminated narrowing conversion error by appending "f" to float constants.
- fluid/voice.cpp: appended "f" to float constants to eliminate narrowing conversion errors/warnings
- libmscore/beam.cpp: conditionally replaced VLA
- libmscore/edit.cpp: conditionally replaced VLA
- libmscore/element.cpp: appended "f" to float constant
- libmscore/fret.cpp: changed or -> ||
- libmscore/layout.cpp: conditionally replaced VLA
- libmscore/mscore.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- libmscore/scorefile.coo: use correct char representation conversion for MSVC
- libmscore/stringdata.cpp: conditionally replaced VLA
- libmscore/system.cpp: conditionally replaced VLA
- libmscroe/text.cpp: replaced range in case statement.
- manual/genManual.cpp: use getopt() replacement.
- midi/midifile.cpp: conditionally replaced VLA. This does not use the default replacement.
- mscore/bb.cpp: replaced range in case statement.
- mscore/capella.cpp: conditionally replaced VLA. Changed and -> &&
- mscore/driver:cpp: preclude errors due to macro redefinitions.
- mscore/editstyle.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- mscore/importgtp-gp6.cpp: conditionally replaced VLA.
- mscore/instrwidget.cpp: conditionally replaced VLA.
- mscore/jackaudio.cpp: conditionally replaced VLA. Preclude errors due to macro redefinitions.
- mscore/jackweakapi.cpp: Preclude errors due to macro redefinitions. Replacement for __atribute__((constructor)) through static object construction for MSVC. Force use of LoadLibraryA instead of LoadLibrary.
- mscore/mididriver.h: Changed not -> !
- mscore/musescore.cpp: Changed not -> !. Conditionally replaced VLA.
- mscore/resourceManager.cpp: conditionally replaced VLA.
- mscore/timeline.cpp: conditionally replaced VLA.
- omr/omrpage.cpp: conditionally replaced VLA.
- synthesizer/msynthesizer.cpp: replaced UNIX sleep(1) method with MSVC Sleep(1000) (equivalent, but in ms instead of seconds)
- synthesizer/msynthsizer.h: appended "f" to float constant
- thirdparty/poppler/config.h: set defines for MSVC to preclude the use of inexistent libraries.
- thirdparty/poppler/poppler/poppler-config.h: set defines for MSVC to preclude the use of inexistent libraries. Eliminated #defines for fmin and fmax which where causing problems.
- thirdparty/poppler/poppler/PSOutputDev.cc: added #include <algorithm> for std::min() and std::max(). Note this is required per-C++ standard.
- thirdparty/portmidi/pm_win/pmwinmm.c: undefined UNICODE to use char-based library functions.
- thirdparty/qzip/qzip.cpp: changed or -> ||
- thirdparty/rtf2html/rtf_keyword.h: file format changed from Apple to UNIX, as MSVC does not supported the former.
(NOT error related, just improvement on previous commit; manual/getopt/README.md: added link to source article)
2018-05-01 19:14:44 +02:00
|
|
|
|
#if (!defined (_MSCVER) && !defined (_MSC_VER))
|
2012-09-29 16:46:45 +02:00
|
|
|
|
char txt[size+1];
|
Solved all compilation errors on MSVC
This commit contains changes required for MuseScore to compile under MSVC with no errors.
There are several general categories of problems that resulted in errors with the compilation. Main issues:
- Variable Length Arrays (VLA). This is a non-standard extension to C++, supported by clang toolchains, but not by MSVC. The initial workaround is to use std::vector<> instead of VLAs, eventually (if needed) with the original variable pointing to the beginning of the allocated array. More efficient alternatives are possible if profiling shows any code using VLAs to be timing-critical.
- Floating-point constants not suffixed with "f" are doubles by default; in some instances, this leads to narrowing conversion errors (in other instances, just warnings).
- MSVC does not support "or"/"and"/"not" in lieu of "||"/"&&"/"!". Changed unconditionally to use standard C++ symbols.
- MSVC does not support the "__builtin_unreachable()" compiler hint. A similar, albeit not exactly equal, alternative is "__assume(0)", which is MSVC-specific.
- MSVC does not support ranges in case statements. Replaced with list of cases instead of range (non-conditionally)
Detailed changes, with per-file comments:
- all.h: opt-in to deprecated features, include <io.h> and <process.h> instead of POSIX <unistd.h>, undefine "STRING_NONE" and "small", which Microsoft defines as macros, which result in compilation errors.
- effects/compressor/zita.cpp: eliminated narrowing conversion error by appending "f" to float constants.
- fluid/voice.cpp: appended "f" to float constants to eliminate narrowing conversion errors/warnings
- libmscore/beam.cpp: conditionally replaced VLA
- libmscore/edit.cpp: conditionally replaced VLA
- libmscore/element.cpp: appended "f" to float constant
- libmscore/fret.cpp: changed or -> ||
- libmscore/layout.cpp: conditionally replaced VLA
- libmscore/mscore.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- libmscore/scorefile.coo: use correct char representation conversion for MSVC
- libmscore/stringdata.cpp: conditionally replaced VLA
- libmscore/system.cpp: conditionally replaced VLA
- libmscroe/text.cpp: replaced range in case statement.
- manual/genManual.cpp: use getopt() replacement.
- midi/midifile.cpp: conditionally replaced VLA. This does not use the default replacement.
- mscore/bb.cpp: replaced range in case statement.
- mscore/capella.cpp: conditionally replaced VLA. Changed and -> &&
- mscore/driver:cpp: preclude errors due to macro redefinitions.
- mscore/editstyle.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- mscore/importgtp-gp6.cpp: conditionally replaced VLA.
- mscore/instrwidget.cpp: conditionally replaced VLA.
- mscore/jackaudio.cpp: conditionally replaced VLA. Preclude errors due to macro redefinitions.
- mscore/jackweakapi.cpp: Preclude errors due to macro redefinitions. Replacement for __atribute__((constructor)) through static object construction for MSVC. Force use of LoadLibraryA instead of LoadLibrary.
- mscore/mididriver.h: Changed not -> !
- mscore/musescore.cpp: Changed not -> !. Conditionally replaced VLA.
- mscore/resourceManager.cpp: conditionally replaced VLA.
- mscore/timeline.cpp: conditionally replaced VLA.
- omr/omrpage.cpp: conditionally replaced VLA.
- synthesizer/msynthesizer.cpp: replaced UNIX sleep(1) method with MSVC Sleep(1000) (equivalent, but in ms instead of seconds)
- synthesizer/msynthsizer.h: appended "f" to float constant
- thirdparty/poppler/config.h: set defines for MSVC to preclude the use of inexistent libraries.
- thirdparty/poppler/poppler/poppler-config.h: set defines for MSVC to preclude the use of inexistent libraries. Eliminated #defines for fmin and fmax which where causing problems.
- thirdparty/poppler/poppler/PSOutputDev.cc: added #include <algorithm> for std::min() and std::max(). Note this is required per-C++ standard.
- thirdparty/portmidi/pm_win/pmwinmm.c: undefined UNICODE to use char-based library functions.
- thirdparty/qzip/qzip.cpp: changed or -> ||
- thirdparty/rtf2html/rtf_keyword.h: file format changed from Apple to UNIX, as MSVC does not supported the former.
(NOT error related, just improvement on previous commit; manual/getopt/README.md: added link to source article)
2018-05-01 19:14:44 +02:00
|
|
|
|
#else
|
|
|
|
|
// MSVC does not support VLA. Replace with std::vector. If profiling determines that the
|
|
|
|
|
// heap allocation is slow, an optimization might be used.
|
|
|
|
|
std::vector<char> vtxt(size+1);
|
|
|
|
|
char* txt = vtxt.data();
|
|
|
|
|
#endif
|
2012-09-29 16:46:45 +02:00
|
|
|
|
cap->read(txt, size);
|
|
|
|
|
txt[size] = 0;
|
|
|
|
|
text = QString(txt);
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("read textObj len %d <%s>", size, txt);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// read
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void SimpleTextObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicDrawObj::read();
|
|
|
|
|
relPos = cap->readPoint();
|
|
|
|
|
align = cap->readByte();
|
|
|
|
|
_font = cap->readFont();
|
2013-05-04 14:24:01 +02:00
|
|
|
|
_text = cap->readQString();
|
2013-04-29 17:22:24 +02:00
|
|
|
|
// qDebug("read SimpletextObj(%f,%f) len %zd <%s>",
|
|
|
|
|
// relPos.x(), relPos.y(), _text.length(), qPrintable(_text));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// LineObj::read
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void LineObj::read()
|
|
|
|
|
{
|
|
|
|
|
BasicDrawObj::read();
|
|
|
|
|
pt1 = cap->readPoint();
|
|
|
|
|
pt2 = cap->readPoint();
|
|
|
|
|
color = cap->readColor();
|
|
|
|
|
lineWidth = cap->readByte();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("LineObj: %f:%f %f:%f width %d", pt1.x(), pt1.y(), pt2.x(), pt2.y(), lineWidth);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// BracketObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void BracketObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
LineObj::read();
|
|
|
|
|
orientation = cap->readByte();
|
|
|
|
|
number = cap->readByte();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// GroupObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void GroupObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicDrawObj::read();
|
|
|
|
|
relPos = cap->readPoint();
|
|
|
|
|
objects = cap->readDrawObjectArray();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// TransposableObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void TransposableObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicDrawObj::read();
|
|
|
|
|
relPos = cap->readPoint();
|
|
|
|
|
b = cap->readByte();
|
|
|
|
|
if (b != 12 && b != 21)
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("TransposableObj::read: warning: unknown drawObjectArray size of %d", b);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
variants = cap->readDrawObjectArray();
|
|
|
|
|
if (variants.size() != b)
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("variants.size %d, expected %d", variants.size(), b);
|
2014-03-04 13:32:32 +01:00
|
|
|
|
Q_ASSERT(variants.size() == b);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
/*int nRefNote =*/ cap->readInt();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// MetafileObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void MetafileObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicRectObj::read();
|
|
|
|
|
unsigned size = cap->readUnsigned();
|
Solved all compilation errors on MSVC
This commit contains changes required for MuseScore to compile under MSVC with no errors.
There are several general categories of problems that resulted in errors with the compilation. Main issues:
- Variable Length Arrays (VLA). This is a non-standard extension to C++, supported by clang toolchains, but not by MSVC. The initial workaround is to use std::vector<> instead of VLAs, eventually (if needed) with the original variable pointing to the beginning of the allocated array. More efficient alternatives are possible if profiling shows any code using VLAs to be timing-critical.
- Floating-point constants not suffixed with "f" are doubles by default; in some instances, this leads to narrowing conversion errors (in other instances, just warnings).
- MSVC does not support "or"/"and"/"not" in lieu of "||"/"&&"/"!". Changed unconditionally to use standard C++ symbols.
- MSVC does not support the "__builtin_unreachable()" compiler hint. A similar, albeit not exactly equal, alternative is "__assume(0)", which is MSVC-specific.
- MSVC does not support ranges in case statements. Replaced with list of cases instead of range (non-conditionally)
Detailed changes, with per-file comments:
- all.h: opt-in to deprecated features, include <io.h> and <process.h> instead of POSIX <unistd.h>, undefine "STRING_NONE" and "small", which Microsoft defines as macros, which result in compilation errors.
- effects/compressor/zita.cpp: eliminated narrowing conversion error by appending "f" to float constants.
- fluid/voice.cpp: appended "f" to float constants to eliminate narrowing conversion errors/warnings
- libmscore/beam.cpp: conditionally replaced VLA
- libmscore/edit.cpp: conditionally replaced VLA
- libmscore/element.cpp: appended "f" to float constant
- libmscore/fret.cpp: changed or -> ||
- libmscore/layout.cpp: conditionally replaced VLA
- libmscore/mscore.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- libmscore/scorefile.coo: use correct char representation conversion for MSVC
- libmscore/stringdata.cpp: conditionally replaced VLA
- libmscore/system.cpp: conditionally replaced VLA
- libmscroe/text.cpp: replaced range in case statement.
- manual/genManual.cpp: use getopt() replacement.
- midi/midifile.cpp: conditionally replaced VLA. This does not use the default replacement.
- mscore/bb.cpp: replaced range in case statement.
- mscore/capella.cpp: conditionally replaced VLA. Changed and -> &&
- mscore/driver:cpp: preclude errors due to macro redefinitions.
- mscore/editstyle.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- mscore/importgtp-gp6.cpp: conditionally replaced VLA.
- mscore/instrwidget.cpp: conditionally replaced VLA.
- mscore/jackaudio.cpp: conditionally replaced VLA. Preclude errors due to macro redefinitions.
- mscore/jackweakapi.cpp: Preclude errors due to macro redefinitions. Replacement for __atribute__((constructor)) through static object construction for MSVC. Force use of LoadLibraryA instead of LoadLibrary.
- mscore/mididriver.h: Changed not -> !
- mscore/musescore.cpp: Changed not -> !. Conditionally replaced VLA.
- mscore/resourceManager.cpp: conditionally replaced VLA.
- mscore/timeline.cpp: conditionally replaced VLA.
- omr/omrpage.cpp: conditionally replaced VLA.
- synthesizer/msynthesizer.cpp: replaced UNIX sleep(1) method with MSVC Sleep(1000) (equivalent, but in ms instead of seconds)
- synthesizer/msynthsizer.h: appended "f" to float constant
- thirdparty/poppler/config.h: set defines for MSVC to preclude the use of inexistent libraries.
- thirdparty/poppler/poppler/poppler-config.h: set defines for MSVC to preclude the use of inexistent libraries. Eliminated #defines for fmin and fmax which where causing problems.
- thirdparty/poppler/poppler/PSOutputDev.cc: added #include <algorithm> for std::min() and std::max(). Note this is required per-C++ standard.
- thirdparty/portmidi/pm_win/pmwinmm.c: undefined UNICODE to use char-based library functions.
- thirdparty/qzip/qzip.cpp: changed or -> ||
- thirdparty/rtf2html/rtf_keyword.h: file format changed from Apple to UNIX, as MSVC does not supported the former.
(NOT error related, just improvement on previous commit; manual/getopt/README.md: added link to source article)
2018-05-01 19:14:44 +02:00
|
|
|
|
#if (!defined (_MSCVER) && !defined (_MSC_VER))
|
2012-09-29 16:46:45 +02:00
|
|
|
|
char enhMetaFileBits[size];
|
Solved all compilation errors on MSVC
This commit contains changes required for MuseScore to compile under MSVC with no errors.
There are several general categories of problems that resulted in errors with the compilation. Main issues:
- Variable Length Arrays (VLA). This is a non-standard extension to C++, supported by clang toolchains, but not by MSVC. The initial workaround is to use std::vector<> instead of VLAs, eventually (if needed) with the original variable pointing to the beginning of the allocated array. More efficient alternatives are possible if profiling shows any code using VLAs to be timing-critical.
- Floating-point constants not suffixed with "f" are doubles by default; in some instances, this leads to narrowing conversion errors (in other instances, just warnings).
- MSVC does not support "or"/"and"/"not" in lieu of "||"/"&&"/"!". Changed unconditionally to use standard C++ symbols.
- MSVC does not support the "__builtin_unreachable()" compiler hint. A similar, albeit not exactly equal, alternative is "__assume(0)", which is MSVC-specific.
- MSVC does not support ranges in case statements. Replaced with list of cases instead of range (non-conditionally)
Detailed changes, with per-file comments:
- all.h: opt-in to deprecated features, include <io.h> and <process.h> instead of POSIX <unistd.h>, undefine "STRING_NONE" and "small", which Microsoft defines as macros, which result in compilation errors.
- effects/compressor/zita.cpp: eliminated narrowing conversion error by appending "f" to float constants.
- fluid/voice.cpp: appended "f" to float constants to eliminate narrowing conversion errors/warnings
- libmscore/beam.cpp: conditionally replaced VLA
- libmscore/edit.cpp: conditionally replaced VLA
- libmscore/element.cpp: appended "f" to float constant
- libmscore/fret.cpp: changed or -> ||
- libmscore/layout.cpp: conditionally replaced VLA
- libmscore/mscore.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- libmscore/scorefile.coo: use correct char representation conversion for MSVC
- libmscore/stringdata.cpp: conditionally replaced VLA
- libmscore/system.cpp: conditionally replaced VLA
- libmscroe/text.cpp: replaced range in case statement.
- manual/genManual.cpp: use getopt() replacement.
- midi/midifile.cpp: conditionally replaced VLA. This does not use the default replacement.
- mscore/bb.cpp: replaced range in case statement.
- mscore/capella.cpp: conditionally replaced VLA. Changed and -> &&
- mscore/driver:cpp: preclude errors due to macro redefinitions.
- mscore/editstyle.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- mscore/importgtp-gp6.cpp: conditionally replaced VLA.
- mscore/instrwidget.cpp: conditionally replaced VLA.
- mscore/jackaudio.cpp: conditionally replaced VLA. Preclude errors due to macro redefinitions.
- mscore/jackweakapi.cpp: Preclude errors due to macro redefinitions. Replacement for __atribute__((constructor)) through static object construction for MSVC. Force use of LoadLibraryA instead of LoadLibrary.
- mscore/mididriver.h: Changed not -> !
- mscore/musescore.cpp: Changed not -> !. Conditionally replaced VLA.
- mscore/resourceManager.cpp: conditionally replaced VLA.
- mscore/timeline.cpp: conditionally replaced VLA.
- omr/omrpage.cpp: conditionally replaced VLA.
- synthesizer/msynthesizer.cpp: replaced UNIX sleep(1) method with MSVC Sleep(1000) (equivalent, but in ms instead of seconds)
- synthesizer/msynthsizer.h: appended "f" to float constant
- thirdparty/poppler/config.h: set defines for MSVC to preclude the use of inexistent libraries.
- thirdparty/poppler/poppler/poppler-config.h: set defines for MSVC to preclude the use of inexistent libraries. Eliminated #defines for fmin and fmax which where causing problems.
- thirdparty/poppler/poppler/PSOutputDev.cc: added #include <algorithm> for std::min() and std::max(). Note this is required per-C++ standard.
- thirdparty/portmidi/pm_win/pmwinmm.c: undefined UNICODE to use char-based library functions.
- thirdparty/qzip/qzip.cpp: changed or -> ||
- thirdparty/rtf2html/rtf_keyword.h: file format changed from Apple to UNIX, as MSVC does not supported the former.
(NOT error related, just improvement on previous commit; manual/getopt/README.md: added link to source article)
2018-05-01 19:14:44 +02:00
|
|
|
|
#else
|
|
|
|
|
// MSVC does not support VLA. Replace with std::vector. If profiling determines that the
|
|
|
|
|
// heap allocation is slow, an optimization might be used.
|
|
|
|
|
std::vector<char> vEnhMetaFileBits(size);
|
|
|
|
|
char* enhMetaFileBits = vEnhMetaFileBits.data();
|
|
|
|
|
#endif
|
2012-09-29 16:46:45 +02:00
|
|
|
|
cap->read(enhMetaFileBits, size);
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("MetaFileObj::read %d bytes", size);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// RectEllipseObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void RectEllipseObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
LineObj::read();
|
|
|
|
|
radius = cap->readInt();
|
|
|
|
|
bFilled = cap->readByte();
|
|
|
|
|
clrFill = cap->readColor();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// PolygonObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void PolygonObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicDrawObj::read();
|
|
|
|
|
|
|
|
|
|
unsigned nPoints = cap->readUnsigned();
|
|
|
|
|
for (unsigned i = 0; i < nPoints; ++i)
|
2013-04-12 22:40:45 +02:00
|
|
|
|
cap->readPoint();
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
|
|
|
|
bFilled = cap->readByte();
|
|
|
|
|
lineWidth = cap->readByte();
|
|
|
|
|
clrFill = cap->readColor();
|
|
|
|
|
clrLine = cap->readColor();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// WavyLineObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void WavyLineObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
LineObj::read();
|
|
|
|
|
waveLen = cap->readByte();
|
|
|
|
|
adapt = cap->readByte();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// NotelinesObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void NotelinesObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicDrawObj::read();
|
|
|
|
|
|
|
|
|
|
x0 = cap->readInt();
|
|
|
|
|
x1 = cap->readInt();
|
|
|
|
|
y = cap->readInt();
|
|
|
|
|
color = cap->readColor();
|
|
|
|
|
|
|
|
|
|
unsigned char b = cap->readByte();
|
|
|
|
|
switch (b) {
|
|
|
|
|
case 1: break; // Einlinienzeile
|
|
|
|
|
case 2: break; // Standard (5 Linien)
|
|
|
|
|
default: {
|
2014-03-04 13:32:32 +01:00
|
|
|
|
Q_ASSERT(b == 0);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
char lines[11];
|
|
|
|
|
cap->read(lines, 11);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2013-04-12 22:40:45 +02:00
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// VoltaObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void VoltaObj::read()
|
|
|
|
|
{
|
|
|
|
|
BasicDrawObj::read();
|
|
|
|
|
|
|
|
|
|
x0 = cap->readInt();
|
|
|
|
|
x1 = cap->readInt();
|
|
|
|
|
y = cap->readInt();
|
|
|
|
|
color = cap->readColor();
|
|
|
|
|
|
2018-09-25 15:58:05 +02:00
|
|
|
|
unsigned char f = cap->readByte();
|
|
|
|
|
bLeft = (f & 1) != 0; // links abgeknickt
|
|
|
|
|
bRight = (f & 2) != 0; // rechts abgeknickt
|
|
|
|
|
bDotted = (f & 4) != 0;
|
|
|
|
|
allNumbers = (f & 8) != 0;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
|
|
|
|
unsigned char numbers = cap->readByte();
|
|
|
|
|
from = numbers & 0x0F;
|
|
|
|
|
to = (numbers >> 4) & 0x0F;
|
2013-05-06 22:10:49 +02:00
|
|
|
|
qDebug("VoltaObj::read x0 %d x1 %d y %d bLeft %d bRight %d bDotted %d allNumbers %d from %d to %d",
|
|
|
|
|
x0, x1, y, bLeft, bRight, bDotted, allNumbers, from, to);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// GuitarObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void GuitarObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicDrawObj::read();
|
|
|
|
|
relPos = cap->readPoint();
|
|
|
|
|
color = cap->readColor();
|
|
|
|
|
flags = cap->readWord();
|
|
|
|
|
strings = cap->readDWord(); // 8 Saiten in 8 Halbbytes
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// TrillObj::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void TrillObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicDrawObj::read();
|
|
|
|
|
x0 = cap->readInt();
|
|
|
|
|
x1 = cap->readInt();
|
|
|
|
|
y = cap->readInt();
|
|
|
|
|
color = cap->readColor();
|
|
|
|
|
trillSign = cap->readByte();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// readDrawObjectArray
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
QList<BasicDrawObj*> Capella::readDrawObjectArray()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
QList<BasicDrawObj*> ol;
|
|
|
|
|
int n = readUnsigned(); // draw obj array
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("readDrawObjectArray %d elements", n);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
for (int i = 0; i < n; ++i) {
|
2014-06-30 11:58:12 +02:00
|
|
|
|
CapellaType type = CapellaType(readByte());
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug(" readDrawObject %d of %d, type %d", i, n, type);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
switch (type) {
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::GROUP: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
GroupObj* o = new GroupObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::TRANSPOSABLE: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
TransposableObj* o = new TransposableObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::METAFILE: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
MetafileObj* o = new MetafileObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::SIMPLE_TEXT: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
SimpleTextObj* o = new SimpleTextObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::TEXT: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
TextObj* o = new TextObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::RECT_ELLIPSE: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
RectEllipseObj* o = new RectEllipseObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::LINE: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
LineObj* o = new LineObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::POLYGON: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
PolygonObj* o = new PolygonObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::WAVY_LINE: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
WavyLineObj* o = new WavyLineObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::SLUR: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
SlurObj* o = new SlurObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::NOTE_LINES: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
NotelinesObj* o = new NotelinesObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::WEDGE: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
WedgeObj* o = new WedgeObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::VOLTA: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
VoltaObj* o = new VoltaObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::BRACKET: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BracketObj* o = new BracketObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::GUITAR: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
GuitarObj* o = new GuitarObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-06-30 11:58:12 +02:00
|
|
|
|
case CapellaType::TRILL: {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
TrillObj* o = new TrillObj(this);
|
|
|
|
|
o->read();
|
|
|
|
|
ol.append(o);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2016-02-11 23:57:06 +01:00
|
|
|
|
qFatal("readDrawObjectArray unsupported type %d", int(type));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
return ol;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// BasicDrawObj
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void BasicDrawObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
modeX = cap->readByte(); // anchor mode
|
|
|
|
|
modeY = cap->readByte();
|
|
|
|
|
distY = cap->readByte();
|
|
|
|
|
flags = cap->readByte();
|
|
|
|
|
nRefNote = cap->readInt();
|
|
|
|
|
short range = cap->readWord();
|
|
|
|
|
nNotes = range & 0x0fff;
|
|
|
|
|
background = range & 0x1000;
|
|
|
|
|
pageRange = (range >> 13) & 0x7;
|
2013-05-06 22:10:49 +02:00
|
|
|
|
qDebug("BasicDrawObj::read modeX %d modeY %d distY %d flags %d nRefNote %d nNotes %d background %d pageRange %d",
|
|
|
|
|
modeX, modeY, distY, flags, nRefNote, nNotes, background, pageRange);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// BasicRectObj
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void BasicRectObj::read()
|
|
|
|
|
{
|
|
|
|
|
BasicDrawObj::read();
|
|
|
|
|
relPos = cap->readPoint();
|
|
|
|
|
width = cap->readInt();
|
|
|
|
|
yxRatio = cap->readInt();
|
|
|
|
|
height = (width * yxRatio) / 0x10000;
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// read
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void BasicDurationalObj::read()
|
|
|
|
|
{
|
|
|
|
|
unsigned char b = cap->readByte();
|
|
|
|
|
nDots = b & 0x03;
|
|
|
|
|
noDuration = b & 0x04;
|
|
|
|
|
postGrace = b & 0x08;
|
|
|
|
|
bSmall = b & 0x10;
|
|
|
|
|
invisible = b & 0x20;
|
|
|
|
|
notBlack = b & 0x40;
|
2014-03-04 13:06:23 +01:00
|
|
|
|
Q_ASSERT(!(b & 0x80));
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
color = notBlack ? cap->readColor() : Qt::black;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
unsigned char c = cap->readByte();
|
|
|
|
|
t = TIMESTEP(c & 0x0f);
|
|
|
|
|
horizontalShift = (c & 0x10) ? cap->readInt() : 0;
|
|
|
|
|
count = 0;
|
2013-04-12 22:40:45 +02:00
|
|
|
|
tripartite = 0;
|
|
|
|
|
isProlonging = 0;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (c & 0x20) {
|
|
|
|
|
unsigned char tuplet = cap->readByte();
|
|
|
|
|
count = tuplet & 0x0f;
|
|
|
|
|
tripartite = (tuplet & 0x10) != 0;
|
|
|
|
|
isProlonging = (tuplet & 0x20) != 0;
|
|
|
|
|
if (tuplet & 0xc0)
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("bad tuplet value 0x%02x", tuplet);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (c & 0x40) {
|
|
|
|
|
objects = cap->readDrawObjectArray();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2014-03-04 13:06:23 +01:00
|
|
|
|
Q_ASSERT(!(c & 0x80));
|
2016-02-11 23:57:06 +01:00
|
|
|
|
qDebug("DurationObj ndots %d nodur %d postgr %d bsm %d inv %d notbl %d t %d hsh %d cnt %d trp %d ispro %d",
|
2016-02-04 08:24:18 +01:00
|
|
|
|
nDots, noDuration, postGrace, bSmall, invisible, notBlack, int(t), horizontalShift, count, tripartite, isProlonging
|
2013-04-12 22:40:45 +02:00
|
|
|
|
);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// RestObj
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
RestObj::RestObj(Capella* c)
|
2014-05-26 18:18:45 +02:00
|
|
|
|
: BasicDurationalObj(c), NoteObj(CapellaNoteObjectType::REST)
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
cap = c;
|
|
|
|
|
fullMeasures = 0;
|
|
|
|
|
vertShift = 0;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void RestObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicDurationalObj::read();
|
|
|
|
|
unsigned char b = cap->readByte();
|
|
|
|
|
bool bMultiMeasures = b & 1;
|
|
|
|
|
bVerticalCentered = b & 2;
|
|
|
|
|
bool bAddVerticalShift = b & 4;
|
2014-03-04 13:06:23 +01:00
|
|
|
|
if (b & 0xf8)
|
|
|
|
|
qFatal("RestObj: res. bits 0x%02x", b);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
fullMeasures = bMultiMeasures ? cap->readUnsigned() : 0;
|
|
|
|
|
vertShift = bAddVerticalShift ? cap->readInt() : 0;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// ChordObj
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
ChordObj::ChordObj(Capella* c)
|
2014-05-26 18:18:45 +02:00
|
|
|
|
: BasicDurationalObj(c), NoteObj(CapellaNoteObjectType::CHORD)
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
cap = c;
|
2014-06-30 10:00:42 +02:00
|
|
|
|
beamMode = BeamMode::AUTO;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// read
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void ChordObj::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2014-06-30 12:08:23 +02:00
|
|
|
|
stemDir = StemDir::AUTO;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
dStemLength = 0;
|
|
|
|
|
nTremoloBars = 0;
|
|
|
|
|
articulation = 0;
|
|
|
|
|
leftTie = false;
|
|
|
|
|
rightTie = false;
|
|
|
|
|
beamShift = 0;
|
|
|
|
|
beamSlope = 0;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
BasicDurationalObj::read();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
unsigned char flags = cap->readByte();
|
2014-06-30 10:00:42 +02:00
|
|
|
|
beamMode = (flags & 0x01) ? BeamMode(cap->readByte()) : BeamMode::AUTO;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
notationStave = (flags & 0x02) ? cap->readChar() : 0;
|
2014-03-04 13:32:32 +01:00
|
|
|
|
Q_ASSERT(notationStave >= -1 && notationStave <= 1);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (flags & 0x04) {
|
2014-06-30 12:08:23 +02:00
|
|
|
|
stemDir = StemDir(cap->readChar());
|
2012-09-29 16:46:45 +02:00
|
|
|
|
dStemLength = cap->readChar();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (flags & 0x08) {
|
|
|
|
|
nTremoloBars = cap->readByte();
|
|
|
|
|
articulation = cap->readByte();
|
|
|
|
|
}
|
|
|
|
|
if (flags & 0x10) {
|
|
|
|
|
unsigned char b = cap->readByte();
|
|
|
|
|
leftTie = b & 1;
|
|
|
|
|
rightTie = b & 2;
|
|
|
|
|
}
|
|
|
|
|
if (flags & 0x20) {
|
|
|
|
|
beamShift = cap->readChar();
|
|
|
|
|
beamSlope = cap->readChar();
|
|
|
|
|
}
|
|
|
|
|
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)
|
2013-05-04 14:24:01 +02:00
|
|
|
|
v.verseNumber = cap->readQString();
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (b & 16)
|
2013-05-04 14:24:01 +02:00
|
|
|
|
v.text = cap->readQString();
|
2012-09-29 16:46:45 +02:00
|
|
|
|
verse.append(v);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
unsigned nNotes = cap->readUnsigned();
|
|
|
|
|
for (unsigned int i = 0; i < nNotes; ++i) {
|
|
|
|
|
CNote n;
|
|
|
|
|
n.explAlteration = 0;
|
|
|
|
|
char c = cap->readChar();
|
|
|
|
|
bool bit7 = c & 0x80;
|
|
|
|
|
bool bit6 = c & 0x40;
|
2016-03-23 23:16:40 +01:00
|
|
|
|
n.pitch = (signed char) c;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (bit7 != bit6) {
|
|
|
|
|
n.explAlteration = 2;
|
|
|
|
|
n.pitch ^= 0x80;
|
|
|
|
|
}
|
|
|
|
|
unsigned char b = cap->readByte();
|
|
|
|
|
n.headType = b & 7;
|
|
|
|
|
n.alteration = ((b >> 3) & 7) - 2; // -2 -- +2
|
|
|
|
|
if (b & 0x40)
|
|
|
|
|
n.explAlteration = 1;
|
|
|
|
|
n.silent = b & 0x80;
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("ChordObj::read() note pitch %d explAlt %d head %d alt %d silent %d",
|
|
|
|
|
n.pitch, n.explAlteration, n.headType, n.alteration, n.silent);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
notes.append(n);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// read
|
|
|
|
|
// return false on error
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2016-09-14 12:08:14 +02:00
|
|
|
|
bool Capella::read(void* p, qint64 len)
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
if (len == 0)
|
2016-09-14 12:08:14 +02:00
|
|
|
|
return true;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
qint64 rv = f->read((char*)p, len);
|
|
|
|
|
if (rv != len)
|
2016-09-14 12:08:14 +02:00
|
|
|
|
return false;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
curPos += len;
|
2016-09-14 12:08:14 +02:00
|
|
|
|
return true;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// readByte
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
unsigned char Capella::readByte()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
unsigned char c;
|
|
|
|
|
read(&c, 1);
|
|
|
|
|
return c;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// readChar
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
char Capella::readChar()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
char c;
|
|
|
|
|
read(&c, 1);
|
|
|
|
|
return c;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// readWord
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
short Capella::readWord()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
short c;
|
|
|
|
|
read(&c, 2);
|
|
|
|
|
return c;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// readDWord
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int Capella::readDWord()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int c;
|
|
|
|
|
read(&c, 4);
|
|
|
|
|
return c;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// readLong
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int Capella::readLong()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int c;
|
|
|
|
|
read(&c, 4);
|
|
|
|
|
return c;
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// readUnsigned
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
unsigned Capella::readUnsigned()
|
|
|
|
|
{
|
|
|
|
|
unsigned char c;
|
|
|
|
|
read(&c, 1);
|
|
|
|
|
if (c == 254) {
|
|
|
|
|
unsigned short s;
|
|
|
|
|
read(&s, 2);
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
else if (c == 255) {
|
|
|
|
|
unsigned s;
|
|
|
|
|
read(&s, 4);
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return c;
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// readInt
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int Capella::readInt()
|
|
|
|
|
{
|
2016-03-23 07:56:50 +01:00
|
|
|
|
signed char c;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
read(&c, 1);
|
|
|
|
|
if (c == -128) {
|
|
|
|
|
short s;
|
|
|
|
|
read(&s, 2);
|
|
|
|
|
return s;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
else if (c == 127) {
|
|
|
|
|
int s;
|
|
|
|
|
read(&s, 4);
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return c;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2013-05-04 14:24:01 +02:00
|
|
|
|
// readString -- read Capella string into newly allocated char buffer
|
|
|
|
|
// note that no carriage return / newline interpretation is done
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
char* Capella::readString()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
unsigned len = readUnsigned();
|
|
|
|
|
char* buffer = new char[len + 1];
|
|
|
|
|
read(buffer, len);
|
|
|
|
|
buffer[len] = 0;
|
|
|
|
|
return buffer;
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-05-04 14:24:01 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// readQString -- read Capella string into QString
|
|
|
|
|
// strings in Capella files may contain \r\n, must remove the \r
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
QString Capella::readQString()
|
|
|
|
|
{
|
2015-01-19 20:33:40 +01:00
|
|
|
|
char* buffer = readString(); // read Capella string
|
|
|
|
|
QString res = QString::fromLatin1(buffer); // and copy into QString
|
|
|
|
|
res = res.remove(QChar('\r')); // remove the \r
|
|
|
|
|
delete [] buffer; // delete memory allocated by readString
|
2013-05-04 14:24:01 +02:00
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// readColor
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
QColor Capella::readColor()
|
|
|
|
|
{
|
|
|
|
|
static const int colors[] = {
|
|
|
|
|
0x000000, // schwarz
|
|
|
|
|
0x000080, // dunkelrot
|
|
|
|
|
0x008000, // dunkelgrün
|
|
|
|
|
0x008080, // ocker
|
|
|
|
|
0x800000, // dunkelblau
|
|
|
|
|
0x800080, // purpurrot
|
|
|
|
|
0x808000, // blaugün
|
|
|
|
|
0x808080, // grau
|
|
|
|
|
0xC0C0C0, // hellgrau
|
|
|
|
|
0x0000FF, // rot
|
|
|
|
|
0x00FF00, // grün
|
|
|
|
|
0x00FFFF, // gelb
|
|
|
|
|
0xFF0000, // blau
|
|
|
|
|
0xFF00FF, // lila
|
|
|
|
|
0xFFFF00, // aquamarin
|
|
|
|
|
0xFFFFFF // weiß
|
|
|
|
|
};
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
QColor c;
|
|
|
|
|
unsigned char b = readByte();
|
|
|
|
|
if (b >= 16) {
|
2014-03-04 13:32:32 +01:00
|
|
|
|
Q_ASSERT(b == 255);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int r = readByte();
|
|
|
|
|
int g = readByte();
|
2018-09-25 15:55:08 +02:00
|
|
|
|
int bi = readByte();
|
|
|
|
|
c = QColor(r, g, bi);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
c = QColor(colors[b]);
|
|
|
|
|
}
|
|
|
|
|
return c;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// readFont
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
QFont Capella::readFont()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int index = readUnsigned();
|
|
|
|
|
if (index == 0) {
|
|
|
|
|
int lfHeight = readLong();
|
|
|
|
|
/*int lfWidth =*/ readLong();
|
|
|
|
|
/*int lfEscapement =*/ readLong();
|
|
|
|
|
/*int lfOrientation =*/ readLong();
|
|
|
|
|
int lfWeight = readLong();
|
|
|
|
|
uchar lfItalic = readByte();
|
|
|
|
|
uchar lfUnderline = readByte();
|
|
|
|
|
uchar lfStrikeOut = readByte();
|
|
|
|
|
/*uchar lfCharSet =*/ readByte();
|
|
|
|
|
/*uchar lfOutPrecision =*/ readByte();
|
|
|
|
|
/*uchar lfClipPrecision =*/ readByte();
|
|
|
|
|
/*uchar lfQuality =*/ readByte();
|
|
|
|
|
/*uchar lfPitchAndFamily =*/ readByte();
|
|
|
|
|
/*QColor color =*/ readColor();
|
2015-01-19 20:33:40 +01:00
|
|
|
|
QString face = readQString();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2015-01-19 20:33:40 +01:00
|
|
|
|
qDebug("Font <%s> size %d, weight %d", qPrintable(face), lfHeight, lfWeight);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
QFont font(face);
|
|
|
|
|
font.setPointSizeF(lfHeight / 1000.0);
|
|
|
|
|
font.setItalic(lfItalic);
|
|
|
|
|
font.setStrikeOut(lfStrikeOut);
|
|
|
|
|
font.setUnderline(lfUnderline);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
switch (lfWeight) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
case 700: font.setWeight(QFont::Bold); break;
|
|
|
|
|
case 400: font.setWeight(QFont::Normal); break;
|
|
|
|
|
case 0: font.setWeight(QFont::Light); break;
|
|
|
|
|
}
|
|
|
|
|
fonts.append(font);
|
|
|
|
|
return font;
|
|
|
|
|
}
|
|
|
|
|
index -= 1;
|
|
|
|
|
if (index >= fonts.size()) {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("illegal font index %d (max %d)", index, fonts.size()-1);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
return fonts[index];
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// readStaveLayout
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
void Capella::readStaveLayout(CapStaffLayout* sl, int idx)
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
sl->barlineMode = readByte();
|
|
|
|
|
sl->noteLines = readByte();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
switch (sl->noteLines) {
|
2012-09-29 16:46:45 +02:00
|
|
|
|
case 1: break; // one line
|
|
|
|
|
case 2: break; // five lines
|
2012-05-26 14:49:10 +02:00
|
|
|
|
default:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
char lines[11];
|
|
|
|
|
f->read(lines, 11);
|
|
|
|
|
curPos += 11;
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
2013-05-04 14:24:01 +02:00
|
|
|
|
qDebug("StaffLayout %d: barlineMode %d noteLines %d", idx, sl->barlineMode, sl->noteLines);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
sl->bSmall = readByte();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("staff size small %d", sl->bSmall);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
sl->topDist = readInt();
|
|
|
|
|
sl->btmDist = readInt();
|
|
|
|
|
sl->groupDist = readInt();
|
|
|
|
|
sl->barlineFrom = readByte();
|
|
|
|
|
sl->barlineTo = readByte();
|
2013-05-04 14:24:01 +02:00
|
|
|
|
// qDebug("topDist %d btmDist %d groupDist %d barlineFrom %d barlineTo %d",
|
|
|
|
|
// sl->topDist, sl->btmDist, sl->groupDist, sl->barlineFrom, sl->barlineTo);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
|
|
|
|
unsigned char clef = readByte();
|
2014-06-30 10:19:58 +02:00
|
|
|
|
sl->form = Form(clef & 7);
|
2014-06-30 10:34:28 +02:00
|
|
|
|
sl->line = ClefLine((clef >> 3) & 7);
|
2014-06-30 10:41:21 +02:00
|
|
|
|
sl->oct = Oct((clef >> 6));
|
2016-02-11 23:57:06 +01:00
|
|
|
|
qDebug(" clef %x form %d, line %d, oct %d", clef, int(sl->form), int(sl->line), int(sl->oct));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// Schlagzeuginformation
|
2012-09-29 16:46:45 +02:00
|
|
|
|
unsigned char b = readByte();
|
|
|
|
|
sl->bPercussion = b & 1; // Schlagzeugkanal verwenden
|
|
|
|
|
sl->bSoundMapIn = b & 2;
|
|
|
|
|
sl->bSoundMapOut = b & 4;
|
|
|
|
|
if (sl->bSoundMapIn) { // Umleitungstabelle für Eingabe vom Keyboard
|
|
|
|
|
uchar iMin = readByte();
|
|
|
|
|
Q_UNUSED(iMin);
|
|
|
|
|
uchar n = readByte();
|
Solved all compilation errors on MSVC
This commit contains changes required for MuseScore to compile under MSVC with no errors.
There are several general categories of problems that resulted in errors with the compilation. Main issues:
- Variable Length Arrays (VLA). This is a non-standard extension to C++, supported by clang toolchains, but not by MSVC. The initial workaround is to use std::vector<> instead of VLAs, eventually (if needed) with the original variable pointing to the beginning of the allocated array. More efficient alternatives are possible if profiling shows any code using VLAs to be timing-critical.
- Floating-point constants not suffixed with "f" are doubles by default; in some instances, this leads to narrowing conversion errors (in other instances, just warnings).
- MSVC does not support "or"/"and"/"not" in lieu of "||"/"&&"/"!". Changed unconditionally to use standard C++ symbols.
- MSVC does not support the "__builtin_unreachable()" compiler hint. A similar, albeit not exactly equal, alternative is "__assume(0)", which is MSVC-specific.
- MSVC does not support ranges in case statements. Replaced with list of cases instead of range (non-conditionally)
Detailed changes, with per-file comments:
- all.h: opt-in to deprecated features, include <io.h> and <process.h> instead of POSIX <unistd.h>, undefine "STRING_NONE" and "small", which Microsoft defines as macros, which result in compilation errors.
- effects/compressor/zita.cpp: eliminated narrowing conversion error by appending "f" to float constants.
- fluid/voice.cpp: appended "f" to float constants to eliminate narrowing conversion errors/warnings
- libmscore/beam.cpp: conditionally replaced VLA
- libmscore/edit.cpp: conditionally replaced VLA
- libmscore/element.cpp: appended "f" to float constant
- libmscore/fret.cpp: changed or -> ||
- libmscore/layout.cpp: conditionally replaced VLA
- libmscore/mscore.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- libmscore/scorefile.coo: use correct char representation conversion for MSVC
- libmscore/stringdata.cpp: conditionally replaced VLA
- libmscore/system.cpp: conditionally replaced VLA
- libmscroe/text.cpp: replaced range in case statement.
- manual/genManual.cpp: use getopt() replacement.
- midi/midifile.cpp: conditionally replaced VLA. This does not use the default replacement.
- mscore/bb.cpp: replaced range in case statement.
- mscore/capella.cpp: conditionally replaced VLA. Changed and -> &&
- mscore/driver:cpp: preclude errors due to macro redefinitions.
- mscore/editstyle.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- mscore/importgtp-gp6.cpp: conditionally replaced VLA.
- mscore/instrwidget.cpp: conditionally replaced VLA.
- mscore/jackaudio.cpp: conditionally replaced VLA. Preclude errors due to macro redefinitions.
- mscore/jackweakapi.cpp: Preclude errors due to macro redefinitions. Replacement for __atribute__((constructor)) through static object construction for MSVC. Force use of LoadLibraryA instead of LoadLibrary.
- mscore/mididriver.h: Changed not -> !
- mscore/musescore.cpp: Changed not -> !. Conditionally replaced VLA.
- mscore/resourceManager.cpp: conditionally replaced VLA.
- mscore/timeline.cpp: conditionally replaced VLA.
- omr/omrpage.cpp: conditionally replaced VLA.
- synthesizer/msynthesizer.cpp: replaced UNIX sleep(1) method with MSVC Sleep(1000) (equivalent, but in ms instead of seconds)
- synthesizer/msynthsizer.h: appended "f" to float constant
- thirdparty/poppler/config.h: set defines for MSVC to preclude the use of inexistent libraries.
- thirdparty/poppler/poppler/poppler-config.h: set defines for MSVC to preclude the use of inexistent libraries. Eliminated #defines for fmin and fmax which where causing problems.
- thirdparty/poppler/poppler/PSOutputDev.cc: added #include <algorithm> for std::min() and std::max(). Note this is required per-C++ standard.
- thirdparty/portmidi/pm_win/pmwinmm.c: undefined UNICODE to use char-based library functions.
- thirdparty/qzip/qzip.cpp: changed or -> ||
- thirdparty/rtf2html/rtf_keyword.h: file format changed from Apple to UNIX, as MSVC does not supported the former.
(NOT error related, just improvement on previous commit; manual/getopt/README.md: added link to source article)
2018-05-01 19:14:44 +02:00
|
|
|
|
Q_ASSERT (n > 0 && iMin + n <= 128);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
f->read(sl->soundMapIn, n);
|
|
|
|
|
curPos += n;
|
|
|
|
|
}
|
|
|
|
|
if (sl->bSoundMapOut) { // Umleitungstabelle für das Vorspielen
|
|
|
|
|
unsigned char iMin = readByte();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
Q_UNUSED(iMin);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
unsigned char n = readByte();
|
Solved all compilation errors on MSVC
This commit contains changes required for MuseScore to compile under MSVC with no errors.
There are several general categories of problems that resulted in errors with the compilation. Main issues:
- Variable Length Arrays (VLA). This is a non-standard extension to C++, supported by clang toolchains, but not by MSVC. The initial workaround is to use std::vector<> instead of VLAs, eventually (if needed) with the original variable pointing to the beginning of the allocated array. More efficient alternatives are possible if profiling shows any code using VLAs to be timing-critical.
- Floating-point constants not suffixed with "f" are doubles by default; in some instances, this leads to narrowing conversion errors (in other instances, just warnings).
- MSVC does not support "or"/"and"/"not" in lieu of "||"/"&&"/"!". Changed unconditionally to use standard C++ symbols.
- MSVC does not support the "__builtin_unreachable()" compiler hint. A similar, albeit not exactly equal, alternative is "__assume(0)", which is MSVC-specific.
- MSVC does not support ranges in case statements. Replaced with list of cases instead of range (non-conditionally)
Detailed changes, with per-file comments:
- all.h: opt-in to deprecated features, include <io.h> and <process.h> instead of POSIX <unistd.h>, undefine "STRING_NONE" and "small", which Microsoft defines as macros, which result in compilation errors.
- effects/compressor/zita.cpp: eliminated narrowing conversion error by appending "f" to float constants.
- fluid/voice.cpp: appended "f" to float constants to eliminate narrowing conversion errors/warnings
- libmscore/beam.cpp: conditionally replaced VLA
- libmscore/edit.cpp: conditionally replaced VLA
- libmscore/element.cpp: appended "f" to float constant
- libmscore/fret.cpp: changed or -> ||
- libmscore/layout.cpp: conditionally replaced VLA
- libmscore/mscore.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- libmscore/scorefile.coo: use correct char representation conversion for MSVC
- libmscore/stringdata.cpp: conditionally replaced VLA
- libmscore/system.cpp: conditionally replaced VLA
- libmscroe/text.cpp: replaced range in case statement.
- manual/genManual.cpp: use getopt() replacement.
- midi/midifile.cpp: conditionally replaced VLA. This does not use the default replacement.
- mscore/bb.cpp: replaced range in case statement.
- mscore/capella.cpp: conditionally replaced VLA. Changed and -> &&
- mscore/driver:cpp: preclude errors due to macro redefinitions.
- mscore/editstyle.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- mscore/importgtp-gp6.cpp: conditionally replaced VLA.
- mscore/instrwidget.cpp: conditionally replaced VLA.
- mscore/jackaudio.cpp: conditionally replaced VLA. Preclude errors due to macro redefinitions.
- mscore/jackweakapi.cpp: Preclude errors due to macro redefinitions. Replacement for __atribute__((constructor)) through static object construction for MSVC. Force use of LoadLibraryA instead of LoadLibrary.
- mscore/mididriver.h: Changed not -> !
- mscore/musescore.cpp: Changed not -> !. Conditionally replaced VLA.
- mscore/resourceManager.cpp: conditionally replaced VLA.
- mscore/timeline.cpp: conditionally replaced VLA.
- omr/omrpage.cpp: conditionally replaced VLA.
- synthesizer/msynthesizer.cpp: replaced UNIX sleep(1) method with MSVC Sleep(1000) (equivalent, but in ms instead of seconds)
- synthesizer/msynthsizer.h: appended "f" to float constant
- thirdparty/poppler/config.h: set defines for MSVC to preclude the use of inexistent libraries.
- thirdparty/poppler/poppler/poppler-config.h: set defines for MSVC to preclude the use of inexistent libraries. Eliminated #defines for fmin and fmax which where causing problems.
- thirdparty/poppler/poppler/PSOutputDev.cc: added #include <algorithm> for std::min() and std::max(). Note this is required per-C++ standard.
- thirdparty/portmidi/pm_win/pmwinmm.c: undefined UNICODE to use char-based library functions.
- thirdparty/qzip/qzip.cpp: changed or -> ||
- thirdparty/rtf2html/rtf_keyword.h: file format changed from Apple to UNIX, as MSVC does not supported the former.
(NOT error related, just improvement on previous commit; manual/getopt/README.md: added link to source article)
2018-05-01 19:14:44 +02:00
|
|
|
|
Q_ASSERT (n > 0 && iMin + n <= 128);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
f->read(sl->soundMapOut, n);
|
|
|
|
|
curPos += n;
|
|
|
|
|
}
|
|
|
|
|
sl->sound = readInt();
|
|
|
|
|
sl->volume = readInt();
|
|
|
|
|
sl->transp = readInt();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" sound %d vol %d transp %d", sl->sound, sl->volume, sl->transp);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
2013-05-04 14:24:01 +02:00
|
|
|
|
sl->descr = readQString();
|
|
|
|
|
sl->name = readQString();
|
|
|
|
|
sl->abbrev = readQString();
|
|
|
|
|
sl->intermediateName = readQString();
|
|
|
|
|
sl->intermediateAbbrev = readQString();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" descr <%s> name <%s> abbrev <%s> iname <%s> iabrev <%s>",
|
2013-05-04 14:24:01 +02:00
|
|
|
|
qPrintable(sl->descr), qPrintable(sl->name), qPrintable(sl->abbrev),
|
|
|
|
|
qPrintable(sl->intermediateName), qPrintable(sl->intermediateAbbrev));
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// readLayout
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void Capella::readLayout()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
smallLineDist = double(readInt()) / 100;
|
|
|
|
|
normalLineDist = double(readInt()) / 100;
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("Capella::readLayout(): smallLineDist %g normalLineDist %g", smallLineDist, normalLineDist);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
topDist = readInt();
|
|
|
|
|
interDist = readInt();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("Capella::readLayout(): topDist %d", topDist);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
txtAlign = readByte(); // Stimmenbezeichnungen 0=links, 1=zentriert, 2=rechts
|
|
|
|
|
adjustVert = readByte(); // 0=nein, 1=au<61>er letzte Seite, 3=alle Seiten
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
unsigned char b = readByte();
|
|
|
|
|
redundantKeys = b & 1;
|
|
|
|
|
modernDoubleNote = b & 2;
|
2014-03-04 13:32:32 +01:00
|
|
|
|
Q_ASSERT((b & 0xFC) == 0); // bits 2...7 reserviert
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
bSystemSeparators = readByte();
|
|
|
|
|
nUnnamed = readInt();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
namesFont = readFont();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// Musterzeilen
|
|
|
|
|
unsigned nStaveLayouts = readUnsigned();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("%d staves", nStaveLayouts);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
for (unsigned iStave = 0; iStave < nStaveLayouts; iStave++) {
|
|
|
|
|
CapStaffLayout* sl = new CapStaffLayout;
|
|
|
|
|
readStaveLayout(sl, iStave);
|
|
|
|
|
_staffLayouts.append(sl);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// system brackets:
|
|
|
|
|
unsigned n = readUnsigned(); // number of brackets
|
|
|
|
|
for (unsigned int i = 0; i < n; i++) {
|
2018-09-25 15:55:08 +02:00
|
|
|
|
CapBracket cb;
|
|
|
|
|
cb.from = readInt();
|
|
|
|
|
cb.to = readInt();
|
|
|
|
|
cb.curly = readByte();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("Bracket%d %d-%d curly %d", i, b.from, b.to, b.curly);
|
2018-09-25 15:55:08 +02:00
|
|
|
|
brackets.append(cb);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2013-04-29 17:22:24 +02:00
|
|
|
|
// qDebug("Capella::readLayout(): done");
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// readExtra
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void Capella::readExtra()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
uchar n = readByte();
|
|
|
|
|
if (n) {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("Capella::readExtra(%d)", n);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
for (int i = 0; i < n; ++i)
|
|
|
|
|
readByte();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// CapClef::read
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void CapClef::read()
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
unsigned char b = cap->readByte();
|
2014-06-30 10:19:58 +02:00
|
|
|
|
form = Form(b & 7);
|
2014-06-30 10:34:28 +02:00
|
|
|
|
line = ClefLine((b >> 3) & 7);
|
2014-06-30 10:41:21 +02:00
|
|
|
|
oct = Oct(b >> 6);
|
2016-02-11 23:57:06 +01:00
|
|
|
|
qDebug("Clef::read form %d line %d oct %d", int(form), int(line), int(oct));
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// clef
|
2012-05-26 14:49:10 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
ClefType CapClef::clef() const
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2012-09-29 16:46:45 +02:00
|
|
|
|
return clefType(form, line, oct);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2014-06-30 10:41:21 +02:00
|
|
|
|
ClefType CapClef::clefType(Form form, ClefLine line, Oct oct)
|
2012-05-26 14:49:10 +02:00
|
|
|
|
{
|
2014-06-30 10:41:21 +02:00
|
|
|
|
int idx = int(form) + (int(line) << 3) + (int(oct) << 5);
|
2013-04-12 22:40:45 +02:00
|
|
|
|
switch (idx) {
|
2014-06-30 10:41:21 +02:00
|
|
|
|
case int(Form::G) + (int(ClefLine::L2) << 3) + (int(Oct::OCT_NULL) << 5): return ClefType::G;
|
2016-09-28 20:34:21 +02:00
|
|
|
|
case int(Form::G) + (int(ClefLine::L2) << 3) + (int(Oct::OCT_ALTA) << 5): return ClefType::G8_VA;
|
|
|
|
|
case int(Form::G) + (int(ClefLine::L2) << 3) + (int(Oct::OCT_BASSA) << 5): return ClefType::G8_VB;
|
2014-06-30 10:41:21 +02:00
|
|
|
|
|
|
|
|
|
case int(Form::C) + (int(ClefLine::L1) << 3) + (int(Oct::OCT_NULL) << 5): return ClefType::C1;
|
|
|
|
|
case int(Form::C) + (int(ClefLine::L2) << 3) + (int(Oct::OCT_NULL) << 5): return ClefType::C2;
|
|
|
|
|
case int(Form::C) + (int(ClefLine::L3) << 3) + (int(Oct::OCT_NULL) << 5): return ClefType::C3;
|
|
|
|
|
case int(Form::C) + (int(ClefLine::L4) << 3) + (int(Oct::OCT_NULL) << 5): return ClefType::C4;
|
|
|
|
|
case int(Form::C) + (int(ClefLine::L5) << 3) + (int(Oct::OCT_NULL) << 5): return ClefType::C5;
|
|
|
|
|
|
|
|
|
|
case int(Form::F) + (int(ClefLine::L4) << 3) + (int(Oct::OCT_NULL) << 5): return ClefType::F;
|
2016-09-28 20:34:21 +02:00
|
|
|
|
case int(Form::F) + (int(ClefLine::L4) << 3) + (int(Oct::OCT_BASSA) << 5): return ClefType::F8_VB;
|
2014-06-30 10:41:21 +02:00
|
|
|
|
case int(Form::F) + (int(ClefLine::L3) << 3) + (int(Oct::OCT_NULL) << 5): return ClefType::F_B;
|
|
|
|
|
case int(Form::F) + (int(ClefLine::L5) << 3) + (int(Oct::OCT_NULL) << 5): return ClefType::F_C;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
default:
|
2014-06-30 10:19:58 +02:00
|
|
|
|
if (form == Form::FORM_NULL)
|
2013-09-05 16:37:49 +02:00
|
|
|
|
return ClefType::INVALID;
|
2016-02-11 23:57:06 +01:00
|
|
|
|
qDebug("unknown clef %d %d %d", int(form), int(line), int(oct));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
2013-09-05 16:37:49 +02:00
|
|
|
|
return ClefType::INVALID;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// CapKey::read
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void CapKey::read()
|
|
|
|
|
{
|
|
|
|
|
unsigned char b = cap->readByte();
|
|
|
|
|
signature = int(b) - 7;
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug(" Key %d", signature);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// CapMeter::read
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void CapMeter::read()
|
|
|
|
|
{
|
|
|
|
|
numerator = cap->readByte();
|
|
|
|
|
uchar d = cap->readByte();
|
|
|
|
|
log2Denom = (d & 0x7f) - 1;
|
|
|
|
|
allaBreve = d & 0x80;
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" Meter %d/%d allaBreve %d", numerator, log2Denom, allaBreve);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (log2Denom > 7 || log2Denom < 0) {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" illegal fraction");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// abort();
|
|
|
|
|
log2Denom = 2;
|
|
|
|
|
numerator = 4;
|
|
|
|
|
}
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// read
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void WedgeObj::read()
|
|
|
|
|
{
|
|
|
|
|
LineObj::read();
|
|
|
|
|
char b = cap->readByte();
|
|
|
|
|
height = b & 0x7f;
|
|
|
|
|
decresc = b & 0x80;
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// CapExplicitBarline::read
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void CapExplicitBarline::read()
|
|
|
|
|
{
|
|
|
|
|
unsigned char b = cap->readByte();
|
2015-01-19 22:04:29 +01:00
|
|
|
|
int type = b & 0x0f;
|
|
|
|
|
if (type == 0) _type = BarLineType::NORMAL;
|
|
|
|
|
else if (type == 1) _type = BarLineType::DOUBLE;
|
|
|
|
|
else if (type == 2) _type = BarLineType::END;
|
|
|
|
|
else if (type == 3) _type = BarLineType::END_REPEAT;
|
|
|
|
|
else if (type == 4) _type = BarLineType::START_REPEAT;
|
2019-04-06 07:54:38 +02:00
|
|
|
|
else if (type == 5) _type = BarLineType::END_START_REPEAT;
|
2015-01-19 22:04:29 +01:00
|
|
|
|
else if (type == 6) _type = BarLineType::BROKEN;
|
|
|
|
|
else _type = BarLineType::NORMAL; // default
|
2012-09-29 16:46:45 +02:00
|
|
|
|
_barMode = b >> 4; // 0 = auto, 1 = nur Zeilen, 2 = durchgezogen
|
2014-03-04 13:32:32 +01:00
|
|
|
|
Q_ASSERT(_barMode <= 2);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2016-02-11 23:57:06 +01:00
|
|
|
|
qDebug(" Expl.Barline type %d mode %d", int(_type), _barMode);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// readVoice
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void Capella::readVoice(CapStaff* cs, int idx)
|
|
|
|
|
{
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" readVoice %d", idx);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (readChar() != 'C')
|
2014-06-30 12:20:12 +02:00
|
|
|
|
throw Capella::Error::BAD_VOICE_SIG;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
CapVoice* v = new CapVoice;
|
|
|
|
|
v->voiceNo = idx;
|
|
|
|
|
v->y0Lyrics = readByte();
|
|
|
|
|
v->dyLyrics = readByte();
|
|
|
|
|
v->lyricsFont = readFont();
|
|
|
|
|
v->stemDir = readByte();
|
|
|
|
|
readExtra();
|
|
|
|
|
|
|
|
|
|
unsigned nNoteObjs = readUnsigned(); // Notenobjekte
|
|
|
|
|
for (unsigned i = 0; i < nNoteObjs; i++) {
|
|
|
|
|
QColor color = Qt::black;
|
|
|
|
|
uchar type = readByte();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug(" Voice %d read object idx %d(%d) type %d", idx, i, nNoteObjs, type);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
readExtra();
|
2014-05-26 18:18:45 +02:00
|
|
|
|
if ((type != uchar(CapellaNoteObjectType::REST)) && (type != uchar(CapellaNoteObjectType::CHORD)) && (type != uchar(CapellaNoteObjectType::PAGE_BKGR)))
|
2012-09-29 16:46:45 +02:00
|
|
|
|
color = readColor();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// Die anderen Objekttypen haben eine komprimierte Farbcodierung
|
2014-05-26 18:18:45 +02:00
|
|
|
|
switch (CapellaNoteObjectType(type)) {
|
|
|
|
|
case CapellaNoteObjectType::REST:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
RestObj* rest = new RestObj(this);
|
|
|
|
|
rest->read();
|
|
|
|
|
v->objects.append(rest);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
break;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::CHORD:
|
|
|
|
|
case CapellaNoteObjectType::PAGE_BKGR:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
ChordObj* chord = new ChordObj(this);
|
|
|
|
|
chord->read();
|
|
|
|
|
v->objects.append(chord);
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
break;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::CLEF:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
CapClef* clef = new CapClef(this);
|
|
|
|
|
clef->read();
|
|
|
|
|
v->objects.append(clef);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::KEY:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
CapKey* key = new CapKey(this);
|
|
|
|
|
key->read();
|
|
|
|
|
v->objects.append(key);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::METER:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
CapMeter* meter = new CapMeter(this);
|
|
|
|
|
meter->read();
|
|
|
|
|
v->objects.append(meter);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2014-05-26 18:18:45 +02:00
|
|
|
|
case CapellaNoteObjectType::EXPL_BARLINE:
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
CapExplicitBarline* bl = new CapExplicitBarline(this);
|
|
|
|
|
bl->read();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("append Expl Barline==========");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
v->objects.append(bl);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
2014-03-04 13:06:23 +01:00
|
|
|
|
qFatal("bad voice type %d", type);
|
2013-04-12 22:40:45 +02:00
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
cs->voices.append(v);
|
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// readStaff
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
void Capella::readStaff(CapSystem* system)
|
|
|
|
|
{
|
|
|
|
|
if (readChar() != 'V')
|
2014-06-30 12:20:12 +02:00
|
|
|
|
throw Capella::Error::BAD_STAFF_SIG;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
CapStaff* staff = new CapStaff;
|
|
|
|
|
//Meter
|
|
|
|
|
staff->numerator = readByte();
|
|
|
|
|
uchar d = readByte();
|
|
|
|
|
staff->log2Denom = (d & 0x7f) - 1;
|
|
|
|
|
staff->allaBreve = d & 0x80;
|
2016-06-20 17:32:40 +02:00
|
|
|
|
qDebug(" CapStaff meter %d/%d allaBreve %d", staff->numerator, staff->log2Denom, staff->allaBreve);
|
|
|
|
|
if (staff->log2Denom > 7 || staff->log2Denom < 0) {
|
|
|
|
|
qDebug(" illegal fraction");
|
|
|
|
|
staff->log2Denom = 2;
|
|
|
|
|
staff->numerator = 4;
|
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
|
|
|
|
staff->iLayout = readByte();
|
|
|
|
|
staff->topDistX = readInt();
|
|
|
|
|
staff->btmDistX = readInt();
|
|
|
|
|
staff->color = readColor();
|
|
|
|
|
readExtra();
|
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug(" Staff iLayout %d", staff->iLayout);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
// Stimmen
|
|
|
|
|
unsigned nVoices = readUnsigned();
|
|
|
|
|
for (unsigned i = 0; i < nVoices; i++)
|
|
|
|
|
readVoice(staff, i);
|
|
|
|
|
system->staves.append(staff);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// readSystem
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void Capella::readSystem()
|
|
|
|
|
{
|
|
|
|
|
if (readChar() != 'S')
|
2014-06-30 12:20:12 +02:00
|
|
|
|
throw Capella::Error::BAD_SYSTEM_SIG;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
|
|
|
|
CapSystem* s = new CapSystem;
|
|
|
|
|
s->nAddBarCount = readInt();
|
|
|
|
|
s->bBarCountReset = readByte();
|
|
|
|
|
s->explLeftIndent = readByte();
|
|
|
|
|
|
2014-06-30 10:00:42 +02:00
|
|
|
|
s->beamMode = BeamMode(readByte());
|
2012-09-29 16:46:45 +02:00
|
|
|
|
s->tempo = readUnsigned();
|
|
|
|
|
s->color = readColor();
|
|
|
|
|
readExtra();
|
|
|
|
|
|
|
|
|
|
unsigned char b = readByte();
|
|
|
|
|
s->bJustified = b & 2;
|
|
|
|
|
s->bPageBreak = (b & 4) != 0;
|
|
|
|
|
s->instrNotation = (b >> 3) & 7;
|
|
|
|
|
|
|
|
|
|
unsigned nStaves = readUnsigned();
|
|
|
|
|
for (unsigned i = 0; i < nStaves; i++)
|
|
|
|
|
readStaff(s);
|
|
|
|
|
systems.append(s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// toTicks
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction BasicDurationalObj::ticks() const
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
if (noDuration)
|
2019-01-30 15:13:54 +01:00
|
|
|
|
return Fraction(0,1);
|
|
|
|
|
Fraction len = {0,1};
|
2012-09-29 16:46:45 +02:00
|
|
|
|
switch (t) {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
case TIMESTEP::D1: len = Fraction(1,1); break;
|
|
|
|
|
case TIMESTEP::D2: len = Fraction(1,2); break;
|
|
|
|
|
case TIMESTEP::D4: len = Fraction(1,4); break;
|
|
|
|
|
case TIMESTEP::D8: len = Fraction(1,8); break;
|
|
|
|
|
case TIMESTEP::D16: len = Fraction(1,16); break;
|
|
|
|
|
case TIMESTEP::D32: len = Fraction(1,32); break;
|
|
|
|
|
case TIMESTEP::D64: len = Fraction(1,64); break;
|
|
|
|
|
case TIMESTEP::D128: len = Fraction(1,128); break;
|
|
|
|
|
case TIMESTEP::D256: len = Fraction(1,256); break;
|
|
|
|
|
case TIMESTEP::D_BREVE: len = Fraction(2,2); break;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
default:
|
2016-02-11 23:57:06 +01:00
|
|
|
|
qDebug("BasicDurationalObj::ticks: illegal duration value %d", int(t));
|
2012-09-29 16:46:45 +02:00
|
|
|
|
break;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2019-01-30 15:13:54 +01:00
|
|
|
|
Fraction slen = len;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
int dots = nDots;
|
|
|
|
|
while (dots--) {
|
2019-01-30 15:13:54 +01:00
|
|
|
|
slen /= Fraction(2,1);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
len += slen;
|
|
|
|
|
}
|
|
|
|
|
return len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// readPoint
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
QPointF Capella::readPoint()
|
|
|
|
|
{
|
|
|
|
|
int x = readInt();
|
|
|
|
|
int y = readInt();
|
|
|
|
|
return QPointF(double(x), double(y));
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// read
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
void Capella::read(QFile* fp)
|
|
|
|
|
{
|
|
|
|
|
f = fp;
|
|
|
|
|
curPos = 0;
|
|
|
|
|
|
|
|
|
|
char signature[9];
|
|
|
|
|
read(signature, 8);
|
|
|
|
|
signature[8] = 0;
|
|
|
|
|
if (memcmp(signature, "cap3-v:", 7) != 0)
|
2014-06-30 12:20:12 +02:00
|
|
|
|
throw Capella::Error::BAD_SIG;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("read Capella file signature <%s>", signature);
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
|
|
|
|
// TODO: test for signature[7] = a-z
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
author = readString();
|
|
|
|
|
keywords = readString();
|
|
|
|
|
comment = readString();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("author <%s> keywords <%s> comment <%s>", author, keywords, comment);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
nRel = readUnsigned(); // 75
|
|
|
|
|
nAbs = readUnsigned(); // 16
|
|
|
|
|
unsigned char b = readByte();
|
|
|
|
|
bUseRealSize = b & 1;
|
|
|
|
|
bAllowCompression = b & 2;
|
|
|
|
|
bPrintLandscape = b & 16;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug(" nRel %d nAbs %d useRealSize %d compresseion %d", nRel, nAbs, bUseRealSize, bAllowCompression);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
readLayout();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
beamRelMin0 = readByte(); // basic setup for beam slope
|
|
|
|
|
beamRelMin1 = readByte();
|
|
|
|
|
beamRelMax0 = readByte();
|
|
|
|
|
beamRelMax1 = readByte();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
readExtra();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2013-04-29 17:22:24 +02:00
|
|
|
|
readDrawObjectArray(); // Galerie (gesammelte Grafikobjekte)
|
2012-09-29 16:46:45 +02:00
|
|
|
|
|
|
|
|
|
unsigned n = readUnsigned();
|
|
|
|
|
if (n) {
|
2013-04-12 22:40:45 +02:00
|
|
|
|
qDebug("Gallery objects");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
|
|
|
|
for (unsigned int i = 0; i < n; ++i) {
|
2013-04-29 17:22:24 +02:00
|
|
|
|
/*char* s =*/ readString(); // Namen der Galerie-Objekte
|
2013-04-12 22:40:45 +02:00
|
|
|
|
// qDebug("Galerie: <%s>", s);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
|
|
|
|
|
2013-04-29 17:22:24 +02:00
|
|
|
|
// qDebug("read backgroundChord");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
backgroundChord = new ChordObj(this);
|
|
|
|
|
backgroundChord->read(); // contains graphic objects on the page background
|
2013-04-29 17:22:24 +02:00
|
|
|
|
// qDebug("read backgroundChord done");
|
2012-09-29 16:46:45 +02:00
|
|
|
|
bShowBarCount = readByte(); // Taktnumerierung zeigen
|
|
|
|
|
barNumberFrame = readByte(); // 0=kein, 1=Rechteck, 2=Ellipse
|
|
|
|
|
nBarDistX = readByte();
|
|
|
|
|
nBarDistY = readByte();
|
|
|
|
|
QFont barNumFont = readFont();
|
|
|
|
|
nFirstPage = readUnsigned(); // Versatz fuer Seitenzaehlung
|
|
|
|
|
leftPageMargins = readUnsigned(); // Seitenraender
|
|
|
|
|
topPageMargins = readUnsigned();
|
|
|
|
|
rightPageMargins = readUnsigned();
|
|
|
|
|
btmPageMargins = readUnsigned();
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
unsigned nSystems = readUnsigned();
|
|
|
|
|
for (unsigned i = 0; i < nSystems; i++)
|
|
|
|
|
readSystem();
|
|
|
|
|
char esig[4];
|
|
|
|
|
read(esig, 4);
|
|
|
|
|
if (memcmp (esig, "\0\0\0\0", 4) != 0)
|
2014-06-30 12:20:12 +02:00
|
|
|
|
throw Capella::Error::BAD_SIG;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
// importCapella
|
|
|
|
|
//---------------------------------------------------------
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2016-03-11 12:18:46 +01:00
|
|
|
|
Score::FileError importCapella(MasterScore* score, const QString& name)
|
2012-09-29 16:46:45 +02:00
|
|
|
|
{
|
|
|
|
|
QFile fp(name);
|
2013-09-05 16:10:40 +02:00
|
|
|
|
if(!fp.exists())
|
2014-05-30 10:17:44 +02:00
|
|
|
|
return Score::FileError::FILE_NOT_FOUND;
|
2012-09-29 16:46:45 +02:00
|
|
|
|
if (!fp.open(QIODevice::ReadOnly))
|
2014-05-30 10:17:44 +02:00
|
|
|
|
return Score::FileError::FILE_OPEN_ERROR;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|
2012-09-29 16:46:45 +02:00
|
|
|
|
Capella cf;
|
|
|
|
|
try {
|
|
|
|
|
cf.read(&fp);
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2014-06-30 12:20:12 +02:00
|
|
|
|
catch (Capella::Error errNo) {
|
2014-02-28 11:14:43 +01:00
|
|
|
|
if (!MScore::noGui) {
|
2013-05-07 13:57:08 +02:00
|
|
|
|
QMessageBox::warning(0,
|
2017-03-28 18:54:29 +02:00
|
|
|
|
QWidget::tr("Import Capella"),
|
2017-08-14 11:48:58 +02:00
|
|
|
|
QWidget::tr("Load failed: %1").arg(cf.error(errNo)),
|
2013-05-07 13:57:08 +02:00
|
|
|
|
QString::null, QWidget::tr("Quit"), QString::null, 0, 1);
|
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
fp.close();
|
|
|
|
|
// avoid another error message box
|
2014-05-30 10:17:44 +02:00
|
|
|
|
return Score::FileError::FILE_NO_ERROR;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2012-09-29 16:46:45 +02:00
|
|
|
|
fp.close();
|
2013-04-12 22:40:45 +02:00
|
|
|
|
convertCapella(score, &cf, false);
|
2014-05-30 10:17:44 +02:00
|
|
|
|
return Score::FileError::FILE_NO_ERROR;
|
2012-05-26 14:49:10 +02:00
|
|
|
|
}
|
2013-05-13 18:49:17 +02:00
|
|
|
|
}
|
2012-05-26 14:49:10 +02:00
|
|
|
|
|