FiguredBass* Score::addFiguredBass() { Element* el = selection().element(); if (el == 0 || (el->type() != NOTE && el->type() != FIGURED_BASS)) { QMessageBox::information(0, QMessageBox::tr("MuseScore:"), QMessageBox::tr("No note or figured bass selected:\n" "Please select a single note or figured bass and retry operation\n"), QMessageBox::Ok, QMessageBox::NoButton); return 0; } ChordRest* cr; if (el->type() == NOTE) cr = static_cast<Note*>(el)->chord(); else if (el->type() == FIGURED_BASS) cr = static_cast<FiguredBass*>(el)->chordRest(); else return 0; QList<Lyrics*> ll = cr->lyricsList(); int no = ll.size(); FiguredBass* fb = new FiguredBass(this); fb->setTrack(cr->track()); fb->setParent(cr); fb->setNo(no); undoAddElement(fb); select(fb, SELECT_SINGLE, 0); return fb; }
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 MuseScore::addTempo() { ChordRest* cr = cs->getSelectedChordRest(); if (!cr) return; // double bps = 2.0; SigEvent event = cs->sigmap()->timesig(cr->tick()); Fraction f = event.nominal(); QString text(QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f))); switch (f.denominator()) { case 1: text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5d)); break; case 2: text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5e)); break; case 4: text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f)); break; case 8: if(f.numerator() % 3 == 0) text = QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f)).arg(QChar(0xd834)).arg(QChar(0xdd6d)); else text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd60)); break; case 16: if(f.numerator() % 3 == 0) text = QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd60)).arg(QChar(0xd834)).arg(QChar(0xdd6d)); else text = text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd61)); break; case 32: if(f.numerator() % 3 == 0) text = QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd61)).arg(QChar(0xd834)).arg(QChar(0xdd6d)); else text = text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd62)); break; case 64: if(f.numerator() % 3 == 0) text = QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd62)).arg(QChar(0xd834)).arg(QChar(0xdd6d)); else text = text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd63)); break; default: break; } TempoText* tt = new TempoText(cs); tt->setParent(cr->segment()); tt->setTrack(cr->track()); tt->setText(text); tt->setFollowText(true); //tt->setTempo(bps); cs->undoAddElement(tt); cv->startEdit(tt); }
void MuseScore::addTempo() { ChordRest* cr = cs->getSelectedChordRest(); if (!cr) return; // double bps = 2.0; SigEvent event = cs->sigmap()->timesig(cr->tick()); Fraction f = event.nominal(); QString text("<sym>noteQuarterUp</sym> = 80"); switch (f.denominator()) { case 1: text = "<sym>noteWhole</sym> = 80"; break; case 2: text = "<sym>noteHalfUp</sym> = 80"; break; case 4: text = "<sym>noteQuarterUp</sym> = 80"; break; case 8: if(f.numerator() % 3 == 0) text = "<sym>noteQuarterUp</sym><sym>textAugmentationDot</sym> = 80"; else text = "<sym>note8thUp</sym> = 80"; break; case 16: if(f.numerator() % 3 == 0) text = text = "<sym>note8thUp</sym><sym>textAugmentationDot</sym> = 80"; else text = "<sym>note16thUp</sym> = 80"; break; case 32: if(f.numerator() % 3 == 0) text = "<sym>note16thUp</sym><sym>textAugmentationDot</sym> = 80"; else text = "<sym>note32thUp</sym> = 80"; break; case 64: if(f.numerator() % 3 == 0) text = "<sym>note32thUp</sym><sym>textAugmentationDot</sym> = 80"; else text = "<sym>note64thUp</sym> = 80"; break; default: break; } TempoText* tt = new TempoText(cs); tt->setParent(cr->segment()); tt->setTrack(cr->track()); tt->setText(text); tt->setFollowText(true); //tt->setTempo(bps); cs->undoAddElement(tt); cv->startEdit(tt); }
void TestChordSymbol::testAddPart() { MasterScore* score = test_pre("add-part"); Segment* seg = score->firstSegment(Segment::Type::ChordRest); ChordRest* cr = seg->cr(0); Harmony* harmony = new Harmony(score); harmony->setHarmony("C7"); harmony->setTrack(cr->track()); harmony->setParent(cr->segment()); score->undoAddElement(harmony); score->doLayout(); test_post(score, "add-part"); }
void MuseScore::addTempo() { ChordRest* cr = cs->getSelectedChordRest(); if (!cr) return; if (editTempo == 0) editTempo = new EditTempo(0); int rv = editTempo->exec(); if (rv == 1) { double bps = editTempo->bpm() / 60.0; TempoText* tt = new TempoText(cs); tt->setParent(cr->segment()); tt->setTrack(cr->track()); tt->setText(editTempo->text()); tt->setTempo(bps); cs->undoAddElement(tt); cs->addRefresh(tt->abbox()); // ?? } }
bool Lyrics::isMelisma() const { // entered as melisma using underscore? if (_ticks > 0) return true; // hyphenated? // if so, it is a melisma only if there is no lyric in same verse on next CR if (_syllabic == Syllabic::BEGIN || _syllabic == Syllabic::MIDDLE) { // find next CR on same track and check for existence of lyric in same verse ChordRest* cr = chordRest(); Segment* s = cr->segment()->next1(); ChordRest* ncr = s ? s->nextChordRest(cr->track()) : nullptr; if (ncr && !ncr->lyrics(_no)) return true; } // default - not a melisma return false; }
bool ChordRest::readProperties(XmlReader& e) { const QStringRef& tag(e.name()); if (tag == "durationType") { setDurationType(e.readElementText()); if (actualDurationType().type() != TDuration::DurationType::V_MEASURE) { if ((type() == Element::Type::REST) && // for backward compatibility, convert V_WHOLE rests to V_MEASURE // if long enough to fill a measure. // OTOH, freshly created (un-initialized) rests have numerator == 0 (< 4/4) // (see Fraction() constructor in fraction.h; this happens for instance // when pasting selection from clipboard): they should not be converted duration().numerator() != 0 && // rest durations are initialized to full measure duration when // created upon reading the <Rest> tag (see Measure::read() ) // so a V_WHOLE rest in a measure of 4/4 or less => V_MEASURE (actualDurationType()==TDuration::DurationType::V_WHOLE && duration() <= Fraction(4, 4)) ) { // old pre 2.0 scores: convert setDurationType(TDuration::DurationType::V_MEASURE); } else // not from old score: set duration fraction from duration type setDuration(actualDurationType().fraction()); } else { if (score()->mscVersion() < 115) { SigEvent event = score()->sigmap()->timesig(e.tick()); setDuration(event.timesig()); } } } else if (tag == "BeamMode") { QString val(e.readElementText()); Beam::Mode bm = Beam::Mode::AUTO; if (val == "auto") bm = Beam::Mode::AUTO; else if (val == "begin") bm = Beam::Mode::BEGIN; else if (val == "mid") bm = Beam::Mode::MID; else if (val == "end") bm = Beam::Mode::END; else if (val == "no") bm = Beam::Mode::NONE; else if (val == "begin32") bm = Beam::Mode::BEGIN32; else if (val == "begin64") bm = Beam::Mode::BEGIN64; else bm = Beam::Mode(val.toInt()); _beamMode = Beam::Mode(bm); } else if (tag == "Attribute" || tag == "Articulation") { // obsolete: "Attribute" Articulation* atr = new Articulation(score()); atr->read(e); add(atr); } else if (tag == "leadingSpace") { qDebug("ChordRest: leadingSpace obsolete"); // _extraLeadingSpace = Spatium(val.toDouble()); e.skipCurrentElement(); } else if (tag == "trailingSpace") { qDebug("ChordRest: trailingSpace obsolete"); // _extraTrailingSpace = Spatium(val.toDouble()); e.skipCurrentElement(); } else if (tag == "Beam") { int id = e.readInt(); Beam* beam = e.findBeam(id); if (beam) beam->add(this); // also calls this->setBeam(beam) else qDebug("Beam id %d not found", id); } else if (tag == "small") _small = e.readInt(); else if (tag == "duration") setDuration(e.readFraction()); else if (tag == "ticklen") { // obsolete (version < 1.12) int mticks = score()->sigmap()->timesig(e.tick()).timesig().ticks(); int i = e.readInt(); if (i == 0) i = mticks; if ((type() == Element::Type::REST) && (mticks == i)) { setDurationType(TDuration::DurationType::V_MEASURE); setDuration(Fraction::fromTicks(i)); } else { Fraction f = Fraction::fromTicks(i); setDuration(f); setDurationType(TDuration(f)); } } else if (tag == "dots") setDots(e.readInt()); else if (tag == "move") _staffMove = e.readInt(); else if (tag == "Slur") { int id = e.intAttribute("id"); if (id == 0) id = e.intAttribute("number"); // obsolete Spanner* spanner = e.findSpanner(id); if (!spanner) qDebug("ChordRest::read(): Slur id %d not found", id); else { QString atype(e.attribute("type")); if (atype == "start") { spanner->setTick(e.tick()); if (spanner->ticks() > 0) // stop has been read first, ticks is tick2 - (-1) spanner->setTick2(spanner->ticks() - 1); spanner->setTrack(track()); if (spanner->type() == Element::Type::SLUR) spanner->setStartElement(this); if (e.pasteMode()) { for (Element* e : spanner->linkList()) { if (e == spanner) continue; Spanner* ls = static_cast<Spanner*>(e); ls->setTick(spanner->tick()); for (Element* ee : linkList()) { ChordRest* cr = static_cast<ChordRest*>(ee); if (cr->score() == ee->score() && cr->staffIdx() == ls->staffIdx()) { ls->setTrack(cr->track()); if (ls->type() == Element::Type::SLUR) ls->setStartElement(cr); break; } } } } } else if (atype == "stop") { spanner->setTick2(e.tick()); spanner->setTrack2(track()); if (spanner->type() == Element::Type::SLUR) spanner->setEndElement(this); Chord* start = static_cast<Chord*>(spanner->startElement()); if (start) spanner->setTrack(start->track()); if (e.pasteMode()) { for (Element* e : spanner->linkList()) { if (e == spanner) continue; Spanner* ls = static_cast<Spanner*>(e); ls->setTick2(spanner->tick2()); for (Element* ee : linkList()) { ChordRest* cr = static_cast<ChordRest*>(ee); if (cr->score() == ee->score() && cr->staffIdx() == ls->staffIdx()) { ls->setTrack2(cr->track()); if (ls->type() == Element::Type::SLUR) ls->setEndElement(cr); break; } } } } } else qDebug("ChordRest::read(): unknown Slur type <%s>", qPrintable(atype)); } e.readNext(); } else if (tag == "Lyrics" /*|| tag == "FiguredBass"*/) { Element* element = Element::name2Element(tag, score()); element->setTrack(e.track()); element->read(e); add(element); } else if (tag == "pos") { QPointF pt = e.readPoint(); if (score()->mscVersion() > 114) setUserOff(pt * spatium()); } else if (tag == "offset") { if (score()->mscVersion() > 114) // || voice() >= 2) { DurationElement::readProperties(e); else if (type() == Element::Type::REST) { DurationElement::readProperties(e); setUserXoffset(0.0); // honor Y offset but not X for rests in older scores } else e.skipCurrentElement(); // ignore manual layout otherwise } else if (DurationElement::readProperties(e)) return true; else return false; return true; }
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(); }