diff --git a/include/DataFile.h b/include/DataFile.h index 452481a7f00..5005c11bc3c 100644 --- a/include/DataFile.h +++ b/include/DataFile.h @@ -101,6 +101,8 @@ class LMMS_EXPORT DataFile : public QDomDocument void cleanMetaNodes( QDomElement de ); + void mapSrcAttributeInElementsWithResources(const QMap& map); + // helper upgrade routines void upgrade_0_2_1_20070501(); void upgrade_0_2_1_20070508(); @@ -130,6 +132,7 @@ class LMMS_EXPORT DataFile : public QDomDocument void upgrade_loopsRename(); void upgrade_noteTypes(); void upgrade_fixCMTDelays(); + void upgrade_fixBassLoopsTypo(); // List of all upgrade methods static const std::vector UPGRADE_METHODS; diff --git a/src/core/DataFile.cpp b/src/core/DataFile.cpp index b7fea852ee5..a55dbd82b95 100644 --- a/src/core/DataFile.cpp +++ b/src/core/DataFile.cpp @@ -84,7 +84,7 @@ const std::vector DataFile::UPGRADE_METHODS = { &DataFile::upgrade_mixerRename , &DataFile::upgrade_bbTcoRename, &DataFile::upgrade_sampleAndHold , &DataFile::upgrade_midiCCIndexing, &DataFile::upgrade_loopsRename , &DataFile::upgrade_noteTypes, - &DataFile::upgrade_fixCMTDelays + &DataFile::upgrade_fixCMTDelays , &DataFile::upgrade_fixBassLoopsTypo, }; // Vector of all versions that have upgrade routines. @@ -640,6 +640,32 @@ void DataFile::cleanMetaNodes( QDomElement _de ) } } +void DataFile::mapSrcAttributeInElementsWithResources(const QMap& map) +{ + for (const auto& [elem, srcAttrs] : ELEMENTS_WITH_RESOURCES) + { + auto elements = elementsByTagName(elem); + + for (const auto& srcAttr : srcAttrs) + { + for (int i = 0; i < elements.length(); ++i) + { + auto item = elements.item(i).toElement(); + + if (item.isNull() || !item.hasAttribute(srcAttr)) { continue; } + + const QString srcVal = item.attribute(srcAttr); + + const auto it = map.constFind(srcVal); + if (it != map.constEnd()) + { + item.setAttribute(srcAttr, *it); + } + } + } + } +} + void DataFile::upgrade_0_2_1_20070501() { @@ -1871,68 +1897,64 @@ void DataFile::upgrade_sampleAndHold() } -// Change loops' filenames in s -void DataFile::upgrade_loopsRename() +static QMap buildReplacementMap() { - auto createEntry = [](const QString& originalName, const QString& bpm, const QString& extension = "ogg") - { - const QString replacement = originalName + " - " + bpm + " BPM." + extension; - return std::pair{originalName + "." + extension, replacement}; + static constexpr auto loopBPMs = std::array{ + std::pair{"bassloops/briff01", "140"}, + std::pair{"bassloops/briff01", "140"}, + std::pair{"bassloops/rave_bass01", "180"}, + std::pair{"bassloops/rave_bass02", "180"}, + std::pair{"bassloops/tb303_01", "123"}, + std::pair{"bassloops/techno_bass01", "140"}, + std::pair{"bassloops/techno_bass02", "140"}, + std::pair{"bassloops/techno_synth01", "140"}, + std::pair{"bassloops/techno_synth02", "140"}, + std::pair{"bassloops/techno_synth03", "130"}, + std::pair{"bassloops/techno_synth04", "140"}, + std::pair{"beats/909beat01", "122"}, + std::pair{"beats/break01", "168"}, + std::pair{"beats/break02", "141"}, + std::pair{"beats/break03", "168"}, + std::pair{"beats/electro_beat01", "120"}, + std::pair{"beats/electro_beat02", "119"}, + std::pair{"beats/house_loop01", "142"}, + std::pair{"beats/jungle01", "168"}, + std::pair{"beats/rave_hihat01", "180"}, + std::pair{"beats/rave_hihat02", "180"}, + std::pair{"beats/rave_kick01", "180"}, + std::pair{"beats/rave_kick02", "180"}, + std::pair{"beats/rave_snare01", "180"}, + std::pair{"latin/latin_brass01", "140"}, + std::pair{"latin/latin_guitar01", "126"}, + std::pair{"latin/latin_guitar02", "140"}, + std::pair{"latin/latin_guitar03", "120"}, }; - static const QMap namesToNamesWithBPMsMap { - { createEntry("bassloops/briff01", "140") }, - { createEntry("bassloops/rave_bass01", "180") }, - { createEntry("bassloops/rave_bass02", "180") }, - { createEntry("bassloops/tb303_01", "123") }, - { createEntry("bassloops/techno_bass01", "140") }, - { createEntry("bassloops/techno_bass02", "140") }, - { createEntry("bassloops/techno_synth01", "140") }, - { createEntry("bassloops/techno_synth02", "140") }, - { createEntry("bassloops/techno_synth03", "130") }, - { createEntry("bassloops/techno_synth04", "140") }, - { createEntry("beats/909beat01", "122") }, - { createEntry("beats/break01", "168") }, - { createEntry("beats/break02", "141") }, - { createEntry("beats/break03", "168") }, - { createEntry("beats/electro_beat01", "120") }, - { createEntry("beats/electro_beat02", "119") }, - { createEntry("beats/house_loop01", "142") }, - { createEntry("beats/jungle01", "168") }, - { createEntry("beats/rave_hihat01", "180") }, - { createEntry("beats/rave_hihat02", "180") }, - { createEntry("beats/rave_kick01", "180") }, - { createEntry("beats/rave_kick02", "180") }, - { createEntry("beats/rave_snare01", "180") }, - { createEntry("latin/latin_brass01", "140") }, - { createEntry("latin/latin_guitar01", "126") }, - { createEntry("latin/latin_guitar02", "140") }, - { createEntry("latin/latin_guitar03", "120") } - }; + QMap namesToNamesWithBPMsMap; - // Replace loop sample names - for (const auto& [elem, srcAttrs] : ELEMENTS_WITH_RESOURCES) + auto insertEntry = [&namesToNamesWithBPMsMap](const QString& originalName, const QString& bpm, const QString& prefix = "", const QString& extension = "ogg") { - auto elements = elementsByTagName(elem); + const QString original = prefix + originalName + "." + extension; + const QString replacement = prefix + originalName + " - " + bpm + " BPM." + extension; - for (const auto& srcAttr : srcAttrs) - { - for (int i = 0; i < elements.length(); ++i) - { - auto item = elements.item(i).toElement(); + namesToNamesWithBPMsMap.insert(original, replacement); + }; - if (item.isNull() || !item.hasAttribute(srcAttr)) { continue; } + for (const auto & loopBPM : loopBPMs) + { + insertEntry(loopBPM.first, loopBPM.second); + insertEntry(loopBPM.first, loopBPM.second, "factorysample:"); + } - const QString srcVal = item.attribute(srcAttr); + return namesToNamesWithBPMsMap; +} - const auto it = namesToNamesWithBPMsMap.constFind(srcVal); - if (it != namesToNamesWithBPMsMap.constEnd()) - { - item.setAttribute(srcAttr, *it); - } - } - } - } +// Change loops' filenames in s +void DataFile::upgrade_loopsRename() +{ + static const QMap namesToNamesWithBPMsMap = buildReplacementMap(); + + mapSrcAttributeInElementsWithResources(namesToNamesWithBPMsMap); } //! Update MIDI CC indexes, so that they are counted from 0. Older releases of LMMS @@ -1957,6 +1979,24 @@ void DataFile::upgrade_midiCCIndexing() } } +void DataFile::upgrade_fixBassLoopsTypo() +{ + static const QMap replacementMap = { + { "bassloopes/briff01.ogg", "bassloops/briff01 - 140 BPM.ogg" }, + { "bassloopes/rave_bass01.ogg", "bassloops/rave_bass01 - 180 BPM.ogg" }, + { "bassloopes/rave_bass02.ogg", "bassloops/rave_bass02 - 180 BPM.ogg" }, + { "bassloopes/tb303_01.ogg","bassloops/tb303_01 - 123 BPM.ogg" }, + { "bassloopes/techno_bass01.ogg", "bassloops/techno_bass01 - 140 BPM.ogg" }, + { "bassloopes/techno_bass02.ogg", "bassloops/techno_bass02 - 140 BPM.ogg" }, + { "bassloopes/techno_synth01.ogg", "bassloops/techno_synth01 - 140 BPM.ogg" }, + { "bassloopes/techno_synth02.ogg", "bassloops/techno_synth02 - 140 BPM.ogg" }, + { "bassloopes/techno_synth03.ogg", "bassloops/techno_synth03 - 130 BPM.ogg" }, + { "bassloopes/techno_synth04.ogg", "bassloops/techno_synth04 - 140 BPM.ogg" } + }; + + mapSrcAttributeInElementsWithResources(replacementMap); +} + void DataFile::upgrade() { // Runs all necessary upgrade methods