gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

savepatchdesc.cpp (3191B)


      1 #include "savepatchdesc.h"
      2 
      3 #include "patchmanager.h"
      4 
      5 #include "jucePluginLib/filetype.h"
      6 
      7 #include "synthLib/sysexToMidi.h"
      8 
      9 namespace jucePluginEditorLib::patchManager
     10 {
     11 	SavePatchDesc::SavePatchDesc(PatchManager& _pm, const int _part, std::string _name)
     12 		: m_patchManager(_pm)
     13 		, m_part(_part)
     14 		, m_name(std::move(_name))
     15 	{
     16 	}
     17 
     18 	SavePatchDesc::SavePatchDesc(PatchManager& _pm, std::map<uint32_t, pluginLib::patchDB::PatchPtr>&& _patches, std::string _name)
     19 		: m_patchManager(_pm)
     20         , m_part(InvalidPart)
     21         , m_patches(std::move(_patches))
     22         , m_name(std::move(_name))
     23 	{
     24 	}
     25 
     26 	std::map<uint32_t, pluginLib::patchDB::PatchPtr>& SavePatchDesc::getPatches() const
     27 	{
     28 		if(m_patches.empty() && isPartValid())
     29 		{
     30 			auto patch = m_patchManager.requestPatchForPart(m_part);
     31 			if(!patch)
     32 				return m_patches;
     33 			m_patches.insert({m_part, patch});
     34 		}
     35 		return m_patches;
     36 	}
     37 
     38 	bool SavePatchDesc::writePatchesToFile(const juce::File& _file) const
     39 	{
     40 		const auto& patches = getPatches();
     41 
     42 		if(patches.empty())
     43 			return false;
     44 
     45 		std::vector<std::vector<uint8_t>> patchesData;
     46 
     47 		for (auto& patch : patches)
     48 		{
     49 			auto data = m_patchManager.applyModifications(patch.second, pluginLib::FileType::Mid, pluginLib::ExportType::DragAndDrop);
     50 			if(data.empty())
     51 				return false;
     52 			patchesData.emplace_back(std::move(data));
     53 		}
     54 
     55 		std::stringstream ss;
     56 
     57 		synthLib::SysexToMidi::write(ss, patchesData);
     58 
     59 		const auto size = ss.tellp();
     60 		std::vector<char> buffer;
     61 		buffer.resize(size);
     62 		ss.read(buffer.data(), size);
     63 
     64 		return _file.replaceWithData(buffer.data(), size);
     65 	}
     66 
     67 	std::string getPatchName(const pluginLib::patchDB::PatchPtr& _patch)
     68 	{
     69 		auto name = _patch->getName();
     70 
     71 		// trim whitespace
     72 		while(!name.empty() && name.back() == ' ')
     73 			name.pop_back();
     74 
     75 		return name;
     76 	}
     77 
     78 	std::string createValidFilename(const std::string& _name)
     79 	{
     80 		std::string result;
     81 		result.reserve(_name.size());
     82 
     83 		const std::string invalid = "\\/:?\"<>|";
     84 
     85 		for (const char c : _name)
     86 		{
     87 			if(invalid.find(c) != std::string::npos)
     88 				result += '_';
     89 			else
     90 				result += c;
     91 		}
     92 		return result;
     93 	}
     94 
     95 	std::string SavePatchDesc::getExportFileName(const pluginLib::Processor& _p) const
     96 	{
     97 		const auto& patches = getPatches();
     98 
     99 		std::string name;
    100 
    101 		if(patches.size() == 1)
    102 		{
    103 			name = getPatchName(patches.begin()->second);		// if there is only one patch, we use the name of the patch
    104 		}
    105 		else if(!m_name.empty())
    106 		{
    107 			name = m_name;									// otherwise use custom name if provided
    108 		}
    109 		else
    110 		{
    111 			name = std::to_string(patches.size()) + " patches";
    112 		}
    113 
    114 		return _p.getProperties().name + " - " + createValidFilename(name) + ".mid";
    115 	}
    116 
    117 	bool SavePatchDesc::writeToFile(const juce::File& _file) const
    118 	{
    119 		return writePatchesToFile(_file);
    120 	}
    121 
    122 	std::vector<pluginLib::patchDB::PatchPtr> SavePatchDesc::getPatchesFromDragSource(const juce::DragAndDropTarget::SourceDetails& _dragSourceDetails)
    123 	{
    124 		const auto* savePatchDesc = fromDragSource(_dragSourceDetails);
    125 
    126 		if(!savePatchDesc)
    127 			return {};
    128 
    129 		std::vector<pluginLib::patchDB::PatchPtr> patches;
    130 
    131 		for (const auto& it : savePatchDesc->getPatches())
    132 			patches.push_back(it.second);
    133 
    134 		return patches;
    135 	}
    136 }