Exemplo n.º 1
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()) {
            // grace before
            // try to tie to note in parent chord
            chord = toChord(chord->parent());
            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(Segment::Type::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;
      }
Exemplo n.º 2
0
Note* Glissando::guessInitialNote(Chord* chord)
      {
      switch (chord->noteType()) {
//            case NoteType::INVALID:
//                  return nullptr;
            // for grace notes before, previous chord is previous chord of parent chord
            case NoteType::ACCIACCATURA:
            case NoteType::APPOGGIATURA:
            case NoteType::GRACE4:
            case NoteType::GRACE16:
            case NoteType::GRACE32:
                  // move unto parent chord and proceed to standard case
                  if (chord->parent() && chord->parent()->type() == Element::Type::CHORD)
                        chord = static_cast<Chord*>(chord->parent());
                  else
                        return nullptr;
                  break;
            // for grace notes after, return top note of parent chord
            case NoteType::GRACE8_AFTER:
            case NoteType::GRACE16_AFTER:
            case NoteType::GRACE32_AFTER:
                  if (chord->parent() && chord->parent()->type() == Element::Type::CHORD)
                        return static_cast<Chord*>(chord->parent())->upNote();
                  else                          // no parent or parent is not a chord?
                        return nullptr;
            case NoteType::NORMAL:
                  {
                  // if chord has grace notes before, the last one is the previous note
                  QVector<Chord*>graces = chord->graceNotesBefore();
                  if (graces.size() > 0)
                        return graces.last()->upNote();
                  }
                  break;                        // else process to standard case
            default:
                  break;
            }

      // standard case (NORMAL or grace before chord)

      // if parent not a segment, can't locate a target note
      if (chord->parent()->type() != Element::Type::SEGMENT)
            return nullptr;

      int         chordTrack  = chord->track();
      Segment*    segm        = chord->segment();
      Part*       part        = chord->part();
      if (segm != nullptr)
            segm = segm->prev1();
      while (segm) {
            // if previous segment is a ChordRest segment
            if (segm->segmentType() == Segment::Type::ChordRest) {
                  Chord* target = nullptr;
                  // look for a Chord in the same track
                  if (segm->element(chordTrack) && segm->element(chordTrack)->type() == Element::Type::CHORD)
                        target = static_cast<Chord*>(segm->element(chordTrack));
                  else              // if no same track, look for other chords in the same instrument
                        for (Element* currChord : segm->elist())
                              if (currChord != nullptr && currChord->type() == Element::Type::CHORD
                                          && static_cast<Chord*>(currChord)->part() == part) {
                                    target = static_cast<Chord*>(currChord);
                                    break;
                                    }
                  // if we found a target previous chord
                  if (target) {
                        // if chord has grace notes after, the last one is the previous note
                        QVector<Chord*>graces = target->graceNotesAfter();
                        if (graces.size() > 0)
                              return graces.last()->upNote();
                        return target->upNote();      // if no grace after, return top note
                        }
                  }
            segm = segm->prev1();
            }
      qDebug("no first note for glissando found");
      return nullptr;
      }