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); }
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 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() ; } }