Merge pull request #20229 from Eism/string_tunings_flats
fixed #19959: Alternate tuning presets need refining
This commit is contained in:
commit
fbf16ab1e1
|
@ -24,28 +24,40 @@
|
|||
"presets": [
|
||||
{
|
||||
"name": "Standard",
|
||||
"value": [40, 45, 50, 55, 59, 64]
|
||||
"value": [40, 45, 50, 55, 59, 64],
|
||||
"useFlats": true
|
||||
},{
|
||||
"name": "Tune down 1/2 step",
|
||||
"value": [39, 44, 49, 54, 58, 63]
|
||||
"value": [39, 44, 49, 54, 58, 63],
|
||||
"useFlats": true
|
||||
},{
|
||||
"name": "Tune down 1 step",
|
||||
"value": [38, 43, 48, 53, 57, 62]
|
||||
"value": [38, 43, 48, 53, 57, 62],
|
||||
"useFlats": true
|
||||
},{
|
||||
"name": "Tune down 2 step",
|
||||
"value": [36, 41, 46, 51, 55, 60]
|
||||
"value": [36, 41, 46, 51, 55, 60],
|
||||
"useFlats": true
|
||||
},{
|
||||
"name": "Dropped D",
|
||||
"value": [38, 45, 50, 55, 59, 64],
|
||||
"useFlats": true
|
||||
},{
|
||||
"name": "Dropped D tune down 1/2 step",
|
||||
"value": [37, 44, 49, 54, 58, 63]
|
||||
"value": [37, 44, 49, 54, 58, 63],
|
||||
"useFlats": true
|
||||
},{
|
||||
"name": "Dropped D Variant",
|
||||
"value": [38, 45, 50, 55, 57, 64]
|
||||
"value": [38, 45, 50, 55, 57, 64],
|
||||
"useFlats": true
|
||||
},{
|
||||
"name": "Double Dropped D",
|
||||
"value": [38, 45, 50, 55, 59, 62]
|
||||
"value": [38, 45, 50, 55, 59, 62],
|
||||
"useFlats": true
|
||||
},{
|
||||
"name": "Dropped C",
|
||||
"value": [36, 43, 48, 53, 57, 62]
|
||||
"value": [36, 43, 48, 53, 57, 62],
|
||||
"useFlats": true
|
||||
},{
|
||||
"name": "Dropped E",
|
||||
"value": [40, 47, 52, 57, 61, 66]
|
||||
|
@ -305,4 +317,4 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
|
|
|
@ -45,6 +45,7 @@ struct instrString {
|
|||
int pitch = 0; // the pitch of the string
|
||||
bool open = false; // true: string is open | false: string is fretted
|
||||
int startFret = 0; // banjo 5th string starts on 5th fret
|
||||
bool useFlat = false;
|
||||
|
||||
bool operator==(const instrString& d) const { return d.pitch == pitch && d.open == open; }
|
||||
};
|
||||
|
|
|
@ -164,9 +164,10 @@ String StringTunings::accessibleInfo() const
|
|||
for (int i = 0; i < numOfStrings; ++i) {
|
||||
string_idx_t index = numOfStrings - i - 1;
|
||||
if (mu::contains(m_visibleStrings, index)) {
|
||||
String pitchStr = pitch2string(stringList[index].pitch);
|
||||
const instrString str = stringList[index];
|
||||
String pitchStr = pitch2string(str.pitch, str.useFlat);
|
||||
if (pitchStr.empty()) {
|
||||
LOGE() << "Invalid get pitch name for " << stringList[index].pitch;
|
||||
LOGE() << "Invalid get pitch name for " << str.pitch;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -252,9 +253,10 @@ String StringTunings::generateText() const
|
|||
for (int i = 0; i < numOfStrings; ++i) {
|
||||
string_idx_t index = numOfStrings - i - 1;
|
||||
if (mu::contains(m_visibleStrings, index)) {
|
||||
String pitchStr = pitch2string(stringList[index].pitch);
|
||||
const instrString str = stringList[index];
|
||||
String pitchStr = pitch2string(str.pitch, str.useFlat);
|
||||
if (pitchStr.empty()) {
|
||||
LOGE() << "Invalid get pitch name for " << stringList[index].pitch;
|
||||
LOGE() << "Invalid get pitch name for " << str.pitch;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -485,7 +485,7 @@ int quantizeLen(int len, int raster)
|
|||
return int(((float)len / raster) + 0.5) * raster; //round to the closest multiple of raster
|
||||
}
|
||||
|
||||
static const char16_t* vall[] = {
|
||||
static const char16_t* valSharp[] = {
|
||||
u"c",
|
||||
u"c♯",
|
||||
u"d",
|
||||
|
@ -499,19 +499,19 @@ static const char16_t* vall[] = {
|
|||
u"a♯",
|
||||
u"b"
|
||||
};
|
||||
static const char16_t* valu[] = {
|
||||
u"C",
|
||||
u"C♯",
|
||||
u"D",
|
||||
u"D♯",
|
||||
u"E",
|
||||
u"F",
|
||||
u"F♯",
|
||||
u"G",
|
||||
u"G♯",
|
||||
u"A",
|
||||
u"A♯",
|
||||
u"B"
|
||||
static const char16_t* valFlat[] = {
|
||||
u"c",
|
||||
u"d♭",
|
||||
u"d",
|
||||
u"e♭",
|
||||
u"e",
|
||||
u"f",
|
||||
u"g♭",
|
||||
u"g",
|
||||
u"a♭",
|
||||
u"a",
|
||||
u"b♭",
|
||||
u"b"
|
||||
};
|
||||
|
||||
/*!
|
||||
|
@ -526,7 +526,7 @@ static const char16_t* valu[] = {
|
|||
* @return
|
||||
* The string representation of the note.
|
||||
*/
|
||||
String pitch2string(int v)
|
||||
String pitch2string(int v, bool useFlats)
|
||||
{
|
||||
if (v < 0 || v > 127) {
|
||||
return String(u"----");
|
||||
|
@ -535,7 +535,13 @@ String pitch2string(int v)
|
|||
String o;
|
||||
o = String::number(octave);
|
||||
int i = v % PITCH_DELTA_OCTAVE;
|
||||
return (octave < 0 ? valu[i] : vall[i]) + o;
|
||||
|
||||
String pitchStr = useFlats ? valFlat[i] : valSharp[i];
|
||||
if (octave < 0) {
|
||||
pitchStr = pitchStr.toUpper();
|
||||
}
|
||||
|
||||
return pitchStr + o;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -553,7 +559,7 @@ int string2pitch(const String& s)
|
|||
return -1;
|
||||
}
|
||||
|
||||
String origin = s;
|
||||
String value = s;
|
||||
|
||||
bool negative = s.contains(u'-');
|
||||
int octave = String(s[s.size() - 1]).toInt() * (negative ? -1 : 1);
|
||||
|
@ -561,11 +567,12 @@ int string2pitch(const String& s)
|
|||
return -1;
|
||||
}
|
||||
|
||||
origin = origin.mid(0, origin.size() - (negative ? 2 : 1));
|
||||
value = value.mid(0, value.size() - (negative ? 2 : 1));
|
||||
value = value.toLower();
|
||||
|
||||
int pitchIndex = -1;
|
||||
for (int i = 0; i < PITCH_DELTA_OCTAVE; ++i) {
|
||||
if (origin.toLower() == String(octave < 0 ? valu[i] : vall[i]).toLower()) {
|
||||
if (value == valFlat[i] || value == valSharp[i]) {
|
||||
pitchIndex = i;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ extern int pitchKeyAdjust(int note, Key);
|
|||
extern int line2pitch(int line, ClefType clef, Key);
|
||||
extern int y2pitch(double y, ClefType clef, double spatium);
|
||||
extern int quantizeLen(int, int);
|
||||
extern String pitch2string(int v);
|
||||
extern String pitch2string(int v, bool useFlats = false);
|
||||
extern int string2pitch(const String& s);
|
||||
extern void transposeInterval(int pitch, int tpc, int* rpitch, int* rtpc, Interval, bool useDoubleSharpsFlats);
|
||||
extern int transposeTpc(int tpc, Interval interval, bool useDoubleSharpsFlats);
|
||||
|
|
|
@ -3972,6 +3972,7 @@ void TRead::read(StringData* item, XmlReader& e)
|
|||
} else if (tag == "string") {
|
||||
instrString strg;
|
||||
strg.open = e.intAttribute("open", 0);
|
||||
strg.useFlat = e.intAttribute("useFlat", 0);
|
||||
strg.pitch = e.readInt();
|
||||
item->stringList().push_back(strg);
|
||||
} else {
|
||||
|
|
|
@ -2609,11 +2609,17 @@ void TWrite::write(const StringData* item, XmlWriter& xml)
|
|||
xml.startElement("StringData");
|
||||
xml.tag("frets", item->frets());
|
||||
for (const instrString& strg : item->stringList()) {
|
||||
XmlWriter::Attributes attrs;
|
||||
|
||||
if (strg.open) {
|
||||
xml.tag("string", { { "open", "1" } }, strg.pitch);
|
||||
} else {
|
||||
xml.tag("string", strg.pitch);
|
||||
attrs.push_back({ "open", "1" });
|
||||
}
|
||||
|
||||
if (strg.useFlat) {
|
||||
attrs.push_back({ "useFlat", "1" });
|
||||
}
|
||||
|
||||
xml.tag("string", attrs, strg.pitch);
|
||||
}
|
||||
xml.endElement();
|
||||
}
|
||||
|
|
|
@ -192,11 +192,15 @@ bool InstrumentsRepository::loadStringTuningsPresets(const io::path_t& path)
|
|||
preset.value.push_back(valueVal.toInt());
|
||||
}
|
||||
|
||||
if (info.number != static_cast<int>(preset.value.size())) {
|
||||
if (info.number != preset.value.size()) {
|
||||
LOGE() << "Invalid preset " << preset.name;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (presetObj.contains("useFlats")) {
|
||||
preset.useFlats = presetObj.value("useFlats").toBool();
|
||||
}
|
||||
|
||||
info.presets.emplace_back(std::move(preset));
|
||||
}
|
||||
|
||||
|
|
|
@ -686,6 +686,7 @@ struct StringTuningPreset
|
|||
{
|
||||
std::string name;
|
||||
std::vector<int> value;
|
||||
bool useFlats = false;
|
||||
};
|
||||
|
||||
struct StringTuningsInfo
|
||||
|
|
|
@ -88,6 +88,7 @@ void StringTuningsSettingsModel::init()
|
|||
item->setShow(contains(visibleStrings, instrStringIndex));
|
||||
item->setNumber(QString::number(i + 1));
|
||||
item->setValue(string.pitch);
|
||||
item->setUseFlat(string.useFlat);
|
||||
item->blockSignals(false);
|
||||
|
||||
m_strings.push_back(item);
|
||||
|
@ -134,6 +135,9 @@ bool StringTuningsSettingsModel::setStringValue(int stringIndex, const QString&
|
|||
|
||||
item->setValue(value);
|
||||
|
||||
bool useFlat = _stringValue.contains("♭");
|
||||
item->setUseFlat(useFlat);
|
||||
|
||||
beginMultiCommands();
|
||||
|
||||
updateCurrentPreset();
|
||||
|
@ -153,7 +157,7 @@ bool StringTuningsSettingsModel::canIncreaseStringValue(const QString& stringVal
|
|||
QString StringTuningsSettingsModel::increaseStringValue(const QString& stringValue)
|
||||
{
|
||||
QString value = convertToUnicode(stringValue);
|
||||
return engraving::pitch2string(engraving::string2pitch(value) + 1);
|
||||
return engraving::pitch2string(engraving::string2pitch(value) + 1, false /* useFlats */);
|
||||
}
|
||||
|
||||
bool StringTuningsSettingsModel::canDecreaseStringValue(const QString& stringValue) const
|
||||
|
@ -165,7 +169,7 @@ bool StringTuningsSettingsModel::canDecreaseStringValue(const QString& stringVal
|
|||
QString StringTuningsSettingsModel::decreaseStringValue(const QString& stringValue)
|
||||
{
|
||||
QString value = convertToUnicode(stringValue);
|
||||
return engraving::pitch2string(engraving::string2pitch(value) - 1);
|
||||
return engraving::pitch2string(engraving::string2pitch(value) - 1, true /* useFlats */);
|
||||
}
|
||||
|
||||
QVariantList StringTuningsSettingsModel::presets(bool withCustom) const
|
||||
|
@ -184,8 +188,9 @@ QVariantList StringTuningsSettingsModel::presets(bool withCustom) const
|
|||
customMap.insert("text", custom);
|
||||
|
||||
QVariantList valueList;
|
||||
for (const StringTuningsItem* item : m_strings) {
|
||||
valueList << item->value();
|
||||
int numOfStrings = static_cast<int>(m_strings.size());
|
||||
for (int i = 0; i < numOfStrings; ++i) {
|
||||
valueList << m_strings.at(numOfStrings - i - 1)->value();
|
||||
}
|
||||
|
||||
customMap.insert("value", valueList);
|
||||
|
@ -210,6 +215,7 @@ QVariantList StringTuningsSettingsModel::presets(bool withCustom) const
|
|||
}
|
||||
|
||||
presetMap.insert("value", valueList);
|
||||
presetMap.insert("useFlats", preset.useFlats);
|
||||
|
||||
presetsList.push_back(presetMap);
|
||||
}
|
||||
|
@ -313,6 +319,7 @@ void StringTuningsSettingsModel::updateStrings()
|
|||
for (const QVariant& _preset : presets) {
|
||||
if (_preset.toMap()["text"].toString() == currentPreset) {
|
||||
QVariantList valueList = _preset.toMap()["value"].toList();
|
||||
bool useFlats = _preset.toMap()["useFlats"].toBool();
|
||||
int numOfStrings = valueList.size();
|
||||
for (int i = 0; i < numOfStrings; ++i) {
|
||||
int valueIndex = numOfStrings - i - 1;
|
||||
|
@ -322,6 +329,7 @@ void StringTuningsSettingsModel::updateStrings()
|
|||
item->setShow(true);
|
||||
item->setNumber(QString::number(i + 1));
|
||||
item->setValue(valueList[valueIndex].toInt());
|
||||
item->setUseFlat(useFlats);
|
||||
item->blockSignals(false);
|
||||
|
||||
m_strings.push_back(item);
|
||||
|
@ -348,7 +356,9 @@ void StringTuningsSettingsModel::saveStrings()
|
|||
|
||||
int numOfStrings = m_strings.size();
|
||||
for (int i = 0; i < numOfStrings; ++i) {
|
||||
stringList[i].pitch = m_strings[numOfStrings - i - 1]->value();
|
||||
const StringTuningsItem* item = m_strings.at(numOfStrings - i - 1);
|
||||
stringList[i].pitch = item->value();
|
||||
stringList[i].useFlat = item->useFlat();
|
||||
}
|
||||
|
||||
beginCommand();
|
||||
|
@ -378,8 +388,9 @@ void StringTuningsSettingsModel::saveStringsVisibleState()
|
|||
void StringTuningsSettingsModel::updateCurrentPreset()
|
||||
{
|
||||
QVariantList currentValueList;
|
||||
for (int i = 0; i < m_strings.size(); ++i) {
|
||||
currentValueList << m_strings[i]->value();
|
||||
int numOfStrings = static_cast<int>(m_strings.size());
|
||||
for (int i = 0; i < numOfStrings; ++i) {
|
||||
currentValueList << m_strings.at(numOfStrings - i - 1)->value();
|
||||
}
|
||||
|
||||
const QVariantList presets = this->presets(false /*withCustom*/);
|
||||
|
@ -471,7 +482,7 @@ int StringTuningsItem::value() const
|
|||
|
||||
QString StringTuningsItem::valueStr() const
|
||||
{
|
||||
return engraving::pitch2string(m_value).toUpper();
|
||||
return engraving::pitch2string(m_value, m_useFlat).toUpper();
|
||||
}
|
||||
|
||||
void StringTuningsItem::setValue(int value)
|
||||
|
@ -483,3 +494,18 @@ void StringTuningsItem::setValue(int value)
|
|||
m_value = value;
|
||||
emit valueChanged();
|
||||
}
|
||||
|
||||
bool StringTuningsItem::useFlat() const
|
||||
{
|
||||
return m_useFlat;
|
||||
}
|
||||
|
||||
void StringTuningsItem::setUseFlat(bool use)
|
||||
{
|
||||
if (m_useFlat == use) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_useFlat = use;
|
||||
emit valueChanged();
|
||||
}
|
||||
|
|
|
@ -107,6 +107,7 @@ class StringTuningsItem : public QObject
|
|||
Q_PROPERTY(QString number READ number NOTIFY numberChanged)
|
||||
Q_PROPERTY(int value READ value NOTIFY valueChanged)
|
||||
Q_PROPERTY(QString valueStr READ valueStr NOTIFY valueChanged)
|
||||
Q_PROPERTY(bool useFlat READ useFlat WRITE setUseFlat NOTIFY valueChanged)
|
||||
|
||||
public:
|
||||
explicit StringTuningsItem(QObject* parent = nullptr);
|
||||
|
@ -121,6 +122,9 @@ public:
|
|||
QString valueStr() const;
|
||||
void setValue(int value);
|
||||
|
||||
bool useFlat() const;
|
||||
void setUseFlat(bool use);
|
||||
|
||||
signals:
|
||||
void showChanged();
|
||||
void numberChanged();
|
||||
|
@ -130,6 +134,7 @@ private:
|
|||
bool m_show = false;
|
||||
QString m_number;
|
||||
int m_value = 0;
|
||||
bool m_useFlat = false;
|
||||
};
|
||||
} //namespace mu::notation
|
||||
|
||||
|
|
Loading…
Reference in New Issue