Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,033 changes: 93 additions & 2,940 deletions src/engraving/data/harmony_to_diagram.xml

Large diffs are not rendered by default.

63 changes: 33 additions & 30 deletions src/engraving/dom/fret.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,6 @@ struct HarmonyMapKey
}
};

struct DiagramInfo {
String harmonyName;
String diagramXml;
String diagramPattern;
};

static std::map<HarmonyMapKey /*key*/, std::vector<DiagramInfo> > s_harmonyToDiagramMap;
static std::unordered_map<String /*pattern*/, std::vector<String /*harmonyName*/> > s_diagramPatternToHarmoniesMap;

Expand Down Expand Up @@ -244,16 +238,7 @@ Segment* FretDiagram::segment() const

void FretDiagram::updateDiagram(const String& harmonyName)
{
if (s_harmonyToDiagramMap.empty()) {
readHarmonyToDiagramFile(HARMONY_TO_DIAGRAM_FILE_PATH);
}

String _harmonyName = harmonyName;

NoteSpellingType spellingType = style().styleV(Sid::chordSymbolSpelling).value<NoteSpellingType>();
HarmonyMapKey key = createHarmonyMapKey(_harmonyName, spellingType, score()->chordList());

std::vector<DiagramInfo> availableDiagrams = muse::value(s_harmonyToDiagramMap, key);
std::vector<DiagramInfo> availableDiagrams = patternsFromHarmony(harmonyName);
if (availableDiagrams.empty()) {
return;
}
Expand All @@ -272,6 +257,7 @@ void FretDiagram::updateDiagram(const String& harmonyName)
read460::TRead::read(this, reader, ctx);

triggerLayout();
return;
}

//---------------------------------------------------------
Expand Down Expand Up @@ -761,21 +747,21 @@ void FretDiagram::applyDiagramPattern(FretDiagram* diagram, const String& patter
}
}

