Skip to content

Commit

Permalink
fixes for transposing instruments
Browse files Browse the repository at this point in the history
  • Loading branch information
wschweer committed Apr 10, 2014
1 parent dc959cc commit d2405f0
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 61 deletions.
64 changes: 40 additions & 24 deletions libmscore/cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,6 @@ void Score::expandVoice()
Note* Score::addPitch(int pitch, bool addFlag)
{
if (addFlag) {
qDebug("Score::addPitch at %d", _is.lastSegment()->tick());
Chord* c = static_cast<Chord*>(_is.lastSegment()->element(_is.track()));

if (c == 0 || c->type() != Element::CHORD) {
Expand Down Expand Up @@ -1087,14 +1086,17 @@ void Score::upDown(bool up, UpDownMode mode)
int tick = oNote->chord()->tick();
Part* part = oNote->staff()->part();
int key = oNote->staff()->key(tick).accidentalType();
int tpc = oNote->tpc();
int tpc1 = oNote->tpc1();
int tpc2 = oNote->tpc2();
int pitch = oNote->pitch();
int newTpc = tpc; // default to unchanged
int newPitch = pitch; // default to unchanged
int newTpc1 = tpc1; // default to unchanged
int newTpc2 = tpc2; // default to unchanged
int newPitch = pitch; // default to unchanged
int string = oNote->string();
int fret = oNote->fret();

switch (oNote->staff()->staffType()->group()) {
#if 0
case PERCUSSION_STAFF_GROUP:
{
Drumset* ds = part->instr()->drumset();
Expand Down Expand Up @@ -1164,7 +1166,7 @@ void Score::upDown(bool up, UpDownMode mode)
}
}
break;

#endif
case STANDARD_STAFF_GROUP:
switch(mode) {
case UP_DOWN_OCTAVE:
Expand All @@ -1180,28 +1182,45 @@ void Score::upDown(bool up, UpDownMode mode)
break;

case UP_DOWN_CHROMATIC:
if (up) {
if (pitch < 127) {
newPitch = pitch + 1;
if (tpc > TPC_A + key)
newTpc = tpc - 5; // up semitone diatonic
if (up && pitch < 127) {
newPitch = pitch + 1;
if (oNote->concertPitch()) {
if (tpc1 > TPC_A + key)
newTpc1 = tpc1 - 5; // up semitone diatonic
else
newTpc = tpc + 7; // up semitone chromatic
newTpc1 = tpc1 + 7; // up semitone chromatic
newTpc2 = oNote->tpc2default(newPitch);
}
else {
if (tpc2 > TPC_A + key)
newTpc2 = tpc2 - 5; // up semitone diatonic
else
newTpc2 = tpc2 + 7; // up semitone chromatic
newTpc1 = oNote->tpc1default(newPitch);
}
}
else {
if (pitch > 0) {
newPitch = pitch - 1;
if (tpc > TPC_C + key)
newTpc = tpc - 7; // down semitone chromatic
else if (!up && pitch > 0) {
newPitch = pitch - 1;
if (oNote->concertPitch()) {
if (tpc1 > TPC_C + key)
newTpc1 = tpc1 - 7; // down semitone chromatic
else
newTpc = tpc + 5; // down semitone diatonic
newTpc1 = tpc1 + 5; // down semitone diatonic
newTpc2 = oNote->tpc2default(newPitch);
}
else {
if (tpc2 > TPC_C + key)
newTpc2 = tpc2 - 7; // down semitone chromatic
else
newTpc2 = tpc2 + 5; // down semitone diatonic
newTpc1 = oNote->tpc1default(newPitch);
}
}

break;

case UP_DOWN_DIATONIC:
#if 0
if (up) {
if (tpc > TPC_A + key) {
if (pitch < 127) {
Expand Down Expand Up @@ -1230,21 +1249,18 @@ void Score::upDown(bool up, UpDownMode mode)
}
}
}

#endif
break;
}
break;
}

if ((oNote->pitch() != newPitch) || (oNote->tpc() != newTpc)) {
if ((oNote->pitch() != newPitch) || (oNote->tpc1() != newTpc1) || oNote->tpc2() != newTpc2) {
// remove accidental if present to make sure
// user added accidentals are removed here.
if (oNote->accidental())
undoRemoveElement(oNote->accidental());
if (oNote->pitch() != newPitch)
undoChangeProperty(oNote, P_PITCH, newPitch);
// TODO-TPC: check
oNote->undoSetTpc(newTpc);
undoChangePitch(oNote, newPitch, newTpc1, newTpc2);
}
// store fret change only if undoChangePitch has not been called,
// as undoChangePitch() already manages fret changes, if necessary
Expand All @@ -1268,7 +1284,7 @@ void Score::upDown(bool up, UpDownMode mode)
_playNote = true;
}
_selection.clear();
foreach(Note* note, el)
for (Note* note : el)
_selection.add(note);
_selection.updateState(); // accidentals may have changed
}
Expand Down
6 changes: 3 additions & 3 deletions libmscore/edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ void Score::putNote(const Position& p, bool replace)
_is.setTrack(staffIdx * VOICES + _is.voice());
_is.setSegment(s);

const Instrument* instr = st->part()->instr();
const Instrument* instr = st->part()->instr(s->tick());
MScore::Direction stemDirection = MScore::AUTO;
NoteVal nval;
StringData* stringData = 0;
Expand Down Expand Up @@ -718,7 +718,7 @@ void Score::putNote(const Position& p, bool replace)
AccidentalVal acci = s->measure()->findAccidental(s, staffIdx, line);
int step = absStep(line, clef);
int octave = step/7;
nval.pitch = step2pitch(step) + octave * 12 + acci;
nval.pitch = step2pitch(step) + octave * 12 + acci + instr->transpose().chromatic;
nval.tpc = step2tpc(step % 7, acci);
}
break;
Expand Down Expand Up @@ -814,7 +814,7 @@ void Score::repitchNote(const Position& p, bool replace)
AccidentalVal acci = s->measure()->findAccidental(s, p.staffIdx, p.line);
int step = absStep(p.line, clef);
int octave = step / 7;
nval.pitch = step2pitch(step) + octave * 12 + acci;
nval.pitch = step2pitch(step) + octave * 12 + acci + st->part()->instr(s->tick())->transpose().chromatic;
nval.tpc = step2tpc(step % 7, acci);

Chord* chord;
Expand Down
2 changes: 1 addition & 1 deletion libmscore/keysig.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class KeySig : public Element {
bool _showCourtesy;
bool _showNaturals;
QList<KeySym*> keySymbols;
KeySigEvent _sig;
KeySigEvent _sig; // concertKeySig, transposingKeySig
void addLayout(SymId sym, qreal x, int y);

public:
Expand Down
62 changes: 51 additions & 11 deletions libmscore/note.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,24 +300,65 @@ void Note::undoSetPitch(int p)
score()->undoChangeProperty(this, P_PITCH, p);
}

//---------------------------------------------------------
// tpc1default
//---------------------------------------------------------

int Note::tpc1default(int p) const
{
int key = 0;
if (staff() && chord()) {
key = staff()->key(chord()->tick()).accidentalType();
if (!concertPitch()) {
Interval interval = staff()->part()->instr()->transpose();
if (!interval.isZero()) {
interval.flip();
key = transposeKey(key, interval);
}
}
}
return pitch2tpc(p, key, PREFER_NEAREST);
}

//---------------------------------------------------------
// tpc2default
//---------------------------------------------------------

int Note::tpc2default(int p) const
{
int key = 0;
if (staff() && chord()) {
key = staff()->key(chord()->tick()).accidentalType();
if (concertPitch()) {
Interval interval = staff()->part()->instr()->transpose();
if (!interval.isZero())
key = transposeKey(key, interval);
}
}
return pitch2tpc(p - transposition(), key, PREFER_NEAREST);
}

#if 0
//---------------------------------------------------------
// tpcFromPitch
//---------------------------------------------------------

int Note::tpcFromPitch(int p) const
{
KeySigEvent key = (staff() && chord()) ? staff()->key(chord()->tick()) : KeySigEvent();
return pitch2tpc(p, key.accidentalType(), PREFER_NEAREST);
int key = (staff() && chord()) ? staff()->key(chord()->tick()).accidentalType() : 0;
return pitch2tpc(p, key, PREFER_NEAREST);
}
#endif

//---------------------------------------------------------
// setTpcFromPitch
//---------------------------------------------------------

void Note::setTpcFromPitch()
{
_tpc[0] = tpcFromPitch(_pitch);
_tpc[1] = tpcFromPitch(_pitch - transposition());
int key = (staff() && chord()) ? staff()->key(chord()->tick()).accidentalType() : 0;
_tpc[0] = pitch2tpc(_pitch, key, PREFER_NEAREST);
_tpc[1] = pitch2tpc(_pitch - transposition(), key, PREFER_NEAREST);
Q_ASSERT(tpcIsValid(_tpc[0]));
Q_ASSERT(tpcIsValid(_tpc[1]));
}
Expand Down Expand Up @@ -708,7 +749,7 @@ void Note::write(Xml& xml) const
}
writeProperty(xml, P_PITCH);
writeProperty(xml, P_TPC1);
if (tpcIsValid(_tpc[1]) && transposition() && _tpc[1] != tpcFromPitch(_pitch - transposition()))
if (transposition() && _tpc[1] != tpc2default(_pitch))
writeProperty(xml, P_TPC2);
writeProperty(xml, P_SMALL);
writeProperty(xml, P_MIRROR_HEAD);
Expand Down Expand Up @@ -1542,9 +1583,8 @@ void Note::layout10(AccidentalState* as)
}
else {
if (_accidental) {
if (_accidental->selected()) {
if (_accidental->selected())
score()->deselect(_accidental);
}
delete _accidental;
_accidental = 0;
}
Expand Down Expand Up @@ -1853,9 +1893,9 @@ void Note::setNval(NoteVal nval)
if (nval.tpc != INVALID_TPC)
setTpc(nval.tpc);
if (_tpc[0] == INVALID_TPC)
_tpc[0] = tpcFromPitch(_pitch);
_tpc[0] = tpc1default(_pitch);
if (_tpc[1] == INVALID_TPC)
_tpc[1] = tpcFromPitch(_pitch - transposition());
_tpc[1] = tpc2default(_pitch);
_headGroup = NoteHeadGroup(nval.headGroup);
}

Expand Down Expand Up @@ -1917,12 +1957,12 @@ bool Note::setProperty(P_ID propertyId, const QVariant& v)
break;
case P_TPC1:
_tpc[0] = v.toInt();
if (chord()->measure() && concertPitch())
if (chord()->measure())
chord()->measure()->updateAccidentals(chord()->staffIdx());
break;
case P_TPC2:
_tpc[1] = v.toInt();
if (chord()->measure() && !concertPitch())
if (chord()->measure())
chord()->measure()->updateAccidentals(chord()->staffIdx());
break;
case P_SMALL:
Expand Down
3 changes: 2 additions & 1 deletion libmscore/note.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,8 @@ class Note : public Element {
void setTpc1(int v) { _tpc[0] = v; }
void setTpc2(int v) { _tpc[1] = v; }
void setTpcFromPitch();
int tpcFromPitch(int pitch) const;
int tpc1default(int pitch) const;
int tpc2default(int pitch) const;
void undoSetTpc1(int tpc) { undoChangeProperty(P_TPC1, tpc); }
void undoSetTpc2(int tpc) { undoChangeProperty(P_TPC2, tpc); }

Expand Down
2 changes: 2 additions & 0 deletions libmscore/score.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2680,6 +2680,8 @@ void Score::cmdConcertPitchChanged(bool flag, bool /*useDoubleSharpsFlats*/)
}
}
}
updateNotes();
setLayoutAll(true);
}

