You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1957 lines
62KB

  1. /* Copyright 2013-2019 Matt Tytel
  2. *
  3. * vital is free software: you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation, either version 3 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * vital is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with vital. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "load_save.h"
  17. #include "modulation_connection_processor.h"
  18. #include "sound_engine.h"
  19. #include "midi_manager.h"
  20. #include "sample_source.h"
  21. #include "synth_base.h"
  22. #include "synth_constants.h"
  23. #include "synth_oscillator.h"
  24. #define QUOTE(x) #x
  25. #define STRINGIFY(x) QUOTE(x)
  26. namespace {
  27. const std::string kLinuxUserDataDirectory = "~/.local/share/vital/";
  28. const std::string kAvailablePacksFile = "available_packs.json";
  29. const std::string kInstalledPacksFile = "packs.json";
  30. Time getBuildTime() {
  31. StringArray date_tokens;
  32. date_tokens.addTokens(STRINGIFY(BUILD_DATE), true);
  33. if (date_tokens.size() != 5)
  34. return Time::getCompilationDate();
  35. int year = date_tokens[0].getIntValue();
  36. int month = date_tokens[1].getIntValue() - 1;
  37. int day = date_tokens[2].getIntValue();
  38. int hour = date_tokens[3].getIntValue();
  39. int minute = date_tokens[4].getIntValue();
  40. return Time(year, month, day, hour, minute);
  41. }
  42. } // namespace
  43. const std::string LoadSave::kUserDirectoryName = "User";
  44. const std::string LoadSave::kPresetFolderName = "Presets";
  45. const std::string LoadSave::kWavetableFolderName = "Wavetables";
  46. const std::string LoadSave::kSkinFolderName = "Skins";
  47. const std::string LoadSave::kSampleFolderName = "Samples";
  48. const std::string LoadSave::kLfoFolderName = "LFOs";
  49. const std::string LoadSave::kAdditionalWavetableFoldersName = "wavetable_folders";
  50. const std::string LoadSave::kAdditionalSampleFoldersName = "sample_folders";
  51. void LoadSave::convertBufferToPcm(json& data, const std::string& field) {
  52. if (data.count(field) == 0)
  53. return;
  54. MemoryOutputStream decoded;
  55. std::string wave_data = data[field];
  56. Base64::convertFromBase64(decoded, wave_data);
  57. int size = static_cast<int>(decoded.getDataSize()) / sizeof(float);
  58. std::unique_ptr<float[]> float_data = std::make_unique<float[]>(size);
  59. memcpy(float_data.get(), decoded.getData(), size * sizeof(float));
  60. std::unique_ptr<int16_t[]> pcm_data = std::make_unique<int16_t[]>(size);
  61. vital::utils::floatToPcmData(pcm_data.get(), float_data.get(), size);
  62. String encoded = Base64::toBase64(pcm_data.get(), sizeof(int16_t) * size);
  63. data[field] = encoded.toStdString();
  64. }
  65. void LoadSave::convertPcmToFloatBuffer(json& data, const std::string& field) {
  66. if (data.count(field) == 0)
  67. return;
  68. MemoryOutputStream decoded;
  69. std::string wave_data = data[field];
  70. Base64::convertFromBase64(decoded, wave_data);
  71. int size = static_cast<int>(decoded.getDataSize()) / sizeof(int16_t);
  72. std::unique_ptr<int16_t[]> pcm_data = std::make_unique<int16_t[]>(size);
  73. memcpy(pcm_data.get(), decoded.getData(), size * sizeof(int16_t));
  74. std::unique_ptr<float[]> float_data = std::make_unique<float[]>(size);
  75. vital::utils::pcmToFloatData(float_data.get(), pcm_data.get(), size);
  76. String encoded = Base64::toBase64(float_data.get(), sizeof(float) * size);
  77. data[field] = encoded.toStdString();
  78. }
  79. json LoadSave::stateToJson(SynthBase* synth, const CriticalSection& critical_section) {
  80. json settings_data;
  81. vital::control_map& controls = synth->getControls();
  82. for (auto& control : controls)
  83. settings_data[control.first] = control.second->value();
  84. vital::Sample* sample = synth->getSample();
  85. if (sample)
  86. settings_data["sample"] = sample->stateToJson();
  87. json modulations;
  88. vital::ModulationConnectionBank& modulation_bank = synth->getModulationBank();
  89. for (int i = 0; i < vital::kMaxModulationConnections; ++i) {
  90. vital::ModulationConnection* connection = modulation_bank.atIndex(i);
  91. json modulation_data;
  92. modulation_data["source"] = connection->source_name;
  93. modulation_data["destination"] = connection->destination_name;
  94. LineGenerator* line_mapping = connection->modulation_processor->lineMapGenerator();
  95. if (!line_mapping->linear())
  96. modulation_data["line_mapping"] = line_mapping->stateToJson();
  97. modulations.push_back(modulation_data);
  98. }
  99. settings_data["modulations"] = modulations;
  100. if (synth->getWavetableCreator(0)) {
  101. json wavetables;
  102. for (int i = 0; i < vital::kNumOscillators; ++i) {
  103. WavetableCreator* wavetable_creator = synth->getWavetableCreator(i);
  104. wavetables.push_back(wavetable_creator->stateToJson());
  105. }
  106. settings_data["wavetables"] = wavetables;
  107. }
  108. json lfos;
  109. for (int i = 0; i < vital::kNumLfos; ++i) {
  110. LineGenerator* lfo_source = synth->getLfoSource(i);
  111. lfos.push_back(lfo_source->stateToJson());
  112. }
  113. settings_data["lfos"] = lfos;
  114. json data;
  115. data["synth_version"] = ProjectInfo::versionString;
  116. data["preset_name"] = synth->getPresetName().toStdString();
  117. data["author"] = synth->getAuthor().toStdString();
  118. data["comments"] = synth->getComments().toStdString();
  119. data["preset_style"] = synth->getStyle().toStdString();
  120. for (int i = 0; i < vital::kNumMacros; ++i) {
  121. std::string name = synth->getMacroName(i).toStdString();
  122. data["macro" + std::to_string(i + 1)] = name;
  123. }
  124. data["settings"] = settings_data;
  125. return data;
  126. }
  127. void LoadSave::loadControls(SynthBase* synth, const json& data) {
  128. vital::control_map controls = synth->getControls();
  129. for (auto& control : controls) {
  130. std::string name = control.first;
  131. if (data.count(name)) {
  132. vital::mono_float value = data[name];
  133. control.second->set(value);
  134. }
  135. else {
  136. vital::ValueDetails details = vital::Parameters::getDetails(name);
  137. control.second->set(details.default_value);
  138. }
  139. }
  140. synth->modWheelGuiChanged(controls["mod_wheel"]->value());
  141. }
  142. void LoadSave::loadModulations(SynthBase* synth, const json& modulations) {
  143. synth->clearModulations();
  144. vital::ModulationConnectionBank& modulation_bank = synth->getModulationBank();
  145. int index = 0;
  146. for (const json& modulation : modulations) {
  147. std::string source = modulation["source"];
  148. std::string destination = modulation["destination"];
  149. vital::ModulationConnection* connection = modulation_bank.atIndex(index);
  150. index++;
  151. if (synth->getEngine()->getModulationSource(source) == nullptr ||
  152. synth->getEngine()->getMonoModulationDestination(destination) == nullptr) {
  153. continue;
  154. }
  155. if (source.length() && destination.length()) {
  156. connection->source_name = source;
  157. connection->destination_name = destination;
  158. synth->connectModulation(connection);
  159. }
  160. if (modulation.count("line_mapping"))
  161. connection->modulation_processor->lineMapGenerator()->jsonToState(modulation["line_mapping"]);
  162. else
  163. connection->modulation_processor->lineMapGenerator()->initLinear();
  164. }
  165. }
  166. void LoadSave::loadSample(SynthBase* synth, const json& json_sample) {
  167. vital::Sample* sample = synth->getSample();
  168. if (sample)
  169. sample->jsonToState(json_sample);
  170. }
  171. void LoadSave::loadWavetables(SynthBase* synth, const json& wavetables) {
  172. if (synth->getWavetableCreator(0) == nullptr)
  173. return;
  174. int i = 0;
  175. for (const json& wavetable : wavetables) {
  176. WavetableCreator* wavetable_creator = synth->getWavetableCreator(i);
  177. wavetable_creator->jsonToState(wavetable);
  178. wavetable_creator->render();
  179. i++;
  180. }
  181. }
  182. void LoadSave::loadLfos(SynthBase* synth, const json& lfos) {
  183. int i = 0;
  184. for (const json& lfo : lfos) {
  185. LineGenerator* lfo_source = synth->getLfoSource(i);
  186. lfo_source->jsonToState(lfo);
  187. lfo_source->render();
  188. i++;
  189. }
  190. }
  191. void LoadSave::loadSaveState(std::map<std::string, String>& state, json data) {
  192. if (data.count("preset_name")) {
  193. std::string preset_name = data["preset_name"];
  194. state["preset_name"] = preset_name;
  195. }
  196. if (data.count("author")) {
  197. std::string author = data["author"];
  198. state["author"] = author;
  199. }
  200. if (data.count("comments")) {
  201. std::string comments = data["comments"];
  202. state["comments"] = comments;
  203. }
  204. if (data.count("preset_style")) {
  205. std::string style = data["preset_style"];
  206. state["style"] = style;
  207. }
  208. for (int i = 0; i < vital::kNumMacros; ++i) {
  209. std::string key = "macro" + std::to_string(i + 1);
  210. if (data.count(key)) {
  211. std::string name = data[key];
  212. state[key] = name;
  213. }
  214. else
  215. state[key] = "MACRO " + std::to_string(i + 1);
  216. }
  217. }
  218. void LoadSave::initSaveInfo(std::map<std::string, String>& save_info) {
  219. save_info["preset_name"] = "";
  220. save_info["author"] = "";
  221. save_info["comments"] = "";
  222. save_info["style"] = "";
  223. for (int i = 0; i < vital::kNumMacros; ++i)
  224. save_info["macro" + std::to_string(i + 1)] = "MACRO " + std::to_string(i + 1);
  225. }
  226. json LoadSave::updateFromOldVersion(json state) {
  227. json settings = state["settings"];
  228. json modulations = settings["modulations"];
  229. json sample = settings["sample"];
  230. json wavetables = settings["wavetables"];
  231. std::string version = state["synth_version"];
  232. if (compareVersionStrings(version, "0.2.0") < 0 || settings.count("sub_octave")) {
  233. int sub_waveform = settings["sub_waveform"];
  234. if (sub_waveform == 4)
  235. sub_waveform = 5;
  236. else if (sub_waveform == 5)
  237. sub_waveform = 4;
  238. settings["sub_waveform"] = sub_waveform;
  239. int sub_octave = settings["sub_octave"];
  240. settings["sub_transpose"] = vital::kNotesPerOctave * sub_octave;
  241. int osc_1_filter_routing = settings["osc_1_filter_routing"];
  242. int osc_2_filter_routing = settings["osc_2_filter_routing"];
  243. int sample_filter_routing = settings["sample_filter_routing"];
  244. int sub_filter_routing = settings["sub_filter_routing"];
  245. settings["filter_1_osc1_input"] = 1 - osc_1_filter_routing;
  246. settings["filter_1_osc2_input"] = 1 - osc_2_filter_routing;
  247. settings["filter_1_sample_input"] = 1 - sample_filter_routing;
  248. settings["filter_1_sub_input"] = 1 - sub_filter_routing;
  249. settings["filter_2_osc1_input"] = osc_1_filter_routing;
  250. settings["filter_2_osc2_input"] = osc_2_filter_routing;
  251. settings["filter_2_sample_input"] = sample_filter_routing;
  252. settings["filter_2_sub_input"] = sub_filter_routing;
  253. int filter_1_style = settings["filter_1_style"];
  254. if (filter_1_style == 2)
  255. filter_1_style = 3;
  256. else if (filter_1_style == 3)
  257. filter_1_style = 2;
  258. settings["filter_1_style"] = filter_1_style;
  259. int filter_2_style = settings["filter_2_style"];
  260. if (filter_2_style == 2)
  261. filter_2_style = 3;
  262. else if (filter_2_style == 3)
  263. filter_2_style = 2;
  264. settings["filter_2_style"] = filter_2_style;
  265. }
  266. if (compareVersionStrings(version, "0.2.1") < 0) {
  267. std::string env_start = "env_";
  268. for (int i = 0; i < vital::kNumEnvelopes; ++i) {
  269. std::string number = std::to_string(i + 1);
  270. std::string attack_string = env_start + number + "_attack";
  271. std::string decay_string = env_start + number + "_decay";
  272. std::string release_string = env_start + number + "_release";
  273. if (settings.count(attack_string) == 0)
  274. break;
  275. settings[attack_string] = std::pow(settings[attack_string], 1.0f / 1.5f);
  276. settings[decay_string] = std::pow(settings[decay_string], 1.0f / 1.5f);
  277. settings[release_string] = std::pow(settings[release_string], 1.0f / 1.5f);
  278. }
  279. if (settings.count("wave_tables"))
  280. settings["wavetables"] = settings["wave_tables"];
  281. }
  282. wavetables = settings["wavetables"];
  283. if (compareVersionStrings(version, "0.2.4") < 0) {
  284. int portamento_type = settings["portamento_type"];
  285. settings["portamento_force"] = std::max(0, portamento_type - 1);
  286. if (portamento_type == 0)
  287. settings["portamento_time"] = -10.0f;
  288. }
  289. if (compareVersionStrings(version, "0.2.5") < 0) {
  290. std::string env_start = "env_";
  291. for (int i = 0; i < vital::kNumEnvelopes; ++i) {
  292. std::string number = std::to_string(i + 1);
  293. std::string attack_string = env_start + number + "_attack";
  294. std::string decay_string = env_start + number + "_decay";
  295. std::string release_string = env_start + number + "_release";
  296. if (settings.count(attack_string) == 0)
  297. break;
  298. float adjust_power = 3.0f / 4.0f;
  299. settings[attack_string] = std::pow(settings[attack_string], adjust_power);
  300. settings[decay_string] = std::pow(settings[decay_string], adjust_power);
  301. settings[release_string] = std::pow(settings[release_string], adjust_power);
  302. }
  303. }
  304. if (compareVersionStrings(version, "0.2.6") < 0) {
  305. std::string lfo_start = "lfo_";
  306. for (int i = 0; i < vital::kNumLfos; ++i) {
  307. std::string number = std::to_string(i + 1);
  308. std::string fade_string = lfo_start + number + "_fade_time";
  309. std::string delay_string = lfo_start + number + "_delay_time";
  310. settings[fade_string] = 0.0f;
  311. settings[delay_string] = 0.0f;
  312. }
  313. }
  314. if (compareVersionStrings(version, "0.2.7") < 0) {
  315. static constexpr float adjustment = 0.70710678119f;
  316. float osc_1_level = settings["osc_1_level"];
  317. float osc_2_level = settings["osc_2_level"];
  318. float sub_level = settings["sub_level"];
  319. float sample_level = settings["sample_level"];
  320. osc_1_level = adjustment * osc_1_level * osc_1_level;
  321. osc_2_level = adjustment * osc_2_level * osc_2_level;
  322. sub_level = adjustment * sub_level * sub_level;
  323. sample_level = adjustment * sample_level * sample_level;
  324. settings["osc_1_level"] = sqrtf(osc_1_level);
  325. settings["osc_2_level"] = sqrtf(osc_2_level);
  326. settings["sub_level"] = sqrtf(sub_level);
  327. settings["sample_level"] = sqrtf(sample_level);
  328. }
  329. if (compareVersionStrings(version, "0.3.0") < 0) {
  330. float reverb_damping = settings["reverb_damping"];
  331. float reverb_feedback = settings["reverb_feedback"];
  332. settings["decay_time"] = (reverb_feedback - 0.8f) * 10.0f;
  333. settings["reverb_high_shelf_gain"] = -reverb_damping * 4.0f;
  334. settings["reverb_pre_high_cutoff"] = 128.0f;
  335. json new_modulations;
  336. for (json& modulation : modulations) {
  337. if (modulation["destination"] == "reverb_damping")
  338. modulation["destination"] = "reverb_high_shelf_gain";
  339. if (modulation["destination"] == "reverb_feedback")
  340. modulation["destination"] = "reverb_decay_time";
  341. new_modulations.push_back(modulation);
  342. }
  343. modulations = new_modulations;
  344. }
  345. if (compareVersionStrings(version, "0.3.1") < 0) {
  346. float sample_transpose = settings["sample_transpose"];
  347. float sample_keytrack = settings["sample_keytrack"];
  348. if (sample_keytrack)
  349. settings["sample_transpose"] = sample_transpose + 28.0f;
  350. }
  351. if (compareVersionStrings(version, "0.3.2") < 0) {
  352. float osc_1_transpose = settings["osc_1_transpose"];
  353. float osc_1_midi_track = settings["osc_1_midi_track"];
  354. if (osc_1_midi_track == 0.0f)
  355. settings["osc_1_transpose"] = osc_1_transpose - 48.0f;
  356. float osc_2_transpose = settings["osc_2_transpose"];
  357. float osc_2_midi_track = settings["osc_2_midi_track"];
  358. if (osc_2_midi_track == 0.0f)
  359. settings["osc_2_transpose"] = osc_2_transpose - 48.0f;
  360. }
  361. if (compareVersionStrings(version, "0.3.4") < 0) {
  362. float float_order = settings["effect_chain_order"];
  363. int effect_order[vital::constants::kNumEffects];
  364. vital::utils::decodeFloatToOrder(effect_order, float_order, vital::constants::kNumEffects - 1);
  365. for (int i = 0; i < vital::constants::kNumEffects - 1; ++i) {
  366. if (effect_order[i] >= vital::constants::kFilterFx)
  367. effect_order[i] += 1;
  368. }
  369. effect_order[vital::constants::kNumEffects - 1] = vital::constants::kFilterFx;
  370. settings["effect_chain_order"] = vital::utils::encodeOrderToFloat(effect_order, vital::constants::kNumEffects);
  371. }
  372. if (compareVersionStrings(version, "0.3.5") < 0) {
  373. float osc_1_distortion_type = settings["osc_1_distortion_type"];
  374. float osc_2_distortion_type = settings["osc_2_distortion_type"];
  375. if (osc_1_distortion_type >= 10.0f)
  376. settings["osc_1_distortion_type"] = osc_1_distortion_type + 1.0f;
  377. if (osc_2_distortion_type >= 10.0f)
  378. settings["osc_2_distortion_type"] = osc_2_distortion_type + 1.0f;
  379. }
  380. if (compareVersionStrings(version, "0.3.6") < 0) {
  381. std::string lfo_start = "lfo_";
  382. for (int i = 0; i < vital::kNumLfos; ++i) {
  383. std::string sync_type_string = lfo_start + std::to_string(i + 1) + "_sync_type";
  384. if (settings.count(sync_type_string)) {
  385. float value = settings[sync_type_string];
  386. if (value >= 2.0f)
  387. settings[sync_type_string] = value - 1.0f;
  388. }
  389. }
  390. }
  391. if (compareVersionStrings(version, "0.3.7") < 0) {
  392. convertBufferToPcm(sample, "samples");
  393. convertBufferToPcm(sample, "samples_stereo");
  394. }
  395. if (compareVersionStrings(version, "0.4.1") < 0) {
  396. bool update = false;
  397. json new_modulations;
  398. for (json& modulation : modulations) {
  399. if (modulation["source"] == "perlin") {
  400. update = true;
  401. modulation["source"] = "random_1";
  402. }
  403. new_modulations.push_back(modulation);
  404. }
  405. if (update) {
  406. modulations = new_modulations;
  407. settings["random_1_sync"] = 0.0f;
  408. settings["random_1_frequency"] = 1.65149612947f;
  409. settings["random_1_stereo"] = 1.0f;
  410. }
  411. }
  412. if (compareVersionStrings(version, "0.4.3") < 0) {
  413. float osc_1_distortion_type = settings["osc_1_distortion_type"];
  414. float osc_1_distortion_amount = settings["osc_1_distortion_amount"];
  415. if (osc_1_distortion_type == vital::SynthOscillator::kFormant) {
  416. settings["osc_1_distortion_amount"] = 0.5f + 0.5f * osc_1_distortion_amount;
  417. int index = 1;
  418. for (json& modulation : modulations) {
  419. if (modulation["destination"] == "osc_1_distortion_amount") {
  420. std::string amount_string = "modulation_" + std::to_string(index) + "_amount";
  421. float last_amount = settings[amount_string];
  422. settings[amount_string] = 0.5f * last_amount;
  423. }
  424. index++;
  425. }
  426. }
  427. float osc_2_distortion_type = settings["osc_2_distortion_type"];
  428. float osc_2_distortion_amount = settings["osc_2_distortion_amount"];
  429. if (osc_2_distortion_type == vital::SynthOscillator::kFormant) {
  430. settings["osc_2_distortion_amount"] = 0.5f + 0.5f * osc_2_distortion_amount;
  431. int index = 1;
  432. for (json& modulation : modulations) {
  433. if (modulation["destination"] == "osc_2_distortion_amount") {
  434. std::string amount_string = "modulation_" + std::to_string(index) + "_amount";
  435. float last_amount = settings[amount_string];
  436. settings[amount_string] = 0.5f * last_amount;
  437. }
  438. index++;
  439. }
  440. }
  441. }
  442. if (compareVersionStrings(version, "0.4.4") < 0) {
  443. float osc_1_distortion_type = settings["osc_1_distortion_type"];
  444. float osc_1_distortion_amount = settings["osc_1_distortion_amount"];
  445. if (osc_1_distortion_type == vital::SynthOscillator::kSync) {
  446. settings["osc_1_distortion_amount"] = 0.5f + 0.5f * osc_1_distortion_amount;
  447. int index = 1;
  448. for (json& modulation : modulations) {
  449. if (modulation["destination"] == "osc_1_distortion_amount") {
  450. std::string amount_string = "modulation_" + std::to_string(index) + "_amount";
  451. float last_amount = settings[amount_string];
  452. settings[amount_string] = 0.5f * last_amount;
  453. }
  454. index++;
  455. }
  456. }
  457. float osc_2_distortion_type = settings["osc_2_distortion_type"];
  458. float osc_2_distortion_amount = settings["osc_2_distortion_amount"];
  459. if (osc_2_distortion_type == vital::SynthOscillator::kSync) {
  460. settings["osc_2_distortion_amount"] = 0.5f + 0.5f * osc_2_distortion_amount;
  461. int index = 1;
  462. for (json& modulation : modulations) {
  463. if (modulation["destination"] == "osc_2_distortion_amount") {
  464. std::string amount_string = "modulation_" + std::to_string(index) + "_amount";
  465. float last_amount = settings[amount_string];
  466. settings[amount_string] = 0.5f * last_amount;
  467. }
  468. index++;
  469. }
  470. }
  471. }
  472. if (compareVersionStrings(version, "0.4.5") < 0) {
  473. float compressor_low_band = settings["compressor_low_band"];
  474. float compressor_high_band = settings["compressor_high_band"];
  475. if (compressor_low_band && compressor_high_band)
  476. settings["compressor_enabled_bands"] = 0;
  477. else if (compressor_low_band)
  478. settings["compressor_enabled_bands"] = 1;
  479. else if (compressor_high_band)
  480. settings["compressor_enabled_bands"] = 2;
  481. else
  482. settings["compressor_enabled_bands"] = 3;
  483. }
  484. if (compareVersionStrings(version, "0.4.7") < 0 && settings.count("osc_1_distortion_type")) {
  485. static const int kRemapResolution = 32;
  486. float osc_1_distortion_type = settings["osc_1_distortion_type"];
  487. if (osc_1_distortion_type)
  488. settings["osc_1_distortion_type"] = osc_1_distortion_type - 1.0f;
  489. float osc_2_distortion_type = settings["osc_2_distortion_type"];
  490. if (osc_2_distortion_type)
  491. settings["osc_2_distortion_type"] = osc_2_distortion_type - 1.0f;
  492. if (osc_1_distortion_type == 1.0f)
  493. settings["osc_1_spectral_morph_type"] = vital::SynthOscillator::kLowPass;
  494. if (osc_2_distortion_type == 1.0f)
  495. settings["osc_2_spectral_morph_type"] = vital::SynthOscillator::kLowPass;
  496. json new_modulations;
  497. for (json& modulation : modulations) {
  498. if (osc_1_distortion_type == 1.0f && modulation["destination"] == "osc_1_distortion_amount")
  499. modulation["destination"] = "osc_1_spectral_morph_amount";
  500. else if (osc_2_distortion_type == 1.0f && modulation["destination"] == "osc_2_distortion_amount")
  501. modulation["destination"] = "osc_2_spectral_morph_amount";
  502. new_modulations.push_back(modulation);
  503. }
  504. osc_1_distortion_type = settings["osc_1_distortion_type"];
  505. osc_2_distortion_type = settings["osc_2_distortion_type"];
  506. if (osc_1_distortion_type == 7 || osc_1_distortion_type == 8 || osc_1_distortion_type == 9) {
  507. float original_fm_amount = settings["osc_1_distortion_amount"];
  508. float new_fm_amount = std::pow(original_fm_amount, 1.0f / 2.0f);
  509. settings["osc_1_distortion_amount"] = new_fm_amount;
  510. int index = 1;
  511. for (json& modulation : new_modulations) {
  512. if (modulation["destination"] == "osc_1_distortion_amount") {
  513. std::string number = std::to_string(index);
  514. std::string amount_string = "modulation_" + number + "_amount";
  515. float last_amount = settings[amount_string];
  516. if (last_amount == 0.0f)
  517. continue;
  518. bool bipolar = settings["modulation_" + number + "_bipolar"] != 0.0f;
  519. float min = std::min(original_fm_amount, original_fm_amount + last_amount);
  520. float max = std::max(original_fm_amount, original_fm_amount + last_amount);
  521. if (bipolar) {
  522. min = std::min(original_fm_amount + last_amount * 0.5f, original_fm_amount - last_amount * 0.5f);
  523. max = std::max(original_fm_amount + last_amount * 0.5f, original_fm_amount - last_amount * 0.5f);
  524. }
  525. float min_target = std::pow(min, 1.0f / 2.0f);
  526. float max_target = std::pow(max, 1.0f / 2.0f);
  527. float new_amount = max_target - min_target;
  528. if (bipolar)
  529. new_amount = 2.0f * std::max(new_fm_amount - min_target, max_target - new_fm_amount);
  530. settings[amount_string] = new_amount;
  531. LineGenerator scale;
  532. scale.initLinear();
  533. scale.setNumPoints(kRemapResolution);
  534. for (int i = 0; i < kRemapResolution; ++i) {
  535. float t = i / (kRemapResolution - 1.0f);
  536. float old_value = vital::utils::interpolate(min, max, t);
  537. float adjusted_old_value = std::pow(old_value, 1.0f / 2.0f);
  538. float y = 1.0f - (adjusted_old_value - min_target) / new_amount;
  539. scale.setPoint(i, std::pair<float, float>(t, y));
  540. }
  541. modulation["line_mapping"] = scale.stateToJson();
  542. }
  543. index++;
  544. }
  545. }
  546. if (osc_2_distortion_type == 7 || osc_2_distortion_type == 8 || osc_2_distortion_type == 9) {
  547. float original_fm_amount = settings["osc_2_distortion_amount"];
  548. float new_fm_amount = std::pow(original_fm_amount, 1.0f / 2.0f);
  549. settings["osc_2_distortion_amount"] = new_fm_amount;
  550. int index = 1;
  551. for (json& modulation : new_modulations) {
  552. if (modulation["destination"] == "osc_2_distortion_amount") {
  553. std::string number = std::to_string(index);
  554. std::string amount_string = "modulation_" + number + "_amount";
  555. float last_amount = settings[amount_string];
  556. if (last_amount == 0.0f)
  557. continue;
  558. bool bipolar = settings["modulation_" + number + "_bipolar"] != 0.0f;
  559. float min = std::min(original_fm_amount, original_fm_amount + last_amount);
  560. float max = std::max(original_fm_amount, original_fm_amount + last_amount);
  561. if (bipolar) {
  562. min = std::min(original_fm_amount + last_amount * 0.5f, original_fm_amount - last_amount * 0.5f);
  563. max = std::max(original_fm_amount + last_amount * 0.5f, original_fm_amount - last_amount * 0.5f);
  564. }
  565. float min_target = std::pow(min, 1.0f / 2.0f);
  566. float max_target = std::pow(max, 1.0f / 2.0f);
  567. float new_amount = max_target - min_target;
  568. if (bipolar)
  569. new_amount = 2.0f * std::max(new_fm_amount - min_target, max_target - new_fm_amount);
  570. settings[amount_string] = new_amount;
  571. LineGenerator scale;
  572. scale.initLinear();
  573. scale.setNumPoints(kRemapResolution);
  574. for (int i = 0; i < kRemapResolution; ++i) {
  575. float t = i / (kRemapResolution - 1.0f);
  576. float old_value = vital::utils::interpolate(min, max, t);
  577. float adjusted_old_value = std::pow(old_value, 1.0f / 2.0f);
  578. float y = 1.0f - (adjusted_old_value - min_target) / new_amount;
  579. scale.setPoint(i, std::pair<float, float>(t, y));
  580. }
  581. modulation["line_mapping"] = scale.stateToJson();
  582. }
  583. index++;
  584. }
  585. }
  586. modulations = new_modulations;
  587. }
  588. if (compareVersionStrings(version, "0.5.0") < 0 && settings.count("sub_on")) {
  589. settings["osc_3_on"] = settings["sub_on"];
  590. settings["osc_3_level"] = settings["sub_level"];
  591. settings["osc_3_pan"] = settings["sub_pan"];
  592. settings["osc_3_transpose"] = settings["sub_transpose"];
  593. if (settings.count("sub_transpose_quantize"))
  594. settings["osc_3_transpose_quantize"] = settings["sub_transpose_quantize"];
  595. settings["osc_3_tune"] = settings["sub_tune"];
  596. settings["osc_3_phase"] = 0.25f;
  597. settings["osc_3_random_phase"] = 0.0f;
  598. float sub_waveform = settings["sub_waveform"];
  599. settings["osc_3_wave_frame"] = sub_waveform * 257.0f / 6.0f;
  600. float sub_filter1 = settings["filter_1_sub_input"];
  601. float sub_filter2 = settings["filter_2_sub_input"];
  602. float sub_direct_out = settings["sub_direct_out"];
  603. if (sub_direct_out)
  604. settings["osc_3_destination"] = 4.0f;
  605. else if (sub_filter1 && sub_filter2)
  606. settings["osc_3_destination"] = 2.0f;
  607. else if (sub_filter2)
  608. settings["osc_3_destination"] = 1.0f;
  609. else if (sub_filter1)
  610. settings["osc_3_destination"] = 0.0f;
  611. else
  612. settings["osc_3_destination"] = 3.0f;
  613. float osc1_filter1 = settings["filter_1_osc1_input"];
  614. float osc1_filter2 = settings["filter_2_osc1_input"];
  615. if (osc1_filter1 && osc1_filter2)
  616. settings["osc_1_destination"] = 2.0f;
  617. else if (osc1_filter2)
  618. settings["osc_1_destination"] = 1.0f;
  619. else if (osc1_filter1)
  620. settings["osc_1_destination"] = 0.0f;
  621. else
  622. settings["osc_1_destination"] = 3.0f;
  623. float osc2_filter1 = settings["filter_1_osc2_input"];
  624. float osc2_filter2 = settings["filter_2_osc2_input"];
  625. if (osc2_filter1 && osc2_filter2)
  626. settings["osc_2_destination"] = 2.0f;
  627. else if (osc2_filter2)
  628. settings["osc_2_destination"] = 1.0f;
  629. else if (osc2_filter1)
  630. settings["osc_2_destination"] = 0.0f;
  631. else
  632. settings["osc_2_destination"] = 3.0f;
  633. float sample_filter1 = settings["filter_1_sample_input"];
  634. float sample_filter2 = settings["filter_2_sample_input"];
  635. if (sample_filter1 && sample_filter2)
  636. settings["sample_destination"] = 2.0f;
  637. else if (sample_filter2)
  638. settings["sample_destination"] = 1.0f;
  639. else if (sample_filter1)
  640. settings["sample_destination"] = 0.0f;
  641. else
  642. settings["sample_destination"] = 3.0f;
  643. vital::Wavetable wavetable(vital::kNumOscillatorWaveFrames);
  644. WavetableCreator wavetable_creator(&wavetable);
  645. wavetable_creator.initPredefinedWaves();
  646. wavetable_creator.setName("Sub");
  647. json new_wavetables;
  648. for (int i = (int)wavetables.size() - 1; i >= 0; --i)
  649. new_wavetables.push_back(wavetables[i]);
  650. new_wavetables.push_back(wavetable_creator.stateToJson());
  651. settings["wavetables"] = new_wavetables;
  652. json new_modulations;
  653. for (json& modulation : modulations) {
  654. if (modulation["destination"] == "sub_transpose")
  655. modulation["destination"] = "osc_3_transpose";
  656. else if (modulation["destination"] == "sub_tune")
  657. modulation["destination"] = "osc_3_tune";
  658. else if (modulation["destination"] == "sub_level")
  659. modulation["destination"] = "osc_3_level";
  660. else if (modulation["destination"] == "sub_pan")
  661. modulation["destination"] = "osc_3_pan";
  662. new_modulations.push_back(modulation);
  663. }
  664. modulations = new_modulations;
  665. }
  666. if (compareVersionStrings(version, "0.5.5") < 0) {
  667. float flanger_tempo = settings["flanger_tempo"];
  668. settings["flanger_tempo"] = flanger_tempo + 1.0f;
  669. float phaser_tempo = settings["phaser_tempo"];
  670. settings["phaser_tempo"] = phaser_tempo + 1.0f;
  671. float chorus_tempo = settings["chorus_tempo"];
  672. settings["chorus_tempo"] = chorus_tempo + 1.0f;
  673. float delay_tempo = settings["delay_tempo"];
  674. settings["delay_tempo"] = delay_tempo + 1.0f;
  675. std::string lfo_start = "lfo_";
  676. for (int i = 0; i < vital::kNumLfos; ++i) {
  677. std::string tempo_string = lfo_start + std::to_string(i + 1) + "_tempo";
  678. if (settings.count(tempo_string)) {
  679. float tempo = settings[tempo_string];
  680. settings[tempo_string] = tempo + 1.0f;
  681. }
  682. }
  683. std::string random_start = "random_";
  684. for (int i = 0; i < vital::kNumRandomLfos; ++i) {
  685. std::string tempo_string = random_start + std::to_string(i + 1) + "_tempo";
  686. if (settings.count(tempo_string)) {
  687. float tempo = settings[tempo_string];
  688. settings[tempo_string] = tempo + 1.0f;
  689. }
  690. }
  691. }
  692. if (compareVersionStrings(version, "0.5.7") < 0) {
  693. settings["delay_aux_sync"] = settings["delay_sync"];
  694. settings["delay_aux_frequency"] = settings["delay_frequency"];
  695. settings["delay_aux_tempo"] = settings["delay_tempo"];
  696. float style = settings["delay_style"];
  697. if (style)
  698. settings["delay_style"] = style + 1.0f;
  699. }
  700. if (compareVersionStrings(version, "0.5.8") < 0)
  701. settings["chorus_damping"] = 1.0f;
  702. if (compareVersionStrings(version, "0.6.5") < 0) {
  703. settings["stereo_mode"] = 1.0f;
  704. float routing = settings["stereo_routing"];
  705. routing *= 0.125f;
  706. if (routing < 0.0f)
  707. settings["stereo_routing"] = 1.0f - routing;
  708. else
  709. settings["stereo_routing"] = routing;
  710. }
  711. if (compareVersionStrings(version, "0.6.6") < 0) {
  712. float stereo_mode = settings["stereo_mode"];
  713. float routing = settings["stereo_routing"];
  714. if (stereo_mode == 0.0f)
  715. settings["stereo_routing"] = 1.0f - routing;
  716. }
  717. if (compareVersionStrings(version, "0.6.7") < 0) {
  718. float chorus_damping = settings["chorus_damping"];
  719. settings["chorus_cutoff"] = 20.0f;
  720. settings["chorus_spread"] = chorus_damping;
  721. json new_modulations;
  722. for (json& modulation : modulations) {
  723. if (modulation["destination"] == "chorus_damping")
  724. modulation["destination"] = "chorus_spread";
  725. new_modulations.push_back(modulation);
  726. }
  727. modulations = new_modulations;
  728. }
  729. if (compareVersionStrings(version, "0.7.1") < 0) {
  730. float osc_1_spectral_morph_type = 0.0f;
  731. if (settings.count("osc_1_spectral_morph_type"))
  732. osc_1_spectral_morph_type = settings["osc_1_spectral_morph_type"];
  733. float osc_2_spectral_morph_type = 0.0f;
  734. if (settings.count("osc_2_spectral_morph_type"))
  735. osc_2_spectral_morph_type = settings["osc_2_spectral_morph_type"];
  736. if (osc_1_spectral_morph_type == 9.0f) {
  737. float osc_1_spectral_morph_amount = settings["osc_1_spectral_morph_amount"];
  738. settings["osc_1_spectral_morph_amount"] = -0.5f * osc_1_spectral_morph_amount + 0.5f;
  739. int index = 1;
  740. for (json& modulation : modulations) {
  741. if (modulation["destination"] == "osc_1_spectral_morph_amount") {
  742. std::string name = "modulation_" + std::to_string(index) + "_amount";
  743. float modulation_amount = settings[name];
  744. settings[name] = modulation_amount * -0.5f;
  745. }
  746. index++;
  747. }
  748. }
  749. if (osc_2_spectral_morph_type == 9.0f) {
  750. float osc_2_spectral_morph_amount = settings["osc_2_spectral_morph_amount"];
  751. settings["osc_2_spectral_morph_amount"] = -0.5f * osc_2_spectral_morph_amount + 0.5f;
  752. int index = 1;
  753. for (json& modulation : modulations) {
  754. if (modulation["destination"] == "osc_2_spectral_morph_amount") {
  755. std::string name = "modulation_" + std::to_string(index) + "_amount";
  756. float modulation_amount = settings[name];
  757. settings[name] = modulation_amount * -0.5f;
  758. }
  759. index++;
  760. }
  761. }
  762. }
  763. if (compareVersionStrings(version, "0.7.5") < 0) {
  764. static constexpr float kFlangerCenterMultiply = 48.0f / 128.0f;
  765. static constexpr float kFlangerCenterOffset = 53.69f;
  766. static constexpr float kPhaserCenterMultiply = 48.0f / 128.0f;
  767. if (settings.count("flanger_center")) {
  768. float flanger_center = settings["flanger_center"];
  769. settings["flanger_center"] = flanger_center + kFlangerCenterOffset;
  770. }
  771. int index = 1;
  772. for (json& modulation : modulations) {
  773. if (modulation["destination"] == "flanger_center") {
  774. std::string name = "modulation_" + std::to_string(index) + "_amount";
  775. float modulation_amount = settings[name];
  776. settings[name] = modulation_amount * kFlangerCenterMultiply;
  777. }
  778. if (modulation["destination"] == "phaser_center") {
  779. std::string name = "modulation_" + std::to_string(index) + "_amount";
  780. float modulation_amount = settings[name];
  781. settings[name] = modulation_amount * kPhaserCenterMultiply;
  782. }
  783. index++;
  784. }
  785. }
  786. if (compareVersionStrings(version, "0.7.6") < 0) {
  787. int filter_1_model = settings["filter_1_model"];
  788. int filter_2_model = settings["filter_2_model"];
  789. if (filter_1_model == 6) {
  790. int filter_1_style = settings["filter_1_style"];
  791. if (filter_1_style == 1)
  792. settings["filter_1_style"] = 3;
  793. }
  794. if (filter_2_model == 6) {
  795. int filter_2_style = settings["filter_2_style"];
  796. if (filter_2_style == 1)
  797. settings["filter_2_style"] = 3;
  798. }
  799. if (settings.count("filter_fx_model")) {
  800. int filter_fx_model = settings["filter_fx_model"];
  801. if (filter_fx_model == 6) {
  802. int filter_fx_style = settings["filter_fx_style"];
  803. if (filter_fx_style == 1)
  804. settings["filter_fx_style"] = 3;
  805. }
  806. }
  807. }
  808. if (compareVersionStrings(version, "0.7.6") < 0) {
  809. if (settings.count("osc_1_spectral_morph_type")) {
  810. float osc_1_spectral_morph_type = settings["osc_1_spectral_morph_type"];
  811. if (osc_1_spectral_morph_type == 10.0f)
  812. settings["osc_1_spectral_morph_type"] = 7.0f;
  813. }
  814. if (settings.count("osc_2_spectral_morph_type")) {
  815. float osc_2_spectral_morph_type = settings["osc_2_spectral_morph_type"];
  816. if (osc_2_spectral_morph_type == 10.0f)
  817. settings["osc_2_spectral_morph_type"] = 7.0f;
  818. }
  819. if (settings.count("osc_3_spectral_morph_type")) {
  820. float osc_3_spectral_morph_type = settings["osc_3_spectral_morph_type"];
  821. if (osc_3_spectral_morph_type == 10.0f)
  822. settings["osc_3_spectral_morph_type"] = 7.0f;
  823. }
  824. }
  825. if (compareVersionStrings(version, "0.8.1") < 0) {
  826. for (int i = 0; i < vital::kNumLfos; ++i) {
  827. std::string name = "lfo_" + std::to_string(i) + "_smooth_mode";
  828. settings[name] = 0.0f;
  829. }
  830. }
  831. if (compareVersionStrings(version, "0.9.0") < 0) {
  832. float filter_1_model = settings["filter_1_model"];
  833. if (filter_1_model == 4) {
  834. settings["filter_1_blend"] = 0.0f;
  835. settings["filter_1_style"] = 0.0f;
  836. int index = 1;
  837. for (json& modulation : modulations) {
  838. if (modulation["destination"] == "filter_1_blend") {
  839. std::string name = "modulation_" + std::to_string(index) + "_amount";
  840. settings[name] = 0.0f;
  841. }
  842. index++;
  843. }
  844. }
  845. float filter_2_model = settings["filter_2_model"];
  846. if (filter_2_model == 4) {
  847. settings["filter_2_blend"] = 0.0f;
  848. settings["filter_2_style"] = 0.0f;
  849. int index = 1;
  850. for (json& modulation : modulations) {
  851. if (modulation["destination"] == "filter_2_blend") {
  852. std::string name = "modulation_" + std::to_string(index) + "_amount";
  853. settings[name] = 0.0f;
  854. }
  855. index++;
  856. }
  857. }
  858. }
  859. settings["modulations"] = modulations;
  860. settings["sample"] = sample;
  861. state["settings"] = settings;
  862. return state;
  863. }
  864. bool LoadSave::jsonToState(SynthBase* synth, std::map<std::string, String>& save_info, json data) {
  865. std::string version = data["synth_version"];
  866. int compare_feature_versions = compareFeatureVersionStrings(version, ProjectInfo::versionString);
  867. if (compare_feature_versions > 0)
  868. return false;
  869. int compare_versions = compareVersionStrings(version, ProjectInfo::versionString);
  870. if (compare_versions < 0 || data["settings"].count("sub_octave"))
  871. data = updateFromOldVersion(data);
  872. json settings = data["settings"];
  873. json modulations = settings["modulations"];
  874. json sample = settings["sample"];
  875. json wavetables = settings["wavetables"];
  876. json lfos = settings["lfos"];
  877. loadControls(synth, settings);
  878. loadModulations(synth, modulations);
  879. loadSample(synth, sample);
  880. loadWavetables(synth, wavetables);
  881. loadLfos(synth, lfos);
  882. loadSaveState(save_info, data);
  883. synth->checkOversampling();
  884. return true;
  885. }
  886. String LoadSave::getAuthorFromFile(const File& file) {
  887. static constexpr int kMaxCharacters = 40;
  888. static constexpr int kMinSize = 60;
  889. FileInputStream file_stream(file);
  890. if (file_stream.getTotalLength() < kMinSize)
  891. return "";
  892. file_stream.readByte();
  893. file_stream.readByte();
  894. MemoryBlock author_memory_block;
  895. file_stream.readIntoMemoryBlock(author_memory_block, 6);
  896. char end_quote = file_stream.readByte();
  897. char colon = file_stream.readByte();
  898. char begin_quote = file_stream.readByte();
  899. if (author_memory_block.toString() != "author" || end_quote != '"' || colon != ':' || begin_quote != '"') {
  900. try {
  901. json parsed_json_state = json::parse(file.loadFileAsString().toStdString(), nullptr, false);
  902. return getAuthor(parsed_json_state);
  903. }
  904. catch (const json::exception& e) {
  905. return "";
  906. }
  907. }
  908. MemoryBlock name_memory_block;
  909. file_stream.readIntoMemoryBlock(name_memory_block, kMaxCharacters);
  910. String name = name_memory_block.toString();
  911. if (!name.contains("\""))
  912. return name.toStdString();
  913. StringArray tokens;
  914. tokens.addTokens(name, "\"", "");
  915. return tokens[0];
  916. }
  917. String LoadSave::getStyleFromFile(const File& file) {
  918. static constexpr int kMinSize = 5000;
  919. FileInputStream file_stream(file);
  920. if (file_stream.getTotalLength() < kMinSize)
  921. return "";
  922. MemoryBlock style_memory_block;
  923. file_stream.readIntoMemoryBlock(style_memory_block, kMinSize);
  924. StringArray tokens;
  925. tokens.addTokens(style_memory_block.toString(), "\"", "");
  926. bool found_style = false;
  927. for (String token : tokens) {
  928. if (found_style && token.trim() != ":")
  929. return token;
  930. if (token == "preset_style")
  931. found_style = true;
  932. }
  933. return "";
  934. }
  935. std::string LoadSave::getAuthor(json data) {
  936. if (data.count("author"))
  937. return data["author"];
  938. return "";
  939. }
  940. std::string LoadSave::getLicense(json data) {
  941. if (data.count("license"))
  942. return data["license"];
  943. return "";
  944. }
  945. File LoadSave::getConfigFile() {
  946. #if defined(JUCE_DATA_STRUCTURES_H_INCLUDED)
  947. PropertiesFile::Options config_options;
  948. config_options.applicationName = "Vial";
  949. config_options.osxLibrarySubFolder = "Application Support";
  950. config_options.filenameSuffix = "config";
  951. #ifdef LINUX
  952. config_options.folderName = "." + String(ProjectInfo::projectName).toLowerCase();
  953. #else
  954. config_options.folderName = String(ProjectInfo::projectName).toLowerCase();
  955. #endif
  956. return config_options.getDefaultFile();
  957. #else
  958. return File();
  959. #endif
  960. }
  961. void LoadSave::writeCrashLog(String crash_log) {
  962. File data_dir = getDataDirectory();
  963. if (!data_dir.exists() || !data_dir.isDirectory())
  964. return;
  965. File file = data_dir.getChildFile("crash.txt");
  966. file.replaceWithText(crash_log);
  967. }
  968. void LoadSave::writeErrorLog(String error_log) {
  969. File data_dir = getDataDirectory();
  970. if (!data_dir.exists() || !data_dir.isDirectory())
  971. return;
  972. File file = getDataDirectory().getChildFile("errors.txt");
  973. file.appendText(error_log + "\n");
  974. }
  975. File LoadSave::getFavoritesFile() {
  976. #if defined(JUCE_DATA_STRUCTURES_H_INCLUDED)
  977. PropertiesFile::Options config_options;
  978. config_options.applicationName = "Vial";
  979. config_options.osxLibrarySubFolder = "Application Support";
  980. config_options.filenameSuffix = "favorites";
  981. #ifdef LINUX
  982. config_options.folderName = "." + String(ProjectInfo::projectName).toLowerCase();
  983. #else
  984. config_options.folderName = String(ProjectInfo::projectName).toLowerCase();
  985. #endif
  986. return config_options.getDefaultFile();
  987. #else
  988. return File();
  989. #endif
  990. }
  991. File LoadSave::getDefaultSkin() {
  992. #if defined(JUCE_DATA_STRUCTURES_H_INCLUDED)
  993. PropertiesFile::Options config_options;
  994. config_options.applicationName = "Vial";
  995. config_options.osxLibrarySubFolder = "Application Support";
  996. config_options.filenameSuffix = "skin";
  997. #ifdef LINUX
  998. config_options.folderName = "." + String(ProjectInfo::projectName).toLowerCase();
  999. #else
  1000. config_options.folderName = String(ProjectInfo::projectName).toLowerCase();
  1001. #endif
  1002. return config_options.getDefaultFile();
  1003. #else
  1004. return File();
  1005. #endif
  1006. }
  1007. json LoadSave::getConfigJson() {
  1008. File config_file = getConfigFile();
  1009. if (!config_file.exists())
  1010. return json();
  1011. try {
  1012. json parsed = json::parse(config_file.loadFileAsString().toStdString(), nullptr, false);
  1013. if (parsed.is_discarded())
  1014. return json();
  1015. return parsed;
  1016. }
  1017. catch (const json::exception& e) {
  1018. return json();
  1019. }
  1020. }
  1021. json LoadSave::getFavoritesJson() {
  1022. File favorites_file = getFavoritesFile();
  1023. if (!favorites_file.exists())
  1024. return json();
  1025. try {
  1026. json parsed = json::parse(favorites_file.loadFileAsString().toStdString(), nullptr, false);
  1027. if (parsed.is_discarded())
  1028. return json();
  1029. return parsed;
  1030. }
  1031. catch (const json::exception& e) {
  1032. return json();
  1033. }
  1034. }
  1035. void LoadSave::addFavorite(const File& new_favorite) {
  1036. json favorites = getFavoritesJson();
  1037. favorites[new_favorite.getFullPathName().toStdString()] = 1;
  1038. saveJsonToFavorites(favorites);
  1039. }
  1040. void LoadSave::removeFavorite(const File& old_favorite) {
  1041. json favorites = getFavoritesJson();
  1042. std::string path = old_favorite.getFullPathName().toStdString();
  1043. if (favorites.count(path)) {
  1044. favorites.erase(path);
  1045. saveJsonToFavorites(favorites);
  1046. }
  1047. }
  1048. std::set<std::string> LoadSave::getFavorites() {
  1049. json favorites_json = getFavoritesJson();
  1050. std::set<std::string> favorites;
  1051. for (auto& pair : favorites_json.items())
  1052. favorites.insert(pair.key());
  1053. return favorites;
  1054. }
  1055. void LoadSave::saveJsonToConfig(json config_state) {
  1056. File config_file = getConfigFile();
  1057. if (!config_file.exists())
  1058. config_file.create();
  1059. config_file.replaceWithText(config_state.dump());
  1060. }
  1061. void LoadSave::saveJsonToFavorites(json favorites_json) {
  1062. File favorites_file = getFavoritesFile();
  1063. if (!favorites_file.exists())
  1064. favorites_file.create();
  1065. favorites_file.replaceWithText(favorites_json.dump());
  1066. }
  1067. void LoadSave::saveAuthor(std::string author) {
  1068. json data = getConfigJson();
  1069. data["author"] = author;
  1070. saveJsonToConfig(data);
  1071. }
  1072. void LoadSave::savePreferredTTWTLanguage(std::string language) {
  1073. json data = getConfigJson();
  1074. data["ttwt_language"] = language;
  1075. saveJsonToConfig(data);
  1076. }
  1077. void LoadSave::saveVersionConfig() {
  1078. json data = getConfigJson();
  1079. data["synth_version"] = ProjectInfo::versionString;
  1080. saveJsonToConfig(data);
  1081. }
  1082. void LoadSave::saveContentVersion(std::string version) {
  1083. json data = getConfigJson();
  1084. data["content_version"] = version;
  1085. saveJsonToConfig(data);
  1086. }
  1087. void LoadSave::saveUpdateCheckConfig(bool check_for_updates) {
  1088. json data = getConfigJson();
  1089. data["check_for_updates"] = check_for_updates;
  1090. saveJsonToConfig(data);
  1091. }
  1092. void LoadSave::saveWorkOffline(bool work_offline) {
  1093. json data = getConfigJson();
  1094. data["work_offline"] = work_offline;
  1095. saveJsonToConfig(data);
  1096. }
  1097. void LoadSave::saveLoadedSkin(const std::string& name) {
  1098. json data = getConfigJson();
  1099. data["loaded_skin"] = name;
  1100. saveJsonToConfig(data);
  1101. }
  1102. void LoadSave::saveAnimateWidgets(bool animate_widgets) {
  1103. json data = getConfigJson();
  1104. data["animate_widgets"] = animate_widgets;
  1105. saveJsonToConfig(data);
  1106. }
  1107. void LoadSave::saveDisplayHzFrequency(bool hz_frequency) {
  1108. json data = getConfigJson();
  1109. data["hz_frequency"] = hz_frequency;
  1110. saveJsonToConfig(data);
  1111. }
  1112. void LoadSave::saveAuthenticated(bool authenticated) {
  1113. json data = getConfigJson();
  1114. data["authenticated"] = authenticated;
  1115. saveJsonToConfig(data);
  1116. }
  1117. void LoadSave::saveWindowSize(float window_size) {
  1118. json data = getConfigJson();
  1119. data["window_size"] = window_size;
  1120. saveJsonToConfig(data);
  1121. }
  1122. void LoadSave::saveLayoutConfig(vital::StringLayout* layout) {
  1123. std::wstring chromatic_layout;
  1124. wchar_t up_key;
  1125. wchar_t down_key;
  1126. if (layout) {
  1127. chromatic_layout = layout->getLayout();
  1128. up_key = layout->getUpKey();
  1129. down_key = layout->getDownKey();
  1130. }
  1131. else {
  1132. chromatic_layout = getComputerKeyboardLayout();
  1133. std::pair<wchar_t, wchar_t> octave_controls = getComputerKeyboardOctaveControls();
  1134. down_key = octave_controls.first;
  1135. up_key = octave_controls.second;
  1136. }
  1137. json layout_data;
  1138. layout_data["chromatic_layout"] = chromatic_layout;
  1139. layout_data["octave_up"] = up_key;
  1140. layout_data["octave_down"] = down_key;
  1141. json data = getConfigJson();
  1142. data["keyboard_layout"] = layout_data;
  1143. saveJsonToConfig(data);
  1144. }
  1145. void LoadSave::saveMidiMapConfig(MidiManager* midi_manager) {
  1146. MidiManager::midi_map midi_learn_map = midi_manager->getMidiLearnMap();
  1147. json midi_mapping_data;
  1148. for (auto& midi_mapping : midi_learn_map) {
  1149. json midi_map_data;
  1150. midi_map_data["source"] = midi_mapping.first;
  1151. json destinations_data;
  1152. for (auto& midi_destination : midi_mapping.second) {
  1153. json destination_data;
  1154. destination_data["destination"] = midi_destination.first;
  1155. destination_data["min_range"] = midi_destination.second->min;
  1156. destination_data["max_range"] = midi_destination.second->max;
  1157. destinations_data.push_back(destination_data);
  1158. }
  1159. midi_map_data["destinations"] = destinations_data;
  1160. midi_mapping_data.push_back(midi_map_data);
  1161. }
  1162. json data = getConfigJson();
  1163. data["midi_learn"] = midi_mapping_data;
  1164. saveJsonToConfig(data);
  1165. }
  1166. void LoadSave::loadConfig(MidiManager* midi_manager, vital::StringLayout* layout) {
  1167. json data = getConfigJson();
  1168. // Computer Keyboard Layout
  1169. if (layout) {
  1170. layout->setLayout(getComputerKeyboardLayout());
  1171. std::pair<wchar_t, wchar_t> octave_controls = getComputerKeyboardOctaveControls();
  1172. layout->setDownKey(octave_controls.first);
  1173. layout->setUpKey(octave_controls.second);
  1174. }
  1175. // Midi Learn Map
  1176. if (data.count("midi_learn")) {
  1177. MidiManager::midi_map midi_learn_map = midi_manager->getMidiLearnMap();
  1178. json midi_mapping_data = data["midi_learn"];
  1179. for (json& midi_map_data : midi_mapping_data) {
  1180. int source = midi_map_data["source"];
  1181. if (midi_map_data.count("destinations")) {
  1182. json destinations_data = midi_map_data["destinations"];
  1183. for (json& midi_destination : destinations_data) {
  1184. std::string dest = midi_destination["destination"];
  1185. midi_learn_map[source][dest] = &vital::Parameters::getDetails(dest);
  1186. }
  1187. }
  1188. }
  1189. midi_manager->setMidiLearnMap(midi_learn_map);
  1190. }
  1191. }
  1192. bool LoadSave::hasDataDirectory() {
  1193. json data = getConfigJson();
  1194. if (data.count("data_directory")) {
  1195. std::string path = data["data_directory"];
  1196. File directory(path);
  1197. File packages = directory.getChildFile(kInstalledPacksFile);
  1198. return directory.exists() && directory.isDirectory() && packages.exists();
  1199. }
  1200. return false;
  1201. }
  1202. File LoadSave::getAvailablePacksFile() {
  1203. json data = getConfigJson();
  1204. if (data.count("data_directory") == 0)
  1205. return File();
  1206. std::string path = data["data_directory"];
  1207. File directory(path);
  1208. if (!directory.exists() || !directory.isDirectory())
  1209. return File();
  1210. return directory.getChildFile(kAvailablePacksFile);
  1211. }
  1212. json LoadSave::getAvailablePacks() {
  1213. File packs_file = getAvailablePacksFile();
  1214. if (!packs_file.exists())
  1215. return json();
  1216. try {
  1217. json parsed = json::parse(packs_file.loadFileAsString().toStdString(), nullptr, false);
  1218. if (parsed.is_discarded())
  1219. return json();
  1220. return parsed;
  1221. }
  1222. catch (const json::exception& e) {
  1223. return json();
  1224. }
  1225. }
  1226. File LoadSave::getInstalledPacksFile() {
  1227. json data = getConfigJson();
  1228. if (data.count("data_directory") == 0)
  1229. return File();
  1230. std::string path = data["data_directory"];
  1231. File directory(path);
  1232. if (!directory.exists() || !directory.isDirectory())
  1233. return File();
  1234. return directory.getChildFile(kInstalledPacksFile);
  1235. }
  1236. json LoadSave::getInstalledPacks() {
  1237. File packs_file = getInstalledPacksFile();
  1238. if (!packs_file.exists())
  1239. return json();
  1240. try {
  1241. json parsed = json::parse(packs_file.loadFileAsString().toStdString(), nullptr, false);
  1242. if (parsed.is_discarded())
  1243. return json();
  1244. return parsed;
  1245. }
  1246. catch (const json::exception& e) {
  1247. return json();
  1248. }
  1249. }
  1250. void LoadSave::saveInstalledPacks(const json& packs) {
  1251. File packs_file = getInstalledPacksFile();
  1252. if (!packs_file.exists())
  1253. packs_file.create();
  1254. packs_file.replaceWithText(packs.dump());
  1255. }
  1256. void LoadSave::markPackInstalled(int id) {
  1257. json packs = getInstalledPacks();
  1258. packs[std::to_string(id)] = 1;
  1259. saveInstalledPacks(packs);
  1260. }
  1261. void LoadSave::markPackInstalled(const std::string& name) {
  1262. json packs = getInstalledPacks();
  1263. std::string cleaned = String(name).removeCharacters(" ._").toLowerCase().toStdString();
  1264. packs[cleaned] = 1;
  1265. saveInstalledPacks(packs);
  1266. }
  1267. void LoadSave::saveDataDirectory(const File& data_directory) {
  1268. json data = getConfigJson();
  1269. std::string path = data_directory.getFullPathName().toStdString();
  1270. data["data_directory"] = path;
  1271. saveJsonToConfig(data);
  1272. }
  1273. bool LoadSave::isInstalled() {
  1274. return getDataDirectory().exists();
  1275. }
  1276. bool LoadSave::wasUpgraded() {
  1277. json data = getConfigJson();
  1278. if (!data.count("synth_version"))
  1279. return true;
  1280. std::string version = data["synth_version"];
  1281. return compareVersionStrings(version, ProjectInfo::versionString) < 0;
  1282. }
  1283. bool LoadSave::isExpired() {
  1284. return getDaysToExpire() < 0;
  1285. }
  1286. bool LoadSave::doesExpire() {
  1287. #ifdef EXPIRE_DAYS
  1288. return true;
  1289. #else
  1290. return false;
  1291. #endif
  1292. }
  1293. int LoadSave::getDaysToExpire() {
  1294. #ifdef EXPIRE_DAYS
  1295. Time current_time = Time::getCurrentTime();
  1296. Time build_time = getBuildTime();
  1297. RelativeTime time_since_compile = current_time - build_time;
  1298. int days_since_compile = time_since_compile.inDays();
  1299. return EXPIRE_DAYS - days_since_compile;
  1300. #else
  1301. return 0;
  1302. #endif
  1303. }
  1304. bool LoadSave::shouldCheckForUpdates() {
  1305. json data = getConfigJson();
  1306. if (!data.count("check_for_updates"))
  1307. return true;
  1308. return data["check_for_updates"];
  1309. }
  1310. bool LoadSave::shouldWorkOffline() {
  1311. json data = getConfigJson();
  1312. if (!data.count("work_offline"))
  1313. return false;
  1314. return data["work_offline"];
  1315. }
  1316. std::string LoadSave::getLoadedSkin() {
  1317. json data = getConfigJson();
  1318. if (!data.count("loaded_skin"))
  1319. return "";
  1320. return data["loaded_skin"];
  1321. }
  1322. bool LoadSave::shouldAnimateWidgets() {
  1323. json data = getConfigJson();
  1324. if (!data.count("animate_widgets"))
  1325. return true;
  1326. return data["animate_widgets"];
  1327. }
  1328. bool LoadSave::displayHzFrequency() {
  1329. json data = getConfigJson();
  1330. if (!data.count("hz_frequency"))
  1331. return false;
  1332. return data["hz_frequency"];
  1333. }
  1334. bool LoadSave::authenticated() {
  1335. json data = getConfigJson();
  1336. if (!data.count("authenticated"))
  1337. return false;
  1338. return data["authenticated"];
  1339. }
  1340. int LoadSave::getOversamplingAmount() {
  1341. json data = getConfigJson();
  1342. if (!data.count("oversampling_amount"))
  1343. return 2;
  1344. return data["oversampling_amount"];
  1345. }
  1346. float LoadSave::loadWindowSize() {
  1347. static constexpr float kMinWindowSize = 0.25f;
  1348. json data = getConfigJson();
  1349. if (!data.count("window_size"))
  1350. return 1.0f;
  1351. return std::max<float>(kMinWindowSize, data["window_size"]);
  1352. }
  1353. String LoadSave::loadVersion() {
  1354. json data = getConfigJson();
  1355. if (!data.count("synth_version"))
  1356. return "0.0.0";
  1357. std::string version = data["synth_version"];
  1358. return version;
  1359. }
  1360. String LoadSave::loadContentVersion() {
  1361. json data = getConfigJson();
  1362. if (!data.count("content_version"))
  1363. return "0.0";
  1364. std::string version = data["content_version"];
  1365. return version;
  1366. }
  1367. std::wstring LoadSave::getComputerKeyboardLayout() {
  1368. json data = getConfigJson();
  1369. if (data.count("keyboard_layout")) {
  1370. json layout = data["keyboard_layout"];
  1371. if (layout.count("chromatic_layout"))
  1372. return layout["chromatic_layout"];
  1373. }
  1374. return vital::kDefaultKeyboard;
  1375. }
  1376. std::string LoadSave::getPreferredTTWTLanguage() {
  1377. json data = getConfigJson();
  1378. if (!data.count("ttwt_language"))
  1379. return "";
  1380. std::string language = data["ttwt_language"];
  1381. return language;
  1382. }
  1383. std::string LoadSave::getAuthor() {
  1384. json data = getConfigJson();
  1385. if (data.count("author"))
  1386. return data["author"];
  1387. return "";
  1388. }
  1389. std::pair<wchar_t, wchar_t> LoadSave::getComputerKeyboardOctaveControls() {
  1390. std::pair<wchar_t, wchar_t> octave_controls(vital::kDefaultKeyboardOctaveDown, vital::kDefaultKeyboardOctaveUp);
  1391. json data = getConfigJson();
  1392. if (data.count("keyboard_layout")) {
  1393. json layout = data["keyboard_layout"];
  1394. std::wstring down = layout["octave_down"];
  1395. std::wstring up = layout["octave_up"];
  1396. octave_controls.first = down[0];
  1397. octave_controls.second = up[0];
  1398. }
  1399. return octave_controls;
  1400. }
  1401. void LoadSave::saveAdditionalFolders(const std::string& name, std::vector<std::string> folders) {
  1402. json data = getConfigJson();
  1403. json wavetable_folders;
  1404. for (std::string& folder : folders)
  1405. wavetable_folders.push_back(folder);
  1406. data[name] = wavetable_folders;
  1407. saveJsonToConfig(data);
  1408. }
  1409. std::vector<std::string> LoadSave::getAdditionalFolders(const std::string& name) {
  1410. json data = getConfigJson();
  1411. std::vector<std::string> folders;
  1412. if (data.count(name)) {
  1413. json folder_list = data[name];
  1414. for (json& folder : folder_list)
  1415. folders.push_back(folder);
  1416. }
  1417. return folders;
  1418. }
  1419. File LoadSave::getDataDirectory() {
  1420. json data = getConfigJson();
  1421. if (data.count("data_directory")) {
  1422. std::string path = data["data_directory"];
  1423. File folder(path);
  1424. if (folder.exists() && folder.isDirectory())
  1425. return folder;
  1426. }
  1427. #ifdef LINUX
  1428. File directory = File(kLinuxUserDataDirectory);
  1429. String xdg_data_home = SystemStats::getEnvironmentVariable ("XDG_DATA_HOME", {});
  1430. if (!xdg_data_home.trim().isEmpty())
  1431. directory = File(xdg_data_home).getChildFile("vial");
  1432. #elif defined(__APPLE__)
  1433. File home_directory = File::getSpecialLocation(File::userHomeDirectory);
  1434. File directory = home_directory.getChildFile("Music").getChildFile("Vial");
  1435. #else
  1436. File documents_dir = File::getSpecialLocation(File::userDocumentsDirectory);
  1437. File directory = documents_dir.getChildFile("Vial");
  1438. #endif
  1439. return directory;
  1440. }
  1441. std::vector<File> LoadSave::getDirectories(const String& folder_name) {
  1442. File data_dir = getDataDirectory();
  1443. std::vector<File> directories;
  1444. if (!data_dir.exists() || !data_dir.isDirectory())
  1445. return directories;
  1446. Array<File> sub_folders;
  1447. sub_folders.add(data_dir);
  1448. data_dir.findChildFiles(sub_folders, File::findDirectories, false);
  1449. for (const File& sub_folder : sub_folders) {
  1450. File directory = sub_folder.getChildFile(folder_name);
  1451. if (directory.exists() && directory.isDirectory())
  1452. directories.push_back(directory);
  1453. }
  1454. return directories;
  1455. }
  1456. std::vector<File> LoadSave::getPresetDirectories() {
  1457. return getDirectories(kPresetFolderName);
  1458. }
  1459. std::vector<File> LoadSave::getWavetableDirectories() {
  1460. return getDirectories(kWavetableFolderName);
  1461. }
  1462. std::vector<File> LoadSave::getSkinDirectories() {
  1463. return getDirectories(kSkinFolderName);
  1464. }
  1465. std::vector<File> LoadSave::getSampleDirectories() {
  1466. return getDirectories(kSampleFolderName);
  1467. }
  1468. std::vector<File> LoadSave::getLfoDirectories() {
  1469. return getDirectories(kLfoFolderName);
  1470. }
  1471. File LoadSave::getUserDirectory() {
  1472. File directory = getDataDirectory().getChildFile(kUserDirectoryName);
  1473. if (!directory.exists())
  1474. directory.createDirectory();
  1475. return directory;
  1476. }
  1477. File LoadSave::getUserPresetDirectory() {
  1478. File directory = getUserDirectory().getChildFile(kPresetFolderName);
  1479. if (!directory.exists())
  1480. directory.createDirectory();
  1481. return directory;
  1482. }
  1483. File LoadSave::getUserWavetableDirectory() {
  1484. File directory = getUserDirectory().getChildFile(kWavetableFolderName);
  1485. if (!directory.exists())
  1486. directory.createDirectory();
  1487. return directory;
  1488. }
  1489. File LoadSave::getUserSkinDirectory() {
  1490. File directory = getUserDirectory().getChildFile(kSkinFolderName);
  1491. if (!directory.exists())
  1492. directory.createDirectory();
  1493. return directory;
  1494. }
  1495. File LoadSave::getUserSampleDirectory() {
  1496. File directory = getUserDirectory().getChildFile(kSampleFolderName);
  1497. if (!directory.exists())
  1498. directory.createDirectory();
  1499. return directory;
  1500. }
  1501. File LoadSave::getUserLfoDirectory() {
  1502. File directory = getUserDirectory().getChildFile(kLfoFolderName);
  1503. if (!directory.exists())
  1504. directory.createDirectory();
  1505. return directory;
  1506. }
  1507. void LoadSave::getAllFilesOfTypeInDirectories(Array<File>& files, const String& extensions,
  1508. const std::vector<File>& directories) {
  1509. files.clear();
  1510. for (const File& directory : directories) {
  1511. if (directory.exists() && directory.isDirectory())
  1512. directory.findChildFiles(files, File::findFiles, true, extensions);
  1513. }
  1514. }
  1515. void LoadSave::getAllPresets(Array<File>& presets) {
  1516. getAllFilesOfTypeInDirectories(presets, String("*.") + vital::kPresetExtension, getPresetDirectories());
  1517. }
  1518. void LoadSave::getAllWavetables(Array<File>& wavetables) {
  1519. getAllFilesOfTypeInDirectories(wavetables, vital::kWavetableExtensionsList, getWavetableDirectories());
  1520. }
  1521. void LoadSave::getAllSkins(Array<File>& skins) {
  1522. getAllFilesOfTypeInDirectories(skins, String("*.") + vital::kSkinExtension, getSkinDirectories());
  1523. }
  1524. void LoadSave::getAllLfos(Array<File>& lfos) {
  1525. getAllFilesOfTypeInDirectories(lfos, String("*.") + vital::kLfoExtension, getLfoDirectories());
  1526. }
  1527. void LoadSave::getAllSamples(Array<File>& samples) {
  1528. getAllFilesOfTypeInDirectories(samples, "*.wav", getSampleDirectories());
  1529. }
  1530. void LoadSave::getAllUserPresets(Array<File>& presets) {
  1531. std::vector<File> directories = {
  1532. getDataDirectory().getChildFile(kPresetFolderName),
  1533. getUserPresetDirectory()
  1534. };
  1535. getAllFilesOfTypeInDirectories(presets, String("*.") + vital::kPresetExtension, directories);
  1536. }
  1537. void LoadSave::getAllUserWavetables(Array<File>& wavetables) {
  1538. std::vector<File> directories = {
  1539. getDataDirectory().getChildFile(kWavetableFolderName),
  1540. getUserWavetableDirectory()
  1541. };
  1542. getAllFilesOfTypeInDirectories(wavetables, vital::kWavetableExtensionsList, directories);
  1543. }
  1544. void LoadSave::getAllUserLfos(Array<File>& lfos) {
  1545. std::vector<File> directories = {
  1546. getDataDirectory().getChildFile(kLfoFolderName),
  1547. getUserLfoDirectory()
  1548. };
  1549. getAllFilesOfTypeInDirectories(lfos, String("*.") + vital::kLfoExtension, directories);
  1550. }
  1551. void LoadSave::getAllUserSamples(Array<File>& samples) {
  1552. std::vector<File> directories = {
  1553. getDataDirectory().getChildFile(kSampleFolderName),
  1554. getUserSampleDirectory()
  1555. };
  1556. getAllFilesOfTypeInDirectories(samples, "*.wav", directories);
  1557. }
  1558. int LoadSave::compareFeatureVersionStrings(String a, String b) {
  1559. a.trim();
  1560. b.trim();
  1561. return compareVersionStrings(a.upToLastOccurrenceOf(".", false, true),
  1562. b.upToLastOccurrenceOf(".", false, true));
  1563. }
  1564. int LoadSave::compareVersionStrings(String a, String b) {
  1565. a.trim();
  1566. b.trim();
  1567. if (a.isEmpty() && b.isEmpty())
  1568. return 0;
  1569. String major_version_a = a.upToFirstOccurrenceOf(".", false, true);
  1570. String major_version_b = b.upToFirstOccurrenceOf(".", false, true);
  1571. if (!major_version_a.containsOnly("0123456789"))
  1572. major_version_a = "0";
  1573. if (!major_version_b.containsOnly("0123456789"))
  1574. major_version_b = "0";
  1575. int major_value_a = major_version_a.getIntValue();
  1576. int major_value_b = major_version_b.getIntValue();
  1577. if (major_value_a > major_value_b)
  1578. return 1;
  1579. else if (major_value_a < major_value_b)
  1580. return -1;
  1581. return compareVersionStrings(a.fromFirstOccurrenceOf(".", false, true),
  1582. b.fromFirstOccurrenceOf(".", false, true));
  1583. }
  1584. File LoadSave::getShiftedFile(const String directory_name, const String& extensions,
  1585. const std::string& additional_folders_name, const File& current_file, int shift) {
  1586. FileSorterAscending file_sorter;
  1587. std::vector<File> directories = getDirectories(directory_name);
  1588. std::vector<std::string> additional = getAdditionalFolders(additional_folders_name);
  1589. for (const std::string& path : additional)
  1590. directories.push_back(File(path));
  1591. Array<File> all_files;
  1592. getAllFilesOfTypeInDirectories(all_files, extensions, directories);
  1593. if (all_files.isEmpty())
  1594. return File();
  1595. all_files.sort(file_sorter);
  1596. int index = all_files.indexOf(current_file);
  1597. if (index < 0)
  1598. return all_files[0];
  1599. return all_files[(index + shift + all_files.size()) % all_files.size()];
  1600. }