String FretDiagram::patternFromDiagram(const FretDiagram* diagram)
String FretDiagram::patternFromDiagram() const
{
const int strings = diagram->strings();
const int offset = diagram->fretOffset();
const int diagramStrings = strings();
const int offset = fretOffset();

StringList patternParts;
const DotMap& dotsMap = diagram->dots();
const DotMap& dotsMap = dots();

for (int i = 0; i < strings; ++i) {
const FretItem::Marker marker = diagram->marker(i);
for (int i = 0; i < diagramStrings; ++i) {
const FretItem::Marker fretMarker = marker(i);

if (marker.mtype == FretMarkerType::CROSS) {
if (fretMarker.mtype == FretMarkerType::CROSS) {
patternParts.push_back(u"X");
continue;
} else if (marker.mtype == FretMarkerType::CIRCLE) {
} else if (fretMarker.mtype == FretMarkerType::CIRCLE) {
patternParts.push_back(u"O");
continue;
}
Expand Down Expand Up @@ -825,16 +811,16 @@ String FretDiagram::patternFromDiagram(const FretDiagram* diagram)

String pattern = patternParts.join(u"");

const BarreMap& barres = diagram->barres();
const BarreMap& _barres = barres();
StringList barreParts;
for (const auto& [fret, b] : barres) {
for (const auto& [fret, b] : _barres) {
if (!b.exists()) {
continue;
}

int adjustedFret = fret + offset;
int start = b.startString;
int end = (b.endString != -1) ? b.endString : strings - 1;
int end = (b.endString != -1) ? b.endString : diagramStrings - 1;

barreParts.push_back(u'B' + String::number(adjustedFret)
+ u'[' + String::number(start)
Expand All @@ -848,11 +834,28 @@ String FretDiagram::patternFromDiagram(const FretDiagram* diagram)
return pattern;
}

std::vector<String> FretDiagram::patternHarmonies(const String& pattern)
std::vector<String> FretDiagram::harmoniesFromPattern(const String& pattern) const
{
if (s_diagramPatternToHarmoniesMap.empty()) {
readHarmonyToDiagramFile(HARMONY_TO_DIAGRAM_FILE_PATH);
}
return muse::value(s_diagramPatternToHarmoniesMap, pattern);
}

std::vector<DiagramInfo> FretDiagram::patternsFromHarmony(const String& harmonyName)
{
if (s_harmonyToDiagramMap.empty()) {
readHarmonyToDiagramFile(HARMONY_TO_DIAGRAM_FILE_PATH);
}

String _harmonyName = harmonyName;

NoteSpellingType spellingType = style().styleV(Sid::chordSymbolSpelling).value<NoteSpellingType>();
HarmonyMapKey key = createHarmonyMapKey(_harmonyName, spellingType, score()->chordList());

return muse::value(s_harmonyToDiagramMap, key);
}

//---------------------------------------------------------
// clear
//---------------------------------------------------------
Expand Down Expand Up @@ -1002,7 +1005,7 @@ void FretDiagram::add(EngravingItem* e)
readHarmonyToDiagramFile(HARMONY_TO_DIAGRAM_FILE_PATH);
}

String pattern = patternFromDiagram(this);
String pattern = patternFromDiagram();
if (!pattern.empty()) {
std::vector<String> matchedHarmonies = muse::value(s_diagramPatternToHarmoniesMap, pattern);
if (!matchedHarmonies.empty()) {
Expand Down Expand Up @@ -1415,7 +1418,7 @@ bool FretDiagram::isCustom(const String& harmonyNameForCompare) const
return true;
}

String currentPattern = patternFromDiagram(this);
String currentPattern = patternFromDiagram();

for (const DiagramInfo& diagram : availableDiagrams) {
if (diagram.diagramPattern == currentPattern) {
Expand Down
11 changes: 9 additions & 2 deletions src/engraving/dom/fret.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ typedef std::map<int, FretItem::Barre> BarreMap;
typedef std::map<int, FretItem::Marker> MarkerMap;
typedef std::map<int, std::vector<FretItem::Dot> > DotMap;

struct DiagramInfo {
String harmonyName;
String diagramXml;
String diagramPattern;
};

//---------------------------------------------------------
// @@ FretDiagram
/// Fretboard diagram
Expand All @@ -137,8 +143,9 @@ class FretDiagram final : public EngravingItem

Segment* segment() const;

static String patternFromDiagram(const FretDiagram* diagram);
static std::vector<String> patternHarmonies(const String& pattern);
String patternFromDiagram() const;
std::vector<String> harmoniesFromPattern(const String& pattern) const;
std::vector<DiagramInfo> patternsFromHarmony(const String& harmonyName);

void updateDiagram(const String& harmonyName);

Expand Down
2 changes: 2 additions & 0 deletions src/engraving/dom/mscore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ bool MScore::svgPrinting = false;
extern void initDrumset();

MsError MScore::_error { MsError::MS_NO_ERROR };
bool MScore::_errorIsWarning = false;

void MScore::registerUiTypes()
{
Expand Down Expand Up @@ -118,6 +119,7 @@ std::string MScore::errorToString(MsError err)
case MsError::CANNOT_REMOVE_KEY_SIG: return "CANNOT_REMOVE_KEY_SIG";
case MsError::CANNOT_JOIN_MEASURE_STAFFTYPE_CHANGE: return "CANNOT_JOIN_MEASURE_STAFFTYPE_CHANGE";
case MsError::CANNOT_REPEAT_SELECTION: return "CANNOT_REPEAT_SELECTION";
case MsError::TRANSPOSE_NO_FRET_DIAGRAM: return "TRANSPOSE_NO_FRET_DIAGRAM";
}

return {};
Expand Down
4 changes: 3 additions & 1 deletion src/engraving/dom/mscore.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ enum class MsError : unsigned char {
CANNOT_REMOVE_KEY_SIG,
CANNOT_JOIN_MEASURE_STAFFTYPE_CHANGE,
CANNOT_REPEAT_SELECTION,
TRANSPOSE_NO_FRET_DIAGRAM,
};

/// \cond PLUGIN_API \private \endcond
Expand All @@ -187,6 +188,7 @@ class MScore
public:

static MsError _error;
static bool _errorIsWarning;

static void registerUiTypes();

Expand Down Expand Up @@ -230,7 +232,7 @@ class MScore
static double horizontalPageGapEven;
static double horizontalPageGapOdd;

static void setError(MsError e) { _error = e; }
static void setError(MsError e, bool warning = false) { _error = e; _errorIsWarning = warning; }

static std::string errorToString(MsError err);
};
Expand Down
32 changes: 32 additions & 0 deletions src/engraving/dom/pitchspelling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1168,4 +1168,36 @@ Key clampKey(Key key, PreferSharpFlat prefer)

return key;
}

int bestEnharmonicFit(const std::vector<int> tpcs, Key key)
{
int keyIndex = int(key) - int(Key::MIN);
if (keyIndex < 0 || keyIndex >= int(Key::NUM_OF)) {
return tpcs.front();
}

// Highest penalty in enharmonicSpelling available (100) + 1
int bestPenalty = 101;
int closestTpc = Tpc::TPC_INVALID;

for (int tpc : tpcs) {
if (tpc == Tpc::TPC_INVALID) {
continue;
}

int lof = tpc - Tpc::TPC_MIN;
if (lof < 0 || lof >= 34) {
continue;
}

int penalty = enharmonicSpelling[keyIndex][lof];

if (penalty < bestPenalty) {
bestPenalty = penalty;
closestTpc = tpc;
}
}

return closestTpc;
}
}
1 change: 1 addition & 0 deletions src/engraving/dom/pitchspelling.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ extern int convertNote(const String& s, NoteSpellingType noteSpelling, NoteCaseT
extern int clampEnharmonic(int tpc, bool useDoubleSharpsFlats = true);
extern int clampPitch(int pitch, bool octaved = false);
extern Key clampKey(Key key, PreferSharpFlat prefer = PreferSharpFlat::NONE);
extern int bestEnharmonicFit(const std::vector<int> tpcs, Key key);

//---------------------------------------------------------
// tpc2alter
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/editing/cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ void Score::endCmd(bool rollback, bool layoutAllParts)
return;
}

if (readOnly() || MScore::_error != MsError::MS_NO_ERROR) {
if (readOnly() || (MScore::_error != MsError::MS_NO_ERROR && !MScore::_errorIsWarning)) {
rollback = true;
}

Expand Down
Loading
Loading