예제 #1
0
ChordRest* prevChordRest(ChordRest* cr)
      {
      if (!cr)
            return 0;
      if (cr->isGrace()) {
            // cr is a grace note
            Chord* c  = static_cast<Chord*>(cr);
            Chord* pc = static_cast<Chord*>(cr->parent());
            QList<Chord*> graceNotesBefore;
            QList<Chord*> graceNotesAfter;

            if(cr->isGraceBefore()){
                  pc->getGraceNotesBefore(&graceNotesBefore);
                  auto i = std::find(graceNotesBefore.begin(),graceNotesBefore.end(), c);
                  if (i == graceNotesBefore.end())
                        return 0;
                  if (i == graceNotesBefore.begin())
                        cr = pc;
                  else
                        return *--i;
                  }
            else {
                  int n = pc->getGraceNotesAfter(&graceNotesAfter);
                  for(int i = 0; i < n; i++){
                        if(c == graceNotesAfter[(i)]){
                              if(i > 0)
                                    return graceNotesAfter[i - 1];
                              else
                                    return 0;
                              }
                        }
                  }
            }
      else {
            if (cr->type() == Element::CHORD) {
                  Chord* c = static_cast<Chord*>(cr);
                  if (!c->graceNotes().empty())
                        return c->graceNotes().back();
                  }
            }
      int track = cr->track();
      Segment::SegmentTypes st = Segment::SegChordRest;
      for (Segment* seg = cr->segment()->prev1(st); seg; seg = seg->prev1(st)) {
            ChordRest* e = static_cast<ChordRest*>(seg->element(track));
            if (e)
                  return e;
            }
      return 0;
      }
예제 #2
0
void TestNote::grace()
      {
      Score* score = readScore(DIR + "grace.mscx");
      score->doLayout();
      Chord* chord = score->firstMeasure()->findChord(0, 0);
      Note* note = chord->upNote();

      // create
      score->setGraceNote(chord, note->pitch(), NoteType::APPOGGIATURA, MScore::division/2);
      Chord* gc = chord->graceNotes().first();
      Note* gn = gc->notes().first();
//      Note* n = static_cast<Note*>(writeReadElement(gn));
//      QCOMPARE(n->noteType(), NoteType::APPOGGIATURA);
//      delete n;

      // tie
      score->startCmd();
      score->select(gn);
      score->cmdAddTie();
      score->endCmd();
//      n = static_cast<Note*>(writeReadElement(gn));
//      QVERIFY(n->tieFor() != 0);
//      delete n;

      // tremolo
      score->startCmd();
      Tremolo* tr = new Tremolo(score);
      tr->setTremoloType(TremoloType::R16);
      tr->setParent(gc);
      tr->setTrack(gc->track());
      score->undoAddElement(tr);
      score->endCmd();
//      Chord* c = static_cast<Chord*>(writeReadElement(gc));
//      QVERIFY(c->tremolo() != 0);
//      delete c;

      // articulation
      score->startCmd();
      Articulation* ar = new Articulation(score);
      ar->setArticulationType(ArticulationType::Sforzatoaccent);
      ar->setParent(gc);
      ar->setTrack(gc->track());
      score->undoAddElement(ar);
      score->endCmd();
//      c = static_cast<Chord*>(writeReadElement(gc));
//      QVERIFY(c->articulations().size() == 1);
//      delete c;

      QVERIFY(saveCompareScore(score, "grace-test.mscx", DIR + "grace-ref.mscx"));

      }
