MuseScore/mscore/capella.cpp

2723 lines
111 KiB
C++
Raw Normal View History

2012-05-26 14:49:10 +02:00
//=============================================================================
// MuseScore
// Linux Music Score Editor
//
// 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"
#include "libmscore/stafftext.h"
#include "libmscore/trill.h"
#include "libmscore/arpeggio.h"
#include "libmscore/breath.h"
#include "libmscore/hairpin.h"
#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",
"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);
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
}
//---------------------------------------------------------
// addArticulationText
//---------------------------------------------------------
2016-10-06 12:21:28 +02:00
static void addArticulationText(Score* score, ChordRest* cr, int track, SymId symId)
{
Articulation* na = new Articulation(score);
na->setTrack(track);
2016-10-06 12:21:28 +02:00
na->setSymId(symId);
cr->add(na);
}
//---------------------------------------------------------
// SetCapGraceDuration
//---------------------------------------------------------
static void SetCapGraceDuration(Chord* chord,ChordObj* o)
{
2014-05-27 10:35:28 +02:00
NoteType nt = NoteType::APPOGGIATURA;
if (o->nTremoloBars > 0)
nt = NoteType::ACCIACCATURA;
((Chord*)chord)->setNoteType(nt);
if (o->t == TIMESTEP::D4) {
2014-05-27 10:35:28 +02:00
((Chord*)chord)->setNoteType(NoteType::GRACE4);
chord->setDurationType(TDuration::DurationType::V_QUARTER);
}
else if (o->t == TIMESTEP::D_BREVE)
((Chord*)chord)->setDurationType(TDuration::DurationType::V_BREVE);
else if (o->t == TIMESTEP::D1)
((Chord*)chord)->setDurationType(TDuration::DurationType::V_WHOLE);
else if (o->t == TIMESTEP::D2)
((Chord*)chord)->setDurationType(TDuration::DurationType::V_HALF);
else if (o->t == TIMESTEP::D16) {
2014-05-27 10:35:28 +02:00
((Chord*)chord)->setNoteType(NoteType::GRACE16);
chord->setDurationType(TDuration::DurationType::V_16TH);
}
else if (o->t == TIMESTEP::D32) {
2014-05-27 10:35:28 +02:00
((Chord*)chord)->setNoteType(NoteType::GRACE32);
chord->setDurationType(TDuration::DurationType::V_32ND);
}
else if (o->t == TIMESTEP::D64)
((Chord*)chord)->setDurationType(TDuration::DurationType::V_64TH);
else if (o->t == TIMESTEP::D128)
((Chord*)chord)->setDurationType(TDuration::DurationType::V_128TH);
else if (o->t == TIMESTEP::D256)
((Chord*)chord)->setDurationType(TDuration::DurationType::V_256TH);
else
((Chord*)chord)->setDurationType(TDuration::DurationType::V_EIGHTH);
}
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
//---------------------------------------------------------
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) {
switch (oo->type) {
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();
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;
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);
break;
case 'u': // fermata up
2016-10-06 12:21:28 +02:00
addArticulationText(score, cr, track, SymId::fermataAbove);
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
qDebug("Import of Capella text articulation %x(%c) not yet implemented", code, code);
break;
case 181: // caesura
{
Breath* b = new Breath(score);
b->setTrack(track);
b->setSymId(SymId::caesura);
Segment* seg = s->measure()->getSegment(SegmentType::Breath, s->tick() + (cr ? cr->actualTicks() : Fraction(0,1)));
seg->add(b);
}
break;
2012-09-29 16:46:45 +02:00
default:
break;
}
2017-01-18 14:16:33 +01:00
if (cr->type() == ElementType::CHORD)
switch (code) {
2016-10-06 12:21:28 +02:00
#if 0 // TODO-ws
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
case 172: // arpeggio (short)
case 173: // arpeggio (long)
{
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;
case 187: // arpeggio (wiggle line, arrow up)
{
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;
case 188: // arpeggio (wiggle line, arrow down)
{
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;
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());
// 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
text->setPlainText(st->text());
2012-09-29 16:46:45 +02:00
QPointF p(st->pos());
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);
text->setOffset(p);
// 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;
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;
}
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;
case CapellaType::TEXT:
qDebug("======================Text:");
2012-09-29 16:46:45 +02:00
break;
default:
break;
2012-09-29 16:46:45 +02:00
}
}
2012-05-26 14:49:10 +02:00
}
//---------------------------------------------------------
// TupletFractionCap
//---------------------------------------------------------
Fraction TupletFractionCap(int tupletCount, bool tuplettrp, bool tupletprol)
{
int dd = 0;
int nn = 0;
qreal exponent = 0;
qreal count = tupletCount;
Fraction f(3,2);
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;
dd = static_cast<int>(qPow(2.0, exponent));
if (tuplettrp)
dd = dd * 3;
qDebug("Tuplet Fraction: %d / %d", nn, dd);
return Fraction(nn, dd);
}
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)
//---------------------------------------------------------
static bool findChordRests(BasicDrawObj const* const o, Score* score, const int track, const Fraction& tick,
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)
int graceNumber = 0;
int graceNumber1 = 0;
bool foundcr1 = false;
Fraction tick2 = tick;
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);
if (!(cho->invisible) && (cho->ticks().isZero())) // grace note
++graceNumber;
else
graceNumber = 0;
}
if (!d)
continue;
if (nobj == no) {
foundcr1 = true;
graceNumber1 = graceNumber;
}
Fraction ticks = Fraction(0,1);
if (foundcr1) {
--n; // found the object corresponding to cr1, count down to find the second one
ticks = d->ticks();
if (d->count) {
Fraction f = TupletFractionCap(d->count, d->tripartite, d->isProlonging);
ticks = ticks / f;
}
if (nobj->type() == CapellaNoteObjectType::REST) {
RestObj* ro = static_cast<RestObj*>(nobj);
if (ro->fullMeasures) {
Measure* m = score->getCreateMeasure(tick2);
Fraction ft = m->ticks();
ticks = ft * ro->fullMeasures;
}
}
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) {
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
}
}
for (Segment* seg = score->tick2segment(tick2); seg; seg = seg->next1()) {
2017-03-08 13:12:26 +01:00
if (seg->segmentType() != SegmentType::ChordRest)
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
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;
}
}
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)) {
qDebug("first or second anchor for BasicDrawObj not found (tick %d type %d track %d first %p second %p)",
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
//---------------------------------------------------------
static Fraction readCapVoice(Score* score, CapVoice* cvoice, int staffIdx, const Fraction& t, bool capxMode)
2012-05-26 14:49:10 +02: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
//
Fraction startTick = tick;
2012-05-26 14:49:10 +02:00
Tuplet* tuplet = 0;
2012-09-29 16:46:45 +02:00
int tupletCount = 0;
bool tuplettrp = false;
bool tupletprol = false;
int nTuplet = 0;
Fraction tupletTick = Fraction(0,1);
2012-05-26 14:49:10 +02:00
QList<Chord*> graceNotes;
2012-09-29 16:46:45 +02:00
foreach(NoteObj* no, cvoice->objects) {
switch (no->type()) {
case CapellaNoteObjectType::REST:
2012-09-29 16:46:45 +02:00
{
qDebug(" <Rest>");
2012-09-29 16:46:45 +02:00
Measure* m = score->getCreateMeasure(tick);
RestObj* o = static_cast<RestObj*>(no);
Fraction ticks = o->ticks();
if (o->invisible && ticks.isZero()) // get rid of placeholders
break;
2012-09-29 16:46:45 +02:00
TDuration d;
d.setVal(ticks.ticks());
2012-09-29 16:46:45 +02:00
if (o->count) {
if (tuplet == 0) {
tupletCount = o->count;
tuplettrp = o->tripartite;
tupletprol = o->isProlonging;
2012-09-29 16:46:45 +02:00
nTuplet = 0;
tupletTick = tick;
tuplet = new Tuplet(score);
Fraction f = TupletFractionCap(tupletCount,tuplettrp,tupletprol);
2012-09-29 16:46:45 +02:00
tuplet->setRatio(f);
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);
Fraction nn = (ticks * tupletCount) / f;
tuplet->setTicks(nn);
2012-09-29 16:46:45 +02:00
}
}
2012-05-26 14:49:10 +02: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) {
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);
rest->setDurationType(TDuration(TDuration::DurationType::V_MEASURE));
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);
TDuration d1;
2012-09-29 16:46:45 +02:00
if (o->fullMeasures) {
d1.setType(TDuration::DurationType::V_MEASURE);
rest->setTicks(m->ticks());
2012-09-29 16:46:45 +02:00
}
else {
d1.setVal(ticks.ticks());
rest->setTicks(d1.fraction());
2012-09-29 16:46:45 +02:00
}
rest->setDurationType(d1);
2012-09-29 16:46:45 +02:00
rest->setTrack(track);
rest->setVisible(!o->invisible);
s->add(rest);
if (tuplet)
tuplet->add(rest);
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 {
tick += ticks / tuplet->ratio();
2013-04-30 16:49:15 +02:00
}
}
else
tick += ticks;
2012-09-29 16:46:45 +02:00
}
break;
case CapellaNoteObjectType::CHORD:
2012-09-29 16:46:45 +02:00
{
qDebug(" <Chord>");
2012-09-29 16:46:45 +02:00
ChordObj* o = static_cast<ChordObj*>(no);
Fraction ticks = o->ticks();
if (o->invisible && ticks.isZero()) { // get rid of placeholders
break;
}
2012-09-29 16:46:45 +02:00
TDuration d;
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
bool isgracenote = (!(o->invisible) && (ticks.isZero()));
2012-09-29 16:46:45 +02:00
if (o->count) {
if (tuplet == 0) {
tupletCount = o->count;
tuplettrp = o->tripartite;
tupletprol = o->isProlonging;
2012-09-29 16:46:45 +02:00
nTuplet = 0;
tupletTick = tick;
tuplet = new Tuplet(score);
Fraction f = TupletFractionCap(tupletCount,tuplettrp,tupletprol);
2012-09-29 16:46:45 +02:00
tuplet->setRatio(f);
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);
Fraction nn = (ticks * tupletCount) / f;
tuplet->setTicks(nn);
2012-09-29 16:46:45 +02:00
}
qDebug("Tuplet at %d: count: %d tri: %d prolonging: %d ticks %d objects %d",
tick.ticks(), o->count, o->tripartite, o->isProlonging, ticks.ticks(),
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);
if (isgracenote) { // grace notes
SetCapGraceDuration(chord,o);
chord->setTicks(chord->durationType().fraction());
}
else { // normal notes
chord->setDurationType(d);
chord->setTicks(d.fraction());
}
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);
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();
}
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;
switch (clef) {
2013-09-05 16:37:49 +02:00
case ClefType::G: off = 0; break;
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;
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;
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;
default: off = 0; qDebug("clefType %d not implemented", int(clef));
2012-09-29 16:46:45 +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] = {
/* -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
for (CNote n : o->notes) {
2012-09-29 16:46:45 +02:00
Note* note = new Note(score);
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
}
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
pitch = pitchKeyAdjust(l, key) + octave * 12;
}
pitch += n.alteration;
pitch += score->staff(staffIdx)->part()->instrument()->transpose().chromatic; // assume not in concert pitch
pitch = limit(pitch, 0, 127);
2012-05-26 14:49:10 +02:00
chord->add(note);
2012-09-29 16:46:45 +02:00
note->setPitch(pitch);
// TODO: compute tpc from pitch & line
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);
}
}
for (Verse v : o->verse) {
2012-09-29 16:46:45 +02:00
Lyrics* l = new Lyrics(score);
l->setTrack(track);
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
processBasicDrawObj(o->objects, s, track, chord);
switch (o->articulation) {
2016-10-06 12:21:28 +02:00
#if 0 // TODO-ws
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
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 {
tick += ticks / tuplet->ratio();
2012-09-29 16:46:45 +02:00
}
}
else
tick += ticks;
}
break;
case CapellaNoteObjectType::CLEF:
2012-09-29 16:46:45 +02:00
{
qDebug(" <Clef>");
2012-09-29 16:46:45 +02:00
CapClef* o = static_cast<CapClef*>(no);
ClefType nclef = o->clef();
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);
Segment* s;
if (tick == m->tick())
2017-03-08 13:12:26 +01:00
s = m->getSegment(SegmentType::HeaderClef, tick);
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;
case CapellaNoteObjectType::KEY:
2012-09-29 16:46:45 +02:00
{
qDebug(" <Key>");
2012-09-29 16:46:45 +02:00
CapKey* o = static_cast<CapKey*>(no);
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);
ks->setKeySigEvent(okey);
s->add(ks);
2012-09-29 16:46:45 +02:00
}
}
break;
case CapellaNoteObjectType::METER:
2012-09-29 16:46:45 +02:00
{
CapMeter* o = static_cast<CapMeter*>(no);
qDebug(" <Meter> tick %d %d/%d", tick.ticks(), o->numerator, 1 << o->log2Denom);
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))
score->sigmap()->add(tick.ticks(), ne);
// 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);
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);
m->setTicks(f);
2012-09-29 16:46:45 +02:00
}
break;
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);
qDebug(" <Barline>");
2013-04-27 21:36:04 +02:00
Measure* pm = 0; // the previous measure (the one terminated by this barline)
if (tick > Fraction(0,1))
pm = score->getCreateMeasure(tick - Fraction::fromTicks(1));
2013-04-27 21:36:04 +02:00
if (pm) {
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
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
BarLineType st = o->type();
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;
case CapellaNoteObjectType::PAGE_BKGR:
qDebug(" <PageBreak>");
2012-09-29 16:46:45 +02:00
break;
}
}
Fraction endTick = tick;
2012-09-29 16:46:45 +02:00
//
// pass II
//
tick = startTick;
foreach(NoteObj* no, cvoice->objects) {
BasicDurationalObj* d = 0;
if (no->type() == CapellaNoteObjectType::REST)
2012-09-29 16:46:45 +02:00
d = static_cast<BasicDurationalObj*>(static_cast<RestObj*>(no));
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;
for (BasicDrawObj* o : d->objects) {
2012-09-29 16:46:45 +02:00
switch (o->type) {
case CapellaType::SIMPLE_TEXT:
// qDebug("simple text at %d", tick);
2012-09-29 16:46:45 +02:00
break;
case CapellaType::WAVY_LINE:
2012-09-29 16:46:45 +02:00
break;
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);
// 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
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)",
tick.ticks(), track, cr1, cr2);
2013-05-02 13:55:23 +02:00
else {
Slur* slur = new Slur(score);
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());
slur->setStartElement(cr1);
slur->setEndElement(cr2);
slur->setTrack(cr1->track());
2013-09-30 10:16:50 +02:00
slur->setTrack2(cr2->track());
score->addElement(slur);
2013-05-02 13:55:23 +02:00
}
2012-09-29 16:46:45 +02:00
}
}
break;
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));
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);
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;
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
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)
volta->setVoltaType(Volta::Type::CLOSED);
2013-05-06 22:10:49 +02:00
else
volta->setVoltaType(Volta::Type::OPEN);
2013-06-10 11:03:34 +02:00
volta->setTick(cr1->measure()->tick());
volta->setTick2(cr2->measure()->tick() + cr2->measure()->ticks());
score->addElement(volta);
2013-05-06 22:10:49 +02:00
}
}
break;
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)",
tick.ticks(), track, cr1, cr2);
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)",
tick.ticks(), track, cr1, cr2);
else {
Hairpin* hp = new Hairpin(score);
if (wdgo->decresc)
hp->setHairpinType(HairpinType::DECRESC_HAIRPIN);
else
hp->setHairpinType(HairpinType::CRESC_HAIRPIN);
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
}
Fraction ticks = d->ticks();
if (d->count) {
Fraction f = TupletFractionCap(d->count, d->tripartite, d->isProlonging);
ticks = ticks / f;
}
if (no->type() == CapellaNoteObjectType::REST) {
2012-09-29 16:46:45 +02:00
RestObj* o = static_cast<RestObj*>(no);
if (o->fullMeasures) {
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) {
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
//---------------------------------------------------------
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) {
qDebug("System:");
for (CapStaff* cstaff : csys->staves) {
2012-09-29 16:46:45 +02:00
CapStaffLayout* cl = cap->staffLayout(cstaff->iLayout);
qDebug(" Staff layout <%s><%s><%s><%s><%s> %d barline %d-%d mode %d",
qPrintable(cl->descr), qPrintable(cl->name), qPrintable(cl->abbrev),
qPrintable(cl->intermediateName), qPrintable(cl->intermediateAbbrev),
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;
foreach(CapSystem* csys, cap->systems) {
2012-09-29 16:46:45 +02:00
staves = qMax(staves, csys->staves.size());
}
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()) {
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);
// 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);
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);
part->setPartName(cl->descr);
part->setPlainLongName(cl->name);
part->setPlainShortName(cl->abbrev);
2012-09-29 16:46: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;
}
s->setSmall(Fraction(0,1), cl->bSmall);
2014-08-11 15:25:55 +02:00
part->insertStaff(s, -1);
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;
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) {
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);
}
MeasureBase* measure = nullptr;
2012-09-29 16:46:45 +02:00
foreach(BasicDrawObj* o, cap->backgroundChord->objects) {
switch (o->type) {
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;
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;
}
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());
// 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();
s->setPlainText(ss);
if (!measure) {
measure = new VBox(score);
measure->setTick(Fraction(0,1));
score->addMeasure(measure, score->measures()->first());
}
2012-09-29 16:46:45 +02:00
measure->add(s);
// 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:
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);
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
Fraction systemTick = Fraction(0,1);
2012-09-29 16:46:45 +02:00
foreach(CapSystem* csys, cap->systems) {
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);
}
*/
Fraction mtick = Fraction(0,1);
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
qDebug(" ReadCapStaff %d/%d", cstaff->numerator, 1 << cstaff->log2Denom);
2012-09-29 16:46:45 +02:00
int staffIdx = cstaff->iLayout;
int voice = 0;
for (CapVoice* cvoice : cstaff->voices) {
Fraction tick = readCapVoice(score, cvoice, staffIdx, systemTick, capxMode);
2012-09-29 16:46:45 +02:00
++voice;
if (tick > mtick)
mtick = tick;
}
}
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);
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) {
if ((m->ticks() == m->timesig())) {
Segment* s = m->getSegment(SegmentType::ChordRest, m->tick());
Rest* rest = new Rest(score);
rest->setDurationType(TDuration::DurationType::V_MEASURE);
rest->setTicks(m->ticks());
rest->setTrack(staffIdx * VOICES);
s->add(rest);
}
else {
auto durList = toDurationList(m->ticks(), true);
int tickOffset = 0;
for (auto d : durList) {
Segment* s = m->getSegment(SegmentType::ChordRest, m->tick() + Fraction::fromTicks(tickOffset));
Rest* rest = new Rest(score);
rest->setDurationType(d);
rest->setTrack(staffIdx * VOICES);
s->add(rest);
tickOffset += d.ticks().ticks();
}
}
2012-09-29 16:46:45 +02:00
}
}
}
// score->connectSlurs();
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);
// 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();
_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();
// 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)
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)
qDebug("variants.size %d, expected %d", variants.size(), b);
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);
// 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)
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: {
Q_ASSERT(b == 0);
2012-09-29 16:46:45 +02:00
char lines[11];
cap->read(lines, 11);
break;
}
}
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();
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
// qDebug("readDrawObjectArray %d elements", n);
2012-09-29 16:46:45 +02:00
for (int i = 0; i < n; ++i) {
CapellaType type = CapellaType(readByte());
2012-05-26 14:49:10 +02:00
// qDebug(" readDrawObject %d of %d, type %d", i, n, type);
2012-09-29 16:46:45 +02:00
switch (type) {
case CapellaType::GROUP: {
2012-09-29 16:46:45 +02:00
GroupObj* o = new GroupObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::TRANSPOSABLE: {
2012-09-29 16:46:45 +02:00
TransposableObj* o = new TransposableObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::METAFILE: {
2012-09-29 16:46:45 +02:00
MetafileObj* o = new MetafileObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::SIMPLE_TEXT: {
2012-09-29 16:46:45 +02:00
SimpleTextObj* o = new SimpleTextObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::TEXT: {
2012-09-29 16:46:45 +02:00
TextObj* o = new TextObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::RECT_ELLIPSE: {
2012-09-29 16:46:45 +02:00
RectEllipseObj* o = new RectEllipseObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::LINE: {
2012-09-29 16:46:45 +02:00
LineObj* o = new LineObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::POLYGON: {
2012-09-29 16:46:45 +02:00
PolygonObj* o = new PolygonObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::WAVY_LINE: {
2012-09-29 16:46:45 +02:00
WavyLineObj* o = new WavyLineObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::SLUR: {
2012-09-29 16:46:45 +02:00
SlurObj* o = new SlurObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::NOTE_LINES: {
2012-09-29 16:46:45 +02:00
NotelinesObj* o = new NotelinesObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::WEDGE: {
2012-09-29 16:46:45 +02:00
WedgeObj* o = new WedgeObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::VOLTA: {
2012-09-29 16:46:45 +02:00
VoltaObj* o = new VoltaObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::BRACKET: {
2012-09-29 16:46:45 +02:00
BracketObj* o = new BracketObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::GUITAR: {
2012-09-29 16:46:45 +02:00
GuitarObj* o = new GuitarObj(this);
o->read();
ol.append(o);
}
break;
case CapellaType::TRILL: {
2012-09-29 16:46:45 +02:00
TrillObj* o = new TrillObj(this);
o->read();
ol.append(o);
}
break;
default:
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;
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;
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)
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
}
Q_ASSERT(!(c & 0x80));
qDebug("DurationObj ndots %d nodur %d postgr %d bsm %d inv %d notbl %d t %d hsh %d cnt %d trp %d ispro %d",
nDots, noDuration, postGrace, bSmall, invisible, notBlack, int(t), horizontalShift, count, tripartite, isProlonging
);
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)
: 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;
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)
: BasicDurationalObj(c), NoteObj(CapellaNoteObjectType::CHORD)
2012-05-26 14:49:10 +02:00
{
2012-09-29 16:46:45 +02:00
cap = c;
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();
beamMode = (flags & 0x01) ? BeamMode(cap->readByte()) : BeamMode::AUTO;
2012-09-29 16:46:45 +02:00
notationStave = (flags & 0x02) ? cap->readChar() : 0;
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)
v.verseNumber = cap->readQString();
2012-09-29 16:46:45 +02:00
if (b & 16)
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;
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()
{
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
}
//---------------------------------------------------------
// 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
//---------------------------------------------------------
// readQString -- read Capella string into QString
// strings in Capella files may contain \r\n, must remove the \r
//---------------------------------------------------------
QString Capella::readQString()
{
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
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) {
Q_ASSERT(b == 255);
2012-09-29 16:46:45 +02:00
int r = readByte();
int g = readByte();
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();
QString face = readQString();
2012-05-26 14:49:10 +02: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
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()) {
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
//---------------------------------------------------------
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();
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;
}
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();
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();
// 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);
sl->line = ClefLine((clef >> 3) & 7);
2014-06-30 10:41:21 +02:00
sl->oct = Oct((clef >> 6));
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
// 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();
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();
qDebug(" sound %d vol %d transp %d", sl->sound, sl->volume, sl->transp);
2012-09-29 16:46:45 +02:00
sl->descr = readQString();
sl->name = readQString();
sl->abbrev = readQString();
sl->intermediateName = readQString();
sl->intermediateAbbrev = readQString();
qDebug(" descr <%s> name <%s> abbrev <%s> iname <%s> iabrev <%s>",
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;
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();
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;
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
// 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++) {
CapBracket cb;
cb.from = readInt();
cb.to = readInt();
cb.curly = readByte();
// qDebug("Bracket%d %d-%d curly %d", i, b.from, b.to, b.curly);
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) {
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);
line = ClefLine((b >> 3) & 7);
2014-06-30 10:41:21 +02:00
oct = Oct(b >> 6);
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);
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;
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;
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;
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;
// 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;
qDebug(" Meter %d/%d allaBreve %d", numerator, log2Denom, allaBreve);
2012-09-29 16:46:45 +02:00
if (log2Denom > 7 || log2Denom < 0) {
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();
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;
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
Q_ASSERT(_barMode <= 2);
2012-05-26 14:49:10 +02: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)
{
qDebug(" readVoice %d", idx);
2012-05-26 14:49:10 +02:00
2012-09-29 16:46:45 +02:00
if (readChar() != 'C')
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();
// qDebug(" Voice %d read object idx %d(%d) type %d", idx, i, nNoteObjs, type);
2012-09-29 16:46:45 +02:00
readExtra();
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
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;
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;
case CapellaNoteObjectType::CLEF:
2012-09-29 16:46:45 +02:00
{
CapClef* clef = new CapClef(this);
clef->read();
v->objects.append(clef);
}
break;
case CapellaNoteObjectType::KEY:
2012-09-29 16:46:45 +02:00
{
CapKey* key = new CapKey(this);
key->read();
v->objects.append(key);
}
break;
case CapellaNoteObjectType::METER:
2012-09-29 16:46:45 +02:00
{
CapMeter* meter = new CapMeter(this);
meter->read();
v->objects.append(meter);
}
break;
case CapellaNoteObjectType::EXPL_BARLINE:
2012-09-29 16:46:45 +02:00
{
CapExplicitBarline* bl = new CapExplicitBarline(this);
bl->read();
qDebug("append Expl Barline==========");
2012-09-29 16:46:45 +02:00
v->objects.append(bl);
}
break;
default:
qFatal("bad voice type %d", type);
}
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')
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;
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();
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')
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();
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
//---------------------------------------------------------
Fraction BasicDurationalObj::ticks() const
2012-09-29 16:46:45 +02:00
{
if (noDuration)
return Fraction(0,1);
Fraction len = {0,1};
2012-09-29 16:46:45 +02:00
switch (t) {
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:
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
}
Fraction slen = len;
2012-09-29 16:46:45 +02:00
int dots = nDots;
while (dots--) {
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)
throw Capella::Error::BAD_SIG;
2012-09-29 16:46: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
// 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
// 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) {
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
// 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)
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);
if(!fp.exists())
return Score::FileError::FILE_NOT_FOUND;
2012-09-29 16:46:45 +02:00
if (!fp.open(QIODevice::ReadOnly))
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
}
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,
QWidget::tr("Import Capella"),
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
return Score::FileError::FILE_NO_ERROR;
2012-05-26 14:49:10 +02:00
}
2012-09-29 16:46:45 +02:00
fp.close();
convertCapella(score, &cf, false);
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