void createTupletNotes( Staff *staff, const std::multimap<ReducedFraction, TupletData> &tuplets) { Score* score = staff->score(); const int track = staff->idx() * VOICES; for (const auto &tupletEvent: tuplets) { const auto &tupletData = tupletEvent.second; if (tupletData.elements.empty()) continue; Tuplet* tuplet = new Tuplet(score); const auto &tupletRatio = tupletLimits(tupletData.tupletNumber).ratio; tuplet->setRatio(tupletRatio.fraction()); tuplet->setDuration(tupletData.len.fraction()); const TDuration baseLen = tupletData.len.fraction() / tupletRatio.denominator(); tuplet->setBaseLen(baseLen); tuplet->setTrack(track); tuplet->setTick(tupletData.onTime.ticks()); tuplet->setVoice(tupletData.voice); Measure* measure = score->tick2measure(tupletData.onTime.ticks()); tuplet->setParent(measure); for (DurationElement *el: tupletData.elements) { tuplet->add(el); el->setTuplet(tuplet); } } }
void MuseScore::tupletDialog() { if (!cs) return; ChordRest* cr = cs->getSelectedChordRest(); if (cr == 0) return; TupletDialog td; if (!td.exec()) return; Tuplet* tuplet = new Tuplet(cs); tuplet->setTrack(cr->track()); tuplet->setTick(cr->tick()); td.setupTuplet(tuplet); // tuplet->setRatio(tuplet->ratio().reduced()); Fraction f1(cr->duration()); tuplet->setDuration(f1); Fraction f = f1 * tuplet->ratio(); f.reduce(); printf("len %s ratio %s base %s\n", qPrintable(f1.print()), qPrintable(tuplet->ratio().print()), qPrintable(f.print())); tuplet->setBaseLen(Fraction(1, f.denominator())); Measure* measure = cr->measure(); tuplet->setParent(measure); cs->cmdCreateTuplet(cr, tuplet); }
void MTrack::createTuplets(int track, Score *score) { for (const auto &tupletEvent: tuplets) { const auto &tupletData = tupletEvent.second; if (tupletData.elements.empty()) continue; Tuplet* tuplet = new Tuplet(score); auto ratioIt = MidiTuplet::tupletRatios().find(tupletData.tupletNumber); Fraction tupletRatio = (ratioIt != MidiTuplet::tupletRatios().end()) ? ratioIt->second : Fraction(2, 2); if (ratioIt == MidiTuplet::tupletRatios().end()) qDebug("Tuplet ratio not found for tuplet number: %d", tupletData.tupletNumber); tuplet->setRatio(tupletRatio); tuplet->setDuration(tupletData.len); TDuration baseLen(tupletData.len / tupletRatio.denominator()); tuplet->setBaseLen(baseLen); tuplet->setTrack(track); tuplet->setTick(tupletData.onTime.ticks()); Measure* measure = score->tick2measure(tupletData.onTime.ticks()); tuplet->setParent(measure); for (DurationElement *el: tupletData.elements) { tuplet->add(el); el->setTuplet(tuplet); } } }
void MsScWriter::doTriplet(Chord* cr, StartStop triplet) { qDebug() << "MsScWriter::doTriplet(" << triplet << ")" ; if (triplet == ST_START) { tuplet = new Tuplet(score); tuplet->setTrack(0); tuplet->setRatio(Fraction(3, 2)); tuplet->setTick(tick); currentMeasure->add(tuplet); } else if (triplet == ST_STOP) { if (tuplet) { cr->setTuplet(tuplet); tuplet->add(cr); tuplet = 0; } else qDebug("BWW::import: triplet stop without triplet start\n"); } else if (triplet == ST_CONTINUE) { if (!tuplet) qDebug("BWW::import: triplet continue without triplet start\n"); } else if (triplet == ST_NONE) { if (tuplet) qDebug("BWW::import: triplet none inside triplet\n"); } else qDebug("unknown triplet type %d\n", triplet); if (tuplet) { cr->setTuplet(tuplet); tuplet->add(cr); } }
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].toLatin1() - '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; } } MScore::Direction dir = MScore::AUTO; if (s.size() >= 23) { if (s[22] == 'u') dir = MScore::UP; else if (s[22] == 'd') dir = MScore::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].toLatin1() - '0'; if (a == 3 && s[20] != ':') b = 2; else { b = s[21].toLatin1() - '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", 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"); 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->setArticulationType(Articulation_Staccato); chord->add(atr); } else if (an[i] == '_') { Articulation* atr = new Articulation(score); atr->setArticulationType(Articulation_Tenuto); chord->add(atr); } else if (an[i] == 'v') { Articulation* atr = new Articulation(score); atr->setArticulationType(Articulation_Upbow); chord->add(atr); } else if (an[i] == 'n') { Articulation* atr = new Articulation(score); atr->setArticulationType(Articulation_Downbow); chord->add(atr); } else if (an[i] == 't') { Articulation* atr = new Articulation(score); atr->setArticulationType(Articulation_Trill); chord->add(atr); } else if (an[i] == 'F') { Articulation* atr = new Articulation(score); atr->setUp(true); atr->setArticulationType(Articulation_Fermata); chord->add(atr); } else if (an[i] == 'E') { Articulation* atr = new Articulation(score); atr->setUp(false); atr->setArticulationType(Articulation_Fermata); chord->add(atr); } else if (an[i] == 'O') { // Articulation* atr = new Articulation(score); // atr->setArticulationType(Articulation_Downbow); // chord->add(atr); qDebug("%06d: open string '%c' not implemented", tick, an[i].toLatin1()); } 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", tick, an[i].toLatin1()); } } if (!dynamics.isEmpty()) { Dynamic* dyn = new Dynamic(score); dyn->setDynamicType(dynamics); dyn->setTrack(gstaff * VOICES); Segment* s = measure->getSegment(Segment::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); }