//---------------------------------------------------------
Expand Down
6 changes: 2 additions & 4 deletions libmscore/transpose.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,7 @@ void Score::transposeKeys(int staffStart, int staffEnd, int tickStart, int tickE
continue;

KeyList* km = staff(staffIdx)->keymap();
for (auto ke = km->lower_bound(tickStart);
ke != km->lower_bound(tickEnd); ++ke) {
for (auto ke = km->lower_bound(tickStart); ke != km->lower_bound(tickEnd); ++ke) {
KeySigEvent oKey = ke->second;
int tick = ke->first;
int nKeyType = transposeKey(oKey.accidentalType(), interval);
Expand All @@ -435,8 +434,7 @@ void Score::transposeKeys(int staffStart, int staffEnd, int tickStart, int tickE
KeySigEvent key = km->key(s->tick());
KeySigEvent okey = km->key(s->tick() - 1);
key.setNaturalType(okey.accidentalType());
undo(new ChangeKeySig(ks, key, ks->showCourtesy(),
ks->showNaturals()));
undo(new ChangeKeySig(ks, key, ks->showCourtesy(), ks->showNaturals()));
}
}
}
Expand Down
26 changes: 9 additions & 17 deletions libmscore/undo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1684,28 +1684,20 @@ void ChangePitch::flip()
int f_pitch = note->pitch();
int f_tpc1 = note->tpc1();
int f_tpc2 = note->tpc2();

// do not change unless necessary: setting note pitch triggers chord re-fretting on TABs
// which triggers ChangePitch(), leading to recursion with negative side effects

bool updateAccid = false;
if (f_pitch != pitch || f_tpc1 != tpc1 || f_tpc2 != tpc2) {
updateAccid = true;
note->setPitch(pitch, tpc1, tpc2);

if (f_pitch == pitch && f_tpc1 == tpc1 && f_tpc2 == tpc2) {
// do not change unless necessary: setting note pitch triggers chord re-fretting on TABs
// which triggers ChangePitch(), leading to recursion with negative side effects
return;
}

note->setPitch(pitch, tpc1, tpc2);
pitch = f_pitch;
tpc1 = f_tpc1;
tpc2 = f_tpc2;

Score* score = note->score();
if (updateAccid) {
Chord* chord = note->chord();
Measure* measure = chord->segment()->measure();
measure->updateAccidentals(chord->staffIdx());
}
score->setLayoutAll(true);
score->setPlaylistDirty(true);
Chord* chord = note->chord();
chord->segment()->measure()->updateAccidentals(chord->staffIdx());
note->score()->setLayoutAll(true);
}

//---------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions libmscore/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,7 @@ int absStep(int tpc, int pitch)
{
int line = tpc2step(tpc) + (pitch / 12) * 7;
int tpcPitch = tpc2pitch(tpc);

if (tpcPitch < 0)
line += 7;
else
Expand Down

0 comments on commit d2405f0

Please sign in to comment.