void MTrack::fillGapWithRests(Score* score, int voice, const Fraction &startChordTickFrac, const Fraction &restLength, int track) { Fraction startChordTick = startChordTickFrac; Fraction restLen = restLength; while (restLen > 0) { Fraction len = restLen; Measure* measure = score->tick2measure(startChordTick.ticks()); if (startChordTick >= Fraction::fromTicks(measure->tick() + measure->ticks())) { qDebug("tick2measure: %d end of score?", startChordTick.ticks()); startChordTick += restLen; restLen = Fraction(0); break; } len = splitDurationOnBarBoundary(len, startChordTick, measure); if (len >= Fraction::fromTicks(measure->ticks())) { // rest to the whole measure len = Fraction::fromTicks(measure->ticks()); if (voice == 0) { TDuration duration(TDuration::V_MEASURE); Rest* rest = new Rest(score, duration); rest->setDuration(measure->len()); rest->setTrack(track); Segment* s = measure->getSegment(rest, startChordTick.ticks()); s->add(rest); } restLen -= len; startChordTick += len; } else { auto dl = toDurationList(measure, voice, startChordTick, len, Meter::DurationType::REST); if (dl.isEmpty()) { qDebug("cannot create duration list for len %d", len.ticks()); restLen = Fraction(0); // fake break; } for (const auto &durationPair: dl) { const TDuration &duration = durationPair.second; const Fraction &tupletRatio = durationPair.first; len = duration.fraction() / tupletRatio; Rest* rest = new Rest(score, duration); rest->setDuration(duration.fraction()); rest->setTrack(track); Segment* s = measure->getSegment(Segment::SegChordRest, startChordTick.ticks()); s->add(rest); addElementToTuplet(voice, startChordTick, len, rest); restLen -= len; startChordTick += len; } } } }
void fillGapsWithRests(Score* score, int ctick, int restLen, int track) { bool useDots = preferences.midiImportOperations.currentTrackOperations().useDots; while (restLen > 0) { int len = restLen; Measure* measure = score->tick2measure(ctick); if (ctick >= measure->tick() + measure->ticks()) { qDebug("tick2measure: %d end of score?", ctick); ctick += restLen; restLen = 0; break; } // split rest on measure boundary if ((ctick + len) > measure->tick() + measure->ticks()) len = measure->tick() + measure->ticks() - ctick; if (len >= measure->ticks()) { len = measure->ticks(); TDuration d(TDuration::V_MEASURE); Rest* rest = new Rest(score, d); rest->setDuration(measure->len()); rest->setTrack(track); Segment* s = measure->getSegment(rest, ctick); s->add(rest); restLen -= len; ctick += len; } else { QList<TDuration> dl = Meter::toDurationList(ctick - measure->tick(), ctick + len - measure->tick(), measure->timesig(), Meter::DurationType::REST, useDots); if (dl.isEmpty()) { qDebug("cannot create duration list for len %d", len); restLen = 0; // fake break; } foreach (TDuration d, dl) { Rest* rest = new Rest(score, d); rest->setDuration(d.fraction()); rest->setTrack(track); Segment* s = measure->getSegment(Segment::SegChordRest, ctick); s->add(rest); restLen -= d.ticks(); ctick += d.ticks(); } } }
void setTempoToScore(Score *score, int tick, double beatsPerSecond) { if (score->tempomap()->find(tick) != score->tempomap()->end()) return; // don't repeat tempo, always set only tempo for tick 0 if (tick > 0 && score->tempo(tick) == beatsPerSecond) return; score->setTempo(tick, beatsPerSecond); auto *data = preferences.midiImportOperations.data(); if (data->trackOpers.showTempoText.value()) { const int tempoInBpm = qRound(beatsPerSecond * 60.0); TempoText *tempoText = new TempoText(score); tempoText->setTempo(beatsPerSecond); tempoText->setXmlText(QString("<sym>metNoteQuarterUp</sym> = %1").arg(tempoInBpm)); tempoText->setTrack(0); Measure *measure = score->tick2measure(tick); if (!measure) { qDebug("MidiTempo::setTempoToScore: no measure for tick %d", tick); return; } Segment *segment = measure->getSegment(Segment::Type::ChordRest, tick); if (!segment) { qDebug("MidiTempo::setTempoToScore: no chord/rest segment for tempo at %d", tick); return; } segment->add(tempoText); data->hasTempoText = true; // to show tempo text column in the MIDI import panel } }
void GuitarPro5::readMeasures(int /*startingTempo*/) { Measure* measure = score->firstMeasure(); bool mixChange = false; for (int bar = 0; bar < measures; ++bar, measure = measure->nextMeasure()) { const GpBar& gpbar = bars[bar]; if (!gpbar.marker.isEmpty()) { Text* s = new RehearsalMark(score); s->setText(gpbar.marker.trimmed()); s->setTrack(0); Segment* segment = measure->getSegment(Segment::Type::ChordRest, measure->tick()); segment->add(s); } Tuplet* tuplets[staves * 2]; // two voices for (int track = 0; track < staves*2; ++track) tuplets[track] = 0; for (int staffIdx = 0; staffIdx < staves; ++staffIdx) { readMeasure(measure, staffIdx, tuplets, mixChange); if (!(((bar == (measures-1)) && (staffIdx == (staves-1))))) { /*int a = */ readChar(); // qDebug(" ======skip %02x", a); } } if (bar == 1 && !mixChange) setTempo(tempo, score->firstMeasure()); } }
void Lilypond::addNote(const LNote& lnote) { createMeasure(); Segment* segment = new Segment(measure); segment->setSubtype(SegChordRest); segment->setTick(tick); segment->setParent(measure); measure->add(segment); Chord* chord = new Chord(score); chord->setTrack(staff->idx() * VOICES); chord->setParent(segment); Duration d; d.setVal(lnote.len); chord->setDurationType(d); segment->add(chord); Note* note = new Note(score); note->setPitch(lnote.pitch); note->setTpcFromPitch(); note->setParent(chord); note->setTrack(staff->idx() * VOICES); chord->add(note); tick += lnote.len; }
//----------------------------------------------------- // //----------------------------------------------------- int readSegments() { int scan_index; int type; int n_beams; int ret; float angle, range; float timestamp; int n_lasers; int level; int n_segments; Segment *s; int num_readings; int position; while ( !feof(fin) ) { //start reading segments ret = fscanf(fin, "%d %f %d %d %d %d %d", &scan_index, ×tamp, &n_lasers, &level, &n_segments, &type, &n_beams); if ( ret == 7 ) { if (mScan!=NULL) { if ( scan_index != mScan->scan_id ) { outputScan(); delete mScan; mScan=NULL; } } if (mScan==NULL) { mScan = new MultiScan(n_lasers); mScan->scan_id = scan_index; //cerr << "mScan->scan_id: " << mScan->scan_id << endl; mScan->timestamp = timestamp; } // read multi scan s = new Segment; s->type = type; for(int k=0; k<n_beams; k++) { Beam *b = new Beam;; fscanf(fin, " %d %d %f %f", &num_readings, &position, &angle, &range ); b->range = range; b->angle = angle; s->add(b); } mScan->scans[level]->add(s); } // end if ( ret == 3 ) { } //end while ( !feof(fin) ) if ( mScan != NULL ) { outputScan(); delete mScan; mScan = NULL; } return 1; }
void MTrack::processPendingNotes(QList<MidiChord> &midiChords, int voice, const Fraction &startChordTickFrac, const Fraction &nextChordTick) { Score* score = staff->score(); int track = staff->idx() * VOICES + voice; Drumset* drumset = staff->part()->instr()->drumset(); bool useDrumset = staff->part()->instr()->useDrumset(); // all midiChords here should have the same onTime value // and all notes in each midiChord should have the same duration Fraction startChordTick = startChordTickFrac; while (!midiChords.isEmpty()) { Fraction tick = startChordTick; Fraction len = nextChordTick - tick; if (len <= Fraction(0)) break; len = findMinDuration(midiChords, len); Measure* measure = score->tick2measure(tick.ticks()); len = splitDurationOnBarBoundary(len, tick, measure); auto dl = toDurationList(measure, voice, tick, len, Meter::DurationType::NOTE); if (dl.isEmpty()) break; const TDuration &d = dl[0].second; const Fraction &tupletRatio = dl[0].first; len = d.fraction() / tupletRatio; Chord* chord = new Chord(score); chord->setTrack(track); chord->setDurationType(d); chord->setDuration(d.fraction()); Segment* s = measure->getSegment(chord, tick.ticks()); s->add(chord); chord->setUserPlayEvents(true); addElementToTuplet(voice, tick, len, chord); for (int k = 0; k < midiChords.size(); ++k) { MidiChord& midiChord = midiChords[k]; setMusicNotesFromMidi(score, midiChord.notes, startChordTick, len, chord, tick, drumset, useDrumset); if (!midiChord.notes.empty() && midiChord.notes.first().len <= len) { midiChords.removeAt(k); --k; continue; } setTies(chord, score, midiChord.notes); for (auto &midiNote: midiChord.notes) midiNote.len -= len; } startChordTick += len; } fillGapWithRests(score, voice, startChordTick, nextChordTick - startChordTick, track); }
void MCursor::addKeySig(Key key) { createMeasures(); Measure* measure = _score->tick2measure(_tick); Segment* segment = measure->getSegment(Segment::Type::KeySig, _tick); int n = _score->nstaves(); for (int i = 0; i < n; ++i) { KeySig* ks = new KeySig(_score); ks->setKey(key); ks->setTrack(i * VOICES); segment->add(ks); } }
//----------------------------------------------------- // segment a scan // ---------------------------------------------------- void LegsDetector::segmentScan(double threshold, int n_readings, double *angles, double *ranges, dyntab_segments *segments) { //cerr << "LegsDetector::segmentScan" << endl; Segment *s; Beam *b=NULL, *b_prev=NULL; s = new Segment; //start with a segment for (int i=0; i<n_readings; i++) { // read the first point b = new Beam; b->range = ranges[i]; b->angle = angles[i]; b->num_readings = n_readings; b->position = i; if ( s->num() > 0 ) { if ( fabs(b_prev->range - b->range) < threshold ) { // same segment b_prev = b; b->segment_id = segments->num(); s->add(b); } else { segments->add(s); s = new Segment; b->segment_id = segments->num(); s->add(b); b_prev = b; } } else { b_prev = b; s->add(b); } } segments->add(s); }
TimeSig* MCursor::addTimeSig(const Fraction& f) { createMeasures(); Measure* measure = _score->tick2measure(_tick); Segment* segment = measure->getSegment(Segment::Type::TimeSig, _tick); TimeSig* ts = 0; for (int i = 0; i < _score->nstaves(); ++i) { ts = new TimeSig(_score); ts->setSig(f, TimeSigType::NORMAL); ts->setTrack(i * VOICES); segment->add(ts); } _score->sigmap()->add(_tick, SigEvent(f)); return ts; }
static void setTempo(Score* score, int tempo) { TempoText* tt = new TempoText(score); tt->setTempo(double(tempo)/60.0); tt->setTrack(0); QTextCursor* c = tt->startCursorEdit(); c->movePosition(QTextCursor::EndOfLine); addSymbolToText(SymCode(0xe105, 1), c); c->insertText(" = "); c->insertText(QString("%1").arg(tempo)); tt->endEdit(); Measure* measure = score->firstMeasure(); Segment* segment = measure->getSegment(Segment::SegChordRest, 0); segment->add(tt); }
void Lilypond::addRest() { createMeasure(); Segment* segment = new Segment(measure); segment->setSubtype(SegChordRest); segment->setTick(tick); segment->setParent(measure); measure->add(segment); Rest* rest = new Rest(score); rest->setTrack(staff->idx() * VOICES); rest->setParent(segment); Duration d; d.setVal(curLen); rest->setDurationType(d); segment->add(rest); tick += curLen; }
Chord* MCursor::addChord(int pitch, const TDuration& duration) { createMeasures(); Measure* measure = _score->tick2measure(_tick); Segment* segment = measure->getSegment(Segment::Type::ChordRest, _tick); Chord* chord = static_cast<Chord*>(segment->element(_track)); if (chord == 0) { chord = new Chord(_score); chord->setTrack(_track); chord->setDurationType(duration); chord->setDuration(duration.fraction()); segment->add(chord); } Note* note = new Note(_score); chord->add(note); note->setPitch(pitch); note->setTpcFromPitch(); _tick += duration.ticks(); return chord; }
void SwingDetector::applySwing() { if (elements.size() != 2 && elements.size() != 3) return; Tuplet *tuplet = nullptr; for (ChordRest *el: elements) { el->setDurationType(TDuration::DurationType::V_EIGHTH); el->setTicks(Fraction(1, 8)); el->setDots(0); if (el->tuplet()) { if (!tuplet) tuplet = el->tuplet(); tuplet->remove(el); el->setTuplet(nullptr); } } const ChordRest *first = elements.front(); const int startTick = first->segment()->tick().ticks(); ChordRest *last = elements.back(); last->segment()->remove(last); Segment *s = last->measure()->getSegment(SegmentType::ChordRest, Fraction::fromTicks(startTick + MScore::division / 2)); s->add(last); if (elements.size() == 3) { // remove central rest ChordRest *cr = elements[1]; cr->score()->removeElement(cr); delete cr; } if (tuplet) { // delete tuplet delete tuplet; tuplet = nullptr; } if (!swingApplied) swingApplied = true; }
void assignKeyListToStaff(const KeyList &kl, Staff *staff) { Score* score = staff->score(); const int track = staff->idx() * VOICES; Key pkey = Key::C; for (auto it = kl.begin(); it != kl.end(); ++it) { const int tick = it->first; Key key = it->second.key(); if ((key == Key::C) && (key == pkey)) // dont insert uneccessary C key continue; pkey = key; KeySig* ks = new KeySig(score); ks->setTrack(track); ks->setGenerated(false); ks->setKey(key); ks->setMag(staff->mag()); Measure* m = score->tick2measure(tick); Segment* seg = m->getSegment(ks, tick); seg->add(ks); } }
void MTrack::convertTrack(const Fraction &lastTick) { Score* score = staff->score(); int key = 0; // TODO-LIB findKey(mtrack, score->sigmap()); int track = staff->idx() * VOICES; int voices = VOICES; for (int voice = 0; voice < voices; ++voice) { // startChordTick is onTime value of all simultaneous notes // chords here are consist of notes with equal durations // several chords may have the same onTime value Fraction startChordTick; QList<MidiChord> midiChords; for (auto it = chords.begin(); it != chords.end();) { const Fraction &nextChordTick = it->first; const MidiChord& midiChord = it->second; if (midiChord.voice != voice) { ++it; continue; } processPendingNotes(midiChords, voice, startChordTick, nextChordTick); // now 'midiChords' list is empty // so - fill it: // collect all midiChords on current tick position startChordTick = nextChordTick; // debug for (;it != chords.end(); ++it) { const MidiChord& midiChord = it->second; if (it->first != startChordTick) break; if (midiChord.voice != voice) continue; midiChords.append(midiChord); } if (midiChords.isEmpty()) break; } // process last chords at the end of the score processPendingNotes(midiChords, voice, startChordTick, lastTick); } createTuplets(track, score); KeyList* km = staff->keymap(); if (!hasKey && !mtrack->drumTrack()) { KeySigEvent ks; ks.setAccidentalType(key); (*km)[0] = ks; } for (auto it = km->begin(); it != km->end(); ++it) { int tick = it->first; KeySigEvent key = it->second; KeySig* ks = new KeySig(score); ks->setTrack(track); ks->setGenerated(false); ks->setKeySigEvent(key); ks->setMag(staff->mag()); Measure* m = score->tick2measure(tick); Segment* seg = m->getSegment(ks, tick); seg->add(ks); } #if 0 // TODO ClefList* cl = staff->clefList(); for (ciClefEvent i = cl->begin(); i != cl->end(); ++i) { int tick = i.key(); Clef* clef = new Clef(score); clef->setClefType(i.value()); clef->setTrack(track); clef->setGenerated(false); clef->setMag(staff->mag()); Measure* m = score->tick2measure(tick); Segment* seg = m->getSegment(clef, tick); seg->add(clef); } #endif }
Score::FileError Score::read114(XmlReader& e) { if (parentScore()) setMscVersion(parentScore()->mscVersion()); for (unsigned int i = 0; i < sizeof(style114)/sizeof(*style114); ++i) style()->set(style114[i].idx, style114[i].val); // old text style defaults TextStyle ts = style()->textStyle("Chord Symbol"); ts.setYoff(-4.0); style()->setTextStyle(ts); TempoMap tm; while (e.readNextStartElement()) { e.setTrack(-1); const QStringRef& tag(e.name()); if (tag == "Staff") readStaff(e); else if (tag == "KeySig") { // not supported KeySig* ks = new KeySig(this); ks->read(e); // customKeysigs.append(ks); delete ks; } else if (tag == "siglist") _sigmap->read(e, _fileDivision); else if (tag == "programVersion") { _mscoreVersion = e.readElementText(); parseVersion(_mscoreVersion); } else if (tag == "programRevision") _mscoreRevision = e.readInt(); else if (tag == "Mag" || tag == "MagIdx" || tag == "xoff" || tag == "Symbols" || tag == "cursorTrack" || tag == "yoff") e.skipCurrentElement(); // obsolete else if (tag == "tempolist") { // store the tempo list to create invisible tempo text later qreal tempo = e.attribute("fix","2.0").toDouble(); tm.setRelTempo(tempo); while (e.readNextStartElement()) { if (e.name() == "tempo") { int tick = e.attribute("tick").toInt(); double tmp = e.readElementText().toDouble(); tick = (tick * MScore::division + _fileDivision/2) / _fileDivision; auto pos = tm.find(tick); if (pos != tm.end()) tm.erase(pos); tm.setTempo(tick, tmp); } else if (e.name() == "relTempo") e.readElementText(); else e.unknown(); } } else if (tag == "playMode") _playMode = PlayMode(e.readInt()); else if (tag == "SyntiSettings") _synthesizerState.read(e); else if (tag == "Spatium") _style.setSpatium (e.readDouble() * MScore::DPMM); else if (tag == "Division") _fileDivision = e.readInt(); else if (tag == "showInvisible") _showInvisible = e.readInt(); else if (tag == "showFrames") _showFrames = e.readInt(); else if (tag == "showMargins") _showPageborders = e.readInt(); else if (tag == "Style") { qreal sp = _style.spatium(); _style.load(e); // adjust this now so chords render properly on read // other style adjustments can wait until reading is finished if (style(StyleIdx::useGermanNoteNames).toBool()) style()->set(StyleIdx::useStandardNoteNames, false); if (_layoutMode == LayoutMode::FLOAT) { // style should not change spatium in // float mode _style.setSpatium(sp); } } else if (tag == "TextStyle") { TextStyle s; s.read(e); qreal spMM = _style.spatium() / MScore::DPMM; if (s.frameWidthMM() != 0.0) s.setFrameWidth(Spatium(s.frameWidthMM() / spMM)); if (s.paddingWidthMM() != 0.0) s.setPaddingWidth(Spatium(s.paddingWidthMM() / spMM)); \ // convert 1.2 text styles s.setName(convertOldTextStyleNames(s.name())); if (s.name() == "Lyrics Odd Lines" || s.name() == "Lyrics Even Lines") s.setAlign((s.align() & ~ Align(AlignmentFlags::VMASK)) | AlignmentFlags::BASELINE); _style.setTextStyle(s); } else if (tag == "page-layout") { if (_layoutMode != LayoutMode::FLOAT && _layoutMode != LayoutMode::SYSTEM) { PageFormat pf; pf.copy(*pageFormat()); pf.read(e, this); setPageFormat(pf); } else e.skipCurrentElement(); } else if (tag == "copyright" || tag == "rights") { Text* text = new Text(this); text->read(e); text->layout(); setMetaTag("copyright", text->plainText()); delete text; } else if (tag == "movement-number") setMetaTag("movementNumber", e.readElementText()); else if (tag == "movement-title") setMetaTag("movementTitle", e.readElementText()); else if (tag == "work-number") setMetaTag("workNumber", e.readElementText()); else if (tag == "work-title") setMetaTag("workTitle", e.readElementText()); else if (tag == "source") setMetaTag("source", e.readElementText()); else if (tag == "metaTag") { QString name = e.attribute("name"); setMetaTag(name, e.readElementText()); } else if (tag == "Part") { Part* part = new Part(this); part->read114(e); _parts.push_back(part); } else if (tag == "Slur") { Slur* slur = new Slur(this); slur->read(e); addSpanner(slur); } else if ((tag == "HairPin") || (tag == "Ottava") || (tag == "TextLine") || (tag == "Volta") || (tag == "Trill") || (tag == "Pedal")) { Spanner* s = static_cast<Spanner*>(Element::name2Element(tag, this)); s->read(e); if (s->track() == -1) s->setTrack(e.track()); else e.setTrack(s->track()); // update current track if (s->tick() == -1) s->setTick(e.tick()); else e.initTick(s->tick()); // update current tick if (s->track2() == -1) s->setTrack2(s->track()); if (s->ticks() == 0) { delete s; qDebug("zero spanner %s ticks: %d", s->name(), s->ticks()); } else { addSpanner(s); } } else if (tag == "Excerpt") { if (MScore::noExcerpts) e.skipCurrentElement(); else { Excerpt* ex = new Excerpt(this); ex->read(e); _excerpts.append(ex); } } else if (tag == "Beam") { Beam* beam = new Beam(this); beam->read(e); beam->setParent(0); // _beams.append(beam); } else if (tag == "name") setName(e.readElementText()); else e.unknown(); } if (e.error() != XmlStreamReader::NoError) return FileError::FILE_BAD_FORMAT; int n = nstaves(); for (int idx = 0; idx < n; ++idx) { Staff* s = _staves[idx]; int track = idx * VOICES; // check barLineSpan if (s->barLineSpan() > (n - idx)) { qDebug("read114: invalid bar line span %d (max %d)", s->barLineSpan(), n - idx); s->setBarLineSpan(n - idx); } for (auto i : e.clefs(idx)) { int tick = i.first; ClefType clefId = i.second; Measure* m = tick2measure(tick); if (!m) continue; if ((tick == m->tick()) && m->prevMeasure()) m = m->prevMeasure(); Segment* seg = m->getSegment(Segment::Type::Clef, tick); if (seg->element(track)) static_cast<Clef*>(seg->element(track))->setGenerated(false); else { Clef* clef = new Clef(this); clef->setClefType(clefId); clef->setTrack(track); clef->setParent(seg); clef->setGenerated(false); seg->add(clef); } } // create missing KeySig KeyList* km = s->keyList(); for (auto i = km->begin(); i != km->end(); ++i) { int tick = i->first; if (tick < 0) { qDebug("read114: Key tick %d", tick); continue; } if (tick == 0 && i->second.key() == Key::C) continue; Measure* m = tick2measure(tick); if (!m) //empty score break; Segment* seg = m->getSegment(Segment::Type::KeySig, tick); if (seg->element(track)) static_cast<KeySig*>(seg->element(track))->setGenerated(false); else { KeySigEvent ke = i->second; KeySig* ks = new KeySig(this); ks->setKeySigEvent(ke); ks->setParent(seg); ks->setTrack(track); ks->setGenerated(false); seg->add(ks); } } } for (std::pair<int,Spanner*> p : spanner()) { Spanner* s = p.second; if (s->type() != Element::Type::SLUR) { if (s->type() == Element::Type::VOLTA) { Volta* volta = static_cast<Volta*>(s); volta->setAnchor(Spanner::Anchor::MEASURE); } } if (s->type() == Element::Type::OTTAVA || s->type() == Element::Type::PEDAL || s->type() == Element::Type::TRILL || s->type() == Element::Type::TEXTLINE) { qreal yo = 0; if (s->type() == Element::Type::OTTAVA) { // fix ottava position yo = styleS(StyleIdx::ottavaY).val() * spatium(); if (s->placement() == Element::Placement::BELOW) yo = -yo + s->staff()->height(); } else if (s->type() == Element::Type::PEDAL) { yo = styleS(StyleIdx::pedalY).val() * spatium(); } else if (s->type() == Element::Type::TRILL) { yo = styleS(StyleIdx::trillY).val() * spatium(); } else if (s->type() == Element::Type::TEXTLINE) { yo = -5.0 * spatium(); } if (!s->spannerSegments().isEmpty()) { for (SpannerSegment* seg : s->spannerSegments()) { if (!seg->userOff().isNull()) seg->setUserYoffset(seg->userOff().y() - yo); } } else { s->setUserYoffset(-yo); } } } connectTies(); // // remove "middle beam" flags from first ChordRest in // measure // for (Measure* m = firstMeasure(); m; m = m->nextMeasure()) { int tracks = nstaves() * VOICES; bool first = true; for (int track = 0; track < tracks; ++track) { for (Segment* s = m->first(); s; s = s->next()) { if (s->segmentType() != Segment::Type::ChordRest) continue; ChordRest* cr = static_cast<ChordRest*>(s->element(track)); if (cr) { if(cr->type() == Element::Type::REST) { Rest* r = static_cast<Rest*>(cr); if (!r->userOff().isNull()) { int lineOffset = r->computeLineOffset(); qreal lineDist = r->staff() ? r->staff()->staffType()->lineDistance().val() : 1.0; r->rUserYoffset() -= (lineOffset * .5 * lineDist * r->spatium()); } } if(!first) { switch(cr->beamMode()) { case Beam::Mode::AUTO: case Beam::Mode::BEGIN: case Beam::Mode::END: case Beam::Mode::NONE: break; case Beam::Mode::MID: case Beam::Mode::BEGIN32: case Beam::Mode::BEGIN64: cr->setBeamMode(Beam::Mode::BEGIN); break; case Beam::Mode::INVALID: if (cr->type() == Element::Type::CHORD) cr->setBeamMode(Beam::Mode::AUTO); else cr->setBeamMode(Beam::Mode::NONE); break; } first = false; } } } } } for (MeasureBase* mb = _measures.first(); mb; mb = mb->next()) { if (mb->type() == Element::Type::VBOX) { Box* b = static_cast<Box*>(mb); qreal y = point(styleS(StyleIdx::staffUpperBorder)); b->setBottomGap(y); } } _fileDivision = MScore::division; // // sanity check for barLineSpan and update ottavas // foreach(Staff* staff, _staves) { int barLineSpan = staff->barLineSpan(); int idx = staffIdx(staff); int n = nstaves(); if (idx + barLineSpan > n) { qDebug("bad span: idx %d span %d staves %d", idx, barLineSpan, n); staff->setBarLineSpan(n - idx); } staff->updateOttava(); }
void GuitarPro5::readTracks() { for (int i = 0; i < staves; ++i) { int tuning[GP_MAX_STRING_NUMBER]; Staff* staff = score->staff(i); Part* part = staff->part(); uchar c = readUChar(); // simulations bitmask if (c & 0x2) { // 12 stringed guitar } if (c & 0x4) { // banjo track } if (i == 0 || version == 500) skip(1); QString name = readPascalString(40); int strings = readInt(); if (strings <= 0 || strings > GP_MAX_STRING_NUMBER) throw GuitarProError::GP_BAD_NUMBER_OF_STRINGS ; for (int j = 0; j < strings; ++j) { tuning[j] = readInt(); } for (int j = strings; j < GP_MAX_STRING_NUMBER; ++j) readInt(); /*int midiPort =*/ readInt(); // -1 int midiChannel = readInt() - 1; /*int midiChannel2 =*/ readInt(); // -1 int frets = readInt(); int capo = readInt(); /*int color =*/ readInt(); skip(version > 500 ? 49 : 44); if (version > 500) { // british stack clean / amp tone readDelphiString(); readDelphiString(); } int tuning2[strings]; for (int k = 0; k < strings; ++k) tuning2[strings-k-1] = tuning[k]; StringData stringData(frets, strings, tuning2); Instrument* instr = part->instr(); instr->setStringData(stringData); part->setPartName(name); part->setLongName(name); instr->setTranspose(Interval(capo)); // // determine clef // int patch = channelDefaults[midiChannel].patch; ClefType clefId = ClefType::G; if (midiChannel == GP_DEFAULT_PERCUSSION_CHANNEL) { clefId = ClefType::PERC; // instr->setUseDrumset(DrumsetKind::GUITAR_PRO); instr->setDrumset(gpDrumset); staff->setStaffType(StaffType::preset(StaffTypes::PERC_DEFAULT)); } else if (patch >= 24 && patch < 32) clefId = ClefType::G3; else if (patch >= 32 && patch < 40) clefId = ClefType::F8; Measure* measure = score->firstMeasure(); Clef* clef = new Clef(score); clef->setClefType(clefId); clef->setTrack(i * VOICES); Segment* segment = measure->getSegment(Segment::Type::Clef, 0); segment->add(clef); Channel& ch = instr->channel(0); if (midiChannel == GP_DEFAULT_PERCUSSION_CHANNEL) { ch.program = 0; ch.bank = 128; } else { ch.program = patch; ch.bank = 0; } ch.volume = channelDefaults[midiChannel].volume; ch.pan = channelDefaults[midiChannel].pan; ch.chorus = channelDefaults[midiChannel].chorus; ch.reverb = channelDefaults[midiChannel].reverb; //qDebug("default2: %d", channelDefaults[i].reverb); // missing: phase, tremolo ch.updateInitList(); } skip(version == 500 ? 2 : 1); }
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(); }
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); }
void MsScWriter::beginMeasure(const Bww::MeasureBeginFlags mbf) { qDebug() << "MsScWriter::beginMeasure()"; ++measureNumber; // create a new measure currentMeasure = new Measure(score); currentMeasure->setTick(tick); currentMeasure->setTimesig(Fraction(beats, beat)); currentMeasure->setNo(measureNumber); score->measures()->add(currentMeasure); if (mbf.repeatBegin) currentMeasure->setRepeatFlags(RepeatStart); if (mbf.irregular) currentMeasure->setIrregular(true); if (mbf.endingFirst || mbf.endingSecond) { Volta* volta = new Volta(score); volta->setTrack(0); volta->endings().clear(); if (mbf.endingFirst) { volta->setText("1"); volta->endings().append(1); ending = 1; } else { volta->setText("2"); volta->endings().append(2); ending = 2; } volta->setStartElement(currentMeasure); currentMeasure->add(volta); lastVolta = volta; } // set clef, key and time signature in the first measure if (measureNumber == 1) { // clef Clef* clef = new Clef(score); clef->setClefType(CLEF_G); clef->setTrack(0); Segment* s = currentMeasure->getSegment(clef, tick); s->add(clef); // keysig KeySigEvent key; key.setAccidentalType(2); KeySig* keysig = new KeySig(score); keysig->setKeySigEvent(key); keysig->setTrack(0); s = currentMeasure->getSegment(keysig, tick); s->add(keysig); // timesig TimeSig* timesig = new TimeSig(score); timesig->setSig(Fraction(beats, beat)); timesig->setTrack(0); s = currentMeasure->getSegment(timesig, tick); s->add(timesig); } }
bool MuseScore::importPdf(Score* score, const QString& path) { Omr* omr = new Omr(path, score); if (!omr->readPdf()) { delete omr; return false; } score->setOmr(omr); qreal sp = omr->spatiumMM(); if (sp == 0.0) sp = 1.5; score->setSpatium(sp * DPMM); score->style()->set(StyleVal(ST_pageFillLimit, 1.0)); score->style()->set(StyleVal(ST_lastSystemFillLimit, 0.0)); score->style()->set(StyleVal(ST_staffLowerBorder, 0.0)); score->style()->set(StyleVal(ST_measureSpacing, 1.0)); PageFormat pF(*score->pageFormat()); pF.setEvenLeftMargin(5.0 * DPMM / DPI); pF.setEvenTopMargin(0); pF.setEvenBottomMargin(0); pF.setOddLeftMargin(5.0 * DPMM / DPI); pF.setOddTopMargin(0); pF.setOddBottomMargin(0); score->setPageFormat(pF); score->style()->set(StyleVal(ST_systemDistance, Spatium(omr->systemDistance()))); score->style()->set(StyleVal(ST_akkoladeDistance, Spatium(omr->staffDistance()))); Part* part = new Part(score); Staff* staff = new Staff(score, part, 0); part->staves()->push_back(staff); score->staves().insert(0, staff); staff = new Staff(score, part, 1); part->staves()->push_back(staff); score->staves().insert(1, staff); part->staves()->front()->setBarLineSpan(part->nstaves()); score->insertPart(part, 0); TDuration d(TDuration::V_MEASURE); Measure* measure = 0; int tick = 0; foreach(const OmrPage* omrPage, omr->pages()) { int nsystems = omrPage->systems().size(); int n = nsystems == 0 ? 1 : nsystems; for (int k = 0; k < n; ++k) { int numMeasures = 1; if (k < nsystems) { const OmrSystem& omrSystem = omrPage->systems().at(k); numMeasures = omrSystem.barLines.size() - 1; if (numMeasures < 1) numMeasures = 1; else if (numMeasures > 50) // sanity check numMeasures = 50; } for (int i = 0; i < numMeasures; ++i) { measure = new Measure(score); measure->setTick(tick); Rest* rest = new Rest(score, d); rest->setDuration(Fraction(4,4)); rest->setTrack(0); Segment* s = measure->getSegment(SegChordRest, tick); s->add(rest); rest = new Rest(score, d); rest->setDuration(Fraction(4,4)); rest->setTrack(4); s->add(rest); score->measures()->add(measure); tick += MScore::division * 4; } if (k < (nsystems-1)) { LayoutBreak* b = new LayoutBreak(score); b->setSubtype(LAYOUT_BREAK_LINE); measure->add(b); } } if (measure) { LayoutBreak* b = new LayoutBreak(score); b->setSubtype(LAYOUT_BREAK_PAGE); measure->add(b); } } //---create bracket score->staff(0)->setBracket(0, BRACKET_AKKOLADE); score->staff(0)->setBracketSpan(0, 2); //---create clefs measure = score->firstMeasure(); if (measure) { Clef* clef = new Clef(score); clef->setClefType(CLEF_G); clef->setTrack(0); Segment* segment = measure->getSegment(SegClef, 0); segment->add(clef); clef = new Clef(score); clef->setClefType(CLEF_F); clef->setTrack(4); segment->add(clef); } score->setShowOmr(true); omr->page(0)->readHeader(score); score->rebuildMidiMapping(); return true; }
void MsScWriter::note(const QString pitch, const QVector<Bww::BeamType> beamList, const QString type, const int dots, bool tieStart, bool /*TODO tieStop */, StartStop triplet, bool grace) { qDebug() << "MsScWriter::note()" << "type:" << type << "dots:" << dots << "grace" << grace ; if (!stepAlterOctMap.contains(pitch) || !typeMap.contains(type)) { // TODO: error message return; } StepAlterOct sao = stepAlterOctMap.value(pitch); int ticks = 4 * MScore::division / type.toInt(); if (dots) ticks = 3 * ticks / 2; qDebug() << "ticks:" << ticks; TDuration durationType(TDuration::V_INVALID); durationType.setVal(ticks); qDebug() << "duration:" << durationType.name(); if (triplet != ST_NONE) ticks = 2 * ticks / 3; BeamMode bm = (beamList.at(0) == Bww::BM_BEGIN) ? BEAM_BEGIN : BEAM_AUTO; Direction sd = AUTO; // create chord Chord* cr = new Chord(score); //ws cr->setTick(tick); cr->setBeamMode(bm); cr->setTrack(0); if (grace) { cr->setNoteType(NOTE_GRACE32); cr->setDurationType(TDuration::V_32ND); sd = UP; } else { if (durationType.type() == TDuration::V_INVALID) durationType.setType(TDuration::V_QUARTER); cr->setDurationType(durationType); sd = DOWN; } cr->setDuration(durationType.fraction()); cr->setDots(dots); cr->setStemDirection(sd); // add note to chord Note* note = new Note(score); note->setTrack(0); xmlSetPitch(note, sao.s.toAscii(), sao.a, sao.o); if (tieStart) { Tie* tie = new Tie(score); note->setTieFor(tie); tie->setStartNote(note); tie->setTrack(0); } cr->add(note); // add chord to measure Segment* s = currentMeasure->getSegment(cr, tick); s->add(cr); if (!grace) { doTriplet(cr, triplet); int tickBefore = tick; tick += ticks; Fraction nl(Fraction::fromTicks(tick - currentMeasure->tick())); currentMeasure->setLen(nl); qDebug() << "MsScWriter::note()" << "tickBefore:" << tickBefore << "tick:" << tick << "nl:" << nl.print() ; } }