diff --git a/src/deluge/gui/ui/browser/browser.cpp b/src/deluge/gui/ui/browser/browser.cpp index 88bd032199..d88e449b6a 100644 --- a/src/deluge/gui/ui/browser/browser.cpp +++ b/src/deluge/gui/ui/browser/browser.cpp @@ -37,6 +37,7 @@ #include "util/functions.h" #include #include +#include using namespace deluge; @@ -395,6 +396,12 @@ Error Browser::readFileItemsForFolder(char const* filePrefixHere, bool allowFold return error; } +// TODO: dubplicate for testing... +static bool isSYXFile(FileItem *item) { + size_t len = item->filename.getLength(); + return(len >= 4 && strcasecmp(item->filename.get()+(len-4), ".syx") == 0); +} + void Browser::deleteFolderAndDuplicateItems(Availability instrumentAvailabilityRequirement) { int32_t writeI = 0; FileItem* nextItem = (FileItem*)fileItems.getElementAddress(0); @@ -445,10 +452,14 @@ void Browser::deleteFolderAndDuplicateItems(Availability instrumentAvailabilityR } } } - } - + } else if (isSYXFile(nextItem)) { + // This is a bit of a hack, but loading every single syx file and checking the signature + // is going to be quite expensive. + //if (nextItem->filePointer.objsize >= 4096) { + goto deleteThisItem; + //} // Or if next item has an Instrument, and we're just a file... - else if (nextItem->instrument) { + } else if (nextItem->instrument) { if (!strcasecmp(readItem->displayName, nextItem->displayName)) { // And if same name... goto deleteThisItem; } diff --git a/src/deluge/gui/ui/load/load_instrument_preset_ui.cpp b/src/deluge/gui/ui/load/load_instrument_preset_ui.cpp index c93879eda2..76beaf50d2 100644 --- a/src/deluge/gui/ui/load/load_instrument_preset_ui.cpp +++ b/src/deluge/gui/ui/load/load_instrument_preset_ui.cpp @@ -314,6 +314,19 @@ static Error getRawFilePath(String* path, FileItem *item) { return path->concatenate(&item->filename); } +SoundInstrument *LoadInstrumentPresetUI::prepareForDX7(FileItem *currentFileItem) { + ParamManagerForTimeline newParamManager; + SoundInstrument* newInstrument = (SoundInstrument *)StorageManager::createNewInstrument(OutputType::SYNTH, &newParamManager); + newInstrument->dirPath.set(¤tDir); + newInstrument->syxPath.set(¤tFileItem->filename); + newInstrument->setupAsBlankSynth(&newParamManager, true); + // TODO: oldInstrumentShouldBeReplaced ?????? + // This is how we feed a ParamManager into the replaceInstrument() function + currentSong->backUpParamManager((ModControllableAudio*)newInstrument->toModControllable(), nullptr, + &newParamManager, true); + return newInstrument; +} + void LoadInstrumentPresetUI::enterKeyPress() { FileItem* currentFileItem = getCurrentFileItem(); @@ -343,15 +356,7 @@ void LoadInstrumentPresetUI::enterKeyPress() { } // TODO: not if we currently is at a freshly loaded DX7 instrument, in case we can just modify it in place - ParamManagerForTimeline newParamManager; - SoundInstrument* newInstrument = (SoundInstrument *)StorageManager::createNewInstrument(OutputType::SYNTH, &newParamManager); - newInstrument->dirPath.set(¤tDir); - newInstrument->syxPath.set(¤tFileItem->filename); - newInstrument->setupAsBlankSynth(&newParamManager, true); - // TODO: oldInstrumentShouldBeReplaced ?????? - // This is how we feed a ParamManager into the replaceInstrument() function - currentSong->backUpParamManager((ModControllableAudio*)newInstrument->toModControllable(), nullptr, - &newParamManager, true); + SoundInstrument *newInstrument = prepareForDX7(currentFileItem); currentSong->replaceInstrument(instrumentToReplace, newInstrument); currentInstrument = newInstrument; instrumentToReplace = newInstrument; @@ -920,9 +925,17 @@ Error LoadInstrumentPresetUI::performLoad(bool doClone) { return Error::NONE; // Happens if navigate over a folder's name (Instrument stays the same), } + bool is_single_syx = false; if (isSYXFile(currentFileItem)) { - // TODO: if this is a single-patch .syx file, treat it as a synth patch already - return Error::NONE; + String path; + getRawFilePath(&path, currentFileItem); + loadDxCartridgeUI.tryLoad(path.get()); + + if (loadDxCartridgeUI.pd->isCartridge()) { + return Error::NONE; + } else { + is_single_syx = true; + } } // then back onto that neighbouring Instrument - you'd incorrectly get a "USED" error without this line. @@ -989,9 +1002,16 @@ Error LoadInstrumentPresetUI::performLoad(bool doClone) { // Browser::checkFP(); // synth or kit - error = StorageManager::loadInstrumentFromFile(currentSong, instrumentClipToLoadFor, outputTypeToLoad, false, - &newInstrument, ¤tFileItem->filePointer, &enteredText, - ¤tDir); + if (is_single_syx) { + SoundInstrument *dxInstrument = prepareForDX7(currentFileItem); + newInstrument = dxInstrument; + loadDxCartridgeUI.pd->unpackProgram(dxInstrument->sources[0].dxPatch->params, 0); + currentFileItem->instrument = newInstrument; + } else { + error = StorageManager::loadInstrumentFromFile(currentSong, instrumentClipToLoadFor, outputTypeToLoad, false, + &newInstrument, ¤tFileItem->filePointer, &enteredText, + ¤tDir); + } if (error != Error::NONE) { return error; @@ -1492,7 +1512,7 @@ PresetNavigationResult LoadInstrumentPresetUI::doPresetNavigation(int32_t offset int32_t newCatalogSearchDirection = (offset >= 0) ? CATALOG_SEARCH_RIGHT : CATALOG_SEARCH_LEFT; readAgainWithSameOffset: toReturn.error = - readFileItemsForFolder(getThingName(outputType), false, allowedFileExtensionsXML, oldNameString.get(), + readFileItemsForFolder(getThingName(outputType), false, allowedFileExtensionsXMLandSYX, oldNameString.get(), FILE_ITEMS_MAX_NUM_ELEMENTS_FOR_NAVIGATION, newCatalogSearchDirection); if (toReturn.error != Error::NONE) { diff --git a/src/deluge/gui/ui/load/load_instrument_preset_ui.h b/src/deluge/gui/ui/load/load_instrument_preset_ui.h index f60e856d6e..32a9f6acac 100644 --- a/src/deluge/gui/ui/load/load_instrument_preset_ui.h +++ b/src/deluge/gui/ui/load/load_instrument_preset_ui.h @@ -27,6 +27,7 @@ class Instrument; class InstrumentClip; class Output; +class SoundInstrument; class LoadInstrumentPresetUI final : public LoadUI { public: @@ -92,6 +93,8 @@ class LoadInstrumentPresetUI final : public LoadUI { bool isInstrumentInList(Instrument* searchInstrument, Output* list); bool findUnusedSlotVariation(String* oldName, String* newName); + SoundInstrument *prepareForDX7(FileItem *currentFileItem); + InstrumentClip* instrumentClipToLoadFor; // Can be NULL - if called from Arranger. Instrument* instrumentToReplace; // The Instrument that's actually successfully loaded and assigned to the Clip.