bool Arpeggio::edit(MuseScoreView*, Grip curGrip, int key, Qt::KeyboardModifiers modifiers, const QString&) { if (curGrip != Grip::END || !(modifiers & Qt::ShiftModifier)) return false; if (key == Qt::Key_Down) { Staff* s = staff(); Part* part = s->part(); int n = part->nstaves(); int ridx = part->staves()->indexOf(s); if (ridx >= 0) { if (_span + ridx < n) ++_span; } } else if (key == Qt::Key_Up) { if (_span > 1) --_span; } else return false; layout(); Chord* c = chord(); rxpos() = -(width() + spatium() * .5); c->layoutArpeggio2(); return true; }
Note* Score::upAlt(Element* element) { Element* re = 0; if (element->type() == REST) { if (_is.track() <= 0) return 0; _is.setTrack(_is.track() - 1); re = searchNote(static_cast<Rest*>(element)->tick(), _is.track()); } else if (element->type() == NOTE) { // find segment Chord* chord = static_cast<Note*>(element)->chord(); Segment* segment = chord->segment(); // collect all notes for this segment in noteList: QList<Note*> rnl; int tracks = nstaves() * VOICES; for (int track = 0; track < tracks; ++track) { Element* el = segment->element(track); if (!el || el->type() != CHORD) continue; rnl.append(static_cast<Chord*>(el)->notes()); qSort(rnl.begin(), rnl.end(), noteLessThan); int idx = rnl.indexOf(static_cast<Note*>(element)); if (idx < rnl.size()-1) ++idx; re = rnl.value(idx); } } if (re == 0) return 0; if (re->type() == CHORD) re = ((Chord*)re)->notes().front(); return (Note*)re; }
Element* Rest::drop(const DropData& data) { Element* e = data.element; switch (e->type()) { case ARTICULATION: if (e->subtype() == Articulation_Fermata) score()->addArticulation(this, (Articulation*)e); return 0; case ICON: { switch(e->subtype()) { case ICON_SBEAM: score()->undoChangeBeamMode(this, BEAM_BEGIN); break; case ICON_MBEAM: score()->undoChangeBeamMode(this, BEAM_MID); break; case ICON_NBEAM: score()->undoChangeBeamMode(this, BEAM_NO); break; case ICON_BEAM32: score()->undoChangeBeamMode(this, BEAM_BEGIN32); break; case ICON_BEAM64: score()->undoChangeBeamMode(this, BEAM_BEGIN64); break; case ICON_AUTOBEAM: score()->undoChangeBeamMode(this, BEAM_AUTO); break; } } delete e; break; case CHORD: { Chord* c = static_cast<Chord*>(e); Note* n = c->upNote(); Direction dir = c->stemDirection(); score()->select(0, SELECT_SINGLE, 0); NoteVal nval; nval.pitch = n->pitch(); nval.headGroup = n->headGroup(); Fraction d = score()->inputState().duration().fraction(); if (!d.isZero()) { Segment* seg = score()->setNoteRest(segment(), track(), nval, d, dir); if (seg) { ChordRest* cr = static_cast<ChordRest*>(seg->element(track())); if (cr) score()->nextInputPos(cr, true); } } delete e; } break; default: return ChordRest::drop(data); } return 0; }
Score* NoteGroups::createScore(int n, TDuration::DurationType t, std::vector<Chord*>* chords) { MCursor c; c.setTimeSig(_sig); c.createScore("score8"); c.addPart("voice"); c.move(0, 0); c.addKeySig(0); TimeSig* nts = c.addTimeSig(_sig); GroupNode node {0, 0}; Groups ng; ng.push_back(node); nts->setGroups(ng); for (int i = 0; i < n; ++i) { Chord* chord = c.addChord(67, t); int tick = chord->rtick(); chord->setBeamMode(_groups.beamMode(tick, t)); chords->push_back(chord); } c.score()->parts().front()->setLongName(""); c.score()->style()->set(ST_linearStretch, 1.1); return c.score(); }
QLineF Arpeggio::dragAnchor() const { Chord* c = chord(); if (c) return QLineF(pagePos(), c->upNote()->pagePos()); return QLineF(); }
Score* NoteGroups::createScore(int n, TDuration::DurationType t, std::vector<Chord*>* chords) { MCursor c; c.setTimeSig(_sig); c.createScore("score8"); c.addPart("voice"); c.move(0, 0); c.addKeySig(Key::C); TimeSig* nts = c.addTimeSig(_sig); GroupNode node {0, 0}; Groups ng; ng.push_back(node); nts->setGroups(ng); for (int i = 0; i < n; ++i) { Chord* chord = c.addChord(67, t); int tick = chord->rtick(); chord->setBeamMode(_groups.beamMode(tick, t)); chords->push_back(chord); } c.score()->pageFormat()->setEvenLeftMargin(0.0); c.score()->pageFormat()->setOddLeftMargin(0.0); c.score()->parts().front()->setLongName(""); c.score()->style()->set(StyleIdx::linearStretch, 1.3); c.score()->style()->set(StyleIdx::MusicalSymbolFont, QString("Bravura")); c.score()->style()->set(StyleIdx::MusicalTextFont, QString("Bravura Text")); return c.score(); }
void Glissando::layout() { Chord* chord = static_cast<Chord*>(parent()); if (chord == 0) { return; } Note* anchor2 = chord->upNote(); Segment* s = chord->segment(); s = s->prev1(); while (s) { if ((s->subtype() & (Segment::SegChordRestGrace)) && s->element(track())) break; s = s->prev1(); } if (s == 0) { qDebug("no segment for first note of glissando found\n"); return; } ChordRest* cr = static_cast<ChordRest*>(s->element(track())); if (cr == 0 || cr->type() != CHORD) { qDebug("no first note for glissando found, track %d\n", track()); return; } Note* anchor1 = static_cast<Chord*>(cr)->upNote(); setPos(0.0, 0.0); QPointF cp1 = anchor1->pagePos(); QPointF cp2 = anchor2->pagePos(); // construct line from notehead to notehead qreal x1 = (anchor1->headWidth()) - (cp2.x() - cp1.x()); qreal y1 = anchor1->pos().y(); qreal x2 = anchor2->pos().x(); qreal y2 = anchor2->pos().y(); // on TAB's, adjust lower end point from string line height to base of note height (= ca. half line spacing) if (chord->staff()->isTabStaff()) { qreal yOff = chord->staff()->lineDistance() * 0.5 * spatium(); if (anchor1->pitch() > anchor2->pitch()) // descending glissando: y2 += yOff; // move ending point to base of note else // ascending glissando: y1 += yOff; // move starting point to base of note } QLineF fullLine(x1, y1, x2, y2); // shorten line on each side by offsets qreal xo = spatium() * .5; qreal yo = xo; // spatium() * .5; QPointF p1 = fullLine.pointAt(xo / fullLine.length()); QPointF p2 = fullLine.pointAt(1 - (yo / fullLine.length())); line = QLineF(p1, p2); qreal lw = spatium() * .15 * .5; QRectF r = QRectF(line.p1(), line.p2()).normalized(); setbbox(r.adjusted(-lw, -lw, lw, lw)); }
void Stem::editDrag(const EditData& ed) { qreal yDelta = ed.delta.y(); _userLen += up() ? -yDelta : yDelta; layout(); Chord* c = static_cast<Chord*>(parent()); if (c->hook()) c->hook()->move(QPointF(0.0, ed.delta.y())); }
void Ambitus::updateRange() { if (!segment()) return; Chord* chord; int firstTrack = track(); int lastTrack = firstTrack + VOICES-1; int pitchTop = -1000; int pitchBottom = 1000; int tpcTop = 0; // Initialized to prevent warning int tpcBottom = 0; // Initialized to prevent warning int trk; Measure* meas = segment()->measure(); Segment* segm = meas->findSegment(SegmentType::ChordRest, segment()->tick()); bool stop = meas->sectionBreak(); while (segm) { // moved to another measure? if (segm->measure() != meas) { // if section break has been found, stop here if (stop) break; // update meas and stop condition meas = segm->measure(); stop = meas->sectionBreak(); } // scan all relevant tracks of this segment for chords for (trk = firstTrack; trk <= lastTrack; trk++) { Element* e = segm->element(trk); if (!e || !e->isChord()) continue; chord = toChord(e); // update pitch range (with associated tpc's) for (Note* n : chord->notes()) { if (!n->play()) // skip notes which are not to be played continue; int pitch = n->ppitch(); if (pitch > pitchTop) { pitchTop = pitch; tpcTop = n->tpc(); } if (pitch < pitchBottom) { pitchBottom = pitch; tpcBottom = n->tpc(); } } } segm = segm->nextCR(); } if (pitchTop > -1000) { // if something has been found, update this _topPitch = pitchTop; _bottomPitch = pitchBottom; _topTpc = tpcTop; _bottomTpc = tpcBottom; } }
bool operator==(const Chord &c1, const Chord &c2) { if (c1.getChordText() != c2.getChordText()) return false; if (c1.getBeat() != c2.getBeat()) return false; return true; }
int Note::GetDrawingDur( ) { Chord* chordParent = dynamic_cast<Chord*>(this->GetFirstParent( CHORD, MAX_CHORD_DEPTH)); if( chordParent ) { return chordParent->GetActualDur(); } else { return GetActualDur(); } }
void DrumTools::drumNoteSelected(int val) { Element* element = drumPalette->element(val); Chord* ch = static_cast<Chord*>(element); Note* note = ch->downNote(); int ticks = MScore::defaultPlayDuration; int pitch = note->pitch(); seq->startNote(staff->part()->instr()->channel(0), pitch, 80, ticks, 0.0); _score->inputState().setDrumNote(note->pitch()); }
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); }
int generator::getNoteFrequencyByIndex(const Chord& tonicChord, int index){ // 1-indexation here int octave = 0; while (index < 1){ octave--; index += 7; } while (index > 7){ octave++; index -= 7; } int baseFrequency = tonicChord.getNote().getFrequency() + octave * 12; // FixMe: do not use switches for this //later if (tonicChord.getMode() == MAJOR){ switch(index){ case 1: return baseFrequency + 0; case 2: return baseFrequency + 2; case 3: return baseFrequency + 4; case 4: return baseFrequency + 5; case 5: return baseFrequency + 7; case 6: return baseFrequency + 9; case 7: return baseFrequency + 11; default: return baseFrequency + 12; } } else { switch(index){ case 1: return baseFrequency + 0; case 2: return baseFrequency + 2; case 3: return baseFrequency + 3; case 4: return baseFrequency + 5; case 5: return baseFrequency + 7; case 6: return baseFrequency + 8; case 7: return baseFrequency + 10; default: return baseFrequency + 12; } } }
Placement Fingering::calculatePlacement() const { Note* n = note(); if (!n) return Placement::ABOVE; Chord* chord = n->chord(); Staff* staff = chord->staff(); Part* part = staff->part(); int nstaves = part->nstaves(); bool voices = chord->measure()->hasVoices(staff->idx()); bool below = voices ? !chord->up() : (nstaves > 1) && (staff->rstaff() == nstaves - 1); return below ? Placement::BELOW : Placement::ABOVE; }
//--------------------------------------------------------- // oscColorNote //--------------------------------------------------------- void MuseScore::oscColorNote(QVariantList list) { qDebug() << list; if(!cs) return; if (list.length() != 2 && list.length() != 3) return; int tick; int pitch; QColor noteColor("red"); //default to red bool ok; tick = list[0].toInt(&ok); if (!ok) return; pitch = list[1].toInt(&ok); if (!ok) return; if(list.length() == 3 && list[2].canConvert(QVariant::String)) { QColor color(list[2].toString()); if(color.isValid()) noteColor = color; } Measure* measure = cs->tick2measure(tick); if(!measure) return; Segment* s = measure->findSegment(Segment::SegChordRest, tick); if (!s) return; //get all chords in segment... int n = cs->nstaves() * VOICES; for (int i = 0; i < n; i++) { Element* e = s->element(i); if (e && e->isChordRest()) { ChordRest* cr = static_cast<ChordRest*>(e); if(cr->type() == Element::CHORD) { Chord* chord = static_cast<Chord*>(cr); for (int idx = 0; idx < chord->notes().length(); idx++) { Note* note = chord->notes()[idx]; if (note->pitch() == pitch) { cs->startCmd(); cs->undo(new ChangeProperty(note, P_COLOR, noteColor)); cs->endCmd(); cs->end(); return; } } } } } }
bool isTied(const Segment *seg, int strack, int voice, Ms::Tie*(Note::*tieFunc)() const) { ChordRest *cr = static_cast<ChordRest *>(seg->element(strack + voice)); if (cr && cr->type() == Element::Type::CHORD) { Chord *chord = static_cast<Chord *>(cr); const auto ¬es = chord->notes(); for (const Note *note: notes) { if ((note->*tieFunc)()) return true; } } return false; }
data_STEMDIRECTION Note::CalcDrawingStemDir() { Chord* chordParent = dynamic_cast<Chord*>(this->GetFirstParent( CHORD, MAX_CHORD_DEPTH)); Beam* beamParent = dynamic_cast<Beam*>(this->GetFirstParent( BEAM, MAX_BEAM_DEPTH)); if( chordParent ) { return chordParent->GetDrawingStemDir(); } else if( beamParent ) { return beamParent->GetDrawingStemDir(); } else { return this->GetStemDir(); } }
data_STEMDIRECTION LayerElement::GetDrawingStemDir() { if (this->Is() == NOTE) { Note *note = dynamic_cast<Note*>(this); assert( note ); return note->GetDrawingStemDir(); } if (this->Is() == CHORD) { Chord *chord = dynamic_cast<Chord*>(this); assert( chord ); return chord->GetDrawingStemDir(); } return STEMDIRECTION_NONE; }
int DrumTools::selectedDrumNote() { int idx = drumPalette->getSelectedIdx(); if (idx < 0) return -1; Element* element = drumPalette->element(idx); if (element && element->type() == Element::Type::CHORD) { Chord* ch = static_cast<Chord*>(element); Note* note = ch->downNote(); return note->pitch(); } else { return -1; } }
void Glissando::layout() { Chord* chord = static_cast<Chord*>(parent()); if (chord == 0) { return; } Note* anchor2 = chord->upNote(); Segment* s = chord->segment(); s = s->prev1(); while (s) { if ((s->subtype() == SegChordRest || s->subtype() == SegGrace) && s->element(track())) break; s = s->prev1(); } if (s == 0) { qDebug("no segment for first note of glissando found\n"); return; } ChordRest* cr = static_cast<ChordRest*>(s->element(track())); if (cr == 0 || cr->type() != CHORD) { qDebug("no first note for glissando found, track %d\n", track()); return; } Note* anchor1 = static_cast<Chord*>(cr)->upNote(); setPos(0.0, 0.0); QPointF cp1 = anchor1->pagePos(); QPointF cp2 = anchor2->pagePos(); // construct line from notehead to notehead qreal x1 = (anchor1->headWidth()) - (cp2.x() - cp1.x()); qreal y1 = anchor1->pos().y(); qreal x2 = anchor2->pos().x(); qreal y2 = anchor2->pos().y(); QLineF fullLine(x1, y1, x2, y2); // shorten line on each side by offsets qreal xo = spatium() * .5; qreal yo = xo; // spatium() * .5; QPointF p1 = fullLine.pointAt(xo / fullLine.length()); QPointF p2 = fullLine.pointAt(1 - (yo / fullLine.length())); line = QLineF(p1, p2); qreal lw = spatium() * .15 * .5; QRectF r = QRectF(line.p1(), line.p2()).normalized(); setbbox(r.adjusted(-lw, -lw, lw, lw)); }
Element* Stem::drop(const DropData& data) { Element* e = data.element; Chord* ch = chord(); switch(e->type()) { case TREMOLO: e->setParent(ch); score()->setLayout(ch->measure()); score()->undoAddElement(e); return e; default: delete e; break; } return 0; }
Element* Rest::drop(const DropData& data) { Element* e = data.element; switch (e->type()) { case ElementType::ARTICULATION: { Articulation* a = static_cast<Articulation*>(e); if (a->articulationType() != ArticulationType::Fermata || !score()->addArticulation(this, a)) { delete e; e = 0; } } return e; case ElementType::CHORD: { Chord* c = static_cast<Chord*>(e); Note* n = c->upNote(); Direction dir = c->stemDirection(); // score()->select(0, SelectType::SINGLE, 0); NoteVal nval; nval.pitch = n->pitch(); nval.headGroup = n->headGroup(); Fraction d = score()->inputState().duration().fraction(); if (!d.isZero()) { Segment* seg = score()->setNoteRest(segment(), track(), nval, d, dir); if (seg) { ChordRest* cr = static_cast<ChordRest*>(seg->element(track())); if (cr) score()->nextInputPos(cr, true); } } delete e; } break; case ElementType::REPEAT_MEASURE: delete e; if (durationType().type() == TDuration::DurationType::V_MEASURE) { measure()->cmdInsertRepeatMeasure(staffIdx()); } break; default: return ChordRest::drop(data); } return 0; }
int DrumTools::selectedDrumNote() { int idx = drumPalette->getSelectedIdx(); if (idx < 0) return -1; Element* element = drumPalette->element(idx); if (element && element->type() == ElementType::CHORD) { Chord* ch = static_cast<Chord*>(element); Note* note = ch->downNote(); auto pitchCell = drumPalette->cellAt(idx); pitchName->setText(pitchCell->name); return note->pitch(); } else { return -1; } }
QPointF Arpeggio::gripAnchor(int n) const { Chord* c = chord(); if (c == 0) return QPointF(); if (n == 0) return c->upNote()->pagePos(); else if (n == 1) { Note* dnote = c->downNote(); int btrack = track() + (_span - 1) * VOICES; ChordRest* bchord = static_cast<ChordRest*>(c->segment()->element(btrack)); if (bchord && bchord->type() == CHORD) dnote = static_cast<Chord*>(bchord)->downNote(); return dnote->pagePos(); } return QPointF(); }
//--------------------------------------------------------- // updateExample //--------------------------------------------------------- void EditDrumset::updateExample() { int pitch = pitchList->currentItem()->data(0, Qt::UserRole).toInt(); if (!nDrumset.isValid(pitch)) { drumNote->add(0, 0, ""); return; } int line = nDrumset.line(pitch); NoteHead::Group noteHead = nDrumset.noteHead(pitch); int voice = nDrumset.voice(pitch); Direction dir = nDrumset.stemDirection(pitch); bool up = (Direction::UP == dir) || (Direction::AUTO == dir && line > 4); Chord* chord = new Chord(gscore); chord->setDurationType(TDuration::DurationType::V_QUARTER); chord->setStemDirection(dir); chord->setTrack(voice); chord->setUp(up); Note* note = new Note(gscore); note->setParent(chord); note->setTrack(voice); note->setPitch(pitch); note->setTpcFromPitch(); note->setLine(line); note->setPos(0.0, gscore->spatium() * .5 * line); note->setHeadType(NoteHead::Type::HEAD_QUARTER); note->setHeadGroup(noteHead); note->setCachedNoteheadSym(Sym::name2id(quarterCmb->currentData().toString())); chord->add(note); Stem* stem = new Stem(gscore); stem->setLen((up ? -3.0 : 3.0) * gscore->spatium()); chord->add(stem); drumNote->add(0, chord, qApp->translate("drumset", nDrumset.name(pitch).toUtf8().constData())); }
void testNotePitch() { Sheet* sheet = new Sheet(); Bar* bar = sheet->addBar(); Part* part = sheet->addPart("part"); Voice* voice = part->addVoice(); Staff* staff = part->addStaff(); VoiceBar* vb = bar->voice(voice); for (int p = -20; p <= 20; p++) { Chord* c = new Chord(QuarterNote); c->addNote(staff, p); vb->addElement(c); } validateOutput(sheet, "notepitch.xml"); delete sheet; }
void testNoteAccidentals() { Sheet* sheet = new Sheet(); Bar* bar = sheet->addBar(); Part* part = sheet->addPart("part"); Voice* voice = part->addVoice(); Staff* staff = part->addStaff(); VoiceBar* vb = bar->voice(voice); for (int a = -2; a <= 2; a++) { Chord* c = new Chord(QuarterNote); c->addNote(staff, 0, a); vb->addElement(c); } validateOutput(sheet, "noteaccidentals.xml"); delete sheet; }
void DrumTools::drumNoteSelected(int val) { Element* element = drumPalette->element(val); if(element && element->type() == CHORD) { Chord* ch = static_cast<Chord*>(element); Note* note = ch->downNote(); int ticks = MScore::defaultPlayDuration; int pitch = note->pitch(); seq->startNote(staff->part()->instr()->channel(0).channel, pitch, 80, ticks, 0.0); _score->inputState().setTrack(element->track()); _score->inputState().setDrumNote(pitch); getAction("voice-1")->setChecked(element->voice() == 0); getAction("voice-2")->setChecked(element->voice() == 1); getAction("voice-3")->setChecked(element->voice() == 2); getAction("voice-4")->setChecked(element->voice() == 3); } }
int main(int argc, char *argv[]) { Jazz::initDefaults(); cout << Jazz::chord["CMaj7"] << endl; cout << Jazz::chord["GMaj7"] << endl; cout << Jazz::chord["Bbm7"] << endl; Chord *c = Jazz::chord["G#Maj7"]; cout << c << endl; cout << c->getKeys()[0]->getMIDIKeys() << endl; cout << Jazz::chord["G#Maj7"] << endl; cout << (*Jazz::chord["C"] + Jazz::key["A"]) << endl; cout << (*Jazz::chord["C"] + Jazz::interval[MINOR_7TH]) << endl; return 0; }