1 /*
2 PresetsStore.cpp - Presets and Clipboard store
3
4 Original ZynAddSubFX author Nasca Octavian Paul
5 Copyright (C) 2002-2005 Nasca Octavian Paul
6 Copyright 2009-2010, Alan Calvert
7 Copyright 2017-2019 Will Godfrey
8
9 This file is part of yoshimi, which is free software: you can redistribute
10 it and/or modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either version 2 of
12 the License, or (at your option) any later version.
13
14 yoshimi is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 FOR A PARTICULAR PURPOSE. See the GNU General Public License (version 2 or
17 later) for more details.
18
19 You should have received a copy of the GNU General Public License along with
20 yoshimi; if not, write to the Free Software Foundation, Inc., 51 Franklin
21 Street, Fifth Floor, Boston, MA 02110-1301, USA.
22
23 This file is a derivative of a ZynAddSubFX original.
24 */
25
26 #include <dirent.h>
27 //#include <iostream>
28
29 #include "Misc/XMLwrapper.h"
30 #include "Params/PresetsStore.h"
31 #include "Misc/FileMgrFuncs.h"
32 #include "Misc/SynthEngine.h"
33
34 using file::make_legit_filename;
35
36
37 extern SynthEngine *firstSynth;
38
39 PresetsStore::_clipboard PresetsStore::clipboard;
40
41
PresetsStore(SynthEngine * _synth)42 PresetsStore::PresetsStore(SynthEngine *_synth) :
43 preset_extension(".xpz"),
44 synth(_synth)
45 {
46 clipboard.data = NULL;
47 clipboard.type.clear();
48
49 for (int i = 0; i < MAX_PRESETS; ++i)
50 {
51 presets[i].file.clear();
52 presets[i].name.clear();
53 }
54 }
55
56
~PresetsStore()57 PresetsStore::~PresetsStore()
58 {
59 if (clipboard.data != NULL)
60 {
61 char *_data = __sync_fetch_and_and(&clipboard.data, 0);
62 free(_data);
63
64 }
65 clearpresets();
66 }
67
68
69 // Clipboard management
copyclipboard(XMLwrapper * xml,const string & type)70 void PresetsStore::copyclipboard(XMLwrapper *xml, const string& type)
71 {
72 clipboard.type = type;
73 if (clipboard.data != NULL)
74 {
75 char *_data = __sync_fetch_and_and(&clipboard.data, 0);
76 free(_data);
77
78 }
79 clipboard.data = xml->getXMLdata();
80 }
81
82
pasteclipboard(XMLwrapper * xml)83 bool PresetsStore::pasteclipboard(XMLwrapper *xml)
84 {
85 if (clipboard.data != NULL)
86 {
87 xml->putXMLdata(clipboard.data);
88 if (synth->getRuntime().effectChange != UNUSED)
89 synth->getRuntime().effectChange |= 0xff0000; // temporary fix
90 return true;
91 }
92 synth->getRuntime().effectChange = UNUSED; // temporary fix
93 return false;
94 }
95
96
checkclipboardtype(const string & type)97 bool PresetsStore::checkclipboardtype(const string& type)
98 {
99 // makes LFO's compatible
100 if (type.find("Plfo") != string::npos
101 && clipboard.type.find("Plfo") != string::npos)
102 return true;
103 return (!type.compare(clipboard.type));
104 }
105
106
clearpresets(void)107 void PresetsStore::clearpresets(void)
108 {
109 for (int i = 0; i < MAX_PRESETS; ++i)
110 {
111 presets[i].file.clear();
112 presets[i].name.clear();
113 }
114 }
115
116
rescanforpresets(const string & type,int root)117 void PresetsStore::rescanforpresets(const string& type, int root)
118 {
119 for (int i = 0; i < MAX_PRESETS; ++i)
120 {
121 presets[i].file.clear();
122 presets[i].name.clear();
123 }
124 int presetk = 0;
125 string ftype = "." + type + preset_extension;
126
127 //std::cout << "type " << type << std::endl;
128 string altType = "";
129 if (type == "Padsyth")
130 altType = ".ADnoteParameters" + preset_extension;
131 else if (type == "Padsythn")
132 altType = ".ADnoteParametersn" + preset_extension;
133 else if (type == "Psubsyth")
134 altType = ".SUBnoteParameters" + preset_extension;
135 else if (type == "Ppadsyth")
136 altType = ".PADnoteParameters" + preset_extension;
137 string dirname = firstSynth->getRuntime().presetsDirlist[root];
138 if (dirname.empty())
139 return;
140 //std::cout << "Preset root " << dirname << std::endl;
141 DIR *dir = opendir(dirname.c_str());
142 if (dir == NULL)
143 return;
144
145 struct dirent *fn;
146 while ((fn = readdir(dir)))
147 {
148 string filename = string(fn->d_name);
149 //std::cout << "file " << filename << std::endl;
150 if (filename.find(ftype) == string::npos)
151 {
152 if (altType.empty() || filename.find(altType) == string::npos)
153 continue;
154 }
155 if (dirname.at(dirname.size() - 1) != '/')
156 dirname += "/";
157 presets[presetk].file = dirname + filename;
158
159 size_t endpos = filename.find(ftype);
160 if (endpos == string::npos)
161 if (!altType.empty())
162 endpos = filename.find(altType);
163 presets[presetk].name = filename.substr(0, endpos);
164 // std::cout << "Preset name " << presets[presetk].name << std::endl;
165 presetk++;
166 if (presetk >= MAX_PRESETS)
167 return;
168 }
169 closedir(dir);
170
171 // sort the presets
172 bool check = true;
173 while (check)
174 {
175 check = false;
176 for (int j = 0; j < MAX_PRESETS - 1; ++j)
177 {
178 for (int i = j + 1; i < MAX_PRESETS; ++i)
179 {
180 if (presets[i].name.empty() || presets[j].name.empty())
181 continue;
182 if (strcasecmp(presets[i].name.c_str(), presets[j].name.c_str()) < 0)
183 {
184 presets[i].file.swap(presets[j].file);
185 presets[i].name.swap(presets[j].name);
186 check = true;
187 }
188 }
189 }
190 }
191 }
192
193
copypreset(XMLwrapper * xml,const string & type,const string & name)194 void PresetsStore::copypreset(XMLwrapper *xml, const string& type, const string& name)
195 {
196 if (firstSynth->getRuntime().presetsDirlist[0].empty())
197 return;
198 synth->getRuntime().xmlType = TOPLEVEL::XML::Presets;
199 synth->getRuntime().Log(name);
200 string tmpfilename = name;
201 make_legit_filename(tmpfilename);
202 string dirname = firstSynth->getRuntime().presetsDirlist[synth->getRuntime().currentPreset];
203 if (dirname.find_last_of("/") != (dirname.size() - 1))
204 dirname += "/";
205 xml->saveXMLfile(dirname + tmpfilename + "." + type + preset_extension);
206 }
207
208
pastepreset(XMLwrapper * xml,int npreset)209 bool PresetsStore::pastepreset(XMLwrapper *xml, int npreset)
210 {
211 if (npreset >= MAX_PRESETS || npreset < 1)
212 return false;
213 npreset--;
214 if (presets[npreset].file.empty())
215 return false;
216 if (synth->getRuntime().effectChange != UNUSED)
217 synth->getRuntime().effectChange |= 0xff0000; // temporary fix
218 return xml->loadXMLfile(presets[npreset].file);
219 }
220
221
deletepreset(int npreset)222 void PresetsStore::deletepreset(int npreset)
223 {
224 if (npreset >= MAX_PRESETS || npreset < 1)
225 return;
226 npreset--;
227 if (!presets[npreset].file.empty())
228 remove(presets[npreset].file.c_str());
229 }
230