Fraction DurationElement::globalDuration() const { Fraction f(_duration); for (Tuplet* t = tuplet(); t; t = t->tuplet()) f /= t->ratio(); return f; }
int GuitarPro5::readBeat(int tick, int voice, Measure* measure, int staffIdx, Tuplet** tuplets, bool /*mixChange*/) { uchar beatBits = readUChar(); bool dotted = beatBits & BEAT_DOTTED; slide = -1; int track = staffIdx * VOICES + voice; if (slides.contains(track)) slide = slides.take(track); int pause = -1; if (beatBits & BEAT_PAUSE) pause = readUChar(); // readDuration int len = readChar(); int tuple = 0; if (beatBits & BEAT_TUPLET) tuple = readInt(); Segment* segment = measure->getSegment(Segment::Type::ChordRest, tick); if (beatBits & BEAT_CHORD) { int numStrings = score->staff(staffIdx)->part()->instr()->stringData()->strings(); skip(17); QString name = readPascalString(21); skip(4); // no header to be read in the GP5 format - default to true. readChord(segment, staffIdx * VOICES, numStrings, name, true); skip(32); } Lyrics* lyrics = 0; if (beatBits & BEAT_LYRICS) { QString txt = readDelphiString(); lyrics = new Lyrics(score); lyrics->setText(txt); } gpLyrics.beatCounter++; if (gpLyrics.beatCounter >= gpLyrics.fromBeat && gpLyrics.lyricTrack == staffIdx+1) { int index = gpLyrics.beatCounter - gpLyrics.fromBeat; if (index < gpLyrics.lyrics.size()) { lyrics = new Lyrics(score); lyrics->setText(gpLyrics.lyrics[index]); } } int beatEffects = 0; if (beatBits & BEAT_EFFECTS) beatEffects = readBeatEffects(track, segment); if (beatBits & BEAT_MIX_CHANGE) readMixChange(measure); int strings = readUChar(); // used strings mask Fraction l = len2fraction(len); // Some beat effects could add a Chord before this ChordRest* cr = segment->cr(track); if (voice != 0 && pause == 0 && strings == 0) cr = 0; else { if (strings == 0) { if (cr) { segment->remove(cr); delete cr; cr = 0; } cr = new Rest(score); } else { if (!cr) cr = new Chord(score); } cr->setTrack(track); TDuration d(l); d.setDots(dotted ? 1 : 0); if (dotted) l = l + (l/2); if (tuple) { Tuplet* tuplet = tuplets[staffIdx * 2 + voice]; if ((tuplet == 0) || (tuplet->elementsDuration() == tuplet->baseLen().fraction() * tuplet->ratio().numerator())) { tuplet = new Tuplet(score); // int track = staffIdx * 2 + voice; tuplets[staffIdx * 2 + voice] = tuplet; tuplet->setTrack(cr->track()); setTuplet(tuplet, tuple); tuplet->setParent(measure); } tuplet->setTrack(cr->track()); tuplet->setBaseLen(l); tuplet->setDuration(l * tuplet->ratio().denominator()); cr->setTuplet(tuplet); tuplet->add(cr); } cr->setDuration(l); if (cr->type() == Element::Type::REST && (pause == 0 || l == measure->len())) cr->setDurationType(TDuration::DurationType::V_MEASURE); else cr->setDurationType(d); if(!segment->cr(track)) segment->add(cr); Staff* staff = cr->staff(); int numStrings = staff->part()->instr()->stringData()->strings(); bool hasSlur = false; for (int i = 6; i >= 0; --i) { if (strings & (1 << i) && ((6-i) < numStrings)) { Note* note = new Note(score); if (dotted) { // there is at most one dotted note in this guitar pro version NoteDot* dot = new NoteDot(score); dot->setIdx(0); dot->setParent(note); dot->setTrack(track); // needed to know the staff it belongs to (and detect tablature) dot->setVisible(true); note->add(dot); } static_cast<Chord*>(cr)->add(note); hasSlur = readNote(6-i, note); note->setTpcFromPitch(); } } createSlur(hasSlur, staffIdx, cr); if (lyrics) cr->add(lyrics); } int rr = readChar(); if (cr && (cr->type() == Element::Type::CHORD)) { Chord* chord = static_cast<Chord*>(cr); applyBeatEffects(chord, beatEffects); if (rr == ARPEGGIO_DOWN) chord->setStemDirection(MScore::Direction::DOWN); else if (rr == ARPEGGIO_UP) chord->setStemDirection(MScore::Direction::UP); } int r = readChar(); if (r & 0x8) { int rrr = readChar(); qDebug(" 3beat read 0x%02x", rrr); } if (cr && (cr->type() == Element::Type::CHORD) && slide > 0) createSlide(slide, cr, staffIdx); restsForEmptyBeats(segment, measure, cr, l, track, tick); return cr ? cr->actualTicks() : measure->ticks(); }