예제 #3
0
Note* searchTieNote(Note* note)
      {
      Note* note2  = 0;
      Chord* chord = note->chord();
      Segment* seg = chord->segment();
      Part* part   = chord->part();
      int strack   = part->staves()->front()->idx() * VOICES;
      int etrack   = strack + part->staves()->size() * VOICES;

      if (chord->isGraceBefore()) {
            chord = toChord(chord->parent());

            // try to tie to next grace note

            int index = chord->graceIndex();
            for (Chord* c : chord->graceNotes()) {
                  if (c->graceIndex() == index + 1) {
                        note2 = c->findNote(note->pitch());
                        if (note2) {
                              printf("found grace-grace tie\n");
                              return note2;
                              }
                        }
                  }

            // try to tie to note in parent chord
            note2 = chord->findNote(note->pitch());
            if (note2)
                  return note2;
            }
      else if (chord->isGraceAfter()) {
            // grace after
            // we will try to tie to note in next normal chord, below
            // meanwhile, set chord to parent chord so the endTick calculation will make sense
            chord = toChord(chord->parent());
            }
      else {
            // normal chord
            // try to tie to grace note after if present
            QVector<Chord*> gna = chord->graceNotesAfter();
            if (!gna.empty()) {
                  Chord* gc = gna[0];
                  note2 = gc->findNote(note->pitch());
                  if (note2)
                        return note2;
                  }
            }
      // at this point, chord is a regular chord, not a grace chord
      // and we are looking for a note in the *next* chord (grace or regular)

      // calculate end of current note duration
      // but err on the safe side in case there is roundoff in tick count
      int endTick = chord->tick() + chord->actualTicks() - 1;

      while ((seg = seg->next1(SegmentType::ChordRest))) {
            // skip ahead to end of current note duration as calculated above
            // but just in case, stop if we find element in current track
            if (seg->tick() < endTick  && !seg->element(chord->track()))
                  continue;
            for (int track = strack; track < etrack; ++track) {
                  Element* e = seg->element(track);
                  if (e == 0 || !e->isChord())
                        continue;
                  Chord* c = toChord(e);
                  // if there are grace notes before, try to tie to first one
                  QVector<Chord*> gnb = c->graceNotesBefore();
                  if (!gnb.empty()) {
                        Chord* gc = gnb[0];
                        Note* gn2 = gc->findNote(note->pitch());
                        if (gn2)
                              return gn2;
                        }
                  int staffIdx = c->staffIdx() + c->staffMove();
                  if (staffIdx != chord->staffIdx() + chord->staffMove())  // cannot happen?
                        continue;
                  for (Note* n : c->notes()) {
                        if (n->pitch() == note->pitch()) {
                              if (note2 == 0 || c->track() == chord->track())
                                    note2 = n;
                              }
                        }
                  }
            if (note2)
                  break;
            }
      return note2;
      }
예제 #4
0
ChordRest* nextChordRest(ChordRest* cr)
      {
      if (!cr)
            return 0;

      if (cr->isGrace()) {
            //
            // cr is a grace note

            Chord* c  = static_cast<Chord*>(cr);
            Chord* pc = static_cast<Chord*>(cr->parent());

            if (cr->isGraceBefore()) {
                  QList<Chord*> graceNotesBefore;
                  pc->getGraceNotesBefore(&graceNotesBefore);
                  auto i = std::find(graceNotesBefore.begin(), graceNotesBefore.end(), c);
                  if (i == graceNotesBefore.end())
                        return 0;   // unable to find self?
                  ++i;
                  if (i != graceNotesBefore.end())
                        return *i;
                  // if this was last grace note before, return parent
                  return pc;
                  }
            else {
                  QList<Chord*> graceNotesAfter;
                  pc->getGraceNotesAfter(&graceNotesAfter);
                  auto i = std::find(graceNotesAfter.begin(), graceNotesAfter.end(), c);
                  if (i == graceNotesAfter.end())
                        return 0;   // unable to find self?
                  ++i;
                  if (i != graceNotesAfter.end())
                        return *i;
                  // if this was last grace note after, fall through to find next main note
                  cr = pc;
                  }
            }
      else {
            //
            // cr is not a grace note
            if (cr->type() == Element::Type::CHORD) {
                  Chord* c = static_cast<Chord*>(cr);
                  if (!c->graceNotes().empty()) {
                        QList<Chord*> graceNotesAfter;
                        c->getGraceNotesAfter(&graceNotesAfter);
                        if (!graceNotesAfter.isEmpty())
                              return graceNotesAfter.first();
                        }
                  }
            }

      int track = cr->track();
      Segment::Type st = Segment::Type::ChordRest;

      for (Segment* seg = cr->segment()->next1MM(st); seg; seg = seg->next1MM(st)) {
            ChordRest* e = static_cast<ChordRest*>(seg->element(track));
            if (e) {
                  if (e->type() == Element::Type::CHORD) {
                        Chord* c = static_cast<Chord*>(e);
                        if (!c->graceNotes().empty()) {
                              QList<Chord*> graceNotesBefore;
                              c->getGraceNotesBefore(&graceNotesBefore);
                              if (!graceNotesBefore.isEmpty())
                                    return graceNotesBefore.first();
                              }
                        }
                  return e;
                  }
            }

      return 0;
      }