Skip to content

Commit

Permalink
fix #22023 MusicXML import/export of simple grace notes
Browse files Browse the repository at this point in the history
  • Loading branch information
lasconic committed Aug 30, 2013
1 parent 4c2e2e9 commit 1eafb0e
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 76 deletions.
7 changes: 5 additions & 2 deletions libmscore/cmd.cpp
Expand Up @@ -515,10 +515,13 @@ void Score::cmdAddInterval(int val, const QList<Note*>& nl)
/// \len is the visual duration of the grace note (1/16 or 1/32)
//---------------------------------------------------------

void Score::setGraceNote(Chord* ch, int pitch, NoteType type, bool /*behind*/, int len)
void Score::setGraceNote(Chord* ch, int pitch, NoteType type, bool /*behind*/, int len, int tpc)
{
Note* note = new Note(this);
note->setPitch(pitch);
if(tpc == INVALID_TPC)
note->setPitch(pitch);
else
note->setPitch(pitch, tpc);

Chord* chord = new Chord(this);
chord->setTrack(ch->track());
Expand Down
3 changes: 2 additions & 1 deletion libmscore/score.h
Expand Up @@ -31,6 +31,7 @@
#include "accidental.h"
#include "note.h"
#include "spannermap.h"
#include "pitchspelling.h"

class QPainter;

Expand Down Expand Up @@ -524,7 +525,7 @@ class Score : public QObject {
void undoAddBracket(Staff* staff, int level, BracketType type, int span);
void undoRemoveBracket(Bracket*);

void setGraceNote(Chord*, int pitch, NoteType type, bool behind, int len);
void setGraceNote(Chord*, int pitch, NoteType type, bool behind, int len, int tpc = INVALID_TPC);

Segment* setNoteRest(Segment*, int track, NoteVal nval, Fraction, MScore::Direction stemDirection = MScore::AUTO);
void changeCRlen(ChordRest* cr, const TDuration&);
Expand Down
6 changes: 4 additions & 2 deletions libmscore/undo.cpp
Expand Up @@ -854,8 +854,10 @@ void Score::undoAddElement(Element* element)
if (element->type() == Element::FINGERING)
element->score()->layoutFingering(static_cast<Fingering*>(element));
else if (element->type() == Element::CHORD) {
for (Note* n : static_cast<Chord*>(element)->notes())
n->setTpcFromPitch();
for (Note* n : static_cast<Chord*>(element)->notes()) {
if(n->tpc() == INVALID_TPC)
n->setTpcFromPitch();
}
element->score()->updateNotes();
}
return;
Expand Down
4 changes: 3 additions & 1 deletion mscore/exportxml.cpp
Expand Up @@ -4348,7 +4348,9 @@ void ExportMusicXml::write(QIODevice* dev)
{
Chord* c = static_cast<Chord*>(el);
const QList<Lyrics*>* ll = &c->lyricsList();

for (Chord* g : c->graceNotes()) {
chord(g, sstaff, ll, part->instr()->useDrumset());
}
chord(c, sstaff, ll, part->instr()->useDrumset());
break;
}
Expand Down
90 changes: 43 additions & 47 deletions mscore/importxml.cpp
Expand Up @@ -1999,12 +1999,12 @@ Measure* MusicXml::xmlMeasure(Part* part, QDomElement e, int number, int measure
measure->setIrregular(true);

int cv = 0; // current voice for chords, default is 0

QList<GraceNoteInfo> graceNotesInfos;
for (e = e.firstChildElement(); !e.isNull(); e = e.nextSiblingElement()) {
if (e.tagName() == "attributes")
xmlAttributes(measure, staff, e.firstChildElement());
else if (e.tagName() == "note") {
xmlNote(measure, staff, part->id(), beam, cv, e);
xmlNote(measure, staff, part->id(), beam, cv, e, graceNotesInfos);
moveTick(measure->tick(), tick, maxtick, noteTypeTickFr, divisions, e);
#ifdef DEBUG_TICK
qDebug(" after inserting note tick=%d", tick);
Expand Down Expand Up @@ -4492,7 +4492,7 @@ static FiguredBass* findLastFiguredBass(int track, Segment* seg)
\a Staff is the number of first staff of the part this note belongs to.
*/

void MusicXml::xmlNote(Measure* measure, int staff, const QString& partId, Beam*& beam, int& currentVoice, QDomElement e)
void MusicXml::xmlNote(Measure* measure, int staff, const QString& partId, Beam*& beam, int& currentVoice, QDomElement e, QList<GraceNoteInfo>& gni)
{
int ticks = 0;
#ifdef DEBUG_TICK
Expand Down Expand Up @@ -4825,8 +4825,6 @@ void MusicXml::xmlNote(Measure* measure, int staff, const QString& partId, Beam*
char c = step[0].toLatin1();
note = new Note(score);
note->setHeadGroup(headGroup);
// note->setTrack(track);
// note->setStaffMove(move);
if (noteheadColor != QColor::Invalid)
note->setColor(noteheadColor);

Expand All @@ -4835,57 +4833,24 @@ void MusicXml::xmlNote(Measure* measure, int staff, const QString& partId, Beam*
note->setVeloOffset(velocity);
}

// if (grace)
// qDebug(" grace: nrOfGraceSegsReq: %d", nrOfGraceSegsReq(pn));
int gl = nrOfGraceSegsReq(pn);
// TODO-S cr = measure->findChord(loc_tick, track, grace);
// implementation of grace notes has changed

cr = measure->findChord(loc_tick, track);
if (cr == 0) {
// Segment::SegmentType st = Segment::SegChordRest;
cr = new Chord(score);
cr->setBeamMode(bm);
cr->setTrack(track);
// qDebug(" grace=%d", grace);
if (grace) {
NoteType nt = NOTE_APPOGGIATURA;
if (graceSlash == "yes")
nt = NOTE_ACCIACCATURA;
((Chord*)cr)->setNoteType(nt);
// the subtraction causes a grace at tick=0 to fail
// cr->setTick(tick - (MScore::division / 2));
if (durationType.type() == TDuration::V_QUARTER) {
((Chord*)cr)->setNoteType(NOTE_GRACE4);
cr->setDurationType(TDuration::V_QUARTER);
}
else if (durationType.type() == TDuration::V_16TH) {
((Chord*)cr)->setNoteType(NOTE_GRACE16);
cr->setDurationType(TDuration::V_16TH);
}
else if (durationType.type() == TDuration::V_32ND) {
((Chord*)cr)->setNoteType(NOTE_GRACE32);
cr->setDurationType(TDuration::V_32ND);
}
else
cr->setDurationType(TDuration::V_EIGHT);
// st = Segment::SegGrace;
}
else {
if(!grace) {
cr = new Chord(score);
cr->setBeamMode(bm);
cr->setTrack(track);

if (durationType.type() == TDuration::V_INVALID)
durationType.setType(TDuration::V_QUARTER);
cr->setDurationType(durationType);
}
cr->setDots(dots);
cr->setDuration(cr->durationType().fraction());
//qDebug(" cr->tick()=%d ", cr->tick());
//TODO-S deal with grace notes
if(gl == 0) {
cr->setDots(dots);
cr->setDuration(cr->durationType().fraction());
Segment* s = measure->getSegment(cr, loc_tick);
s->add(cr);
}
}
cr->setStaffMove(move);
if(cr)
cr->setStaffMove(move);

// pitch must be set before adding note to chord as note
// is inserted into pitch sorted list (ws)
Expand All @@ -4902,8 +4867,39 @@ void MusicXml::xmlNote(Measure* measure, int staff, const QString& partId, Beam*
}
else
xmlSetPitch(note, c, alter, octave, ottava, track);

if(grace) {
NoteType nt = NOTE_APPOGGIATURA;
int len = MScore::division/2;
if (graceSlash == "yes")
nt = NOTE_ACCIACCATURA;
if (durationType.type() == TDuration::V_QUARTER) {
nt = NOTE_GRACE4;
len = MScore::division;
}
else if (durationType.type() == TDuration::V_16TH) {
nt = NOTE_GRACE16;
len = MScore::division/4;
}
else if (durationType.type() == TDuration::V_32ND) {
nt = NOTE_GRACE32;
len = MScore::division/8;
}
gni.append({nt, note->pitch(), note->tpc(), len});
delete note;
return;
}

cr->add(note);

if(!grace && gni.size() > 0) {
for (int i = gni.size() - 1; i >= 0; --i) {
GraceNoteInfo g = gni.at(i);
score->setGraceNote(static_cast<Chord*>(cr), g.pitch, g.type, false, g.len, g.tpc);
}
gni.clear();
}

static_cast<Chord*>(cr)->setNoStem(noStem);

// qDebug("staff for new note: %p (staff=%d, relStaff=%d)",
Expand Down
10 changes: 9 additions & 1 deletion mscore/musicxml.h
Expand Up @@ -28,6 +28,7 @@

#include "libmscore/fraction.h"
#include "libmscore/mscore.h"
#include "libmscore/pitchspelling.h"
#include "importxmlfirstpass.h"
#include "musicxmlsupport.h"

Expand Down Expand Up @@ -152,6 +153,13 @@ class JumpMarkerDesc {

typedef QList<JumpMarkerDesc> JumpMarkerDescList;

struct GraceNoteInfo {
NoteType type;
int pitch;
int tpc;
int len;
};

//---------------------------------------------------------
// MusicXml
//---------------------------------------------------------
Expand Down Expand Up @@ -228,7 +236,7 @@ class MusicXml {
QMap<int, Lyrics*>& defyLyrics,
QList<Lyrics*>& unNumbrdLyrics);
void xmlNotations(Note* note, ChordRest* cr, int trk, int ticks, QDomElement node);
void xmlNote(Measure*, int stave, const QString& partId, Beam*& beam, int& currentVoice, QDomElement node);
void xmlNote(Measure*, int stave, const QString& partId, Beam*& beam, int& currentVoice, QDomElement node, QList<GraceNoteInfo>&);
void xmlHarmony(QDomElement node, int tick, Measure* m, int staff);
int xmlClef(QDomElement, int staffIdx, Measure*);
void readPageFormat(PageFormat* pf, QDomElement de, qreal conversion);
Expand Down
14 changes: 7 additions & 7 deletions mtest/musicxml/io/testGrace1.xml
Expand Up @@ -29,7 +29,7 @@
<part id="P1">
<measure number="1">
<attributes>
<divisions>8</divisions>
<divisions>1</divisions>
<key>
<fifths>0</fifths>
<mode>major</mode>
Expand All @@ -48,7 +48,7 @@
<step>G</step>
<octave>4</octave>
</pitch>
<duration>8</duration>
<duration>1</duration>
<voice>1</voice>
<type>quarter</type>
<stem>up</stem>
Expand All @@ -68,7 +68,7 @@
<step>G</step>
<octave>4</octave>
</pitch>
<duration>8</duration>
<duration>1</duration>
<voice>1</voice>
<type>quarter</type>
<stem>up</stem>
Expand All @@ -90,7 +90,7 @@
<step>G</step>
<octave>4</octave>
</pitch>
<duration>8</duration>
<duration>1</duration>
<voice>1</voice>
<type>quarter</type>
<stem>up</stem>
Expand All @@ -110,7 +110,7 @@
<step>G</step>
<octave>4</octave>
</pitch>
<duration>16</duration>
<duration>2</duration>
<voice>1</voice>
<type>half</type>
<stem>up</stem>
Expand All @@ -132,7 +132,7 @@
<step>G</step>
<octave>4</octave>
</pitch>
<duration>8</duration>
<duration>1</duration>
<voice>1</voice>
<type>quarter</type>
<stem>up</stem>
Expand All @@ -153,7 +153,7 @@
<step>G</step>
<octave>4</octave>
</pitch>
<duration>8</duration>
<duration>1</duration>
<voice>1</voice>
<type>quarter</type>
<stem>up</stem>
Expand Down

0 comments on commit 1eafb0e

Please sign in to comment.