Added basic chord symbol realization

This commit is contained in:
Peter Hieu Vu 2019-05-20 22:08:09 -07:00 committed by Igor Korsukov
parent 1137e606ff
commit 86a4e7b105
91 changed files with 27540 additions and 84 deletions

View file

@ -98,6 +98,7 @@
#define PREF_IO_PORTMIDI_OUTPUTLATENCYMILLISECONDS "io/portMidi/outputLatencyMilliseconds"
#define PREF_IO_PULSEAUDIO_USEPULSEAUDIO "io/pulseAudio/usePulseAudio"
#define PREF_SCORE_CHORD_PLAYONADDNOTE "score/chord/playOnAddNote"
#define PREF_SCORE_HARMONY_PLAYWHENEDITING "score/harmony/playWhileEditing"
#define PREF_SCORE_MAGNIFICATION "score/magnification"
#define PREF_SCORE_NOTE_PLAYONCLICK "score/note/playOnClick"
#define PREF_SCORE_NOTE_DEFAULTPLAYDURATION "score/note/defaultPlayDuration"

View file

@ -50,7 +50,7 @@ add_library (
jump.h key.h keylist.h keysig.h lasso.h layout.h layoutbreak.h ledgerline.h letring.h line.h location.h
lyrics.h marker.h mcursor.h measure.h measurebase.h mscore.h mscoreview.h musescoreCore.h navigate.h note.h notedot.h
noteevent.h noteline.h ossia.h ottava.h page.h palmmute.h part.h pedal.h pitch.h pitchspelling.h pitchvalue.h
pos.h property.h range.h read206.h rehearsalmark.h repeat.h repeatlist.h rest.h revisions.h score.h scoreElement.h segment.h
pos.h property.h range.h read206.h realizedharmony.h rehearsalmark.h repeat.h repeatlist.h rest.h revisions.h score.h scoreElement.h segment.h
segmentlist.h select.h sequencer.h shadownote.h shape.h sig.h slur.h slurtie.h spacer.h spanner.h spannermap.h spatium.h
staff.h stafflines.h staffstate.h stafftext.h stafftextbase.h stafftype.h stafftypechange.h stafftypelist.h stem.h
stemslash.h stringdata.h style.h sym.h symbol.h synthesizerstate.h system.h systemdivider.h systemtext.h tempo.h
@ -93,7 +93,7 @@ add_library (
sticking.cpp
read114.cpp
read206.cpp
read301.cpp stafftypelist.cpp stafftypechange.cpp
read301.cpp realizedharmony.cpp stafftypelist.cpp stafftypechange.cpp
bracketItem.cpp
lyricsline.cpp
layoutlinear.cpp

View file

@ -31,7 +31,7 @@ HChord::HChord(const QString& str)
};
keys = 0;
QStringList sl = str.split(" ", QString::SkipEmptyParts);
foreach(const QString& s, sl) {
for (const QString& s : sl) {
for (int i = 0; i < 12; ++i) {
if (s == scaleNames[0][i] || s == scaleNames[1][i]) {
operator+=(i);
@ -248,7 +248,7 @@ void HChord::add(const QList<HDegree>& degreeList)
0, 2, 4, 5, 7, 9, 11
};
// factor in the degrees
foreach(const HDegree& d, degreeList) {
for (const HDegree& d : degreeList) {
int dv = degreeTable[(d.value() - 1) % 7] + d.alter();
int dv1 = degreeTable[(d.value() - 1) % 7];
@ -414,7 +414,7 @@ void ChordToken::write(XmlWriter& xml) const
break;
}
xml.stag(t);
foreach(const QString& s, names)
for (const QString& s : names)
xml.tag("name", s);
writeRenderList(xml, &renderList, "render");
xml.etag();
@ -764,10 +764,11 @@ bool ParsedChord::parse(const QString& s, const ChordList* cl, bool syntaxOnly,
extl << "6" << "9";
correctXmlText();
}
_extension = "69";
chord += 9;
chord += 2;
}
foreach (QString e, extl) {
for (QString e : extl) {
QString d = "add" + e;
_xmlDegrees += d;
}
@ -1111,7 +1112,7 @@ bool ParsedChord::parse(const QString& s, const ChordList* cl, bool syntaxOnly,
// fix "add" / "alt" conflicts
// so add9,altb9 -> addb9
QStringList altList = _xmlDegrees.filter("alt");
foreach (const QString& d, altList) {
for (const QString& d : altList) {
QString unalt(d);
unalt.replace(QRegExp("alt[b#]"),"add");
if (_xmlDegrees.removeAll(unalt) > 0) {
@ -1233,7 +1234,7 @@ QString ParsedChord::fromXml(const QString& rawKind, const QString& rawKindText,
extension = 6;
// get modifier info from degree list
foreach (const HDegree& d, dl) {
for (const HDegree& d : dl) {
QString mod;
int v = d.value();
switch (d.type()) {
@ -1351,7 +1352,7 @@ QString ParsedChord::fromXml(const QString& rawKind, const QString& rawKindText,
}
if (parens)
_name += "(";
foreach (QString mod, _modifierList) {
for (QString mod : _modifierList) {
mod.replace("major","maj");
if (kindText != "" && kind.contains("suspended") && mod.startsWith("sus"))
continue;
@ -1370,7 +1371,7 @@ QString ParsedChord::fromXml(const QString& rawKind, const QString& rawKindText,
_xmlText = kindText;
_xmlSymbols = useSymbols;
_xmlParens = useParens;
foreach (const HDegree& d, dl) {
for (const HDegree& d : dl) {
if (kind == "half-diminished" && d.type() == HDegreeType::ALTER && d.alter() == -1 && d.value() == 5)
continue;
_xmlDegrees += d.text();
@ -1599,11 +1600,11 @@ void ChordDescription::write(XmlWriter& xml) const
xml.stag(QString("chord id=\"%1\"").arg(id));
else
xml.stag(QString("chord"));
foreach(const QString& s, names)
for (const QString& s : names)
xml.tag("name", s);
xml.tag("xml", xmlKind);
xml.tag("voicing", chord.voicing());
foreach(const QString& s, xmlDegrees)
for (const QString& s : xmlDegrees)
xml.tag("degree", s);
writeRenderList(xml, &renderList, "render");
xml.etag();
@ -1773,7 +1774,7 @@ void ChordList::write(XmlWriter& xml) const
}
if (_autoAdjust)
xml.tagE(QString("autoAdjust mag=\"%1\" adjust=\"%2\"").arg(_nmag).arg(_nadjust));
foreach (ChordToken t, chordTokenList)
for (ChordToken t : chordTokenList)
t.write(xml);
if (!renderListRoot.empty())
writeRenderList(xml, &renderListRoot, "renderRoot");

View file

@ -133,6 +133,7 @@ class ParsedChord {
const QString& quality() const { return _quality; }
const QString& extension() const { return _extension; }
const QString& modifiers() const { return _modifiers; }
const QStringList& modifierList() const { return _modifierList; }
const QString& xmlKind() const { return _xmlKind; }
const QString& xmlText() const { return _xmlText; }
const QString& xmlSymbols() const { return _xmlSymbols; }

View file

@ -3096,6 +3096,214 @@ void Score::cmdSlashRhythm()
}
}
//---------------------------------------------------------
// cmdRealizeChordSymbols
/// Realize selected chord symbols into notes on the staff.
///
/// If a voicing and duration type are specified, the
/// harmony voicing settings will be overridden by the
/// passed parameters. Otherwise, the settings set on the
/// harmony object will be used.
//---------------------------------------------------------
void Score::cmdRealizeChordSymbols(bool literal, Voicing voicing, HDuration durationType)
{
const QList<Element*> elist = selection().elements();
for (Element* e : elist) {
if (!e->isHarmony())
continue;
Harmony* h = toHarmony(e);
if (!h->isRealizable())
continue;
RealizedHarmony r = h->getRealizedHarmony();
Segment* seg = toSegment(h->parent());
Fraction duration = r.getActualDuration(durationType);
Fraction tick = seg->tick();
bool concertPitch = styleB(Sid::concertPitch);
Chord* chord = new Chord(this); //chord template
chord->setTrack(h->track()); //set track so notes have a track to sit on
//create chord from notes
RealizedHarmony::PitchMap notes;
if (voicing == Voicing::INVALID || durationType == HDuration::INVALID)
notes = r.notes(); //no override, just use notes from realize harmony
else {
//generate notes list based on overridden settings
int offset = 0;
Interval interval = h->staff()->part()->instrument(h->tick())->transpose();
if (!concertPitch)
offset = interval.chromatic;
notes = r.generateNotes(h->rootTpc(), h->baseTpc(),
literal, voicing, offset);
}
RealizedHarmony::PitchMapIterator i(notes); //add notes to chord
while (i.hasNext()) {
i.next();
Note* note = new Note(this);
NoteVal nval;
nval.pitch = i.key();
if (concertPitch)
nval.tpc1 = i.value();
else
nval.tpc2 = i.value();
chord->add(note); //add note first to set track and such
note->setNval(nval, tick);
}
setChord(seg, h->track(), chord, duration); //add chord using template
delete chord;
}
}
//---------------------------------------------------------
// setChord
// return segment of last created chord
//---------------------------------------------------------
Segment* Score::setChord(Segment* segment, int track, Chord* chordTemplate, Fraction dur, Direction stemDirection)
{
Q_ASSERT(segment->segmentType() == SegmentType::ChordRest);
Fraction tick = segment->tick();
Chord* nr = 0; //current added chord used so we can select the last added chord and so we can apply ties
std::vector<Tie*> tie(chordTemplate->notes().size()); //keep pointer to a tie for each note in the chord in case we need to tie notes
ChordRest* cr = toChordRest(segment->element(track)); //chord rest under the segment for the specified track
bool addTie = false;
Measure* measure = 0;
//keep creating chords and tieing them until we created the full duration asked for (dur)
for (;;) {
if (track % VOICES)
expandVoice(segment, track);
Tuplet* t = cr ? cr->tuplet() : 0;
Fraction tDur = segment->ticks();
Segment* seg = segment->next();
//we need to get a correct subduration so that makeGap can function properly
//since makeGap() takes "normal" duration rather than actual length
while (seg) {
if (seg->segmentType() == SegmentType::ChordRest) {
//design choice made to keep multiple notes across a tuplet as tied single notes rather than combining them
//since it's arguably more readable, but the other code is still here (commented)
ChordRest* testCr = toChordRest(seg->element(track));
//code here allows us to combine tuplet realization together which I have opted not to do for readability (of the music)
//if (!!t ^ (testCr && testCr->tuplet())) //stop if we started with a tuplet and reach something that's not a tuplet,
// break; //or start with not a tuplet and reach a tuplet
if (testCr && testCr->tuplet()) //stop on tuplet
break;
tDur += seg->ticks();
}
if (tDur >= dur) { //do not go further than the duration asked for
tDur = dur;
break;
}
seg = seg->next(); //iterate only across measure (hence usage of next() rather than next1())
}
if (t)
tDur *= t->ratio(); //scale by tuplet ratio to get "normal" length rather than actual length when dealing with tuplets
// the returned gap ends at the measure boundary or at tuplet end
Fraction dd = makeGap(segment, track, tDur, t);
if (dd.isZero()) {
qDebug("cannot get gap at %d type: %d/%d", tick.ticks(), dur.numerator(),
dur.denominator());
break;
}
measure = segment->measure();
std::vector<TDuration> dl = toDurationList(dd, true);
size_t n = dl.size();
//add chord, tieing when necessary within measure
for (size_t i = 0; i < n; ++i) {
const TDuration& d = dl[i];
//create new chord from template and add it
Chord* chord = new Chord(*chordTemplate);
nr = chord;
chord->setTrack(track);
chord->setDurationType(d);
chord->setTicks(d.fraction());
chord->setStemDirection(stemDirection);
chord->setTuplet(t);
undoAddCR(chord, measure, tick);
//if there is something to tie, complete tie backwards
//and add the tie to score
const std::vector<Note*> notes = chord->notes();
if (addTie) {
for (size_t i = 0; i < notes.size(); ++i) {
tie[i]->setEndNote(notes[i]);
notes[i]->setTieBack(tie[i]);
undoAddElement(tie[i]);
}
addTie = false;
}
//if we're not the last element in the duration list,
//set tie forward
if (i+1 < n) {
for (size_t i = 0; i < notes.size(); ++i) {
tie[i] = new Tie(this);
tie[i]->setStartNote(notes[i]);
tie[i]->setTrack(track);
notes[i]->setTieFor(tie[i]);
addTie = true;
}
}
setPlayChord(true);
segment = chord->segment();
tick += chord->actualTicks();
}
//subtract the duration already realized and move on
if (t)
dur -= dd / t->ratio();
else
dur -= dd;
//we are done when there is no duration left to realize
if (dur.isZero())
break;
//go to next segment unless we are at the score (which means we will just be done there)
Segment* nseg = tick2segment(tick, false, SegmentType::ChordRest);
if (nseg == 0) {
qDebug("reached end of score");
break;
}
segment = nseg;
cr = toChordRest(segment->element(track));
if (cr == 0) {
if (track % VOICES)
cr = addRest(segment, track, TDuration(TDuration::DurationType::V_MEASURE), 0);
else {
qDebug("no rest in voice 0");
break;
}
}
//
// Note does not fit on current measure, create Tie to
// next part of note
std::vector<Note*> notes = nr->notes();
for (size_t i = 0; i < notes.size(); ++i) {
tie[i] = new Tie(this);
tie[i]->setStartNote(notes[i]);
tie[i]->setTrack(notes[i]->track());
notes[i]->setTieFor(tie[i]);
}
}
if (!tie.empty())
connectTies();
if (nr)
select(nr, SelectType::SINGLE, 0);
return segment;
}
//---------------------------------------------------------
// cmdResequenceRehearsalMarks
/// resequences rehearsal marks within a range selection
@ -3887,7 +4095,7 @@ void Score::cmd(const QAction* a, EditData& ed)
{ "grace16after", [](Score* cs, EditData&){ cs->cmdAddGrace(NoteType::GRACE16_AFTER, MScore::division / 4); }},
{ "grace32after", [](Score* cs, EditData&){ cs->cmdAddGrace(NoteType::GRACE32_AFTER, MScore::division / 8); }},
{ "explode", [](Score* cs, EditData&){ cs->cmdExplode(); }},
{ "implode", [](Score* cs, EditData&){ cs-> cmdImplode(); }},
{ "implode", [](Score* cs, EditData&){ cs->cmdImplode(); }},
{ "slash-fill", [](Score* cs, EditData&){ cs->cmdSlashFill(); }},
{ "slash-rhythm", [](Score* cs, EditData&){ cs->cmdSlashRhythm(); }},
{ "resequence-rehearsal-marks", [](Score* cs, EditData&){ cs->cmdResequenceRehearsalMarks(); }},

View file

@ -150,7 +150,14 @@ void Excerpt::createExcerpt(Excerpt* excerpt)
// Set instruments and create linked staffs
for (const Part* part : parts) {
Part* p = new Part(score);
p->setInstrument(*part->instrument());
//properly set harmony channel for newly created part
const Instrument* instr = part->instrument();
int chanIdx = instr->channelIdx("harmony");
p->setInstrument(*instr);
if (chanIdx != -1)
p->setHarmonyChannel(const_cast<Channel*>(instr->channel(chanIdx)));
p->setPartName(part->partName());
for (Staff* staff : *part->staves()) {

View file

@ -101,6 +101,8 @@ QString Harmony::rootName()
QString Harmony::baseName()
{
determineRootBaseSpelling();
if (_baseTpc == Tpc::TPC_INVALID)
return rootName();
return tpc2name(_baseTpc, _baseSpelling, _baseCase);
}
@ -125,7 +127,7 @@ void Harmony::resolveDegreeList()
// try to find the chord in chordList
const ChordList* cl = score()->style().chordList();
foreach(const ChordDescription& cd, *cl) {
for (const ChordDescription& cd : *cl) {
if ((cd.chord == hc) && !cd.names.empty()) {
qDebug("ResolveDegreeList: found in table as %s", qPrintable(cd.names.front()));
_id = cd.id;
@ -143,6 +145,10 @@ qDebug("ResolveDegreeList: not found in table");
const ElementStyle chordSymbolStyle {
{ Sid::harmonyPlacement, Pid::PLACEMENT },
{ Sid::minHarmonyDistance, Pid::MIN_DISTANCE },
{ Sid::harmonyPlay, Pid::PLAY },
{ Sid::harmonyVoiceLiteral, Pid::HARMONY_VOICE_LITERAL },
{ Sid::harmonyVoicing, Pid::HARMONY_VOICING },
{ Sid::harmonyDuration, Pid::HARMONY_DURATION }
};
//---------------------------------------------------------
@ -161,6 +167,7 @@ Harmony::Harmony(Score* s)
_harmonyType = HarmonyType::STANDARD;
_leftParen = false;
_rightParen = false;
_realizedHarmony = RealizedHarmony(this);
initElementStyle(&chordSymbolStyle);
}
@ -180,6 +187,7 @@ Harmony::Harmony(const Harmony& h)
_textName = h._textName;
_userName = h._userName;
_function = h._function;
_realizedHarmony = h._realizedHarmony;
for (const TextSegment* s : h.textList) {
TextSegment* ns = new TextSegment();
ns->set(s->text, s->font, s->x, s->y);
@ -193,7 +201,7 @@ Harmony::Harmony(const Harmony& h)
Harmony::~Harmony()
{
foreach(const TextSegment* ts, textList)
for (const TextSegment* ts : textList)
delete ts;
if (_parsedForm)
delete _parsedForm;
@ -272,6 +280,8 @@ void Harmony::write(XmlWriter& xml) const
if (!_function.isEmpty())
xml.tag("function", _function);
TextBase::writeProperties(xml, false, true);
//Pid::PLAY, Pid::HARMONY_VOICE_LITERAL, Pid::HARMONY_VOICING, Pid::HARMONY_DURATION
//written by the above function call because they are part of element style
if (_rightParen)
xml.tagE("rightParen");
xml.etag();
@ -341,6 +351,14 @@ void Harmony::read(XmlReader& e)
;
else if (readProperty(tag, e, Pid::HARMONY_TYPE))
;
else if (readProperty(tag, e, Pid::PLAY))
;
else if (readProperty(tag, e, Pid::HARMONY_VOICE_LITERAL))
;
else if (readProperty(tag, e, Pid::HARMONY_VOICING))
;
else if (readProperty(tag, e, Pid::HARMONY_DURATION))
;
else if (!TextBase::readProperties(e))
e.unknown();
}
@ -823,6 +841,10 @@ void Harmony::endEdit(EditData& ed)
s.replace("\ue262", "\u266f"); // sharp
}
//play chord on edit and set dirty
score()->setPlayChord(true);
_realizedHarmony.setDirty(true);
// render and layout chord symbol
// (needs to be done here if text hasn't changed, or redone if replacemens were performed above)
score()->startCmd();
@ -931,6 +953,87 @@ QString HDegree::text() const
return ss;
}
//---------------------------------------------------------
// findNext
/// find the next Harmony in the score
///
/// returns 0 if there is none
//---------------------------------------------------------
Harmony* Harmony::findNext() const
{
Segment* seg = toSegment(parent());
Segment* cur = seg->next1();
while (cur) {
//find harmony on same track
Element* e = cur->findAnnotation(ElementType::HARMONY,
track(), track());
if (e) {
//we have found harmony element
return toHarmony(e);
}
cur = cur->next1();
}
return 0;
}
//---------------------------------------------------------
// findPrev
/// find the previous Harmony in the score
///
/// returns 0 if there is none
//---------------------------------------------------------
Harmony* Harmony::findPrev() const
{
Segment* seg = toSegment(parent());
Segment* cur = seg->prev1();
while (cur) {
//find harmony on same track
Element* e = cur->findAnnotation(ElementType::HARMONY,
track(), track());
if (e) {
//we have found harmony element
return toHarmony(e);
}
cur = cur->prev1();
}
return 0;
}
//---------------------------------------------------------
// ticksTilNext
/// finds ticks until the next chord symbol or end of score
///
/// stopAtMeasureEnd being set to true will have the loop
/// stop at measure end.
//---------------------------------------------------------
Fraction Harmony::ticksTilNext(bool stopAtMeasureEnd) const
{
Segment* seg = toSegment(parent());
Fraction duration = seg->ticks();
Segment* cur = seg->next1();
while (cur) {
if (stopAtMeasureEnd && (cur->measure() != seg->measure()))
break; //limit by measure end
//find harmony on same track
Element* e = cur->findAnnotation(ElementType::HARMONY,
track(), track());
if (e) {
//we have found the next chord symbol
//set duration to the difference between
//the two chord symbols
duration = e->tick() - tick();
break;
}
//keep adding the duration of the current segment
//in case we are not able to find a next
//chord symbol
duration += cur->ticks();
cur = cur->next1();
}
return duration;
}
//---------------------------------------------------------
// fromXml
// lookup harmony in harmony data base
@ -941,12 +1044,12 @@ const ChordDescription* Harmony::fromXml(const QString& kind, const QList<HDegre
{
QStringList degrees;
foreach(const HDegree& d, dl)
for (const HDegree& d : dl)
degrees.append(d.text());
QString lowerCaseKind = kind.toLower();
const ChordList* cl = score()->style().chordList();
foreach(const ChordDescription& cd, *cl) {
for (const ChordDescription& cd : *cl) {
QString k = cd.xmlKind;
QString lowerCaseK = k.toLower(); // required for xmlKind Tristan
QStringList d = cd.xmlDegrees;
@ -968,7 +1071,7 @@ const ChordDescription* Harmony::fromXml(const QString& kind)
{
QString lowerCaseKind = kind.toLower();
const ChordList* cl = score()->style().chordList();
foreach(const ChordDescription& cd, *cl) {
for (const ChordDescription& cd : *cl) {
if (lowerCaseKind == cd.xmlKind)
return &cd;
}
@ -1014,7 +1117,7 @@ const ChordDescription* Harmony::descr(const QString& name, const ParsedChord* p
const ChordList* cl = score()->style().chordList();
const ChordDescription* match = 0;
if (cl) {
foreach (const ChordDescription& cd, *cl) {
for (const ChordDescription& cd : *cl) {
for (const QString& s : cd.names) {
if (s == name)
return &cd;
@ -1069,6 +1172,54 @@ const ChordDescription* Harmony::getDescription(const QString& name, const Parse
return cd;
}
//---------------------------------------------------------
// getRealizedHarmony
// get realized harmony or create one for the current symbol
// also updates the realized harmony and accounts for
// transposition. RealizedHarmony objects cannot be cached
// since the notes generated depends on context rather than
// just root, bass, chord symbol, and voicing.
//---------------------------------------------------------
const RealizedHarmony& Harmony::getRealizedHarmony()
{
int offset = 0; //semitone offset for pitch adjustment
Staff* st = staff();
Interval interval = st->part()->instrument(tick())->transpose();
if (!score()->styleB(Sid::concertPitch))
offset = interval.chromatic;
//Adjust for Nashville Notation, might be temporary
if (_harmonyType == HarmonyType::NASHVILLE && !_realizedHarmony.valid()) {
Key key = staff()->key(tick());
//parse root
int rootTpc = function2Tpc(_function, key);
//parse bass
int slash = _textName.lastIndexOf('/');
int bassTpc;
if (slash == -1)
bassTpc = Tpc::TPC_INVALID;
else
bassTpc = function2Tpc(_textName.mid(slash + 1), key);
_realizedHarmony.update(rootTpc, bassTpc, offset);
}
else
_realizedHarmony.update(_rootTpc, _baseTpc, offset);
return _realizedHarmony;
}
//---------------------------------------------------------
// realizedHarmony
// get realized harmony or create one for the current symbol
// without updating the realized harmony
//---------------------------------------------------------
RealizedHarmony& Harmony::realizedHarmony()
{
return _realizedHarmony;
}
//---------------------------------------------------------
// generateDescription
// generate new chord description from _textName
@ -1786,7 +1937,7 @@ QString Harmony::screenReaderInfo() const
aux = aux.replace("#", QObject::tr("")).replace("<", "");
QString extension = "";
foreach (QString s, aux.split(">", QString::SkipEmptyParts)) {
for (QString s : aux.split(">", QString::SkipEmptyParts)) {
if (!s.contains("blues"))
s.replace("b", QObject::tr(""));
extension += s + " ";
@ -1855,9 +2006,25 @@ Element* Harmony::drop(EditData& data)
QVariant Harmony::getProperty(Pid pid) const
{
if (pid == Pid::HARMONY_TYPE)
return QVariant(int(_harmonyType));
return TextBase::getProperty(pid);
switch (pid) {
case Pid::PLAY:
return QVariant(_play);
break;
case Pid::HARMONY_TYPE:
return QVariant(int(_harmonyType));
break;
case Pid::HARMONY_VOICE_LITERAL:
return _realizedHarmony.literal();
break;
case Pid::HARMONY_VOICING:
return int(_realizedHarmony.voicing());
break;
case Pid::HARMONY_DURATION:
return int(_realizedHarmony.duration());
break;
default:
return TextBase::getProperty(pid);
}
}
//---------------------------------------------------------
@ -1866,17 +2033,32 @@ QVariant Harmony::getProperty(Pid pid) const
bool Harmony::setProperty(Pid pid, const QVariant& v)
{
if (pid == Pid::HARMONY_TYPE) {
setHarmonyType(HarmonyType(v.toInt()));
return true;
switch (pid) {
case Pid::PLAY:
setPlay(v.toBool());
break;
case Pid::HARMONY_TYPE:
setHarmonyType(HarmonyType(v.toInt()));
break;
case Pid::HARMONY_VOICE_LITERAL:
_realizedHarmony.setLiteral(v.toBool());
break;
case Pid::HARMONY_VOICING:
_realizedHarmony.setVoicing(Voicing(v.toInt()));
break;
case Pid::HARMONY_DURATION:
_realizedHarmony.setDuration(HDuration(v.toInt()));
break;
default:
if (TextBase::setProperty(pid, v)) {
if (pid == Pid::TEXT)
setHarmony(v.toString());
render();
break;
}
return false;
}
else if (TextBase::setProperty(pid, v)) {
if (pid == Pid::TEXT)
setHarmony(plainText());
render();
return true;
}
return false;
return true;
}
//---------------------------------------------------------

View file

@ -15,6 +15,7 @@
#include "text.h"
#include "pitchspelling.h"
#include "realizedharmony.h"
namespace Ms {
@ -83,11 +84,14 @@ class Harmony final : public TextBase {
bool showSpell = false; // show spell check warning
HarmonyType _harmonyType; // used to control rendering, transposition, export, etc.
RealizedHarmony _realizedHarmony; //the realized harmony used for playback
QList<HDegree> _degreeList;
QList<QFont> fontList; // temp values used in render()
QList<TextSegment*> textList; // rendered chord
bool _leftParen, _rightParen; // include opening and/or closing parenthesis
bool _play; // whether or not to play back the harmony
mutable QRectF _tbbox;
@ -112,6 +116,9 @@ class Harmony final : public TextBase {
void setId(int d) { _id = d; }
int id() const { return _id; }
void setPlay(bool p) { _play = p; }
bool play() const { return _play; }
void setBaseCase(NoteCaseType c) { _baseCase = c; }
void setRootCase(NoteCaseType c) { _rootCase = c; }
@ -120,12 +127,19 @@ class Harmony final : public TextBase {
void setLeftParen(bool leftParen) { _leftParen = leftParen; }
void setRightParen(bool rightParen) { _rightParen = rightParen; }
Harmony* findNext() const;
Harmony* findPrev() const;
Fraction ticksTilNext(bool stopAtMeasureEnd = false) const;
const ChordDescription* descr() const;
const ChordDescription* descr(const QString&, const ParsedChord* pc = 0) const;
const ChordDescription* getDescription();
const ChordDescription* getDescription(const QString&, const ParsedChord* pc = 0);
const ChordDescription* generateDescription();
RealizedHarmony& realizedHarmony();
const RealizedHarmony& getRealizedHarmony();
void determineRootBaseSpelling(NoteSpellingType& rootSpelling, NoteCaseType& rootCase,
NoteSpellingType& baseSpelling, NoteCaseType& baseCase);
@ -138,6 +152,11 @@ class Harmony final : public TextBase {
virtual bool edit(EditData&) override;
virtual void endEdit(EditData&) override;
bool isRealizable() const
{
return (_rootTpc != Tpc::TPC_INVALID)
|| (_harmonyType == HarmonyType::NASHVILLE); // unable to fully check at for nashville at the moment
}
QString hFunction() const { return _function; }
QString hUserName() const { return _userName; }
QString hTextName() const { return _textName; }

View file

@ -313,6 +313,7 @@ class Instrument {
const QList<Channel*>& channel() const { return _channel; }
void appendChannel(Channel* c) { _channel.append(c); }
void removeChannel(Channel* c) { _channel.removeOne(c);}
void clearChannels() { _channel.clear(); }
void setMidiActions(const QList<NamedEventList>& l) { _midiActions = l; }

View file

@ -24,8 +24,8 @@ class XmlReader;
class NoteEvent {
int _pitch; // relative pitch to note pitch
int _ontime; // 1/1000 of nominal note len
int _len; // 1/1000 of nominal note len
int _ontime; // one unit is 1/1000 of nominal note len
int _len; // one unit is 1/1000 of nominal note len
public:
constexpr static int NOTE_LENGTH = 1000;

View file

@ -551,6 +551,60 @@ int Part::harmonyCount() const
return count;
}
//---------------------------------------------------------
// updateHarmonyChannels
/// update the harmony channel by creating a new channel
/// when appropriate or using the existing one
///
/// checkRemoval can be set to true to check to see if we
/// can remove the harmony channel
//---------------------------------------------------------
void Part::updateHarmonyChannels(bool checkRemoval)
{
// usage of harmony count is okay even if expensive since checking harmony channel will shortcircuit if existent
// harmonyCount will only be called on loading of a score (where it will need to be scanned for harmony anyway)
// or when the first harmony of a score is just added
if (checkRemoval) {
//may be a bit expensive since it gets called after every single delete or undo, but it should be okay for now
//~OPTIM~
if (harmonyCount() == 0) {
Instrument* instr = instrument();
int hChannel = instr->channelIdx("harmony");
if (hChannel != -1) {
instr->removeChannel(instr->channel(hChannel));
_harmonyChannel = 0;
masterScore()->rebuildMidiMapping();
masterScore()->updateChannel();
score()->setInstrumentsChanged(true);
score()->setLayoutAll(); //do we need this?
return;
}
}
}
if (!_harmonyChannel) {
Instrument* instr = instrument();
int hChannel = instr->channelIdx("harmony");
if (hChannel != -1) {
//we already have a channel, but it's just not properly set yet
//so we just need to set it
_harmonyChannel = instr->channel(hChannel);
return;
}
if (harmonyCount() > 0) {
Channel* c = new Channel(*instr->channel(0));
c->setName("harmony");
instr->appendChannel(c);
_harmonyChannel = c;
masterScore()->rebuildMidiMapping();
masterScore()->updateChannel();
score()->setInstrumentsChanged(true);
score()->setLayoutAll(); //do we need this?
}
}
}
//---------------------------------------------------------
// hasPitchedStaff
//---------------------------------------------------------

View file

@ -63,6 +63,7 @@ class Part final : public ScoreElement {
int _color; ///User specified color for helping to label parts
PreferSharpFlat _preferSharpFlat;
Channel* _harmonyChannel = 0; ///channel which harmony is played
public:
Part(Score* = 0);
@ -138,6 +139,10 @@ class Part final : public ScoreElement {
bool hasTabStaff() const;
bool hasDrumStaff() const;
void updateHarmonyChannels(bool checkRemoval = false);
const Channel* harmonyChannel() const { return _harmonyChannel; }
void setHarmonyChannel(Channel* c) { _harmonyChannel = c; }
const Part* masterPart() const;
Part* masterPart();

View file

@ -805,5 +805,77 @@ int tpc2degree(int tpc, Key key)
return (names.indexOf(stepName) - names.indexOf(scale) +28) % 7;
}
//---------------------------------------------------------
// tpcInterval
/// Finds tpc of a note based on an altered interval
/// from a starting note
//---------------------------------------------------------
int tpcInterval(int startTpc, int interval, int alter)
{
Q_ASSERT(interval > 0);
static const int intervals[7] = {
// 1 2 3 4 5 6 7
0, 2, 4, -1, 1, 3, 5
};
int result = startTpc + intervals[(interval - 1) % 7] + alter * TPC_DELTA_SEMITONE;
//ensure that we don't have anything more than double sharp or double flat
//(I know, breaking some convention, but it's the best we can do for now)
while (result > Tpc::TPC_MAX)
result -= TPC_DELTA_ENHARMONIC;
while (result < Tpc::TPC_MIN)
result += TPC_DELTA_ENHARMONIC;
return result;
}
//---------------------------------------------------------
// step2pitchInterval
/// Finds pitch between notes a specified altered interval away
///
/// For example:
/// step = 3, alter = 0 means major 3rd
/// step = 5, alter = -1 means diminished 5
/// step = 6, alter = 2 means augmented sixth
//---------------------------------------------------------
int step2pitchInterval(int step, int alter)
{
Q_ASSERT(step > 0);
static const int intervals[7] = {
// 1 2 3 4 5 6 7
0, 2, 4, 5, 7, 9, 11
};
return intervals[(step - 1) % 7] + alter;
}
//----------------------------------------------
// function2Tpc
/// might be temporary, just used to parse nashville notation now
///
//----------------------------------------------
int function2Tpc(const QString& s, Key key) {
//TODO - PHV: allow for alternate spellings
int alter = 0;
int step;
if (!s.isEmpty() && s[0].isDigit()) {
step = s[0].digitValue();
}
else if (s.size() > 1 && s[1].isDigit()) {
step = s[1].digitValue();
if (s[0] == 'b')
alter = -1;
else if (s[0] == '#')
alter = 1;
}
else
return Tpc::TPC_INVALID;
int keyTpc = int(key) + 14; //tpc of key (ex. F# major would be Tpc::F_S)
return tpcInterval(keyTpc, step, alter);
}
}

View file

@ -85,6 +85,9 @@ extern int tpc2alterByKey(int tpc, Key);
extern int pitch2absStepByKey(int pitch, int tpc, Key, int* pAlter);
extern int absStep2pitchByKey(int step, Key);
extern int tpc2degree(int tpc, Key key);
extern int tpcInterval(int startTpc, int interval, int alter);
extern int step2pitchInterval(int step, int alter);
extern int function2Tpc(const QString& s, Key key);
//---------------------------------------------------------
// tpc2alter

View file

@ -228,6 +228,9 @@ static constexpr PropertyMetaData propertyList[] = {
{ Pid::FRET_NUT, true, "showNut", P_TYPE::BOOL, DUMMY_QT_TRANSLATE_NOOP("propertyName", "show nut") },
{ Pid::FRET_OFFSET, true, "fretOffset", P_TYPE::INT, DUMMY_QT_TRANSLATE_NOOP("propertyName", "fret offset") },
{ Pid::FRET_NUM_POS, true, "fretNumPos", P_TYPE::INT, DUMMY_QT_TRANSLATE_NOOP("propertyName", "fret number position") },
{ Pid::HARMONY_VOICE_LITERAL, true, "harmonyVoiceLiteral", P_TYPE::BOOL, DUMMY_QT_TRANSLATE_NOOP("propertyName", "harmony voice literal") },
{ Pid::HARMONY_VOICING, true, "harmonyVoicing", P_TYPE::INT, DUMMY_QT_TRANSLATE_NOOP("propertyName", "harmony voicing") },
{ Pid::HARMONY_DURATION, true, "harmonyDuration", P_TYPE::INT, DUMMY_QT_TRANSLATE_NOOP("propertyName", "harmony duration") },
{ Pid::SYSTEM_BRACKET, false, "type", P_TYPE::INT, DUMMY_QT_TRANSLATE_NOOP("propertyName", "type") },
{ Pid::GAP, false, 0, P_TYPE::BOOL, DUMMY_QT_TRANSLATE_NOOP("propertyName", "gap") },

View file

@ -238,6 +238,10 @@ enum class Pid {
FRET_OFFSET,
FRET_NUM_POS,
HARMONY_VOICE_LITERAL,
HARMONY_VOICING,
HARMONY_DURATION,
SYSTEM_BRACKET,
GAP,
AUTOPLACE,

View file

@ -3269,6 +3269,10 @@ Score::FileError MasterScore::read114(XmlReader& e)
rebuildMidiMapping();
updateChannel();
for (Part* p : parts()) {
p->updateHarmonyChannels();
}
// treat reading a 1.14 file as import
// on save warn if old file will be overwritten
setCreated(true);

View file

@ -3903,6 +3903,11 @@ static bool readScore(Score* score, XmlReader& e)
ms->updateChannel();
// ms->createPlayEvents();
}
for (Part* p : score->parts()) {
p->updateHarmonyChannels();
}
return true;
}

View file

@ -264,6 +264,10 @@ bool Score::read(XmlReader& e)
fixTicks();
masterScore()->rebuildMidiMapping();
masterScore()->updateChannel();
for (Part* p : _parts) {
p->updateHarmonyChannels();
}
// createPlayEvents();
return true;
}

View file

@ -0,0 +1,551 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2016 Werner Schweer and others
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#include "realizedharmony.h"
#include "pitchspelling.h"
#include "staff.h"
#include "chordlist.h"
#include "harmony.h"
#include "fraction.h"
#include "segment.h"
namespace Ms {
//---------------------------------------------------
// setVoicing
/// sets the voicing and dirty flag if the passed
/// voicing is different than current
//---------------------------------------------------
void RealizedHarmony::setVoicing(Voicing v)
{
if (_voicing == v)
return;
_voicing = v;
cascadeDirty(true);
}
//---------------------------------------------------
// setDuration
/// sets the duration and dirty flag if the passed
/// HDuration is different than current
//---------------------------------------------------
void RealizedHarmony::setDuration(HDuration d)
{
if (_duration == d)
return;
_duration = d;
cascadeDirty(true);
}
//---------------------------------------------------
// setLiteral
/// sets literal/jazz and dirty flag if the passed
/// bool is different than current
//---------------------------------------------------
void RealizedHarmony::setLiteral(bool literal)
{
if (_literal == literal)
return;
_literal = literal;
cascadeDirty(true);
}
//---------------------------------------------------
// notes
/// returns the list of notes
//---------------------------------------------------
const RealizedHarmony::PitchMap& RealizedHarmony::notes() const
{
Q_ASSERT(!_dirty);
//with the way that the code is currently structured, there should be no way to
//get to this function with dirty flag set although in the future it may be
//better to just update if dirty here
return _notes;
}
//---------------------------------------------------
// generateNotes
/// generates a note list based on the passed parameters
//---------------------------------------------------
const RealizedHarmony::PitchMap RealizedHarmony::generateNotes(int rootTpc, int bassTpc,
bool literal, Voicing voicing, int transposeOffset) const
{
//The octave which to generate the body of the harmony, this is static const for now
//but may be user controlled in the future
static const int DEFAULT_OCTAVE = 5; //octave above middle C
PitchMap notes;
int rootPitch = tpc2pitch(rootTpc) + transposeOffset;
//euclidian mod, we need to treat this new pitch as a pitch between
//0 and 11, so that voicing remains consistent across transposition
if (rootPitch < 0)
rootPitch += PITCH_DELTA_OCTAVE;
else
rootPitch %= PITCH_DELTA_OCTAVE;
//create root note or bass note in second octave below middle C
if (bassTpc != Tpc::TPC_INVALID && voicing != Voicing::ROOT_ONLY)
notes.insert(tpc2pitch(bassTpc) + transposeOffset
+ (DEFAULT_OCTAVE-2)*PITCH_DELTA_OCTAVE, bassTpc);
else
notes.insert(rootPitch + (DEFAULT_OCTAVE-2)*PITCH_DELTA_OCTAVE, rootTpc);
switch (voicing) {
case Voicing::ROOT_ONLY: //already added root/bass so we are good
break;
case Voicing::AUTO: //auto is close voicing for now since it is the most robust
//but just render the root if the harmony isn't understandable
if (!_harmony->parsedForm()->understandable())
break;
// FALLTHROUGH
case Voicing::CLOSE://Voices notes in close position in the first octave above middle C
{
notes.insert(rootPitch + DEFAULT_OCTAVE*PITCH_DELTA_OCTAVE, rootTpc);
//ensure that notes fall under a specific range
//for now this range is between 5*12 and 6*12
PitchMap intervals = getIntervals(rootTpc, literal);
PitchMapIterator i(intervals);
while (i.hasNext()) {
i.next();
notes.insert((rootPitch + (i.key() % 128)) % PITCH_DELTA_OCTAVE +
DEFAULT_OCTAVE*PITCH_DELTA_OCTAVE, i.value());
}
}
break;
case Voicing::DROP_2:
{
//select 4 notes from list
PitchMap intervals = normalizeNoteMap(getIntervals(rootTpc, literal), rootTpc, rootPitch, 4);
PitchMapIterator i(intervals);
i.toBack();
int counter = 0; //counter to drop the second note
while (i.hasPrevious()) {
i.previous();
if (++counter == 2)
notes.insert(i.key() + (DEFAULT_OCTAVE-1)*PITCH_DELTA_OCTAVE, i.value());
else
notes.insert(i.key() + DEFAULT_OCTAVE*PITCH_DELTA_OCTAVE, i.value());
}
}
break;
case Voicing::THREE_NOTE:
{
//Insert 2 notes in the octave above middle C
PitchMap intervals = normalizeNoteMap(getIntervals(rootTpc, literal), rootTpc, rootPitch, 2, true);
PitchMapIterator i(intervals);
i.next();
notes.insert(i.key() + DEFAULT_OCTAVE*PITCH_DELTA_OCTAVE, i.value());
i.next();
notes.insert(i.key() + DEFAULT_OCTAVE*PITCH_DELTA_OCTAVE, i.value());
}
break;
case Voicing::FOUR_NOTE:
case Voicing::SIX_NOTE:
//FALLTHROUGH
{
//four/six note voicing, drop every other note
PitchMap relIntervals = getIntervals(rootTpc, literal);
PitchMap intervals;
if (voicing == Voicing::FOUR_NOTE)
intervals = normalizeNoteMap(relIntervals, rootTpc, rootPitch, 3, true);
else //voicing == Voicing::SIX_NOTE
intervals = normalizeNoteMap(relIntervals, rootTpc, rootPitch, 5, true);
PitchMapIterator i(intervals);
i.toBack();
int counter = 0; //how many notes have been added
while (i.hasPrevious()) {
i.previous();
if (counter % 2)
notes.insert(i.key() + (DEFAULT_OCTAVE-1)*PITCH_DELTA_OCTAVE, i.value());
else
notes.insert(i.key() + DEFAULT_OCTAVE*PITCH_DELTA_OCTAVE, i.value());
++counter;
}
}
break;
default:
break;
}
return notes;
}
//---------------------------------------------------
// update
/// updates the current note map, this is where all
/// of the rhythm and voicing choices matter since
/// the voicing algorithms depend on this.
///
/// transposeOffset -- is the necessary adjustment
/// that is added to the root and bass
/// to get the correct sounding pitch
///
/// TODO -: Don't worry about realized harmony for
/// RNA harmony?
//---------------------------------------------------
void RealizedHarmony::update(int rootTpc, int bassTpc, int transposeOffset /*= 0*/)
{
//on transposition the dirty flag is set by the harmony, but it's a little
//bit risky design since these 3 parameters rely on the dirty bit and are not
//otherwise checked by RealizedHarmony. This saves us 3 ints of space, but
//has the added risk
if (!_dirty) {
Q_ASSERT(_harmony->harmonyType() != HarmonyType::STANDARD || (_notes.first() == rootTpc || _notes.first() == bassTpc));
return;
}
_notes = generateNotes(rootTpc, bassTpc, _literal, _voicing, transposeOffset);
_dirty = false;
}
//--------------------------------------------------
// getActualDuration
/// gets the fraction duration for how long
/// the harmony should be realized based
/// on the HDuration set.
///
/// This is opposed to RealizedHarmony::duration()
/// which returns the HDuration, which is the duration
/// setting.
///
/// Specifying a parameter finds a duration based on the
/// passed duration type while not specifying a parameter
/// uses the setting set by the user for the specific
/// harmony object.
//--------------------------------------------------
Fraction RealizedHarmony::getActualDuration(HDuration durationType) const
{
HDuration dur;
if (durationType != HDuration::INVALID)
dur = durationType;
else
dur = _duration;
switch (dur)
{
case HDuration::UNTIL_NEXT_CHORD_SYMBOL:
return _harmony->ticksTilNext(false);
break;
case HDuration::STOP_AT_MEASURE_END:
return _harmony->ticksTilNext(true);
break;
case HDuration::SEGMENT_DURATION:
return toSegment(_harmony->parent())->ticks();
break;
default:
return Fraction(0, 1);
}
}
//---------------------------------------------------
// getIntervals
/// gets a weighted map from intervals to TPCs based on
/// a passed root tpc (this allows for us to
/// keep pitches, but transpose notes on the score)
///
/// Weighting System:
/// - Rank 0: 3rd, altered 5th, suspensions (characteristic notes)
/// - Rank 1: 7th
/// - Rank 2: 9ths
/// - Rank 3: 13ths where applicable and (in minor chords) 11ths
/// - Rank 3: Other alterations and additions
/// - Rank 4: 5th and (in major/dominant chords) 11th
//---------------------------------------------------
RealizedHarmony::PitchMap RealizedHarmony::getIntervals(int rootTpc, bool literal) const
{
//RANKING SYSTEM
static const int RANK_MULT = 128; //used as multiplier and mod since MIDI pitch goes from 0-127
static const int RANK_3RD = 0;
static const int RANK_7TH = 1;
static const int RANK_9TH = 2;
static const int RANK_ADD = 3;
static const int RANK_OMIT = 4;
static const int FIFTH = 7 + RANK_MULT*RANK_OMIT;
PitchMap ret;
const ParsedChord* p = _harmony->parsedForm();
QString quality = p->quality();
int ext = p->extension().toInt();
const QStringList& modList = p->modifierList();
int omit = 0; //omit flags for which notes to omit (for notes that are altered
//or specified to be omitted as a modification) so that they
//are not later added
bool alt5 = false; //altered 5
//handle modifiers
for (QString s : modList) {
//find number, split up mods
bool modded = false;
for (int c = 0; c < s.length(); ++c) {
if (s[c].isDigit()) {
Q_ASSERT(c > 0); //we shouldn't have just a number
int alter = 0;
int cutoff = c;
int deg = s.right(s.length() - c).toInt();
//account for if the flat/sharp is stuck to the end of add
if (s[c-1] == '#') {
cutoff -= 1;
alter = +1;
}
else if (s[c-1] == 'b') {
cutoff -= 1;
alter = -1;
}
QString extType = s.left(cutoff);
if (extType == "" || extType == "major") { //alteration
if (deg == 9)
ret.insert(step2pitchInterval(deg, alter) + RANK_MULT*RANK_9TH, tpcInterval(rootTpc, deg, alter));
else
ret.insert(step2pitchInterval(deg, alter) + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, deg, alter));
if (deg == 5)
alt5 = true;
omit |= 1 << deg;
modded = true;
}
else if (extType == "sus") {
ret.insert(step2pitchInterval(deg, alter) + RANK_MULT*RANK_3RD, tpcInterval(rootTpc, deg, alter));
omit |= 1 << 3;
modded = true;
}
else if (extType == "no") {
omit |= 1 << deg;
modded = true;
}
}
}
//check for special chords, if we haven't modded anything yet there is a special or incomprehensible modifier
if (!modded) {
if (s == "phryg") {
ret.insert(step2pitchInterval(9, -1) + RANK_MULT*RANK_9TH, tpcInterval(rootTpc, 9, -1));
omit |= 1 << 9;
}
else if (s == "lyd") {
ret.insert(step2pitchInterval(11, +1) + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 11, +1));
omit |= 1 << 11;
}
else if (s == "blues") {
ret.insert(step2pitchInterval(9, +1) + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 9, +1));
omit |= 1 << 9;
}
else if (s == "alt") {
ret.insert(step2pitchInterval(5, -1) + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 5, -1));
ret.insert(step2pitchInterval(5, +1) + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 5, +1));
omit |= 1 << 5;
ret.insert(step2pitchInterval(9, -1) + RANK_MULT*RANK_9TH, tpcInterval(rootTpc, 9, -1));
ret.insert(step2pitchInterval(9, +1) + RANK_MULT*RANK_9TH, tpcInterval(rootTpc, 9, +1));
omit |= 1 << 9;
}
else //no easy way to realize tristan chords since they are more analytical tools
omit = ~0;
}
}
//handle ext = 5: power chord so omit the 3rd
if (ext == 5)
omit |= 1 << 3;
//handle chord quality
if (quality == "minor") {
if (!(omit & (1 << 3)))
ret.insert(step2pitchInterval(3, -1) + RANK_MULT*RANK_3RD, tpcInterval(rootTpc, 3, -1)); //min3
if (!(omit & (1 << 5)))
ret.insert(step2pitchInterval(5, 0) + RANK_MULT*RANK_OMIT, tpcInterval(rootTpc, 5, 0)); //p5
}
else if (quality == "augmented") {
if (!(omit & (1 << 3)))
ret.insert(step2pitchInterval(3, 0) + RANK_MULT*RANK_3RD, tpcInterval(rootTpc, 3, 0)); //maj3
if (!(omit & (1 << 5)))
ret.insert(step2pitchInterval(5, +1) + RANK_MULT*RANK_3RD, tpcInterval(rootTpc, 5, +1)); //p5
}
else if (quality == "diminished" || quality == "half-diminished") {
if (!(omit & (1 << 3)))
ret.insert(step2pitchInterval(3, -1) + RANK_MULT*RANK_3RD, tpcInterval(rootTpc, 3, -1)); //min3
if (!(omit & (1 << 5)))
ret.insert(step2pitchInterval(5, -1) + RANK_MULT*RANK_3RD, tpcInterval(rootTpc, 5, -1)); //dim5
alt5 = true;
}
else { //major or dominant
if (!(omit & (1 << 3)))
ret.insert(step2pitchInterval(3, 0) + RANK_MULT*RANK_3RD, tpcInterval(rootTpc, 3, 0)); //maj3
if (!(omit & (1 << 5)))
ret.insert(step2pitchInterval(5, 0) + RANK_MULT*RANK_OMIT, tpcInterval(rootTpc, 5, 0)); //p5
}
//handle extension
switch (ext) {
case 13:
if (!(omit & (1 << 13))) {
ret.insert(9 + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 13, 0)); //maj13
omit |= 1 << 13;
}
// FALLTHROUGH
case 11:
if (!(omit & (1 << 11))) {
if (quality == "minor")
ret.insert(5 + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 11, 0)); //maj11
else if (literal)
ret.insert(5 + RANK_MULT*RANK_OMIT, tpcInterval(rootTpc, 11, 0)); //maj11
omit |= 1 << 11;
}
// FALLTHROUGH
case 9:
if (!(omit & (1 << 9))) {
ret.insert(2 + RANK_MULT*RANK_9TH, tpcInterval(rootTpc, 9, 0)); //maj9
omit |= 1 << 9;
}
// FALLTHROUGH
case 7:
if (!(omit & (1 << 7))) {
if (quality == "major")
ret.insert(11 + RANK_MULT*RANK_7TH, tpcInterval(rootTpc, 7, 0));
else if (quality == "diminished")
ret.insert(9 + RANK_MULT*RANK_7TH, tpcInterval(rootTpc, 7, -2));
else //dominant or augmented or minor
ret.insert(10 + RANK_MULT*RANK_7TH, tpcInterval(rootTpc, 7, -1));
}
break;
case 6:
if (!(omit & (1 << 6))) {
ret.insert(9 + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 6, 0)); //maj6
omit |= 1 << 13; //no need to add/alter 6 chords
}
break;
case 5:
//omitted third already
break;
case 4:
if (!(omit & (1 << 4)))
ret.insert(5 + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 4, 0)); //p4
break;
case 2:
if (!(omit & (1 << 2)))
ret.insert(2 + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 2, 0)); //maj2
omit |= 1 << 9; //make sure we don't add altered 9 when theres a 2
break;
case 69:
ret.insert(9 + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 6, 0)); //maj6
ret.insert(2 + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 9, 0)); //maj6
omit = ~0; //no additions/alterations for a 69 chord
break;
default:
break;
}
Harmony* next = _harmony->findNext();
if (!_literal && next) {
//jazz interpretation
QString qNext = next->parsedForm()->quality();
//pitch from current to next harmony normalized to a range between 0 and 12
//add PITCH_DELTA_OCTAVE before modulo so that we can ensure arithmetic mod rather than computer mod
//int keyTpc = int(next->staff()->key(next->tick())) + 14; //tpc of key (ex. F# major would be Tpc::F_S)
//int keyTpcMinor = keyTpc + 3;
int pitchBetween = (tpc2pitch(next->rootTpc()) + PITCH_DELTA_OCTAVE - tpc2pitch(rootTpc)) % PITCH_DELTA_OCTAVE;
bool maj7 = qNext == "major" && next->parsedForm()->extension() >= 7; //whether or not the next chord has major 7
//commented code: dont add 9 for diminished chords
if (!(omit & (1 << 9))) {// && !(alt5 && (quality == "minor" || quality == "diminished" || quality == "half-diminished"))) {
if (quality == "dominant" && pitchBetween == 5 && (qNext == "minor" || maj7)) {
//flat 9 when resolving a fourth up to a minor chord or major 7th
ret.insert(1 + RANK_MULT*RANK_9TH, tpcInterval(rootTpc, 9, -1));
}
else //add major 9
ret.insert(2 + RANK_MULT*RANK_9TH, tpcInterval(rootTpc, 9, 0));
}
if (!(omit & (1 << 13)) && !alt5) {
if (quality == "dominant" && pitchBetween == 5 && (qNext == "minor" || false)) {
//flat 13 for dominant to chord a P4 up
//only for minor chords for now
ret.remove(FIFTH);
ret.insert(8 + RANK_MULT*RANK_ADD, tpcInterval(rootTpc, 13, -1));
}
//major 13 considered, but too dependent on melody and voicing of other chord
//no implementation for now
}
}
return ret;
}
//---------------------------------------------------
// normalizeNoteMap
/// normalize the pitch map from intervals to create pitches between 0 and 12
/// and resolve any weighting system.
///
/// enforceMaxEquals - enforce the max as a goal so that the max is how many notes is inserted
//---------------------------------------------------
RealizedHarmony::PitchMap RealizedHarmony::normalizeNoteMap(const PitchMap& intervals, int rootTpc, int rootPitch, int max, bool enforceMaxAsGoal) const
{
PitchMap ret;
PitchMapIterator itr(intervals);
for (int i = 0; i < max; ++i) {
if (!itr.hasNext())
break;
itr.next();
ret.insert((itr.key() % 128 + rootPitch) % PITCH_DELTA_OCTAVE, itr.value()); //128 is RANK_MULT
}
//redo insertions if we must have a specific number of notes with insertMulti
if (enforceMaxAsGoal) {
while (ret.size() < max) {
ret.insertMulti(rootPitch, rootTpc); //duplicate root
int size = max - ret.size();
itr = PitchMapIterator(intervals); //reset iterator
for (int i = 0; i < size; ++i) {
if (!itr.hasNext())
break;
itr.next();
ret.insertMulti((itr.key() % 128 + rootPitch) % PITCH_DELTA_OCTAVE, itr.value());
}
}
}
else if (ret.size() < max) //insert another root if we have room in general
ret.insertMulti(rootPitch, rootTpc);
return ret;
}
//---------------------------------------------------
// cascadeDirty
/// cascades the dirty flag backwards so that everything is properly set
/// this is required since voicing algorithms may look ahead
///
/// NOTE: FOR NOW ALGORITHMS DO NOT LOOK BACKWARDS AND SO THERE IS NO
/// REQUIREMENT TO CASCADE FORWARD, IN THE FUTURE IT MAY BECOME IMPORTANT
/// TO CASCADE FORWARD AS WELL
//---------------------------------------------------
void RealizedHarmony::cascadeDirty(bool dirty)
{
if (dirty && !_dirty) { //only cascade when we want to set our clean realized harmony to dirty
Harmony* prev = _harmony->findPrev();
if (prev)
prev->realizedHarmony().cascadeDirty(dirty);
}
_dirty = dirty;
}
}

109
libmscore/realizedharmony.h Normal file
View file

@ -0,0 +1,109 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2016 Werner Schweer and others
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#ifndef __REALIZEDHARMONY_H__
#define __REALIZEDHARMONY_H__
namespace Ms {
class Harmony;
class Fraction;
//voicing modes to use
enum class Voicing : signed char {
INVALID = -1,
AUTO = 0,
ROOT_ONLY,
CLOSE,
DROP_2,
SIX_NOTE,
FOUR_NOTE,
THREE_NOTE
};
//duration to realize notes for
enum class HDuration : signed char {
INVALID = -1,
UNTIL_NEXT_CHORD_SYMBOL = 0, //lasts until the next chord symbol or end of the schore
STOP_AT_MEASURE_END, //lasts until next chord symbol or measure end
SEGMENT_DURATION //lasts for the duration of the segment
};
//-----------------------------------------
// Realized Harmony
/// holds information and functions
/// to assist in the realization of chord
/// symbols. This is what is used to
/// allow for chord symbol playback
//-----------------------------------------
class RealizedHarmony {
public:
using PitchMap = QMap<int, int>; //map from pitch to tpc
using PitchMapIterator = QMapIterator<int, int>;
private:
Harmony* _harmony;
PitchMap _notes;
Voicing _voicing;
HDuration _duration;
//whether or not the current notes QMap is up to date
bool _dirty;
bool _literal; //use all notes when possible and do not add any notes
public:
RealizedHarmony() : _harmony(0), _notes(PitchMap()), _dirty(1) {}
RealizedHarmony(Harmony* h) : _harmony(h), _notes(PitchMap()), _dirty(1) {}
void setVoicing(Voicing);
void setDuration(HDuration);
void setLiteral(bool);
void setDirty(bool dirty) { cascadeDirty(dirty); } //set dirty flag and cascade
Voicing voicing() const { return _voicing; }
HDuration duration() const { return _duration; }
bool literal() const { return _literal; }
bool valid() const { return !_dirty && _harmony; }
const QList<int> pitches() const { return notes().keys(); }
const QList<int> tpcs() const { return notes().values(); }
const PitchMap& notes() const;
const PitchMap generateNotes(int rootTpc, int bassTpc, bool literal,
Voicing voicing, int transposeOffset) const;
void update(int rootTpc, int bassTpc, int transposeOffset = 0); //updates the notes map
Fraction getActualDuration(HDuration durationType = HDuration::INVALID) const;
private:
PitchMap getIntervals(int rootTpc, bool literal = true) const;
PitchMap normalizeNoteMap(const PitchMap& intervals, int rootTpc, int rootPitch, int max = 128, bool enforceMaxAsGoal = false) const;
void cascadeDirty(bool dirty);
};
}
#endif // __REALIZEDHARMONY_H__

View file

@ -524,6 +524,47 @@ static int getControllerFromCC(int cc)
return controller;
}
//---------------------------------------------------------
// renderHarmony
/// renders chord symbols
//---------------------------------------------------------
static void renderHarmony(EventMap* events, Measure* m, Harmony* h, int tickOffset)
{
if (!h->isRealizable())
return;
Staff* staff = m->score()->staff(h->track() / VOICES);
const Channel* channel = staff->part()->harmonyChannel();
Q_ASSERT(channel);
events->registerChannel(channel->channel());
if (!staff->primaryStaff())
return;
int staffIdx = staff->idx();
int velocity = staff->velocities().val(h->tick());
RealizedHarmony r = h->getRealizedHarmony();
QList<int> pitches = r.pitches();
NPlayEvent ev(ME_NOTEON, channel->channel(), 0, velocity);
Fraction duration = r.getActualDuration();
int onTime = h->tick().ticks() + tickOffset;
int offTime = onTime + duration.ticks();
ev.setOriginatingStaff(staffIdx);
ev.setTuning(0.0);
//add play events
for (int p : pitches) {
ev.setPitch(p);
ev.setVelo(velocity);
events->insert(std::pair<int, NPlayEvent>(onTime, ev));
ev.setVelo(0);
events->insert(std::pair<int, NPlayEvent>(offTime, ev));
}
}
//---------------------------------------------------------
// collectMeasureEventsSimple
// the original, velocity-only method of collecting events.
@ -540,6 +581,17 @@ static void collectMeasureEventsSimple(EventMap* events, Measure* m, Staff* staf
for (Segment* seg = m->first(st); seg; seg = seg->next(st)) {
int tick = seg->tick().ticks();
//render harmony
for (Element* e : seg->annotations()) {
if (!e->isHarmony() || (e->track() < strack) || (e->track() >= etrack))
continue;
Harmony* h = toHarmony(e);
if (!h->play())
continue;
renderHarmony(events, m, h, tickOffset);
}
for (int track = strack; track < etrack; ++track) {
// skip linked staves, except primary
if (!m->score()->staff(track / VOICES)->primaryStaff()) {
@ -608,6 +660,17 @@ static void collectMeasureEventsDefault(EventMap* events, Measure* m, Staff* sta
int etrack = nextStaffIdx * VOICES;
for (Segment* seg = m->first(st); seg; seg = seg->next(st)) {
Fraction tick = seg->tick();
//render harmony
for (Element* e : seg->annotations()) {
if (!e->isHarmony() || (e->track() < strack) || (e->track() >= etrack))
continue;
Harmony* h = toHarmony(e);
if (!h->play())
continue;
renderHarmony(events, m, h, tickOffset);
}
for (int track = strack; track < etrack; ++track) {
// Skip linked staves, except primary
Staff* st1 = m->score()->staff(track / VOICES);

View file

@ -1490,6 +1490,9 @@ void Score::addElement(Element* element)
createPlayEvents(toChord(cr));
}
break;
case ElementType::HARMONY:
element->part()->updateHarmonyChannels();
break;
default:
break;
@ -1651,6 +1654,9 @@ void Score::removeElement(Element* element)
createPlayEvents(toChord(cr));
}
break;
case ElementType::HARMONY:
element->part()->updateHarmonyChannels(true);
break;
default:
break;
@ -2748,9 +2754,12 @@ void Score::cmdConcertPitchChanged(bool flag, bool /*useDoubleSharpsFlats*/)
// don't transpose all links
// just ones resulting from mmrests
Harmony* he = toHarmony(se); // toHarmony() does not work as e is an ScoreElement
if (he->staff() == h->staff())
if (he->staff() == h->staff()) {
undoTransposeHarmony(he, rootTpc, baseTpc);
}
}
//realized harmony should be invalid after a transpose command
Q_ASSERT(!h->realizedHarmony().valid());
}
}
}

View file

@ -100,6 +100,8 @@ enum class Key;
enum class HairpinType : signed char;
enum class SegmentType;
enum class OttavaType : char;
enum class Voicing : signed char;
enum class HDuration : signed char;
enum class POS : char { CURRENT, LEFT, RIGHT };
@ -684,6 +686,7 @@ class Score : public QObject, public ScoreElement {
Note* setGraceNote(Chord*, int pitch, NoteType type, int len);
Segment* setNoteRest(Segment*, int track, NoteVal nval, Fraction, Direction stemDirection = Direction::AUTO, bool forceAccidental = false, bool rhythmic = false);
Segment* setChord(Segment*, int track, Chord* chord, Fraction, Direction stemDirection = Direction::AUTO);
void changeCRlen(ChordRest* cr, const TDuration&);
void changeCRlen(ChordRest* cr, const Fraction&, bool fillWithRest=true);
void createCRSequence(const Fraction& f, ChordRest* cr, const Fraction& tick);
@ -1166,6 +1169,7 @@ class Score : public QObject, public ScoreElement {
void cmdResequenceRehearsalMarks();
void cmdExchangeVoice(int, int);
void cmdRemoveEmptyTrailingMeasures();
void cmdRealizeChordSymbols(bool lit = true, Voicing v = Voicing(-1), HDuration durationType = HDuration(-1));
void setAccessibleInfo(QString s) { accInfo = s.remove(":").remove(";"); }
QString accessibleInfo() const { return accInfo; }

View file

@ -275,6 +275,10 @@ static const StyleType styleTypes[] {
{ Sid::harmonyPlacement, "harmonyPlacement", int(Placement::ABOVE) },
{ Sid::romanNumeralPlacement, "romanNumeralPlacement", int(Placement::BELOW) },
{ Sid::nashvilleNumberPlacement, "nashvilleNumberPlacement", int(Placement::ABOVE) },
{ Sid::harmonyPlay, "harmonyPlay", true },
{ Sid::harmonyVoiceLiteral, "harmonyVoiceLiteral", true },
{ Sid::harmonyVoicing, "harmonyVoicing", int(Voicing::AUTO) },
{ Sid::harmonyDuration, "harmonyDuration", int(HDuration::UNTIL_NEXT_CHORD_SYMBOL) },
{ Sid::chordSymbolAPosAbove, "chordSymbolPosAbove", QPointF(.0, -2.5) },
{ Sid::chordSymbolAPosBelow, "chordSymbolPosBelow", QPointF(.0, 3.5) },

View file

@ -246,6 +246,10 @@ enum class Sid {
harmonyPlacement,
romanNumeralPlacement,
nashvilleNumberPlacement,
harmonyPlay,
harmonyVoiceLiteral,
harmonyVoicing,
harmonyDuration,
chordSymbolAPosAbove,
chordSymbolAPosBelow,

View file

@ -1341,6 +1341,7 @@ TransposeHarmony::TransposeHarmony(Harmony* h, int rtpc, int btpc)
void TransposeHarmony::flip(EditData*)
{
harmony->realizedHarmony().setDirty(true); //harmony should be re-realized after transposition
int baseTpc1 = harmony->baseTpc();
int rootTpc1 = harmony->rootTpc();
harmony->setBaseTpc(baseTpc);

View file

@ -97,7 +97,7 @@ QT5_WRAP_UI (ui_headers
articulation.ui metaedit.ui paletteProperties.ui paletteCellProperties.ui selectdialog.ui selectnotedialog.ui
synthcontrol.ui splitstaff.ui keyedit.ui selectinstr.ui
editstafftype.ui
editpitch.ui editstringdata.ui editraster.ui mediadialog.ui albummanager.ui layer.ui
editpitch.ui editstringdata.ui editraster.ui mediadialog.ui albummanager.ui layer.ui realizeharmonydialog.ui
omrpanel.ui masterpalette.ui harmonyedit.ui pathlistdialog.ui
note_groups.ui resourceManager.ui stafftypetemplates.ui
startcenter.ui scorePreview.ui scoreBrowser.ui templateBrowser.ui
@ -208,6 +208,7 @@ QT5_WRAP_UI (ui_headers
inspector/align_select.ui
inspector/font_style_select.ui
inspector/offset_select.ui
inspector/voicing_select.ui
inspector/scale_select.ui
inspector/size_select.ui
inspector/inspector_stem.ui
@ -335,7 +336,7 @@ add_library(mscoreapp STATIC
seq.h shortcut.h shortcutcapturedialog.h simplebutton.h splitstaff.h stafftextproperties.h
startcenter.h startupWizard.h stringutils.h svggenerator.h symboldialog.h synthcontrol.h
templateBrowser.h textcursor.h textpalette.h texttools.h timedialog.h timeline.h timesigproperties.h
toolbarEditor.h toolbuttonmenu.h transposedialog.h tremolobarcanvas.h
toolbarEditor.h toolbuttonmenu.h transposedialog.h tremolobarcanvas.h realizeharmonydialog.h
tupletdialog.h updatechecker.h uploadscoredialog.h waveview.h webpage.h workspace.h
recordbutton.h greendotbutton prefsdialog.h prefsdialog.cpp
@ -358,7 +359,7 @@ add_library(mscoreapp STATIC
simplebutton.cpp musedata.cpp
editdrumset.cpp editstaff.cpp
timesigproperties.cpp newwizard.cpp transposedialog.cpp
excerptsdialog.cpp metaedit.cpp magbox.cpp
excerptsdialog.cpp metaedit.cpp magbox.cpp realizeharmonydialog.cpp
capella.cpp capxml.cpp exportaudio.cpp
synthcontrol.cpp drumroll.cpp pianoroll.cpp piano.cpp
pianokeyboard.cpp pianolevels.cpp pianolevelschooser.cpp pianolevelsfilter.cpp
@ -414,6 +415,7 @@ add_library(mscoreapp STATIC
inspector/alignSelect.cpp
inspector/fontStyleSelect.cpp
inspector/offsetSelect.cpp
inspector/voicingSelect.cpp
inspector/scaleSelect.cpp
inspector/sizeSelect.cpp
inspector/inspectorTextBase.cpp

View file

@ -413,11 +413,11 @@ void ScoreView::mousePressEventNormal(QMouseEvent* ev)
}
}
}
if (e && e->isNote()) {
e->score()->updateCapo();
mscore->play(e);
}
if (e) {
if (e->isNote() || e->isHarmony()) {
e->score()->updateCapo();
mscore->play(e);
}
_score = e->score();
_score->setUpdateAll();
}
@ -811,6 +811,10 @@ void ScoreView::keyPressEvent(QKeyEvent* ev)
harmonyBeatsTab(true, editData.modifiers & Qt::ShiftModifier);
return;
}
else if (editData.key == Qt::Key_Return) {
changeState(ViewState::NORMAL);
return;
}
}
else if (editData.element->isFiguredBass()) {
if (editData.key == Qt::Key_Space && !(editData.modifiers & CONTROL_MODIFIER)) {

View file

@ -320,7 +320,7 @@ bool ExportMidi::write(QIODevice* device, bool midiExpandRepeats, bool exportRPN
for (auto i = events.begin(); i != events.end(); ++i) {
const NPlayEvent& event = i->second;
if (event.isMuted())
if (event.isMuted(cs))
continue;
if (event.discard() == staffIdx + 1 && event.velo() > 0)
// turn note off so we can restrike it in another track

View file

@ -74,7 +74,8 @@ QVariant InspectorBase::getValue(const InspectorItem& ii) const
}
else if (qobject_cast<Awl::ColorLabel*>(w))
v = static_cast<Awl::ColorLabel*>(w)->color();
else if (qobject_cast<QCheckBox*>(w) || qobject_cast<QPushButton*>(w) || qobject_cast<QToolButton*>(w))
else if (qobject_cast<QCheckBox*>(w) || qobject_cast<QPushButton*>(w) ||
qobject_cast<QToolButton*>(w) || qobject_cast<QRadioButton*>(w))
v = w->property("checked");
else if (qobject_cast<QLineEdit*>(w))
v = w->property("text");
@ -224,6 +225,8 @@ void InspectorBase::setValue(const InspectorItem& ii, QVariant val)
static_cast<QCheckBox*>(w)->setChecked(val.toBool());
else if (qobject_cast<Awl::ColorLabel*>(w))
static_cast<Awl::ColorLabel*>(w)->setColor(val.value<QColor>());
else if (qobject_cast<QRadioButton*>(w))
static_cast<QRadioButton*>(w)->setChecked(val.toBool());
else if (qobject_cast<QPushButton*>(w))
static_cast<QPushButton*>(w)->setChecked(val.toBool());
else if (qobject_cast<QToolButton*>(w))
@ -598,6 +601,8 @@ void InspectorBase::mapSignals(const std::vector<InspectorItem>& il, const std::
connect(qobject_cast<QCheckBox*>(w), QOverload<bool>::of(&QCheckBox::toggled), [=] { valueChanged(i); });
else if (qobject_cast<Awl::ColorLabel*>(w))
connect(qobject_cast<Awl::ColorLabel*>(w), QOverload<QColor>::of(&Awl::ColorLabel::colorChanged), [=] { valueChanged(i); });
else if (qobject_cast<QRadioButton*>(w))
connect(qobject_cast<QRadioButton*>(w), QOverload<bool>::of(&QRadioButton::toggled), [=] { valueChanged(i); });
else if (qobject_cast<QPushButton*>(w))
connect(qobject_cast<QPushButton*>(w), QOverload<bool>::of(&QPushButton::toggled), [=] { valueChanged(i); });
else if (qobject_cast<QToolButton*>(w))

View file

@ -26,7 +26,11 @@ InspectorHarmony::InspectorHarmony(QWidget* parent)
const std::vector<InspectorItem> iiList = {
{ Pid::SUB_STYLE, 0, h.style, h.resetStyle },
{ Pid::PLACEMENT, 0, h.placement, h.resetPlacement }
{ Pid::PLACEMENT, 0, h.placement, h.resetPlacement },
{ Pid::PLAY, 0, h.play, h.resetPlay },
{ Pid::HARMONY_VOICE_LITERAL, 0, h.voicingSelect->interpretBox, h.resetVoicing },
{ Pid::HARMONY_VOICING, 0, h.voicingSelect->voicingBox, h.resetVoicing},
{ Pid::HARMONY_DURATION, 0, h.voicingSelect->durationBox, h.resetVoicing}
};
const std::vector<InspectorPanel> ppList = {

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>198</width>
<height>104</height>
<height>144</height>
</rect>
</property>
<property name="accessibleName">
@ -53,6 +53,9 @@
<bold>true</bold>
</font>
</property>
<property name="accessibleName">
<string>Reset 'Play' value</string>
</property>
<property name="text">
<string>Chord Symbol</string>
</property>
@ -89,16 +92,16 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="style">
<item row="0" column="2">
<widget class="Ms::ResetButton" name="resetStyle" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="accessibleName">
<string>Style</string>
<string>Reset 'Style' value</string>
</property>
</widget>
</item>
@ -115,6 +118,32 @@
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="Ms::ResetButton" name="resetPlacement" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="accessibleName">
<string>Reset 'Placement' value</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="style">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="accessibleName">
<string>Style</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="placement">
<property name="sizePolicy">
@ -138,21 +167,35 @@
</item>
</widget>
</item>
<item row="0" column="2">
<widget class="Ms::ResetButton" name="resetStyle" native="true">
<item row="2" column="2">
<widget class="Ms::ResetButton" name="resetPlay" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="accessibleName">
<string>Reset 'Style' value</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="Ms::ResetButton" name="resetPlacement" native="true">
<item row="2" column="0" colspan="2">
<widget class="QCheckBox" name="play">
<property name="text">
<string>Play</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<widget class="Ms::VoicingSelect" name="voicingSelect" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="3" column="2">
<widget class="Ms::ResetButton" name="resetVoicing" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -160,7 +203,7 @@
</sizepolicy>
</property>
<property name="accessibleName">
<string>Reset 'Placement' value</string>
<string>Reset 'Voicing' Value</string>
</property>
</widget>
</item>
@ -170,10 +213,16 @@
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Ms::VoicingSelect</class>
<extends>QWidget</extends>
<header>inspector/voicingSelect.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>Ms::ResetButton</class>
<extends>QWidget</extends>
<header>inspector/resetButton.h</header>
<header location="global">inspector/resetButton.h</header>
<container>1</container>
</customwidget>
</customwidgets>

View file

@ -0,0 +1,68 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2016 Werner Schweer and others
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#include "voicingSelect.h"
namespace Ms {
VoicingSelect::VoicingSelect(QWidget* parent)
: QWidget(parent)
{
setupUi(this);
//setup changed signals
connect(interpretBox, SIGNAL(currentIndexChanged(int)), SLOT(_voicingChanged()));
connect(voicingBox, SIGNAL(currentIndexChanged(int)), SLOT(_voicingChanged()));
connect(durationBox, SIGNAL(currentIndexChanged(int)), SLOT(_voicingChanged()));
}
void VoicingSelect::_voicingChanged()
{
emit voicingChanged(interpretBox->currentIndex(), voicingBox->currentIndex(), durationBox->currentIndex());
}
void VoicingSelect::blockVoicingSignals(bool val)
{
interpretBox->blockSignals(val);
voicingBox->blockSignals(val);
durationBox->blockSignals(val);
}
void VoicingSelect::setVoicing(int idx)
{
blockVoicingSignals(true);
voicingBox->setCurrentIndex(idx);
blockVoicingSignals(false);
}
void VoicingSelect::setLiteral(bool literal)
{
blockVoicingSignals(true);
interpretBox->setCurrentIndex(literal);
blockVoicingSignals(false);
}
void VoicingSelect::setDuration(int idx)
{
blockVoicingSignals(true);
durationBox->setCurrentIndex(idx);
blockVoicingSignals(false);
}
}

View file

@ -0,0 +1,51 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2016 Werner Schweer and others
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//============================================================================
#ifndef __VOICINGSELECT_H__
#define __VOICINGSELECT_H__
#include "ui_voicing_select.h"
namespace Ms {
class VoicingSelect : public QWidget, public Ui::VoicingSelect {
Q_OBJECT
void blockVoicingSignals(bool);
private slots:
void _voicingChanged();
signals:
void voicingChanged(bool, int, int);
public:
VoicingSelect(QWidget* parent);
int getVoicing() { return voicingBox->currentIndex(); }
bool getLiteral() { return interpretBox->currentIndex(); }
int getDuration() { return durationBox->currentIndex(); }
void setVoicing(int idx);
void setLiteral(bool literal);
void setDuration(int duration);
};
}
#endif // VOICINGSELECT_H

View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>VoicingSelect</class>
<widget class="QWidget" name="VoicingSelect">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>331</width>
<height>174</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Interpretation</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="interpretBox">
<property name="currentIndex">
<number>1</number>
</property>
<item>
<property name="text">
<string>Jazz</string>
</property>
</item>
<item>
<property name="text">
<string>Literal</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Voicing</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="voicingBox">
<item>
<property name="text">
<string>Auto</string>
</property>
</item>
<item>
<property name="text">
<string>Root Only</string>
</property>
</item>
<item>
<property name="text">
<string>Close</string>
</property>
</item>
<item>
<property name="text">
<string>Drop 2</string>
</property>
</item>
<item>
<property name="text">
<string>Six Note</string>
</property>
</item>
<item>
<property name="text">
<string>Four Note</string>
</property>
</item>
<item>
<property name="text">
<string>Three Note</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Duration</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="durationBox">
<item>
<property name="text">
<string>Until next chord symbol</string>
</property>
</item>
<item>
<property name="text">
<string>Stop at measure</string>
</property>
</item>
<item>
<property name="text">
<string>Segment duration</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View file

@ -23,6 +23,7 @@
#include "instrdialog.h"
#include "preferences.h"
#include "prefsdialog.h"
#include "realizeharmonydialog.h"
#include "icons.h"
#include "libmscore/xml.h"
#include "seq.h"
@ -1689,6 +1690,8 @@ MuseScore::MuseScore()
menuTools->addAction(getAction("explode"));
menuTools->addAction(getAction("implode"));
menuTools->addAction(getAction("realize-chord-symbols"));
menuVoices = new QMenu("");
for (auto i : { "voice-x12", "voice-x13", "voice-x14", "voice-x23", "voice-x24", "voice-x34" })
menuVoices->addAction(getAction(i));
@ -4664,6 +4667,19 @@ void MuseScore::play(Element* e) const
}
seq->startNoteTimer(MScore::defaultPlayDuration);
}
else if (e->isHarmony() && preferences.getBool(PREF_SCORE_HARMONY_PLAYWHENEDITING)) {
seq->stopNotes();
Harmony* h = toHarmony(e);
if (!h->isRealizable())
return;
RealizedHarmony r = h->getRealizedHarmony();
QList<int> pitches = r.pitches();
int channel = e->part()->harmonyChannel()->channel();
for (int pitch : pitches)
seq->startNote(channel, pitch, 80, 0);
seq->startNoteTimer(MScore::defaultPlayDuration);
}
}
void MuseScore::play(Element* e, int pitch) const
@ -5768,6 +5784,50 @@ void MuseScore::transpose()
cs->deselectAll();
}
//---------------------------------------------------------
// cmdRealizeChordSymbols
/// Realize selected chord symbols into notes on the staff.
/// Currently just pops up a dialog to list TPCs,
/// Intervals, and pitches.
//---------------------------------------------------------
void MuseScore::realizeChordSymbols()
{
if (!cs)
return;
if (!cs->selection().isList()) {
QErrorMessage err;
err.showMessage(tr("Invalid selection. Cannot realize chord"));
err.exec();
return;
}
QList<Harmony*> hlist;
for (Element* e : cs->selection().elements()) {
if (e->isHarmony())
hlist << toHarmony(e);
}
RealizeHarmonyDialog dialog;
if (!hlist.empty()) {
dialog.setChordList(hlist);
}
else {
QErrorMessage err;
err.showMessage(tr("No chord selected. Cannot realize chord"));
err.exec();
return;
}
if (dialog.exec()) { //realize the chord symbols onto the track
cs->startCmd();
cs->cmdRealizeChordSymbols(dialog.getLiteral(),
dialog.optionsOverride() ? Voicing(dialog.getVoicing()) : Voicing::INVALID,
dialog.optionsOverride() ? HDuration(dialog.getDuration()) : HDuration::INVALID);
cs->endCmd();
}
}
//---------------------------------------------------------
// cmd
//---------------------------------------------------------
@ -6210,6 +6270,8 @@ void MuseScore::cmd(QAction* a, const QString& cmd)
changeScore(-1);
else if (cmd == "transpose")
transpose();
else if (cmd == "realize-chord-symbols")
realizeChordSymbols();
else if (cmd == "save-style") {
QString name = getStyleFilename(false);
if (!name.isEmpty()) {

View file

@ -696,6 +696,7 @@ class MuseScore : public QMainWindow, public MuseScoreCore {
void selectSimilarInRange(Element* e);
void selectElementDialog(Element* e);
void transpose();
void realizeChordSymbols();
Q_INVOKABLE void openExternalLink(const QString&);

View file

@ -144,6 +144,7 @@ void Preferences::init(bool storeInMemoryOnly)
{PREF_IO_PORTMIDI_OUTPUTLATENCYMILLISECONDS, new IntPreference(0)},
{PREF_IO_PULSEAUDIO_USEPULSEAUDIO, new BoolPreference(defaultUsePulseAudio, false)},
{PREF_SCORE_CHORD_PLAYONADDNOTE, new BoolPreference(true, false)},
{PREF_SCORE_HARMONY_PLAYWHENEDITING, new BoolPreference(true, false)},
{PREF_SCORE_MAGNIFICATION, new DoublePreference(1.0, false)},
{PREF_SCORE_NOTE_PLAYONCLICK, new BoolPreference(true, false)},
{PREF_SCORE_NOTE_DEFAULTPLAYDURATION, new IntPreference(300 /* ms */, false)},

View file

@ -368,6 +368,7 @@ void PreferenceDialog::updateValues(bool useDefaultValues)
realtimeDelay->setValue(preferences.getInt(PREF_IO_MIDI_REALTIMEDELAY));
playNotes->setChecked(preferences.getBool(PREF_SCORE_NOTE_PLAYONCLICK));
playChordOnAddNote->setChecked(preferences.getBool(PREF_SCORE_CHORD_PLAYONADDNOTE));
playHarmonyWhenEditing->setChecked(preferences.getBool(PREF_SCORE_HARMONY_PLAYWHENEDITING));
checkUpdateStartup->setChecked(preferences.getBool(PREF_UI_APP_STARTUP_CHECKUPDATE));
@ -993,6 +994,7 @@ void PreferenceDialog::apply()
preferences.setPreference(PREF_IO_OSC_PORTNUMBER, oscPort->value());
preferences.setPreference(PREF_IO_OSC_USEREMOTECONTROL, oscServer->isChecked());
preferences.setPreference(PREF_SCORE_CHORD_PLAYONADDNOTE, playChordOnAddNote->isChecked());
preferences.setPreference(PREF_SCORE_HARMONY_PLAYWHENEDITING, playHarmonyWhenEditing->isChecked());
preferences.setPreference(PREF_SCORE_NOTE_DEFAULTPLAYDURATION, defaultPlayDuration->value());
preferences.setPreference(PREF_SCORE_NOTE_PLAYONCLICK, playNotes->isChecked());
preferences.setPreference(PREF_UI_APP_STARTUP_CHECKUPDATE, checkUpdateStartup->isChecked());

View file

@ -1278,6 +1278,26 @@
<bool>true</bool>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="1" column="0">
<widget class="QCheckBox" name="playChordOnAddNote">
<property name="text">
<string>Play whole chord when editing</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_37">
<property name="text">
@ -1307,26 +1327,13 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="playChordOnAddNote">
<item row="2" column="0">
<widget class="QCheckBox" name="playHarmonyWhenEditing">
<property name="text">
<string>Play whole chord when editing</string>
<string>Play harmony when editing</string>
</property>
</widget>
</item>
<item row="0" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
@ -4291,6 +4298,7 @@ Adjusting latency can help synchronize your MIDI hardware with MuseScore's inter
<tabstop>playNotes</tabstop>
<tabstop>defaultPlayDuration</tabstop>
<tabstop>playChordOnAddNote</tabstop>
<tabstop>playHarmonyWhenEditing</tabstop>
<tabstop>rcGroup</tabstop>
<tabstop>rewindActive</tabstop>
<tabstop>recordRewind</tabstop>

View file

@ -199,8 +199,10 @@ void ScoreView::createElementPropertyMenu(Element* e, QMenu* popup)
|| e->isFiguredBass()) {
genPropertyMenuText(e, popup);
}
else if (e->isHarmony())
else if (e->isHarmony()) {
genPropertyMenu1(e, popup);
popup->addAction(getAction("realize-chord-symbols"));
}
else if (e->isTempoText())
genPropertyMenu1(e, popup);
else if (e->isKeySig()) {

View file

@ -0,0 +1,104 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2016 Werner Schweer and others
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#include "realizeharmonydialog.h"
#include "libmscore/harmony.h"
#include "libmscore/staff.h"
namespace Ms {
//---------------------------------------------------------
// RealizeHarmonyDialog
//---------------------------------------------------------
RealizeHarmonyDialog::RealizeHarmonyDialog(QWidget *parent)
: QDialog(parent)
{
setObjectName("TestingName");
setupUi(this);
chordTable->setVisible(false);
connect(showButton, SIGNAL(clicked()), SLOT(toggleChordTable()));
voicingSelect->setLiteral(true);
//make the chord list uneditable
chordTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
//---------------------------------------------------------
// toggleChordTable
//---------------------------------------------------------
void RealizeHarmonyDialog::toggleChordTable()
{
int visible = chordTable->isVisible();
chordTable->setVisible(!visible);
showButton->setText(!visible ? tr("Show less...") : tr("Show more..."));
}
//---------------------------------------------------------
// setChordList
/// fill the chord list with the list of harmonies
//---------------------------------------------------------
void RealizeHarmonyDialog::setChordList(QList<Harmony*> hlist)
{
static const QStringList header = { "ID", "Name", "Intervals", "Notes" };
QString s; //chord label string
int rows = hlist.size();
chordTable->setRowCount(rows);
chordTable->setColumnCount(header.size());
chordTable->setHorizontalHeaderLabels(header);
for (int i = 0; i < rows; ++i) {
Harmony* h = hlist.at(i);
if (!h->isRealizable())
continue;
s += h->harmonyName() + " ";
QString intervals;
QString noteNames;
int rootTpc;
//adjust for nashville function
if (h->harmonyType() == HarmonyType::NASHVILLE)
rootTpc = function2Tpc(h->hFunction(), h->staff()->key(h->tick()));
else
rootTpc = h->rootTpc();
noteNames = tpc2name(rootTpc, NoteSpellingType::STANDARD, NoteCaseType::AUTO);
RealizedHarmony::PitchMap map = h->getRealizedHarmony().notes();
for (int pitch : map.keys()) {
intervals += QString::number((pitch - tpc2pitch(rootTpc)) % 128 % 12) + " ";
}
for (int tpc : map.values()) {
noteNames += ", " + tpc2name(tpc, NoteSpellingType::STANDARD, NoteCaseType::AUTO);
}
chordTable->setItem(i, 0, new QTableWidgetItem(QString::number(h->id())));
chordTable->setItem(i, 1, new QTableWidgetItem(h->harmonyName()));
chordTable->setItem(i, 2, new QTableWidgetItem(intervals));
chordTable->setItem(i, 3, new QTableWidgetItem(noteNames));
}
chordLabel->setText(s);
//set table uneditable again
chordTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
}
}

View file

@ -0,0 +1,47 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2016 Werner Schweer and others
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//=============================================================================
#ifndef __REALIZEHARMONYDIALOG_H__
#define __REALIZEHARMONYDIALOG_H__
#include "ui_realizeharmonydialog.h"
namespace Ms {
class Harmony;
class RealizeHarmonyDialog : public QDialog, Ui::RealizeHarmonyDialogBase {
Q_OBJECT
private slots:
void toggleChordTable();
public:
RealizeHarmonyDialog(QWidget* parent = 0);
void setChordList(QList<Harmony*>);
bool getLiteral() { return voicingSelect->getLiteral(); }
int getVoicing() { return voicingSelect->getVoicing(); }
int getDuration() { return voicingSelect->getDuration(); }
bool optionsOverride() { return optionsBox->isChecked(); }
};
}
#endif // REALIZEHARMONYDIALOG_H

View file

@ -0,0 +1,256 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RealizeHarmonyDialogBase</class>
<widget class="QDialog" name="RealizeHarmonyDialogBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>548</width>
<height>368</height>
</rect>
</property>
<property name="windowTitle">
<string>Realize Chord Symbols</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QWidget" name="widget_2" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Chord symbols to be realized:</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>16</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="chordLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>chordLabel</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="optionsBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Override With Custom Options</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="Ms::VoicingSelect" name="voicingSelect" native="true"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QTableWidget" name="chordTable">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="horizontalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustIgnored</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<attribute name="horizontalHeaderStretchLastSection">
<bool>true</bool>
</attribute>
</widget>
</item>
<item>
<widget class="QWidget" name="buttonBar" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="showButton">
<property name="text">
<string>Show more...</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
<property name="centerButtons">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Ms::VoicingSelect</class>
<extends>QWidget</extends>
<header>inspector/voicingSelect.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>RealizeHarmonyDialogBase</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>386</x>
<y>419</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>RealizeHarmonyDialogBase</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>450</x>
<y>419</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View file

@ -1788,7 +1788,7 @@ bool ScoreView::normalPaste(Fraction scale)
void ScoreView::cmdGotoElement(Element* e)
{
if (e) {
if (e->type() == ElementType::NOTE)
if (e->type() == ElementType::NOTE || e->type() == ElementType::HARMONY)
score()->setPlayNote(true);
score()->select(e, SelectType::SINGLE, 0);
if (e)

View file

@ -551,7 +551,7 @@ void Seq::playEvent(const NPlayEvent& event, unsigned framePos)
{
int type = event.type();
if (type == ME_NOTEON) {
if (!event.isMuted()) {
if (!event.isMuted(cs->playbackScore())) {
if (event.discard()) { // ignore noteoff but restrike noteon
if (event.velo() > 0)
putEvent(NPlayEvent(ME_NOTEON, event.channel(), event.pitch(), 0) ,framePos);

View file

@ -3561,6 +3561,16 @@ Shortcut Shortcut::_sc[] = {
Icons::Invalid_ICON,
Qt::WindowShortcut
},
{
MsWidget::SCORE_TAB,
STATE_NORMAL,
"realize-chord-symbols",
QT_TRANSLATE_NOOP("action","Realize Chord Symbols"),
QT_TRANSLATE_NOOP("action","Realize chord symbols"),
0,
Icons::Invalid_ICON,
Qt::WindowShortcut
},
{
MsWidget::SCORE_TAB,
STATE_NORMAL,

View file

@ -70,6 +70,9 @@
<Channel>
<program value="24"/>
</Channel>
<Channel name="harmony">
<program value="24"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -63,6 +63,9 @@
<Channel>
<program value="24"/>
</Channel>
<Channel name="harmony">
<program value="24"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
@ -158,6 +161,9 @@
<Channel>
<program value="24"/>
</Channel>
<Channel name="harmony">
<program value="24"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -63,6 +63,9 @@
<Channel>
<program value="27"/>
</Channel>
<Channel name="harmony">
<program value="27"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -63,6 +63,9 @@
<Channel>
<program value="27"/>
</Channel>
<Channel name="harmony">
<program value="27"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -94,6 +94,9 @@
<Channel>
<program value="65"/>
</Channel>
<Channel name="harmony">
<program value="65"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
@ -354,6 +357,9 @@
<Channel>
<program value="65"/>
</Channel>
<Channel name="harmony">
<program value="65"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,386 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.01">
<Score>
<LayerTag id="0" tag="default"></LayerTag>
<currentLayer>0</currentLayer>
<Division>480</Division>
<Style>
<pageWidth>8.27</pageWidth>
<pageHeight>11.69</pageHeight>
<pagePrintableWidth>7.4826</pagePrintableWidth>
<minMeasureWidth>12</minMeasureWidth>
<concertPitch>1</concertPitch>
<Spatium>1.76389</Spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer"></metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle"></metaTag>
<metaTag name="poet"></metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle"></metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Piano</trackName>
<Instrument>
<longName>Piano</longName>
<shortName>Pno.</shortName>
<trackName>Piano</trackName>
<minPitchP>21</minPitchP>
<maxPitchP>108</maxPitchP>
<minPitchA>21</minPitchA>
<maxPitchA>108</maxPitchA>
<transposeDiatonic>-1</transposeDiatonic>
<transposeChromatic>-2</transposeChromatic>
<instrumentId>keyboard.piano</instrumentId>
<Articulation>
<velocity>100</velocity>
<gateTime>95</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>150</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzatoStaccato">
<velocity>150</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoStaccato">
<velocity>120</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoTenuto">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<program value="0"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<VBox>
<height>10</height>
</VBox>
<Measure>
<voice>
<KeySig>
<accidental>-4</accidental>
</KeySig>
<Harmony>
<root>13</root>
<name>m7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>12</root>
<name>m7</name>
<offset x="1.66488" y="-2.29189"/>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>11</root>
<name>7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>10</root>
<name>maj7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>9</root>
<name>maj7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>15</root>
<name>7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>14</root>
<name>maj7</name>
<offset x="-1.66488" y="-2.5"/>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>14</root>
<name>+</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>14</root>
<name>m7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>13</root>
<name>m7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>12</root>
<name>7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>11</root>
<name>maj7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>10</root>
<name>maj7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<name>m7(b5)</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
<location>
<fractions>-1/2</fractions>
</location>
<Harmony>
<root>16</root>
<name>7</name>
</Harmony>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>15</root>
<name>maj7</name>
<offset x="-2.70543" y="-2.60405"/>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>whole</durationType>
</Rest>
<location>
<fractions>-1/2</fractions>
</location>
<Harmony>
<root>18</root>
<name>7(#9)</name>
</Harmony>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<name>m7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>16</root>
<name>7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>15</root>
<name>maj7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>20</root>
<name>m7(b5)</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>19</root>
<name>7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>18</root>
<name>maj7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>14</root>
<name>7(#5)</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>13</root>
<name>m7</name>
</Harmony>
<Rest>
<durationType>whole</durationType>
</Rest>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,601 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.01">
<Score>
<LayerTag id="0" tag="default"></LayerTag>
<currentLayer>0</currentLayer>
<Division>480</Division>
<Style>
<pageWidth>8.27</pageWidth>
<pageHeight>11.69</pageHeight>
<pagePrintableWidth>7.4826</pagePrintableWidth>
<Spatium>1.76389</Spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer"></metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle"></metaTag>
<metaTag name="poet"></metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle"></metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Piano</trackName>
<Instrument>
<longName>Piano</longName>
<shortName>Pno.</shortName>
<trackName>Piano</trackName>
<minPitchP>21</minPitchP>
<maxPitchP>108</maxPitchP>
<minPitchA>21</minPitchA>
<maxPitchA>108</maxPitchA>
<clef staff="2">F</clef>
<Articulation>
<velocity>100</velocity>
<gateTime>95</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>150</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzatoStaccato">
<velocity>150</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoStaccato">
<velocity>120</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoTenuto">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<program value="0"/>
</Channel>
<Channel name="harmony">
<program value="0"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<VBox>
<height>10</height>
</VBox>
<Measure>
<voice>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Harmony>
<root>17</root>
</Harmony>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<Accidental>
<subtype>accidentalSharp</subtype>
</Accidental>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
<Harmony>
<root>17</root>
</Harmony>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
</Harmony>
<Chord>
<durationType>whole</durationType>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
</location>
</next>
</Spanner>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<Accidental>
<subtype>accidentalSharp</subtype>
</Accidental>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
</location>
</next>
</Spanner>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
</location>
</next>
</Spanner>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
</location>
</next>
</Spanner>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Chord>
<durationType>whole</durationType>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
</location>
</next>
</Spanner>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
</location>
</prev>
</Spanner>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
</location>
</next>
</Spanner>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
</location>
</prev>
</Spanner>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
</location>
</next>
</Spanner>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
</location>
</prev>
</Spanner>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<Spanner type="Tie">
<Tie>
</Tie>
<next>
<location>
<measures>1</measures>
</location>
</next>
</Spanner>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
</location>
</prev>
</Spanner>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<LayoutBreak>
<subtype>line</subtype>
</LayoutBreak>
<voice>
<Chord>
<durationType>whole</durationType>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
</location>
</prev>
</Spanner>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
</location>
</prev>
</Spanner>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
</location>
</prev>
</Spanner>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<Spanner type="Tie">
<prev>
<location>
<measures>-1</measures>
</location>
</prev>
</Spanner>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<harmonyDuration>1</harmonyDuration>
</Harmony>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<Accidental>
<subtype>accidentalSharp</subtype>
</Accidental>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
<Harmony>
<root>17</root>
<harmonyDuration>1</harmonyDuration>
</Harmony>
<Chord>
<durationType>half</durationType>
<Note>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<harmonyDuration>1</harmonyDuration>
</Harmony>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<Accidental>
<subtype>accidentalSharp</subtype>
</Accidental>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<LayoutBreak>
<subtype>line</subtype>
</LayoutBreak>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<harmonyDuration>2</harmonyDuration>
</Harmony>
<Chord>
<durationType>eighth</durationType>
<Note>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<Accidental>
<subtype>accidentalSharp</subtype>
</Accidental>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
<Rest>
<durationType>eighth</durationType>
</Rest>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>71</pitch>
<tpc>19</tpc>
</Note>
</Chord>
<Harmony>
<root>17</root>
<harmonyDuration>2</harmonyDuration>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>74</pitch>
<tpc>16</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<harmonyDuration>2</harmonyDuration>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<Accidental>
<subtype>accidentalSharp</subtype>
</Accidental>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>77</pitch>
<tpc>13</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>79</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>81</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<LayoutBreak>
<subtype>line</subtype>
</LayoutBreak>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

View file

@ -0,0 +1,393 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.01">
<Score>
<LayerTag id="0" tag="default"></LayerTag>
<currentLayer>0</currentLayer>
<Division>480</Division>
<Style>
<pageWidth>8.27</pageWidth>
<pageHeight>11.69</pageHeight>
<pagePrintableWidth>7.4826</pagePrintableWidth>
<Spatium>1.76389</Spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer"></metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle"></metaTag>
<metaTag name="poet"></metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle"></metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Piano</trackName>
<Instrument>
<longName>Piano</longName>
<shortName>Pno.</shortName>
<trackName>Piano</trackName>
<minPitchP>21</minPitchP>
<maxPitchP>108</maxPitchP>
<minPitchA>21</minPitchA>
<maxPitchA>108</maxPitchA>
<clef staff="2">F</clef>
<Articulation>
<velocity>100</velocity>
<gateTime>95</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>150</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzatoStaccato">
<velocity>150</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoStaccato">
<velocity>120</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoTenuto">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<program value="0"/>
</Channel>
<Channel name="harmony">
<program value="0"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<VBox>
<height>10</height>
</VBox>
<Measure>
<voice>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Harmony>
<root>17</root>
</Harmony>
<Chord>
<durationType>eighth</durationType>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
<Rest>
<durationType>eighth</durationType>
</Rest>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>71</pitch>
<tpc>19</tpc>
</Note>
</Chord>
<Harmony>
<root>17</root>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>72</pitch>
<tpc>14</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>74</pitch>
<tpc>16</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>77</pitch>
<tpc>13</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>79</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>81</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<LayoutBreak>
<subtype>line</subtype>
</LayoutBreak>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<harmonyDuration>1</harmonyDuration>
</Harmony>
<Chord>
<durationType>eighth</durationType>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
<Rest>
<durationType>eighth</durationType>
</Rest>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>71</pitch>
<tpc>19</tpc>
</Note>
</Chord>
<Harmony>
<root>17</root>
<harmonyDuration>1</harmonyDuration>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>72</pitch>
<tpc>14</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>74</pitch>
<tpc>16</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<harmonyDuration>1</harmonyDuration>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>77</pitch>
<tpc>13</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>79</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>81</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<LayoutBreak>
<subtype>line</subtype>
</LayoutBreak>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<harmonyDuration>2</harmonyDuration>
</Harmony>
<Chord>
<durationType>eighth</durationType>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
<Rest>
<durationType>eighth</durationType>
</Rest>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>71</pitch>
<tpc>19</tpc>
</Note>
</Chord>
<Harmony>
<root>17</root>
<harmonyDuration>2</harmonyDuration>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>72</pitch>
<tpc>14</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>74</pitch>
<tpc>16</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<harmonyDuration>2</harmonyDuration>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>76</pitch>
<tpc>18</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>77</pitch>
<tpc>13</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>79</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>81</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<LayoutBreak>
<subtype>line</subtype>
</LayoutBreak>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,465 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.01">
<Score>
<LayerTag id="0" tag="default"></LayerTag>
<currentLayer>0</currentLayer>
<Division>480</Division>
<Style>
<pageWidth>8.27</pageWidth>
<pageHeight>11.69</pageHeight>
<pagePrintableWidth>7.4826</pagePrintableWidth>
<minMeasureWidth>12</minMeasureWidth>
<concertPitch>1</concertPitch>
<Spatium>1.76389</Spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer"></metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle"></metaTag>
<metaTag name="poet"></metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle"></metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Piano</trackName>
<Instrument>
<longName>Piano</longName>
<shortName>Pno.</shortName>
<trackName>Piano</trackName>
<minPitchP>21</minPitchP>
<maxPitchP>108</maxPitchP>
<minPitchA>21</minPitchA>
<maxPitchA>108</maxPitchA>
<transposeDiatonic>-1</transposeDiatonic>
<transposeChromatic>-2</transposeChromatic>
<instrumentId>keyboard.piano</instrumentId>
<Articulation>
<velocity>100</velocity>
<gateTime>95</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>150</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzatoStaccato">
<velocity>150</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoStaccato">
<velocity>120</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoTenuto">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<controller ctrl="0" value="0"/>
<controller ctrl="32" value="0"/>
<program value="4"/>
</Channel>
<Channel name="harmony">
<controller ctrl="0" value="0"/>
<controller ctrl="32" value="0"/>
<program value="4"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<VBox>
<height>10</height>
</VBox>
<Measure>
<voice>
<Harmony>
<root>13</root>
<name>m7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>12</root>
<name>m7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
<offset x="1.66488" y="-2.29189"/>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>11</root>
<name>7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>10</root>
<name>maj7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>9</root>
<name>maj7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>15</root>
<name>7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>14</root>
<name>maj7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
<offset x="-1.66488" y="-2.5"/>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>14</root>
<name>+</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>14</root>
<name>m7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>13</root>
<name>m7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>12</root>
<name>7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>11</root>
<name>maj7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>10</root>
<name>maj7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<name>m7(b5)</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
<location>
<fractions>-1/2</fractions>
</location>
<Harmony>
<root>16</root>
<name>7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>15</root>
<name>maj7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
<offset x="-2.70543" y="-2.60405"/>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
<location>
<fractions>-1/2</fractions>
</location>
<Harmony>
<root>18</root>
<name>7(#9)</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>17</root>
<name>m7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>16</root>
<name>7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>15</root>
<name>maj7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>20</root>
<name>m7(b5)</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>19</root>
<name>7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>18</root>
<name>maj7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>14</root>
<name>7(#5)</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>13</root>
<name>m7</name>
<harmonyVoiceLiteral>0</harmonyVoiceLiteral>
<harmonyVoicing>3</harmonyVoicing>
</Harmony>
<Rest>
<durationType>measure</durationType>
<duration>4/4</duration>
</Rest>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

View file

@ -0,0 +1,274 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.01">
<Score>
<LayerTag id="0" tag="default"></LayerTag>
<currentLayer>0</currentLayer>
<Division>480</Division>
<Style>
<pageWidth>8.27</pageWidth>
<pageHeight>11.69</pageHeight>
<pagePrintableWidth>7.4826</pagePrintableWidth>
<Spatium>1.76389</Spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer"></metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle"></metaTag>
<metaTag name="poet"></metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle"></metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Piano</trackName>
<Instrument>
<longName>Piano</longName>
<shortName>Pno.</shortName>
<trackName>Piano</trackName>
<minPitchP>21</minPitchP>
<maxPitchP>108</maxPitchP>
<minPitchA>21</minPitchA>
<maxPitchA>108</maxPitchA>
<instrumentId>keyboard.piano</instrumentId>
<Articulation>
<velocity>100</velocity>
<gateTime>95</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>150</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzatoStaccato">
<velocity>150</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoStaccato">
<velocity>120</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoTenuto">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<program value="0"/>
</Channel>
<Channel name="harmony">
<program value="0"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<Measure>
<voice>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Harmony>
<root>17</root>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
</Chord>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>12</root>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<Accidental>
<subtype>accidentalFlat</subtype>
</Accidental>
<pitch>46</pitch>
<tpc>12</tpc>
</Note>
</Chord>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>21</root>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<Accidental>
<subtype>accidentalSharp</subtype>
</Accidental>
<pitch>37</pitch>
<tpc>21</tpc>
</Note>
</Chord>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>30</root>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<Accidental>
<subtype>accidentalDoubleSharp</subtype>
</Accidental>
<pitch>40</pitch>
<tpc>18</tpc>
<tpc2>30</tpc2>
</Note>
</Chord>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>4</root>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<Accidental>
<subtype>accidentalDoubleFlat</subtype>
</Accidental>
<pitch>38</pitch>
<tpc>16</tpc>
<tpc2>4</tpc2>
</Note>
</Chord>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>13</root>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>41</pitch>
<tpc>13</tpc>
</Note>
</Chord>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>15</root>
</Harmony>
<Chord>
<durationType>quarter</durationType>
<Note>
<pitch>43</pitch>
<tpc>15</tpc>
</Note>
</Chord>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

View file

@ -0,0 +1,232 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.01">
<Score>
<LayerTag id="0" tag="default"></LayerTag>
<currentLayer>0</currentLayer>
<Division>480</Division>
<Style>
<pageWidth>8.27</pageWidth>
<pageHeight>11.69</pageHeight>
<pagePrintableWidth>7.4826</pagePrintableWidth>
<Spatium>1.76389</Spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer"></metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle"></metaTag>
<metaTag name="poet"></metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle"></metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Piano</trackName>
<Instrument>
<longName>Piano</longName>
<shortName>Pno.</shortName>
<trackName>Piano</trackName>
<minPitchP>21</minPitchP>
<maxPitchP>108</maxPitchP>
<minPitchA>21</minPitchA>
<maxPitchA>108</maxPitchA>
<instrumentId>keyboard.piano</instrumentId>
<Articulation>
<velocity>100</velocity>
<gateTime>95</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>150</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzatoStaccato">
<velocity>150</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoStaccato">
<velocity>120</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoTenuto">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<program value="0"/>
</Channel>
<Channel name="harmony">
<program value="0"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<Measure>
<voice>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Harmony>
<root>17</root>
</Harmony>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>12</root>
</Harmony>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>21</root>
</Harmony>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>30</root>
</Harmony>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>4</root>
</Harmony>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>13</root>
</Harmony>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>15</root>
</Harmony>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

View file

@ -0,0 +1,149 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.01">
<Score>
<LayerTag id="0" tag="default"></LayerTag>
<currentLayer>0</currentLayer>
<Division>480</Division>
<Style>
<Spatium>1.76389</Spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer"></metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle"></metaTag>
<metaTag name="poet"></metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle"></metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Flute</trackName>
<Instrument>
<longName>Flute</longName>
<shortName>Fl.</shortName>
<trackName>Flute</trackName>
<minPitchP>59</minPitchP>
<maxPitchP>98</maxPitchP>
<minPitchA>60</minPitchA>
<maxPitchA>93</maxPitchA>
<Articulation>
<velocity>100</velocity>
<gateTime>95</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<program value="73"/>
</Channel>
<Channel name="harmony">
<program value="73"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<VBox>
<height>10</height>
</VBox>
<Measure>
<voice>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Harmony>
<root>17</root>
<name>7</name>
</Harmony>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>45</pitch>
<tpc>17</tpc>
</Note>
<Note>
<Accidental>
<subtype>accidentalSharp</subtype>
</Accidental>
<pitch>61</pitch>
<tpc>21</tpc>
</Note>
<Note>
<pitch>64</pitch>
<tpc>18</tpc>
</Note>
<Note>
<pitch>67</pitch>
<tpc>15</tpc>
</Note>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
<Measure>
<voice>
<Harmony>
<root>16</root>
</Harmony>
<Chord>
<durationType>whole</durationType>
<Note>
<pitch>38</pitch>
<tpc>16</tpc>
</Note>
<Note>
<pitch>62</pitch>
<tpc>16</tpc>
</Note>
<Note>
<Accidental>
<subtype>accidentalSharp</subtype>
</Accidental>
<pitch>66</pitch>
<tpc>20</tpc>
</Note>
<Note>
<pitch>69</pitch>
<tpc>17</tpc>
</Note>
</Chord>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,236 @@
<?xml version="1.0" encoding="UTF-8"?>
<museScore version="3.01">
<Score>
<LayerTag id="0" tag="default"></LayerTag>
<currentLayer>0</currentLayer>
<Division>480</Division>
<Style>
<pageWidth>8.27</pageWidth>
<pageHeight>11.69</pageHeight>
<pagePrintableWidth>7.4826</pagePrintableWidth>
<Spatium>1.76389</Spatium>
</Style>
<showInvisible>1</showInvisible>
<showUnprintable>1</showUnprintable>
<showFrames>1</showFrames>
<showMargins>0</showMargins>
<metaTag name="arranger"></metaTag>
<metaTag name="composer">Composer</metaTag>
<metaTag name="copyright"></metaTag>
<metaTag name="lyricist"></metaTag>
<metaTag name="movementNumber"></metaTag>
<metaTag name="movementTitle"></metaTag>
<metaTag name="poet"></metaTag>
<metaTag name="source"></metaTag>
<metaTag name="translator"></metaTag>
<metaTag name="workNumber"></metaTag>
<metaTag name="workTitle"></metaTag>
<Part>
<Staff id="1">
<StaffType group="pitched">
<name>stdNormal</name>
</StaffType>
</Staff>
<trackName>Piano</trackName>
<Instrument>
<longName>Piano</longName>
<shortName>Pno.</shortName>
<trackName>Piano</trackName>
<minPitchP>21</minPitchP>
<maxPitchP>108</maxPitchP>
<minPitchA>21</minPitchA>
<maxPitchA>108</maxPitchA>
<clef staff="2">F</clef>
<Articulation>
<velocity>100</velocity>
<gateTime>95</gateTime>
</Articulation>
<Articulation name="staccatissimo">
<velocity>100</velocity>
<gateTime>33</gateTime>
</Articulation>
<Articulation name="staccato">
<velocity>100</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="portato">
<velocity>100</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="tenuto">
<velocity>100</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="marcato">
<velocity>120</velocity>
<gateTime>67</gateTime>
</Articulation>
<Articulation name="sforzato">
<velocity>150</velocity>
<gateTime>100</gateTime>
</Articulation>
<Articulation name="sforzatoStaccato">
<velocity>150</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoStaccato">
<velocity>120</velocity>
<gateTime>50</gateTime>
</Articulation>
<Articulation name="marcatoTenuto">
<velocity>120</velocity>
<gateTime>100</gateTime>
</Articulation>
<Channel>
<program value="0"/>
</Channel>
<Channel name="harmony">
<program value="0"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
<VBox>
<height>10</height>
</VBox>
<Measure>
<voice>
<TimeSig>
<sigN>4</sigN>
<sigD>4</sigD>
</TimeSig>
<Tuplet>
<normalNotes>2</normalNotes>
<actualNotes>3</actualNotes>
<baseNote>half</baseNote>
<Number>
<style>Tuplet</style>
<text>3</text>
</Number>
</Tuplet>
<Rest>
<durationType>half</durationType>
</Rest>
<Harmony>
<root>17</root>
</Harmony>
<Rest>
<durationType>half</durationType>
</Rest>
<Rest>
<durationType>half</durationType>
</Rest>
<endTuplet/>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Tuplet>
<normalNotes>2</normalNotes>
<actualNotes>3</actualNotes>
<baseNote>quarter</baseNote>
<Number>
<style>Tuplet</style>
<text>3</text>
</Number>
</Tuplet>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Harmony>
<root>19</root>
</Harmony>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
<endTuplet/>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<voice>
<Rest>
<durationType>half</durationType>
</Rest>
<Tuplet>
<normalNotes>2</normalNotes>
<actualNotes>3</actualNotes>
<baseNote>16th</baseNote>
<Number>
<style>Tuplet</style>
<text>3</text>
</Number>
</Tuplet>
<Rest>
<durationType>16th</durationType>
</Rest>
<Harmony>
<root>14</root>
</Harmony>
<Rest>
<durationType>16th</durationType>
</Rest>
<Rest>
<durationType>16th</durationType>
</Rest>
<endTuplet/>
<Rest>
<durationType>eighth</durationType>
</Rest>
<Rest>
<durationType>quarter</durationType>
</Rest>
</voice>
</Measure>
<Measure>
<LayoutBreak>
<subtype>line</subtype>
</LayoutBreak>
<voice>
<Rest>
<durationType>quarter</durationType>
</Rest>
<Tuplet>
<normalNotes>2</normalNotes>
<actualNotes>3</actualNotes>
<baseNote>32nd</baseNote>
<Number>
<style>Tuplet</style>
<text>3</text>
</Number>
</Tuplet>
<Rest>
<durationType>32nd</durationType>
</Rest>
<Harmony>
<root>16</root>
</Harmony>
<Rest>
<durationType>32nd</durationType>
</Rest>
<Rest>
<durationType>32nd</durationType>
</Rest>
<endTuplet/>
<Rest>
<durationType>16th</durationType>
</Rest>
<Rest>
<durationType>eighth</durationType>
</Rest>
<Rest>
<durationType>half</durationType>
</Rest>
</voice>
</Measure>
</Staff>
</Score>
</museScore>

File diff suppressed because it is too large Load diff

View file

@ -68,6 +68,9 @@
<Channel>
<program value="73"/>
</Channel>
<Channel name="harmony">
<program value="73"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
@ -178,6 +181,9 @@
<Channel>
<program value="73"/>
</Channel>
<Channel name="harmony">
<program value="73"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -68,6 +68,9 @@
<Channel>
<program value="73"/>
</Channel>
<Channel name="harmony">
<program value="73"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -37,6 +37,9 @@ class TestChordSymbol : public QObject, public MTest {
MasterScore* test_pre(const char* p);
void test_post(MasterScore* score, const char* p);
void selectAllChordSymbols(MasterScore* score);
void realizeSelectionVoiced(MasterScore* score, Voicing voicing);
private slots:
void initTestCase();
void testExtend();
@ -46,6 +49,17 @@ class TestChordSymbol : public QObject, public MTest {
void testNoSystem();
void testTranspose();
void testTransposePart();
void testRealizeClose();
void testRealizeDrop2();
void testRealize3Note();
void testRealize4Note();
void testRealize6Note();
void testRealizeConcertPitch();
void testRealizeTransposed();
void testRealizeOverride();
void testRealizeTriplet();
void testRealizeDuration();
void testRealizeJazz();
};
//---------------------------------------------------------
@ -78,6 +92,41 @@ void TestChordSymbol::test_post(MasterScore* score, const char* p)
delete score;
}
//---------------------------------------------------------
// TestChordSymbol
/// select all chord symbols within the specified score
//---------------------------------------------------------
void TestChordSymbol::selectAllChordSymbols(MasterScore* score)
{
//find a chord symbol
Segment* seg = score->firstSegment(SegmentType::ChordRest);
Element* e = 0;
while (seg) {
e = seg->findAnnotation(ElementType::HARMONY,
0, score->ntracks());
if (e)
break;
seg = seg->next1();
}
score->selectSimilar(e, false);
}
//---------------------------------------------------------
// realizeSelectionVoiced
/// realize the current selection of the score using
/// the specified voicing
//---------------------------------------------------------
void TestChordSymbol::realizeSelectionVoiced(MasterScore* score, Voicing voicing)
{
for (Element* e : score->selection().elements()) {
if (e->isHarmony())
e->setProperty(Pid::HARMONY_VOICING, int(voicing));
}
score->startCmd();
score->cmdRealizeChordSymbols();
score->endCmd();
}
void TestChordSymbol::testExtend()
{
MasterScore* score = test_pre("extend");
@ -194,5 +243,170 @@ void TestChordSymbol::testTransposePart()
test_post(score, "transpose-part");
}
//---------------------------------------------------------
// testRealizeClose
/// check close voicing algorithm
//---------------------------------------------------------
void TestChordSymbol::testRealizeClose()
{
MasterScore* score = test_pre("realize");
selectAllChordSymbols(score);
realizeSelectionVoiced(score, Voicing::CLOSE);
test_post(score, "realize-close");
}
//---------------------------------------------------------
// testRealizeDrop2
/// check Drop 2 voicing algorithm
//---------------------------------------------------------
void TestChordSymbol::testRealizeDrop2()
{
MasterScore* score = test_pre("realize");
selectAllChordSymbols(score);
realizeSelectionVoiced(score, Voicing::DROP_2);
test_post(score, "realize-drop2");
}
//---------------------------------------------------------
// testRealize3Note
/// check 3 note voicing algorithm
//---------------------------------------------------------
void TestChordSymbol::testRealize3Note()
{
MasterScore* score = test_pre("realize");
selectAllChordSymbols(score);
realizeSelectionVoiced(score, Voicing::THREE_NOTE);
test_post(score, "realize-3note");
}
//---------------------------------------------------------
// testRealize4Note
/// check 4 note voicing algorithm
//---------------------------------------------------------
void TestChordSymbol::testRealize4Note()
{
MasterScore* score = test_pre("realize");
selectAllChordSymbols(score);
realizeSelectionVoiced(score, Voicing::FOUR_NOTE);
test_post(score, "realize-4note");
}
//---------------------------------------------------------
// testRealize6Note
/// check 6 note voicing algorithm
//---------------------------------------------------------
void TestChordSymbol::testRealize6Note()
{
MasterScore* score = test_pre("realize");
selectAllChordSymbols(score);
realizeSelectionVoiced(score, Voicing::SIX_NOTE);
test_post(score, "realize-6note");
}
//---------------------------------------------------------
// testRealizeConcertPitch
/// Check if the note pitches and tpcs are correct after realizing
/// chord symbols on transposed instruments.
//---------------------------------------------------------
void TestChordSymbol::testRealizeConcertPitch()
{
MasterScore* score = test_pre("realize-concert-pitch");
//concert pitch off
score->startCmd();
score->cmdConcertPitchChanged(false, true);
score->endCmd();
//realize all chord symbols
selectAllChordSymbols(score);
score->startCmd();
score->cmdRealizeChordSymbols();
score->endCmd();
test_post(score, "realize-concert-pitch");
}
//---------------------------------------------------------
// testRealizeTransposed
/// Check if the note pitches and tpcs are correct after
/// transposing the score
//---------------------------------------------------------
void TestChordSymbol::testRealizeTransposed()
{
MasterScore* score = test_pre("transpose");
//transpose
score->cmdSelectAll();
score->transpose(TransposeMode::BY_INTERVAL, TransposeDirection::UP, Key::C, 4, false, true, true);
//realize all chord symbols
selectAllChordSymbols(score);
score->startCmd();
score->cmdRealizeChordSymbols();
score->endCmd();
test_post(score, "realize-transpose");
}
//---------------------------------------------------------
// testRealizeOverride
/// Check for correctness when using the override
/// feature for realizing chord symbols
//---------------------------------------------------------
void TestChordSymbol::testRealizeOverride()
{
MasterScore* score = test_pre("realize-override");
//realize all chord symbols
selectAllChordSymbols(score);
score->startCmd();
score->cmdRealizeChordSymbols(true, Voicing::ROOT_ONLY, HDuration::SEGMENT_DURATION);
score->endCmd();
test_post(score, "realize-override");
}
//---------------------------------------------------------
// testRealizeTriplet
/// Check for correctness when realizing chord symbols on triplets
//---------------------------------------------------------
void TestChordSymbol::testRealizeTriplet()
{
MasterScore* score = test_pre("realize-triplet");
//realize all chord symbols
selectAllChordSymbols(score);
score->startCmd();
score->cmdRealizeChordSymbols();
score->endCmd();
test_post(score, "realize-triplet");
}
//---------------------------------------------------------
// testRealizeDuration
/// Check for correctness when realizing chord symbols
/// with different durations
//---------------------------------------------------------
void TestChordSymbol::testRealizeDuration()
{
MasterScore* score = test_pre("realize-duration");
//realize all chord symbols
selectAllChordSymbols(score);
score->startCmd();
score->cmdRealizeChordSymbols();
score->endCmd();
test_post(score, "realize-duration");
}
//---------------------------------------------------------
// testRealizeJazz
/// Check for correctness when realizing chord symbols
/// with jazz mode
//---------------------------------------------------------
void TestChordSymbol::testRealizeJazz()
{
MasterScore* score = test_pre("realize-jazz");
//realize all chord symbols
selectAllChordSymbols(score);
score->startCmd();
score->cmdRealizeChordSymbols();
score->endCmd();
test_post(score, "realize-jazz");
}
QTEST_MAIN(TestChordSymbol)
#include "tst_chordsymbol.moc"

View file

@ -7,5 +7,15 @@ cp ../../../build.debug/mtest/libmscore/chordsymbol/extend-test.mscx extend-re
cp ../../../build.debug/mtest/libmscore/chordsymbol/no-system-test.mscx no-system-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/transpose-part-test.mscx transpose-part-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/transpose-test.mscx transpose-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/realize-override-test.mscx realize-override-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/realize-concert-pitch-test.mscx realize-concert-pitch-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/realize-transpose-test.mscx realize-transpose-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/realize-triplet-test.mscx realize-triplet-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/realize-jazz-test.mscx realize-jazz-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/realize-duration-test.mscx realize-duration-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/realize-close-test.mscx realize-close-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/realize-drop2-test.mscx realize-drop2-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/realize-6note-test.mscx realize-6note-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/realize-4note-test.mscx realize-4note-ref.mscx
cp ../../../build.debug/mtest/libmscore/chordsymbol/realize-3note-test.mscx realize-3note-ref.mscx

View file

@ -79,6 +79,11 @@
<controller ctrl="93" value="30"/>
<controller ctrl="91" value="30"/>
</Channel>
<Channel name="harmony">
<program value="73"/>
<controller ctrl="93" value="30"/>
<controller ctrl="91" value="30"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -79,6 +79,11 @@
<controller ctrl="93" value="30"/>
<controller ctrl="91" value="30"/>
</Channel>
<Channel name="harmony">
<program value="73"/>
<controller ctrl="93" value="30"/>
<controller ctrl="91" value="30"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -178,6 +178,9 @@
<Channel name="tremolo">
<program value="44"/>
</Channel>
<Channel name="harmony">
<program value="43"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">
@ -347,6 +350,9 @@
<Channel name="tremolo">
<program value="44"/>
</Channel>
<Channel name="harmony">
<program value="43"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -53,6 +53,8 @@
</Articulation>
<Channel>
</Channel>
<Channel name="harmony">
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -54,6 +54,9 @@
<Channel>
<program value="73"/>
</Channel>
<Channel name="harmony">
<program value="73"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -54,6 +54,9 @@
<Channel>
<program value="52"/>
</Channel>
<Channel name="harmony">
<program value="52"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -54,6 +54,12 @@
<gateTime>100</gateTime>
</Articulation>
<Channel>
<midiPort>0</midiPort>
<midiChannel>0</midiChannel>
</Channel>
<Channel name="harmony">
<midiPort>0</midiPort>
<midiChannel>2</midiChannel>
</Channel>
</Instrument>
</Part>
@ -89,6 +95,8 @@
<gateTime>100</gateTime>
</Articulation>
<Channel>
<midiPort>0</midiPort>
<midiChannel>1</midiChannel>
</Channel>
</Instrument>
</Part>
@ -1112,6 +1120,8 @@
</Articulation>
<Channel>
</Channel>
<Channel name="harmony">
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -54,6 +54,12 @@
<gateTime>100</gateTime>
</Articulation>
<Channel>
<midiPort>0</midiPort>
<midiChannel>0</midiChannel>
</Channel>
<Channel name="harmony">
<midiPort>0</midiPort>
<midiChannel>2</midiChannel>
</Channel>
</Instrument>
</Part>
@ -89,6 +95,8 @@
<gateTime>100</gateTime>
</Articulation>
<Channel>
<midiPort>0</midiPort>
<midiChannel>1</midiChannel>
</Channel>
</Instrument>
</Part>
@ -1094,6 +1102,8 @@
</Articulation>
<Channel>
</Channel>
<Channel name="harmony">
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -54,6 +54,12 @@
<gateTime>100</gateTime>
</Articulation>
<Channel>
<midiPort>0</midiPort>
<midiChannel>0</midiChannel>
</Channel>
<Channel name="harmony">
<midiPort>0</midiPort>
<midiChannel>2</midiChannel>
</Channel>
</Instrument>
</Part>
@ -89,6 +95,8 @@
<gateTime>100</gateTime>
</Articulation>
<Channel>
<midiPort>0</midiPort>
<midiChannel>1</midiChannel>
</Channel>
</Instrument>
</Part>
@ -1094,6 +1102,8 @@
</Articulation>
<Channel>
</Channel>
<Channel name="harmony">
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -54,6 +54,12 @@
<gateTime>100</gateTime>
</Articulation>
<Channel>
<midiPort>0</midiPort>
<midiChannel>0</midiChannel>
</Channel>
<Channel name="harmony">
<midiPort>0</midiPort>
<midiChannel>2</midiChannel>
</Channel>
</Instrument>
</Part>
@ -89,6 +95,8 @@
<gateTime>100</gateTime>
</Articulation>
<Channel>
<midiPort>0</midiPort>
<midiChannel>1</midiChannel>
</Channel>
</Instrument>
</Part>
@ -1094,6 +1102,8 @@
</Articulation>
<Channel>
</Channel>
<Channel name="harmony">
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -54,6 +54,12 @@
<gateTime>100</gateTime>
</Articulation>
<Channel>
<midiPort>0</midiPort>
<midiChannel>0</midiChannel>
</Channel>
<Channel name="harmony">
<midiPort>0</midiPort>
<midiChannel>2</midiChannel>
</Channel>
</Instrument>
</Part>
@ -89,6 +95,8 @@
<gateTime>100</gateTime>
</Articulation>
<Channel>
<midiPort>0</midiPort>
<midiChannel>1</midiChannel>
</Channel>
</Instrument>
</Part>

View file

@ -81,6 +81,11 @@
<midiPort>0</midiPort>
<midiChannel>2</midiChannel>
</Channel>
<Channel name="harmony">
<program value="0"/>
<midiPort>0</midiPort>
<midiChannel>1</midiChannel>
</Channel>
</Instrument>
</Part>
<Part>
@ -982,6 +987,9 @@
<Channel>
<program value="0"/>
</Channel>
<Channel name="harmony">
<program value="0"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -69,6 +69,9 @@
<Channel name="tremolo">
<program value="44"/>
</Channel>
<Channel name="harmony">
<program value="40"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -54,6 +54,9 @@
<Channel>
<program value="73"/>
</Channel>
<Channel name="harmony">
<program value="73"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -57,6 +57,9 @@
<Channel>
<program value="73"/>
</Channel>
<Channel name="harmony">
<program value="73"/>
</Channel>
</Instrument>
</Part>
<Staff id="1">

View file

@ -17,6 +17,7 @@
#include "libmscore/staff.h"
#include "libmscore/instrument.h"
#include "libmscore/part.h"
#include "libmscore/score.h"
namespace Ms {
@ -170,7 +171,7 @@ NPlayEvent::NPlayEvent(BeatType beatType)
// isMuted
//---------------------------------------------------------
bool NPlayEvent::isMuted() const
bool NPlayEvent::isMuted(Score* score) const
{
const Note* n = note();
if (n) {
@ -180,6 +181,15 @@ bool NPlayEvent::isMuted() const
const Channel* a = instr->playbackChannel(n->subchannel(), cs);
return a->mute() || a->soloMute() || !staff->playbackVoice(n->voice());
}
else if (score) {
//maybe we have a harmony channel to account for
Staff* staff = score->staff(getOriginatingStaff());
if (!staff)
return false;
const Channel* a = staff->part()->harmonyChannel();
if (a) //if there is a harmony channel
return a->mute() || a->soloMute();
}
return false;
}

View file

@ -19,6 +19,7 @@ namespace Ms {
class Note;
class XmlWriter;
class Score;
enum class BeatType : char;
@ -254,7 +255,7 @@ class NPlayEvent : public PlayEvent {
void setOriginatingStaff(int i) { _origin = i; }
void setDiscard(int d) { _discard = d; }
int discard() const { return _discard; }
bool isMuted() const;
bool isMuted(Score* score = 0) const;
};
//---------------------------------------------------------