Skip to content

Commit

Permalink
fix musescore#21923 correct microtonal accidentals in transposing ins…
Browse files Browse the repository at this point in the history
…truments
  • Loading branch information
sammik committed Apr 21, 2024
1 parent 8e079ba commit 2b84d31
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 124 deletions.
43 changes: 30 additions & 13 deletions src/engraving/dom/accidental.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,26 +307,31 @@ double Accidental::subtype2centOffset(AccidentalType st)
}

//---------------------------------------------------------
// name2subtype
// symId2subtype
//---------------------------------------------------------

AccidentalType Accidental::name2subtype(const AsciiStringView& tag)
AccidentalType Accidental::symId2subtype(SymId symId)
{
SymId symId = SymNames::symIdByName(tag);
if (symId == SymId::noSym) {
// LOGD("no symbol found");
} else {
int i = 0;
for (const Acc& acc : ACC_LIST) {
if (acc.sym == symId) {
return AccidentalType(i);
}
++i;
int i = 0;
for (const Acc& acc : ACC_LIST) {
if (acc.sym == symId) {
return AccidentalType(i);
}
++i;
}
return AccidentalType::NONE;
}

//---------------------------------------------------------
// name2subtype
//---------------------------------------------------------

AccidentalType Accidental::name2subtype(const AsciiStringView& tag)
{
SymId symId = SymNames::symIdByName(tag);
return symId2subtype(symId);
}

//---------------------------------------------------------
// setSubtype
//---------------------------------------------------------
Expand Down Expand Up @@ -365,6 +370,18 @@ AccidentalType Accidental::value2subtype(AccidentalVal v)
return AccidentalType::NONE;
}

//---------------------------------------------------------
// accidentalType
//---------------------------------------------------------
AccidentalType Accidental::accidentalType() const
{
if (style().styleB(Sid::concertPitch)) {
return m_accidentalType[0];
} else {
return m_accidentalType[1];
}
}

//---------------------------------------------------------
// acceptDrop
//---------------------------------------------------------
Expand Down Expand Up @@ -433,7 +450,7 @@ void Accidental::undoSetSmall(bool val)
PropertyValue Accidental::getProperty(Pid propertyId) const
{
switch (propertyId) {
case Pid::ACCIDENTAL_TYPE: return int(m_accidentalType);
case Pid::ACCIDENTAL_TYPE: return int(accidentalType());
case Pid::SMALL: return m_isSmall;
case Pid::ACCIDENTAL_BRACKET: return int(bracket());
case Pid::ACCIDENTAL_ROLE: return role();
Expand Down
118 changes: 114 additions & 4 deletions src/engraving/dom/accidental.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,112 @@ class Factory;
class Note;
enum class AccidentalVal : signed char;

// transposition table for microtonal accidentals
const SymId accTable[] = {
SymId::noSym,
// standard accidentals
SymId::accidentalTripleFlat,
SymId::accidentalDoubleFlat,
SymId::accidentalFlat,
SymId::accidentalNatural,
SymId::accidentalSharp,
SymId::accidentalDoubleSharp,
SymId::accidentalTripleSharp,
SymId::noSym,
// natural sharp
SymId::accidentalNatural,
SymId::accidentalNaturalSharp,
SymId::accidentalSharp,
SymId::noSym,
// natural flat
SymId::accidentalDoubleFlat,
SymId::accidentalNaturalFlat,
SymId::accidentalNatural,
SymId::noSym,
// natural sharp sharp
SymId::accidentalSharp,
SymId::accidentalSharpSharp,
SymId::accidentalTripleSharp,
SymId::noSym,
// Gould quarter tone
// arrow down
SymId::accidentalFiveQuarterTonesFlatArrowDown,
SymId::accidentalThreeQuarterTonesFlatArrowDown,
SymId::accidentalQuarterToneFlatNaturalArrowDown,
SymId::accidentalQuarterToneSharpArrowDown,
SymId::accidentalThreeQuarterTonesSharpArrowDown,
SymId::accidentalFiveQuarterTonesFlatArrowDown,
SymId::noSym,
// arrow up
SymId::accidentalThreeQuarterTonesFlatArrowUp,
SymId::accidentalQuarterToneFlatArrowUp,
SymId::accidentalQuarterToneSharpNaturalArrowUp,
SymId::accidentalThreeQuarterTonesSharpArrowUp,
SymId::accidentalFiveQuarterTonesSharpArrowUp,
SymId::noSym,
// Stein-Zimmermann
// basic
SymId::accidentalThreeQuarterTonesFlatZimmermann,
SymId::accidentalQuarterToneFlatStein,
SymId::accidentalQuarterToneSharpStein,
SymId::accidentalThreeQuarterTonesSharpStein,
SymId::noSym,
// narrow (as variant of above)
SymId::accidentalNarrowReversedFlatAndFlat,
SymId::accidentalNarrowReversedFlat,
SymId::accidentalQuarterToneSharpStein,
// Extended Helmholtz-Ellis (just intonation)
// one syntonic comma down arrow
SymId::accidentalDoubleFlatOneArrowDown,
SymId::accidentalFlatOneArrowDown,
SymId::accidentalNaturalOneArrowDown,
SymId::accidentalSharpOneArrowDown,
SymId::accidentalDoubleSharpOneArrowDown,
SymId::noSym,
// one syntonic comma up arrow
SymId::accidentalDoubleFlatOneArrowUp,
SymId::accidentalFlatOneArrowUp,
SymId::accidentalNaturalOneArrowUp,
SymId::accidentalSharpOneArrowUp,
SymId::accidentalDoubleSharpOneArrowUp,
SymId::noSym,
// two syntonic commas down
SymId::accidentalDoubleFlatTwoArrowsDown,
SymId::accidentalFlatTwoArrowsDown,
SymId::accidentalNaturalTwoArrowsDown,
SymId::accidentalSharpTwoArrowsDown,
SymId::accidentalDoubleSharpTwoArrowsDown,
SymId::noSym,
// two syntonic commas up
SymId::accidentalDoubleFlatTwoArrowsUp,
SymId::accidentalFlatTwoArrowsUp,
SymId::accidentalNaturalTwoArrowsUp,
SymId::accidentalSharpTwoArrowsUp,
SymId::accidentalDoubleSharpTwoArrowsUp,
SymId::noSym,
// three syntonic commas down
SymId::accidentalDoubleFlatThreeArrowsDown,
SymId::accidentalFlatThreeArrowsDown,
SymId::accidentalNaturalThreeArrowsDown,
SymId::accidentalSharpThreeArrowsDown,
SymId::accidentalDoubleSharpThreeArrowsDown,
SymId::noSym,
// three syntonic commas up
SymId::accidentalDoubleFlatThreeArrowsUp,
SymId::accidentalFlatThreeArrowsUp,
SymId::accidentalNaturalThreeArrowsUp,
SymId::accidentalSharpThreeArrowsUp,
SymId::accidentalDoubleSharpThreeArrowsUp,
SymId::noSym,
// equal tempered semitone
SymId::accidentalDoubleFlatEqualTempered,
SymId::accidentalFlatEqualTempered,
SymId::accidentalNaturalEqualTempered,
SymId::accidentalSharpEqualTempered,
SymId::accidentalDoubleSharpEqualTempered,
SymId::noSym
};

//---------------------------------------------------------
// AccidentalBracket
//---------------------------------------------------------
Expand Down Expand Up @@ -72,10 +178,12 @@ class Accidental final : public EngravingItem

TranslatableString subtypeUserName() const override;
void setSubtype(const AsciiStringView& s);
int subtype() const override { return (int)m_accidentalType; }
int subtype() const override { return (int)accidentalType(); }

void setAccidentalType(AccidentalType t) { m_accidentalType = t; }
AccidentalType accidentalType() const { return m_accidentalType; }
void setAccidentalType(AccidentalType t) { m_accidentalType[0] = t; m_accidentalType[1] = t; }
void setAccidentalTypeConcert(AccidentalType t) { m_accidentalType[0] = t; }
void setAccidentalTypeTransposing(AccidentalType t) { m_accidentalType[1] = t; }
AccidentalType accidentalType() const;

void setRole(AccidentalRole r) { m_role = r; }
AccidentalRole role() const { return m_role; }
Expand Down Expand Up @@ -105,6 +213,7 @@ class Accidental final : public EngravingItem
static SymId subtype2symbol(AccidentalType);
static AsciiStringView subtype2name(AccidentalType);
static AccidentalType value2subtype(AccidentalVal);
static AccidentalType symId2subtype(SymId symId);
static AccidentalType name2subtype(const AsciiStringView&);
static bool isMicrotonal(AccidentalType t) { return t > AccidentalType::FLAT3; }
static double subtype2centOffset(AccidentalType);
Expand Down Expand Up @@ -134,7 +243,8 @@ class Accidental final : public EngravingItem

Accidental(EngravingItem* parent);

AccidentalType m_accidentalType = AccidentalType::NONE;
// accidental for concert pitch and accidetnal for transposing pitch may differ in microtonality
AccidentalType m_accidentalType[2] = { AccidentalType::NONE, AccidentalType::NONE };
AccidentalBracket m_bracket = AccidentalBracket::NONE;
AccidentalRole m_role = AccidentalRole::AUTO;
bool m_isSmall = false;
Expand Down
34 changes: 33 additions & 1 deletion src/engraving/dom/cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2226,6 +2226,9 @@ static void changeAccidental2(Note* n, int pitch, int tpc)
Staff* st = chord->staff();
int fret = n->fret();
int string = n->string();
Accidental* accidental = n->accidental();
int microAccShift = 0;
bool concertPitch = n->style().styleB(Sid::concertPitch);

if (st->isTabStaff(chord->tick())) {
if (pitch != n->pitch()) {
Expand All @@ -2239,9 +2242,38 @@ static void changeAccidental2(Note* n, int pitch, int tpc)
}
}
}

int tpc1;
int tpc2 = n->transposeTpc(tpc);
if (n->style().styleB(Sid::concertPitch)) {
// for microtonal accidentals, always use "natural tpc"
if (accidental && Accidental::isMicrotonal(accidental->accidentalType()) && tpc2 > Tpc::TPC_INVALID) {
while (tpc2 < Tpc::TPC_F) {
tpc2 += TPC_DELTA_SEMITONE;
microAccShift --;
}
while (tpc2 > Tpc::TPC_B) {
tpc2 -= TPC_DELTA_SEMITONE;
microAccShift ++;
}
}
// update microtonal accidental if needed
if (microAccShift != 0) {
AccidentalType accidentalType = accidental->accidentalType();
SymId sym = accidental->symId();
int accIndex = std::distance(std::begin(accTable), std::find(std::begin(accTable), std::end(accTable), sym));
if (accIndex < std::end(accTable) - std::begin(accTable)) {
sym = accTable[accIndex + microAccShift];
if (sym != SymId::noSym) {
accidentalType = accidental->symId2subtype(sym);
}
}
if (concertPitch) {
accidental->setAccidentalTypeTransposing(accidentalType);
} else {
accidental->setAccidentalTypeConcert(accidentalType);
}
}
if (concertPitch) {
tpc1 = tpc;
} else {
tpc1 = tpc2;
Expand Down
106 changes: 0 additions & 106 deletions src/engraving/dom/key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,112 +33,6 @@
using namespace mu;

namespace mu::engraving {
// transposition table for microtonal accidentals
const SymId accTable[] = {
SymId::noSym,
// standard accidentals
SymId::accidentalTripleFlat,
SymId::accidentalDoubleFlat,
SymId::accidentalFlat,
SymId::accidentalNatural,
SymId::accidentalSharp,
SymId::accidentalDoubleSharp,
SymId::accidentalTripleSharp,
SymId::noSym,
// natural sharp
SymId::accidentalNatural,
SymId::accidentalNaturalSharp,
SymId::accidentalSharp,
SymId::noSym,
// natural flat
SymId::accidentalDoubleFlat,
SymId::accidentalNaturalFlat,
SymId::accidentalNatural,
SymId::noSym,
// natural sharp sharp
SymId::accidentalSharp,
SymId::accidentalSharpSharp,
SymId::accidentalTripleSharp,
SymId::noSym,
// Gould quarter tone
// arrow down
SymId::accidentalFiveQuarterTonesFlatArrowDown,
SymId::accidentalThreeQuarterTonesFlatArrowDown,
SymId::accidentalQuarterToneFlatNaturalArrowDown,
SymId::accidentalQuarterToneSharpArrowDown,
SymId::accidentalThreeQuarterTonesSharpArrowDown,
SymId::accidentalFiveQuarterTonesFlatArrowDown,
SymId::noSym,
// arrow up
SymId::accidentalThreeQuarterTonesFlatArrowUp,
SymId::accidentalQuarterToneFlatArrowUp,
SymId::accidentalQuarterToneSharpNaturalArrowUp,
SymId::accidentalThreeQuarterTonesSharpArrowUp,
SymId::accidentalFiveQuarterTonesSharpArrowUp,
SymId::noSym,
// Stein-Zimmermann
// basic
SymId::accidentalThreeQuarterTonesFlatZimmermann,
SymId::accidentalQuarterToneFlatStein,
SymId::accidentalQuarterToneSharpStein,
SymId::accidentalThreeQuarterTonesSharpStein,
SymId::noSym,
// narrow (as variant of above)
SymId::accidentalNarrowReversedFlatAndFlat,
SymId::accidentalNarrowReversedFlat,
SymId::accidentalQuarterToneSharpStein,
// Extended Helmholtz-Ellis (just intonation)
// one syntonic comma down arrow
SymId::accidentalDoubleFlatOneArrowDown,
SymId::accidentalFlatOneArrowDown,
SymId::accidentalNaturalOneArrowDown,
SymId::accidentalSharpOneArrowDown,
SymId::accidentalDoubleSharpOneArrowDown,
SymId::noSym,
// one syntonic comma up arrow
SymId::accidentalDoubleFlatOneArrowUp,
SymId::accidentalFlatOneArrowUp,
SymId::accidentalNaturalOneArrowUp,
SymId::accidentalSharpOneArrowUp,
SymId::accidentalDoubleSharpOneArrowUp,
SymId::noSym,
// two syntonic commas down
SymId::accidentalDoubleFlatTwoArrowsDown,
SymId::accidentalFlatTwoArrowsDown,
SymId::accidentalNaturalTwoArrowsDown,
SymId::accidentalSharpTwoArrowsDown,
SymId::accidentalDoubleSharpTwoArrowsDown,
SymId::noSym,
// two syntonic commas up
SymId::accidentalDoubleFlatTwoArrowsUp,
SymId::accidentalFlatTwoArrowsUp,
SymId::accidentalNaturalTwoArrowsUp,
SymId::accidentalSharpTwoArrowsUp,
SymId::accidentalDoubleSharpTwoArrowsUp,
SymId::noSym,
// three syntonic commas down
SymId::accidentalDoubleFlatThreeArrowsDown,
SymId::accidentalFlatThreeArrowsDown,
SymId::accidentalNaturalThreeArrowsDown,
SymId::accidentalSharpThreeArrowsDown,
SymId::accidentalDoubleSharpThreeArrowsDown,
SymId::noSym,
// three syntonic commas up
SymId::accidentalDoubleFlatThreeArrowsUp,
SymId::accidentalFlatThreeArrowsUp,
SymId::accidentalNaturalThreeArrowsUp,
SymId::accidentalSharpThreeArrowsUp,
SymId::accidentalDoubleSharpThreeArrowsUp,
SymId::noSym,
// equal tempered semitone
SymId::accidentalDoubleFlatEqualTempered,
SymId::accidentalFlatEqualTempered,
SymId::accidentalNaturalEqualTempered,
SymId::accidentalSharpEqualTempered,
SymId::accidentalDoubleSharpEqualTempered,
SymId::noSym
};

//---------------------------------------------------------
// enforceLimits - ensure _key
// is within acceptable limits (-7 .. +7).
Expand Down

0 comments on commit 2b84d31

Please sign in to comment.