746 lines
24 KiB
C++
746 lines
24 KiB
C++
//=============================================================================
|
|
// MuseScore
|
|
// Linux Music Score Editor
|
|
// $Id: musedata.cpp 5497 2012-03-26 10:59:16Z lasconic $
|
|
//
|
|
// Copyright (C) 2007 Werner Schweer and others
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License version 2.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
//=============================================================================
|
|
|
|
#include "musedata.h"
|
|
#include "musescore.h"
|
|
#include "libmscore/score.h"
|
|
#include "libmscore/part.h"
|
|
#include "libmscore/staff.h"
|
|
#include "libmscore/barline.h"
|
|
#include "libmscore/clef.h"
|
|
#include "libmscore/key.h"
|
|
#include "libmscore/note.h"
|
|
#include "libmscore/chord.h"
|
|
#include "libmscore/rest.h"
|
|
#include "libmscore/text.h"
|
|
#include "libmscore/bracket.h"
|
|
#include "libmscore/tuplet.h"
|
|
#include "libmscore/slur.h"
|
|
#include "libmscore/dynamic.h"
|
|
#include "libmscore/lyrics.h"
|
|
#include "libmscore/articulation.h"
|
|
#include "libmscore/sig.h"
|
|
#include "libmscore/measure.h"
|
|
#include "libmscore/timesig.h"
|
|
#include "libmscore/segment.h"
|
|
|
|
//---------------------------------------------------------
|
|
// musicalAttribute
|
|
//---------------------------------------------------------
|
|
|
|
void MuseData::musicalAttribute(QString s, Part* part)
|
|
{
|
|
QStringList al = s.mid(3).split(" ", QString::SkipEmptyParts);
|
|
foreach(QString item, al) {
|
|
if (item.startsWith("K:")) {
|
|
int key = item.mid(2).toInt();
|
|
foreach(Staff* staff, *(part->staves()))
|
|
(*staff->keymap())[curTick] = key;
|
|
}
|
|
else if (item.startsWith("Q:")) {
|
|
_division = item.mid(2).toInt();
|
|
}
|
|
else if (item.startsWith("T:")) {
|
|
QStringList tl = item.mid(2).split("/");
|
|
if (tl.size() != 2) {
|
|
qDebug("bad time sig <%s>\n", qPrintable(item));
|
|
continue;
|
|
}
|
|
int z = tl[0].toInt();
|
|
int n = tl[1].toInt();
|
|
if ((z > 0) && (n > 0)) {
|
|
//TODO score->sigmap()->add(curTick, Fraction(z, n));
|
|
TimeSig* ts = new TimeSig(score);
|
|
Staff* staff = part->staff(0);
|
|
ts->setTrack(staff->idx() * VOICES);
|
|
Measure* measure = score->tick2measure(curTick);
|
|
Segment* s = measure->getSegment(ts, curTick);
|
|
s->add(ts);
|
|
}
|
|
}
|
|
else if (item.startsWith("X:"))
|
|
;
|
|
else if (item[0] == 'C') {
|
|
int staffIdx = 1;
|
|
// int col = 2;
|
|
if (item[1].isDigit()) {
|
|
staffIdx = item.mid(1,1).toInt();
|
|
// col = 3;
|
|
}
|
|
staffIdx -= 1;
|
|
/* int clef = item.mid(col).toInt();
|
|
ClefType mscoreClef = CLEF_G;
|
|
switch(clef) {
|
|
case 4: mscoreClef = CLEF_G; break;
|
|
case 22: mscoreClef = CLEF_F; break;
|
|
case 13: mscoreClef = CLEF_C3; break;
|
|
case 14: mscoreClef = CLEF_C2; break;
|
|
case 15: mscoreClef = CLEF_C1; break;
|
|
default:
|
|
qDebug("unknown clef %d\n", clef);
|
|
break;
|
|
}
|
|
*/
|
|
// Staff* staff = part->staff(staffIdx);
|
|
// staff->setClef(curTick, mscoreClef);
|
|
}
|
|
else
|
|
qDebug("unknown $key <%s>\n", qPrintable(item));
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// readChord
|
|
//---------------------------------------------------------
|
|
|
|
void MuseData::readChord(Part*, const QString& s)
|
|
{
|
|
// a b c d e f g
|
|
static int table[7] = { 9, 11, 0, 2, 4, 5, 7 };
|
|
|
|
int step = s[1].toAscii() - 'A';
|
|
int alter = 0;
|
|
int octave = 0;
|
|
for (int i = 2; i < 4; ++i) {
|
|
if (s[i] == '#')
|
|
alter += 1;
|
|
else if (s[i] == 'f')
|
|
alter -= 1;
|
|
else if (s[i].isDigit()) {
|
|
octave = s.mid(i,1).toInt();
|
|
break;
|
|
}
|
|
}
|
|
int staffIdx = 0;
|
|
if (s.size() >= 24) {
|
|
if (s[23].isDigit())
|
|
staffIdx = s.mid(23,1).toInt() - 1;
|
|
}
|
|
int pitch = table[step] + alter + (octave + 1) * 12;
|
|
if (pitch < 0)
|
|
pitch = 0;
|
|
if (pitch > 127)
|
|
pitch = 127;
|
|
|
|
Chord* chord = (Chord*)chordRest;
|
|
Note* note = new Note(score);
|
|
note->setPitch(pitch);
|
|
note->setTpcFromPitch();
|
|
note->setTrack(staffIdx * VOICES + voice);
|
|
chord->add(note);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// openSlur
|
|
//---------------------------------------------------------
|
|
|
|
void MuseData::openSlur(int idx, int tick, Staff* staff, int voice)
|
|
{
|
|
int staffIdx = staff->idx();
|
|
if (slur[idx]) {
|
|
qDebug("%06d: slur %d already open\n", tick, idx+1);
|
|
return;
|
|
}
|
|
slur[idx] = new Slur(score);
|
|
slur[idx]->setStart(tick, staffIdx * VOICES + voice);
|
|
slur[idx]->setTrack(staffIdx * VOICES + voice);
|
|
score->add(slur[idx]);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// closeSlur
|
|
//---------------------------------------------------------
|
|
|
|
void MuseData::closeSlur(int idx, int tick, Staff* staff, int voice)
|
|
{
|
|
if (slur[idx]) {
|
|
slur[idx]->setEnd(tick, staff->idx() * VOICES + voice);
|
|
slur[idx] = 0;
|
|
}
|
|
else
|
|
qDebug("%06d: slur %d not open\n", tick, idx+1);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// readNote
|
|
//---------------------------------------------------------
|
|
|
|
void MuseData::readNote(Part* part, const QString& s)
|
|
{
|
|
// a b c d e f g
|
|
static int table[7] = { 9, 11, 0, 2, 4, 5, 7 };
|
|
|
|
int step = s[0].toAscii() - 'A';
|
|
int alter = 0;
|
|
int octave = 0;
|
|
for (int i = 1; i < 3; ++i) {
|
|
if (s[i] == '#')
|
|
alter += 1;
|
|
else if (s[i] == 'f')
|
|
alter -= 1;
|
|
else if (s[i].isDigit()) {
|
|
octave = s.mid(i,1).toInt();
|
|
break;
|
|
}
|
|
}
|
|
Direction dir = AUTO;
|
|
if (s.size() >= 23) {
|
|
if (s[22] == 'u')
|
|
dir = UP;
|
|
else if (s[22] == 'd')
|
|
dir = DOWN;
|
|
}
|
|
|
|
int staffIdx = 0;
|
|
if (s.size() >= 24) {
|
|
if (s[23].isDigit())
|
|
staffIdx = s.mid(23,1).toInt() - 1;
|
|
}
|
|
Staff* staff = part->staff(staffIdx);
|
|
int gstaff = staff->idx();
|
|
|
|
int pitch = table[step] + alter + (octave + 1) * 12;
|
|
if (pitch < 0)
|
|
pitch = 0;
|
|
if (pitch > 127)
|
|
pitch = 127;
|
|
int ticks = s.mid(5, 3).toInt();
|
|
ticks = (ticks * MScore::division + _division/2) / _division;
|
|
int tick = curTick;
|
|
curTick += ticks;
|
|
|
|
Tuplet* tuplet = 0;
|
|
if (s.size() >= 22) {
|
|
int a = 1;
|
|
int b = 1;
|
|
if (s[19] != ' ') {
|
|
a = s[19].toAscii() - '0';
|
|
if (a == 3 && s[20] != ':')
|
|
b = 2;
|
|
else {
|
|
b = s[21].toAscii() - '0';
|
|
}
|
|
}
|
|
if (a == 3 && b == 2) { // triplet
|
|
if (chordRest && chordRest->tuplet() && ntuplet) {
|
|
tuplet = chordRest->tuplet();
|
|
}
|
|
else {
|
|
tuplet = new Tuplet(score);
|
|
tuplet->setTrack(gstaff * VOICES);
|
|
tuplet->setTick(tick);
|
|
ntuplet = a;
|
|
tuplet->setRatio(Fraction(a, b));
|
|
measure->add(tuplet);
|
|
}
|
|
}
|
|
else if (a == 1 && b == 1)
|
|
;
|
|
else
|
|
qDebug("unsupported tuple %d/%d\n", a, b);
|
|
}
|
|
|
|
Chord* chord = new Chord(score);
|
|
chordRest = chord;
|
|
chord->setTrack(gstaff * VOICES);
|
|
chord->setStemDirection(dir);
|
|
if (tuplet) {
|
|
chord->setTuplet(tuplet);
|
|
tuplet->add(chord);
|
|
--ntuplet;
|
|
}
|
|
TDuration d;
|
|
d.setVal(ticks);
|
|
chord->setDurationType(d);
|
|
|
|
Segment* segment = measure->getSegment(chord, tick);
|
|
|
|
voice = 0;
|
|
for (; voice < VOICES; ++voice) {
|
|
Element* e = segment->element(gstaff * VOICES + voice);
|
|
if (e == 0) {
|
|
chord->setTrack(gstaff * VOICES + voice);
|
|
segment->add(chord);
|
|
break;
|
|
}
|
|
}
|
|
if (voice == VOICES) {
|
|
qDebug("cannot allocate voice\n");
|
|
delete chord;
|
|
return;
|
|
}
|
|
Note* note = new Note(score);
|
|
note->setPitch(pitch);
|
|
note->setTpcFromPitch();
|
|
note->setTrack(gstaff * VOICES + voice);
|
|
chord->add(note);
|
|
|
|
QString dynamics;
|
|
QString an = s.mid(31, 11);
|
|
for (int i = 0; i < an.size(); ++i) {
|
|
if (an[i] == '(')
|
|
openSlur(0, tick, staff, voice);
|
|
else if (an[i] == ')')
|
|
closeSlur(0, tick, staff, voice);
|
|
else if (an[i] == '[')
|
|
openSlur(1, tick, staff, voice);
|
|
else if (an[i] == ']')
|
|
closeSlur(1, tick, staff, voice);
|
|
else if (an[i] == '{')
|
|
openSlur(2, tick, staff, voice);
|
|
else if (an[i] == '}')
|
|
closeSlur(2, tick, staff, voice);
|
|
else if (an[i] == 'z')
|
|
openSlur(3, tick, staff, voice);
|
|
else if (an[i] == 'x')
|
|
closeSlur(3, tick, staff, voice);
|
|
else if (an[i] == '.') {
|
|
Articulation* atr = new Articulation(score);
|
|
atr->setSubtype(Articulation_Staccato);
|
|
chord->add(atr);
|
|
}
|
|
else if (an[i] == '_') {
|
|
Articulation* atr = new Articulation(score);
|
|
atr->setSubtype(Articulation_Tenuto);
|
|
chord->add(atr);
|
|
}
|
|
else if (an[i] == 'v') {
|
|
Articulation* atr = new Articulation(score);
|
|
atr->setSubtype(Articulation_Upbow);
|
|
chord->add(atr);
|
|
}
|
|
else if (an[i] == 'n') {
|
|
Articulation* atr = new Articulation(score);
|
|
atr->setSubtype(Articulation_Downbow);
|
|
chord->add(atr);
|
|
}
|
|
else if (an[i] == 't') {
|
|
Articulation* atr = new Articulation(score);
|
|
atr->setSubtype(Articulation_Trill);
|
|
chord->add(atr);
|
|
}
|
|
else if (an[i] == 'F') {
|
|
Articulation* atr = new Articulation(score);
|
|
atr->setUp(true);
|
|
atr->setSubtype(Articulation_Fermata);
|
|
chord->add(atr);
|
|
}
|
|
else if (an[i] == 'E') {
|
|
Articulation* atr = new Articulation(score);
|
|
atr->setUp(false);
|
|
atr->setSubtype(Articulation_Fermata);
|
|
chord->add(atr);
|
|
}
|
|
else if (an[i] == 'O') {
|
|
// Articulation* atr = new Articulation(score);
|
|
// atr->setSubtype(Articulation_Downbow);
|
|
// chord->add(atr);
|
|
qDebug("%06d: open string '%c' not implemented\n", tick, an[i].toAscii());
|
|
}
|
|
else if (an[i] == '&') {
|
|
// skip editorial level
|
|
if (i <= an.size() && an[i+1].isDigit())
|
|
++i;
|
|
}
|
|
else if (an[i] == 'p')
|
|
dynamics += "p";
|
|
else if (an[i] == 'm')
|
|
dynamics += "m";
|
|
else if (an[i] == 'f')
|
|
dynamics += "f";
|
|
else if (an[i] == '-') // tie
|
|
;
|
|
else if (an[i] == '*') // start tuplet
|
|
;
|
|
else if (an[i] == '!') // stop tuplet
|
|
;
|
|
else if (an[i] == '+') // cautionary accidental
|
|
;
|
|
else if (an[i] == 'X') // ???
|
|
;
|
|
else if (an[i] == ' ')
|
|
;
|
|
else {
|
|
qDebug("%06d: notation '%c' not implemented\n", tick, an[i].toAscii());
|
|
}
|
|
}
|
|
if (!dynamics.isEmpty()) {
|
|
Dynamic* dyn = new Dynamic(score);
|
|
dyn->setSubtype(dynamics);
|
|
dyn->setTrack(gstaff * VOICES);
|
|
Segment* s = measure->getSegment(SegChordRest, tick);
|
|
s->add(dyn);
|
|
}
|
|
|
|
QString txt = s.mid(43, 36);
|
|
if (!txt.isEmpty()) {
|
|
QStringList sl = txt.split("|");
|
|
int no = 0;
|
|
foreach(QString w, sl) {
|
|
w = diacritical(w);
|
|
Lyrics* l = new Lyrics(score);
|
|
l->setText(w);
|
|
l->setNo(no++);
|
|
l->setTrack(gstaff * VOICES);
|
|
Segment* segment = measure->tick2segment(tick);
|
|
segment->add(l);
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// diacritical
|
|
// TODO: not complete
|
|
//---------------------------------------------------------
|
|
|
|
QString MuseData::diacritical(QString s)
|
|
{
|
|
struct TAB {
|
|
const char* a;
|
|
const char* b;
|
|
} tab[] = {
|
|
{ "\\\\", "\\" },
|
|
{ "\\2s", "ß" },
|
|
{ "\\3a", "ä" },
|
|
{ "\\3o", "ö" },
|
|
{ "\\3u", "ü" },
|
|
|
|
{ "\\s2", "ß" },
|
|
{ "\\a3", "ä" },
|
|
{ "\\o3", "ö" },
|
|
{ "\\u3", "ü" },
|
|
};
|
|
for (unsigned int i = 0; i < sizeof(tab)/sizeof(*tab); ++i) {
|
|
s = s.replace(tab[i].a, QString::fromUtf8(tab[i].b));
|
|
}
|
|
return s;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// readRest
|
|
//---------------------------------------------------------
|
|
|
|
void MuseData::readRest(Part* part, const QString& s)
|
|
{
|
|
int ticks = s.mid(5, 3).toInt();
|
|
ticks = (ticks * MScore::division + _division/2) / _division;
|
|
|
|
int tick = curTick;
|
|
curTick += ticks;
|
|
|
|
int staffIdx = 0;
|
|
if (s.size() >= 24) {
|
|
if (s[23].isDigit())
|
|
staffIdx = s.mid(23,1).toInt() - 1;
|
|
}
|
|
Staff* staff = part->staff(staffIdx);
|
|
int gstaff = staff->idx();
|
|
|
|
TDuration d;
|
|
d.setVal(ticks);
|
|
Rest* rest = new Rest(score, d);
|
|
rest->setDuration(d.fraction());
|
|
chordRest = rest;
|
|
rest->setTrack(gstaff * VOICES);
|
|
Segment* segment = measure->getSegment(rest, tick);
|
|
|
|
voice = 0;
|
|
for (; voice < VOICES; ++voice) {
|
|
Element* e = segment->element(gstaff * VOICES + voice);
|
|
if (e == 0) {
|
|
rest->setTrack(gstaff * VOICES + voice);
|
|
segment->add(rest);
|
|
break;
|
|
}
|
|
}
|
|
if (voice == VOICES) {
|
|
qDebug("cannot allocate voice\n");
|
|
delete rest;
|
|
return;
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// readBackup
|
|
//---------------------------------------------------------
|
|
|
|
void MuseData::readBackup(const QString& s)
|
|
{
|
|
int ticks = s.mid(5, 3).toInt();
|
|
ticks = (ticks * MScore::division + _division/2) / _division;
|
|
if (s[0] == 'b')
|
|
curTick -= ticks;
|
|
else
|
|
curTick += ticks;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// createMeasure
|
|
//---------------------------------------------------------
|
|
|
|
Measure* MuseData::createMeasure()
|
|
{
|
|
for (MeasureBase* mb = score->first(); mb; mb = mb->next()) {
|
|
if (mb->type() != MEASURE)
|
|
continue;
|
|
Measure* m = (Measure*)mb;
|
|
int st = m->tick();
|
|
int l = m->ticks();
|
|
if (curTick == st)
|
|
return m;
|
|
if (curTick > st && curTick < (st+l)) {
|
|
// irregular measure
|
|
#if 0 // TODO
|
|
Fraction f = score->sigmap()->timesig(st).fraction();
|
|
score->sigmap()->add(st, curTick - st, f);
|
|
score->sigmap()->add(curTick, f);
|
|
#endif
|
|
break;
|
|
}
|
|
if (curTick < st + l) {
|
|
qDebug("cannot create measure at %d\n", curTick);
|
|
return 0;
|
|
}
|
|
}
|
|
Measure* measure = new Measure(score);
|
|
measure->setTick(curTick);
|
|
|
|
#if 0
|
|
foreach(Staff* s, score->staves()) {
|
|
if (s->isTop()) {
|
|
BarLine* barLine = new BarLine(score);
|
|
barLine->setStaff(s);
|
|
measure->setEndBarLine(barLine);
|
|
}
|
|
}
|
|
#endif
|
|
score->add(measure);
|
|
return measure;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// readPart
|
|
//---------------------------------------------------------
|
|
|
|
void MuseData::readPart(QStringList sl, Part* part)
|
|
{
|
|
int line = 10;
|
|
QString s;
|
|
for (; line < sl.size(); ++line) {
|
|
s = sl[line];
|
|
if (!s.isEmpty() && s[0] == '$')
|
|
break;
|
|
}
|
|
if (line >= sl.size()) {
|
|
qDebug(" $ not found in part\n");
|
|
return;
|
|
}
|
|
curTick = 0;
|
|
slur[0] = 0;
|
|
slur[1] = 0;
|
|
slur[2] = 0;
|
|
slur[3] = 0;
|
|
measure = 0;
|
|
measure = createMeasure();
|
|
for (; line < sl.size(); ++line) {
|
|
s = sl[line];
|
|
// qDebug("%6d: <%s>\n", curTick, qPrintable(s));
|
|
char c = s[0].toAscii();
|
|
switch(c) {
|
|
case 'A':
|
|
case 'B':
|
|
case 'C':
|
|
case 'D':
|
|
case 'E':
|
|
case 'F':
|
|
case 'G':
|
|
readNote(part, s);
|
|
break;
|
|
case ' ': // chord
|
|
readChord(part, s);
|
|
break;
|
|
case 'r':
|
|
readRest(part, s);
|
|
break;
|
|
case 'g': // grace note
|
|
case 'c': // cue note
|
|
case 'f': // basso continuo
|
|
break;
|
|
case 'b': // backspace
|
|
case 'i': // forward space
|
|
readBackup(s);
|
|
break;
|
|
case 'm': // measure line / bar line
|
|
measure = createMeasure();
|
|
break;
|
|
case '*': // musical direction
|
|
break;
|
|
case 'P': // print suggestion
|
|
break;
|
|
case 'S': // sound record
|
|
break;
|
|
case '$':
|
|
musicalAttribute(s, part);
|
|
break;
|
|
default:
|
|
qDebug("unknown record <%s>\n", qPrintable(s));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// countStaves
|
|
//---------------------------------------------------------
|
|
|
|
int MuseData::countStaves(const QStringList& sl)
|
|
{
|
|
int staves = 1;
|
|
for (int i = 10; i < sl.size(); ++i) {
|
|
QString s = sl[i];
|
|
char c = s[0].toAscii();
|
|
switch(c) {
|
|
case 'A':
|
|
case 'B':
|
|
case 'C':
|
|
case 'D':
|
|
case 'E':
|
|
case 'F':
|
|
case 'G':
|
|
case 'r':
|
|
{
|
|
int staffIdx = 1;
|
|
if (s.size() >= 24) {
|
|
if (s[23].isDigit())
|
|
staffIdx = s.mid(23,1).toInt();
|
|
}
|
|
if (staffIdx > staves)
|
|
staves = staffIdx;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return staves;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// read
|
|
// return false on error
|
|
//---------------------------------------------------------
|
|
|
|
bool MuseData::read(const QString& name)
|
|
{
|
|
QFile fp(name);
|
|
if (!fp.open(QIODevice::ReadOnly)) {
|
|
qDebug("cannot open file <%s>\n", qPrintable(name));
|
|
return false;
|
|
}
|
|
QTextStream ts(&fp);
|
|
QStringList part;
|
|
bool commentMode = false;
|
|
for (;;) {
|
|
QString s(ts.readLine());
|
|
if (s.isNull())
|
|
break;
|
|
if (s.isEmpty()) {
|
|
if (!commentMode)
|
|
part.append(QString(""));
|
|
continue;
|
|
}
|
|
if (s[0] == '&') {
|
|
commentMode = !commentMode;
|
|
continue;
|
|
}
|
|
if (commentMode)
|
|
continue;
|
|
if (s[0] == '@')
|
|
continue;
|
|
if (s[0] == '/') {
|
|
parts.append(part);
|
|
|
|
Part* mpart = new Part(score);
|
|
int staves = countStaves(part);
|
|
for (int i = 0; i < staves; ++i) {
|
|
Staff* staff = new Staff(score, mpart, i);
|
|
mpart->insertStaff(staff);
|
|
score->staves().push_back(staff);
|
|
if ((staves == 2) && (i == 0)) {
|
|
staff->setBracket(0, BRACKET_AKKOLADE);
|
|
staff->setBracketSpan(0, 2);
|
|
}
|
|
}
|
|
score->appendPart(mpart);
|
|
if(part.size() > 8)
|
|
mpart->setLongName(part[8]);
|
|
part.clear();
|
|
continue;
|
|
}
|
|
if (s[0] == 'a') {
|
|
part.back().append(s.mid(1));
|
|
continue;
|
|
}
|
|
part.append(s);
|
|
}
|
|
fp.close();
|
|
return true;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// convert
|
|
//---------------------------------------------------------
|
|
|
|
void MuseData::convert()
|
|
{
|
|
for (int pn = 0; pn < parts.size(); ++pn) {
|
|
Part* part = (score->parts())[pn];
|
|
readPart(parts[pn], part);
|
|
}
|
|
#if 0
|
|
// crash if system does not fit on page (too many instruments)
|
|
|
|
Measure* measure = score->tick2measure(0);
|
|
if (measure) {
|
|
Text* text = new Text(score);
|
|
text->setSubtype(TEXT_TITLE);
|
|
text->setText(parts[0][6]);
|
|
text->setText("mops");
|
|
measure->add(text);
|
|
text = new Text(score);
|
|
text->setSubtype(TEXT_SUBTITLE);
|
|
text->setText(parts[0][6]);
|
|
measure->add(text);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// importMuseData
|
|
// return true on success
|
|
//---------------------------------------------------------
|
|
|
|
bool MuseScore::importMuseData(Score* score, const QString& name)
|
|
{
|
|
MuseData md(score);
|
|
if (!md.read(name))
|
|
return false;
|
|
md.convert();
|
|
return true;
|
|
}
|
|
|