TrackerSettings.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977
  1. /*
  2. * TrackerSettings.h
  3. * -----------------
  4. * Purpose: Header file for application setting handling.
  5. * Notes : (currently none)
  6. * Authors: Olivier Lapicque
  7. * OpenMPT Devs
  8. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  9. */
  10. #pragma once
  11. #include "openmpt/all/BuildSettings.hpp"
  12. #include "mpt/uuid/uuid.hpp"
  13. #include "../common/Logging.h"
  14. #include "../common/version.h"
  15. #include "openmpt/soundbase/SampleFormat.hpp"
  16. #include "../soundlib/MixerSettings.h"
  17. #include "../soundlib/Resampler.h"
  18. #include "../sounddsp/EQ.h"
  19. #include "../sounddsp/DSP.h"
  20. #include "../sounddsp/Reverb.h"
  21. #include "openmpt/sounddevice/SoundDevice.hpp"
  22. #include "StreamEncoderSettings.h"
  23. #include "Settings.h"
  24. #include <array>
  25. #include <bitset>
  26. OPENMPT_NAMESPACE_BEGIN
  27. namespace SoundDevice {
  28. class Manager;
  29. } // namespace SoundDevice
  30. namespace Tuning {
  31. class CTuningCollection;
  32. } // namespace Tuning
  33. using CTuningCollection = Tuning::CTuningCollection;
  34. // User-defined colors
  35. enum ModColor : uint8
  36. {
  37. MODCOLOR_BACKNORMAL = 0,
  38. MODCOLOR_TEXTNORMAL,
  39. MODCOLOR_BACKCURROW,
  40. MODCOLOR_TEXTCURROW,
  41. MODCOLOR_BACKSELECTED,
  42. MODCOLOR_TEXTSELECTED,
  43. MODCOLOR_SAMPLE,
  44. MODCOLOR_BACKPLAYCURSOR,
  45. MODCOLOR_TEXTPLAYCURSOR,
  46. MODCOLOR_BACKHILIGHT,
  47. MODCOLOR_NOTE,
  48. MODCOLOR_INSTRUMENT,
  49. MODCOLOR_VOLUME,
  50. MODCOLOR_PANNING,
  51. MODCOLOR_PITCH,
  52. MODCOLOR_GLOBALS,
  53. MODCOLOR_ENVELOPES,
  54. MODCOLOR_VUMETER_LO,
  55. MODCOLOR_VUMETER_MED,
  56. MODCOLOR_VUMETER_HI,
  57. MODCOLOR_SEPSHADOW,
  58. MODCOLOR_SEPFACE,
  59. MODCOLOR_SEPHILITE,
  60. MODCOLOR_BLENDCOLOR,
  61. MODCOLOR_DODGY_COMMANDS,
  62. MODCOLOR_BACKSAMPLE,
  63. MODCOLOR_SAMPLESELECTED,
  64. MODCOLOR_BACKENV,
  65. MODCOLOR_VUMETER_LO_VST,
  66. MODCOLOR_VUMETER_MED_VST,
  67. MODCOLOR_VUMETER_HI_VST,
  68. MODCOLOR_ENVELOPE_RELEASE,
  69. MODCOLOR_SAMPLE_LOOPMARKER,
  70. MODCOLOR_SAMPLE_SUSTAINMARKER,
  71. MODCOLOR_SAMPLE_CUEPOINT,
  72. MAX_MODCOLORS,
  73. // Internal color codes (not saved to color preset files)
  74. MODCOLOR_2NDHIGHLIGHT,
  75. MODCOLOR_DEFAULTVOLUME,
  76. MODCOLOR_DUMMYCOMMAND,
  77. MAX_MODPALETTECOLORS
  78. };
  79. // Pattern Setup (contains also non-pattern related settings)
  80. // Feel free to replace the deprecated flags by new flags, but be sure to
  81. // update TrackerSettings::TrackerSettings() as well.
  82. #define PATTERN_PLAYNEWNOTE 0x01 // play new notes while recording
  83. #define PATTERN_SMOOTHSCROLL 0x02 // scroll tick by tick, not row by row
  84. #define PATTERN_STDHIGHLIGHT 0x04 // enable primary highlight (measures)
  85. #define PATTERN_NOFOLLOWONCLICK 0x08 // disable song follow when clicking into pattern
  86. #define PATTERN_CENTERROW 0x10 // always center active row
  87. #define PATTERN_WRAP 0x20 // wrap around cursor in editor
  88. #define PATTERN_EFFECTHILIGHT 0x40 // effect syntax highlighting
  89. #define PATTERN_HEXDISPLAY 0x80 // display row number in hex
  90. #define PATTERN_FLATBUTTONS 0x100 // flat toolbar buttons
  91. #define PATTERN_PLAYNAVIGATEROW 0x200 // play whole row when navigating
  92. #define PATTERN_SINGLEEXPAND 0x400 // single click to expand tree
  93. #define PATTERN_PLAYEDITROW 0x800 // play all notes on the current row while entering notes
  94. #define PATTERN_NOEXTRALOUD 0x1000 // no loud samples in sample editor
  95. #define PATTERN_DRAGNDROPEDIT 0x2000 // enable drag and drop editing
  96. #define PATTERN_2NDHIGHLIGHT 0x4000 // activate secondary highlight (beats)
  97. #define PATTERN_MUTECHNMODE 0x8000 // ignore muted channels
  98. #define PATTERN_SHOWPREVIOUS 0x10000 // show prev/next patterns
  99. #define PATTERN_CONTSCROLL 0x20000 // continous pattern scrolling
  100. #define PATTERN_KBDNOTEOFF 0x40000 // Record note-off events
  101. #define PATTERN_FOLLOWSONGOFF 0x80000 // follow song off by default
  102. #define PATTERN_PLAYTRANSPOSE 0x100000 // Preview note transposition
  103. #define PATTERN_NOCLOSEDIALOG 0x200000 // Don't use OpenMPT's custom close dialog with a list of saved files when closing the main window
  104. #define PATTERN_DBLCLICKSELECT 0x400000 // Double-clicking pattern selects whole channel
  105. #define PATTERN_OLDCTXMENUSTYLE 0x800000 // Hide pattern context menu entries instead of greying them out.
  106. #define PATTERN_SYNCMUTE 0x1000000 // maintain sample sync on mute
  107. #define PATTERN_AUTODELAY 0x2000000 // automatically insert delay commands in pattern when entering notes
  108. #define PATTERN_NOTEFADE 0x4000000 // alt. note fade behaviour when entering notes
  109. #define PATTERN_OVERFLOWPASTE 0x8000000 // continue paste in the next pattern instead of cutting off
  110. #define PATTERN_SHOWDEFAULTVOLUME 0x10000000 // if there is no volume command next to note+instr, display the sample's default volume.
  111. #define PATTERN_RESETCHANNELS 0x20000000 // reset channels when looping
  112. #define PATTERN_LIVEUPDATETREE 0x40000000 // update active sample / instr icons in treeview
  113. #define PATTERN_SYNCSAMPLEPOS 0x80000000 // sync sample positions when seeking
  114. #define PATTERNFONT_SMALL UL_("@1")
  115. #define PATTERNFONT_LARGE UL_("@2")
  116. // MIDI Setup
  117. #define MIDISETUP_RECORDVELOCITY 0x01 // Record MIDI velocity
  118. #define MIDISETUP_TRANSPOSEKEYBOARD 0x02 // Apply transpose value to MIDI Notes
  119. #define MIDISETUP_MIDITOPLUG 0x04 // Pass MIDI messages to plugins
  120. #define MIDISETUP_MIDIVOL_TO_NOTEVOL 0x08 // Combine MIDI volume to note velocity
  121. #define MIDISETUP_RECORDNOTEOFF 0x10 // Record MIDI Note Off to pattern
  122. #define MIDISETUP_RESPONDTOPLAYCONTROLMSGS 0x20 // Respond to Restart/Continue/Stop MIDI commands
  123. #define MIDISETUP_MIDIMACROCONTROL 0x80 // Record MIDI controller changes a MIDI macro changes in pattern
  124. #define MIDISETUP_PLAYPATTERNONMIDIIN 0x100 // Play pattern if MIDI Note is received and playback is paused
  125. #define MIDISETUP_ENABLE_RECORD_DEFAULT 0x200 // Enable MIDI recording by default
  126. #define MIDISETUP_MIDIMACROPITCHBEND 0x400 // Record MIDI pitch bend messages a MIDI macro changes in pattern
  127. #ifndef NO_EQ
  128. // EQ
  129. struct EQPresetPacked
  130. {
  131. char szName[12]; // locale encoding
  132. uint32le Gains[MAX_EQ_BANDS];
  133. uint32le Freqs[MAX_EQ_BANDS];
  134. };
  135. MPT_BINARY_STRUCT(EQPresetPacked, 60)
  136. struct EQPreset
  137. {
  138. char szName[12]; // locale encoding
  139. uint32 Gains[MAX_EQ_BANDS];
  140. uint32 Freqs[MAX_EQ_BANDS];
  141. };
  142. template<> inline SettingValue ToSettingValue(const EQPreset &val)
  143. {
  144. EQPresetPacked valpacked;
  145. std::memcpy(valpacked.szName, val.szName, std::size(valpacked.szName));
  146. std::copy(val.Gains, val.Gains + MAX_EQ_BANDS, valpacked.Gains);
  147. std::copy(val.Freqs, val.Freqs + MAX_EQ_BANDS, valpacked.Freqs);
  148. return SettingValue(EncodeBinarySetting<EQPresetPacked>(valpacked), "EQPreset");
  149. }
  150. template<> inline EQPreset FromSettingValue(const SettingValue &val)
  151. {
  152. ASSERT(val.GetTypeTag() == "EQPreset");
  153. EQPresetPacked valpacked = DecodeBinarySetting<EQPresetPacked>(val.as<std::vector<std::byte> >());
  154. EQPreset valresult;
  155. std::memcpy(valresult.szName, valpacked.szName, std::size(valresult.szName));
  156. std::copy(valpacked.Gains, valpacked.Gains + MAX_EQ_BANDS, valresult.Gains);
  157. std::copy(valpacked.Freqs, valpacked.Freqs + MAX_EQ_BANDS, valresult.Freqs);
  158. return valresult;
  159. }
  160. #endif // !NO_EQ
  161. template<> inline SettingValue ToSettingValue(const mpt::UUID &val) { return SettingValue(val.ToUString()); }
  162. template<> inline mpt::UUID FromSettingValue(const SettingValue &val) { return mpt::UUID::FromString(val.as<mpt::ustring>()); }
  163. // Chords
  164. struct MPTChord
  165. {
  166. enum
  167. {
  168. notesPerChord = 4,
  169. relativeMode = 0x3F,
  170. noNote = int8_min,
  171. };
  172. using NoteType = int8;
  173. uint8 key; // Base note
  174. std::array<NoteType, notesPerChord - 1> notes; // Additional chord notes
  175. };
  176. using MPTChords = std::array<MPTChord, 3 * 12>; // 3 octaves
  177. // MIDI recording
  178. enum RecordAftertouchOptions
  179. {
  180. atDoNotRecord = 0,
  181. atRecordAsVolume,
  182. atRecordAsMacro,
  183. };
  184. // New file action
  185. enum NewFileAction
  186. {
  187. nfDefaultFormat = 0,
  188. nfSameAsCurrent,
  189. nfDefaultTemplate
  190. };
  191. // Sample editor preview behaviour
  192. enum SampleEditorKeyBehaviour
  193. {
  194. seNoteOffOnNewKey = 0,
  195. seNoteOffOnKeyUp,
  196. seNoteOffOnKeyRestrike,
  197. };
  198. enum SampleEditorDefaultFormat
  199. {
  200. dfFLAC,
  201. dfWAV,
  202. dfRAW,
  203. dfS3I,
  204. };
  205. enum class TimelineFormat
  206. {
  207. Seconds = 0,
  208. Samples,
  209. SamplesPow2,
  210. };
  211. enum class DefaultChannelColors
  212. {
  213. NoColors = 0,
  214. Rainbow,
  215. Random,
  216. };
  217. class SampleUndoBufferSize
  218. {
  219. protected:
  220. size_t sizeByte;
  221. int32 sizePercent;
  222. void CalculateSize();
  223. public:
  224. enum
  225. {
  226. defaultSize = 10, // In percent
  227. };
  228. SampleUndoBufferSize(int32 percent = defaultSize) : sizePercent(percent) { CalculateSize(); }
  229. void Set(int32 percent) { sizePercent = percent; CalculateSize(); }
  230. int32 GetSizeInPercent() const { return sizePercent; }
  231. size_t GetSizeInBytes() const { return sizeByte; }
  232. };
  233. template<> inline SettingValue ToSettingValue(const SampleUndoBufferSize &val) { return SettingValue(val.GetSizeInPercent()); }
  234. template<> inline SampleUndoBufferSize FromSettingValue(const SettingValue &val) { return SampleUndoBufferSize(val.as<int32>()); }
  235. mpt::ustring IgnoredCCsToString(const std::bitset<128> &midiIgnoreCCs);
  236. std::bitset<128> StringToIgnoredCCs(const mpt::ustring &in);
  237. mpt::ustring SettingsModTypeToString(MODTYPE modtype);
  238. MODTYPE SettingsStringToModType(const mpt::ustring &str);
  239. template<> inline SettingValue ToSettingValue(const RecordAftertouchOptions &val) { return SettingValue(int32(val)); }
  240. template<> inline RecordAftertouchOptions FromSettingValue(const SettingValue &val) { return RecordAftertouchOptions(val.as<int32>()); }
  241. template<> inline SettingValue ToSettingValue(const SampleEditorKeyBehaviour &val) { return SettingValue(int32(val)); }
  242. template<> inline SampleEditorKeyBehaviour FromSettingValue(const SettingValue &val) { return SampleEditorKeyBehaviour(val.as<int32>()); }
  243. template<> inline SettingValue ToSettingValue(const TimelineFormat &val) { return SettingValue(int32(val)); }
  244. template<> inline TimelineFormat FromSettingValue(const SettingValue &val) { return TimelineFormat(val.as<int32>()); }
  245. template<> inline SettingValue ToSettingValue(const DefaultChannelColors & val) { return SettingValue(int32(val)); }
  246. template<> inline DefaultChannelColors FromSettingValue(const SettingValue& val) { return DefaultChannelColors(val.as<int32>()); }
  247. template<> inline SettingValue ToSettingValue(const MODTYPE &val) { return SettingValue(SettingsModTypeToString(val), "MODTYPE"); }
  248. template<> inline MODTYPE FromSettingValue(const SettingValue &val) { ASSERT(val.GetTypeTag() == "MODTYPE"); return SettingsStringToModType(val.as<mpt::ustring>()); }
  249. template<> inline SettingValue ToSettingValue(const PlugVolumeHandling &val)
  250. {
  251. return SettingValue(int32(val), "PlugVolumeHandling");
  252. }
  253. template<> inline PlugVolumeHandling FromSettingValue(const SettingValue &val)
  254. {
  255. ASSERT(val.GetTypeTag() == "PlugVolumeHandling");
  256. if((uint32)val.as<int32>() > PLUGIN_VOLUMEHANDLING_MAX)
  257. {
  258. return PLUGIN_VOLUMEHANDLING_IGNORE;
  259. }
  260. return static_cast<PlugVolumeHandling>(val.as<int32>());
  261. }
  262. template<> inline SettingValue ToSettingValue(const std::vector<uint32> &val) { return mpt::String::Combine(val, U_(",")); }
  263. template<> inline std::vector<uint32> FromSettingValue(const SettingValue &val) { return mpt::String::Split<uint32>(val, U_(",")); }
  264. template<> inline SettingValue ToSettingValue(const std::vector<mpt::ustring> &val) { return mpt::String::Combine(val, U_(";")); }
  265. template<> inline std::vector<mpt::ustring> FromSettingValue(const SettingValue &val) { return mpt::String::Split<mpt::ustring>(val, U_(";")); }
  266. template<> inline SettingValue ToSettingValue(const SampleFormat &val) { return SettingValue(val.AsInt()); }
  267. template<> inline SampleFormat FromSettingValue(const SettingValue &val) { return SampleFormat::FromInt(val.as<int32>()); }
  268. template<> inline SettingValue ToSettingValue(const SoundDevice::ChannelMapping &val) { return SettingValue(val.ToUString(), "ChannelMapping"); }
  269. template<> inline SoundDevice::ChannelMapping FromSettingValue(const SettingValue &val) { ASSERT(val.GetTypeTag() == "ChannelMapping"); return SoundDevice::ChannelMapping::FromString(val.as<mpt::ustring>()); }
  270. template<> inline SettingValue ToSettingValue(const ResamplingMode &val) { return SettingValue(int32(val)); }
  271. template<> inline ResamplingMode FromSettingValue(const SettingValue &val) { return ResamplingMode(val.as<int32>()); }
  272. template<> inline SettingValue ToSettingValue(const Resampling::AmigaFilter &val) { return SettingValue(int32(val)); }
  273. template<> inline Resampling::AmigaFilter FromSettingValue(const SettingValue &val) { return static_cast<Resampling::AmigaFilter>(val.as<int32>()); }
  274. template<> inline SettingValue ToSettingValue(const NewFileAction &val) { return SettingValue(int32(val)); }
  275. template<> inline NewFileAction FromSettingValue(const SettingValue &val) { return NewFileAction(val.as<int32>()); }
  276. template<> inline SettingValue ToSettingValue(const std::bitset<128> &val)
  277. {
  278. return SettingValue(IgnoredCCsToString(val), "IgnoredCCs");
  279. }
  280. template<> inline std::bitset<128> FromSettingValue(const SettingValue &val)
  281. {
  282. ASSERT(val.GetTypeTag() == "IgnoredCCs");
  283. return StringToIgnoredCCs(val.as<mpt::ustring>());
  284. }
  285. template<> inline SettingValue ToSettingValue(const SampleEditorDefaultFormat &val)
  286. {
  287. mpt::ustring format;
  288. switch(val)
  289. {
  290. case dfWAV:
  291. format = U_("wav");
  292. break;
  293. case dfFLAC:
  294. default:
  295. format = U_("flac");
  296. break;
  297. case dfRAW:
  298. format = U_("raw");
  299. break;
  300. case dfS3I:
  301. format = U_("s3i");
  302. break;
  303. }
  304. return SettingValue(format);
  305. }
  306. template<> inline SampleEditorDefaultFormat FromSettingValue(const SettingValue &val)
  307. {
  308. mpt::ustring format = mpt::ToLowerCase(val.as<mpt::ustring>());
  309. if(format == U_("wav"))
  310. return dfWAV;
  311. if(format == U_("raw"))
  312. return dfRAW;
  313. if(format == U_("s3i"))
  314. return dfS3I;
  315. else // if(format == U_("flac"))
  316. return dfFLAC;
  317. }
  318. enum SoundDeviceStopMode
  319. {
  320. SoundDeviceStopModeClosed = 0,
  321. SoundDeviceStopModeStopped = 1,
  322. SoundDeviceStopModePlaying = 2,
  323. };
  324. template<> inline SettingValue ToSettingValue(const SoundDeviceStopMode &val)
  325. {
  326. return SettingValue(static_cast<int32>(val));
  327. }
  328. template<> inline SoundDeviceStopMode FromSettingValue(const SettingValue &val)
  329. {
  330. return static_cast<SoundDeviceStopMode>(static_cast<int32>(val));
  331. }
  332. enum ProcessPriorityClass
  333. {
  334. ProcessPriorityClassIDLE = IDLE_PRIORITY_CLASS,
  335. ProcessPriorityClassBELOW = BELOW_NORMAL_PRIORITY_CLASS,
  336. ProcessPriorityClassNORMAL = NORMAL_PRIORITY_CLASS,
  337. ProcessPriorityClassABOVE = ABOVE_NORMAL_PRIORITY_CLASS,
  338. ProcessPriorityClassHIGH = HIGH_PRIORITY_CLASS,
  339. ProcessPriorityClassREALTIME = REALTIME_PRIORITY_CLASS
  340. };
  341. template<> inline SettingValue ToSettingValue(const ProcessPriorityClass &val)
  342. {
  343. mpt::ustring s;
  344. switch(val)
  345. {
  346. case ProcessPriorityClassIDLE:
  347. s = U_("idle");
  348. break;
  349. case ProcessPriorityClassBELOW:
  350. s = U_("below");
  351. break;
  352. case ProcessPriorityClassNORMAL:
  353. s = U_("normal");
  354. break;
  355. case ProcessPriorityClassABOVE:
  356. s = U_("above");
  357. break;
  358. case ProcessPriorityClassHIGH:
  359. s = U_("high");
  360. break;
  361. case ProcessPriorityClassREALTIME:
  362. s = U_("realtime");
  363. break;
  364. default:
  365. s = U_("normal");
  366. break;
  367. }
  368. return SettingValue(s);
  369. }
  370. template<> inline ProcessPriorityClass FromSettingValue(const SettingValue &val)
  371. {
  372. ProcessPriorityClass result = ProcessPriorityClassNORMAL;
  373. mpt::ustring s = val.as<mpt::ustring>();
  374. if(s.empty())
  375. {
  376. result = ProcessPriorityClassNORMAL;
  377. } else if(s == U_("idle"))
  378. {
  379. result = ProcessPriorityClassIDLE;
  380. } else if(s == U_("below"))
  381. {
  382. result = ProcessPriorityClassBELOW;
  383. } else if(s == U_("normal"))
  384. {
  385. result = ProcessPriorityClassNORMAL;
  386. } else if(s == U_("above"))
  387. {
  388. result = ProcessPriorityClassABOVE;
  389. } else if(s == U_("high"))
  390. {
  391. result = ProcessPriorityClassHIGH;
  392. } else if(s == U_("realtime"))
  393. {
  394. result = ProcessPriorityClassREALTIME;
  395. } else
  396. {
  397. result = ProcessPriorityClassNORMAL;
  398. }
  399. return result;
  400. }
  401. template<> inline SettingValue ToSettingValue(const mpt::Date::Unix &val)
  402. {
  403. time_t t = val;
  404. const tm* lastUpdate = gmtime(&t);
  405. CString outDate;
  406. if(lastUpdate)
  407. {
  408. outDate.Format(_T("%04d-%02d-%02d %02d:%02d"), lastUpdate->tm_year + 1900, lastUpdate->tm_mon + 1, lastUpdate->tm_mday, lastUpdate->tm_hour, lastUpdate->tm_min);
  409. }
  410. return SettingValue(mpt::ToUnicode(outDate), "UTC");
  411. }
  412. template<> inline mpt::Date::Unix FromSettingValue(const SettingValue &val)
  413. {
  414. MPT_ASSERT(val.GetTypeTag() == "UTC");
  415. std::string s = mpt::ToCharset(mpt::Charset::Locale, val.as<mpt::ustring>());
  416. tm lastUpdate;
  417. MemsetZero(lastUpdate);
  418. if(sscanf(s.c_str(), "%04d-%02d-%02d %02d:%02d", &lastUpdate.tm_year, &lastUpdate.tm_mon, &lastUpdate.tm_mday, &lastUpdate.tm_hour, &lastUpdate.tm_min) == 5)
  419. {
  420. lastUpdate.tm_year -= 1900;
  421. lastUpdate.tm_mon--;
  422. }
  423. time_t outTime = mpt::Date::Unix::FromUTC(lastUpdate);
  424. if(outTime < 0)
  425. {
  426. outTime = 0;
  427. }
  428. return mpt::Date::Unix(outTime);
  429. }
  430. struct FontSetting
  431. {
  432. enum FontFlags
  433. {
  434. None = 0,
  435. Bold = 1,
  436. Italic = 2,
  437. };
  438. mpt::ustring name;
  439. int32 size;
  440. FlagSet<FontFlags> flags;
  441. FontSetting(const mpt::ustring &name = U_(""), int32 size = 120, FontFlags flags = None) : name(name), size(size), flags(flags) { }
  442. bool operator== (const FontSetting &other) const
  443. {
  444. return name == other.name && size == other.size && flags == other.flags;
  445. }
  446. bool operator!= (const FontSetting &other) const
  447. {
  448. return !(*this == other);
  449. }
  450. };
  451. MPT_DECLARE_ENUM(FontSetting::FontFlags)
  452. template<> inline SettingValue ToSettingValue(const FontSetting &val)
  453. {
  454. return SettingValue(mpt::ToUnicode(val.name) + U_(",") + mpt::ufmt::val(val.size) + U_("|") + mpt::ufmt::val(val.flags.GetRaw()));
  455. }
  456. template<> inline FontSetting FromSettingValue(const SettingValue &val)
  457. {
  458. FontSetting setting(val.as<mpt::ustring>());
  459. std::size_t sizeStart = setting.name.rfind(UC_(','));
  460. if(sizeStart != std::string::npos)
  461. {
  462. const std::vector<mpt::ustring> fields = mpt::String::Split<mpt::ustring>(setting.name.substr(sizeStart + 1), U_("|"));
  463. if(fields.size() >= 1)
  464. {
  465. setting.size = ConvertStrTo<int32>(fields[0]);
  466. }
  467. if(fields.size() >= 2)
  468. {
  469. setting.flags = static_cast<FontSetting::FontFlags>(ConvertStrTo<int32>(fields[1]));
  470. }
  471. setting.name.resize(sizeStart);
  472. }
  473. return setting;
  474. }
  475. class DefaultAndWorkingDirectory
  476. {
  477. protected:
  478. mpt::PathString m_Default;
  479. mpt::PathString m_Working;
  480. public:
  481. DefaultAndWorkingDirectory();
  482. DefaultAndWorkingDirectory(const mpt::PathString &def);
  483. ~DefaultAndWorkingDirectory();
  484. public:
  485. void SetDefaultDir(const mpt::PathString &filenameFrom, bool stripFilename = false);
  486. void SetWorkingDir(const mpt::PathString &filenameFrom, bool stripFilename = false);
  487. mpt::PathString GetDefaultDir() const;
  488. mpt::PathString GetWorkingDir() const;
  489. private:
  490. bool InternalSet(mpt::PathString &dest, const mpt::PathString &filenameFrom, bool stripFilename);
  491. };
  492. class ConfigurableDirectory
  493. : public DefaultAndWorkingDirectory
  494. {
  495. protected:
  496. SettingsContainer &conf;
  497. Setting<mpt::PathString> m_Setting;
  498. public:
  499. ConfigurableDirectory(SettingsContainer &conf, const AnyStringLocale &section, const AnyStringLocale &key, const mpt::PathString &def);
  500. ~ConfigurableDirectory();
  501. };
  502. class DebugSettings
  503. {
  504. private:
  505. SettingsContainer &conf;
  506. private:
  507. // Debug
  508. #if !defined(MPT_LOG_IS_DISABLED)
  509. Setting<int> DebugLogLevel;
  510. Setting<std::string> DebugLogFacilitySolo;
  511. Setting<std::string> DebugLogFacilityBlocked;
  512. Setting<bool> DebugLogFileEnable;
  513. Setting<bool> DebugLogDebuggerEnable;
  514. Setting<bool> DebugLogConsoleEnable;
  515. #endif
  516. Setting<bool> DebugTraceEnable;
  517. Setting<uint32> DebugTraceSize;
  518. Setting<bool> DebugTraceAlwaysDump;
  519. Setting<bool> DebugStopSoundDeviceOnCrash;
  520. Setting<bool> DebugStopSoundDeviceBeforeDump;
  521. Setting<bool> DebugDelegateToWindowsHandler;
  522. public:
  523. DebugSettings(SettingsContainer &conf);
  524. ~DebugSettings();
  525. };
  526. namespace SoundDevice
  527. {
  528. namespace Legacy
  529. {
  530. typedef uint16 ID;
  531. inline constexpr SoundDevice::Legacy::ID MaskType = 0xff00;
  532. inline constexpr SoundDevice::Legacy::ID MaskIndex = 0x00ff;
  533. inline constexpr int ShiftType = 8;
  534. inline constexpr int ShiftIndex = 0;
  535. inline constexpr SoundDevice::Legacy::ID TypeWAVEOUT = 0;
  536. inline constexpr SoundDevice::Legacy::ID TypeDSOUND = 1;
  537. inline constexpr SoundDevice::Legacy::ID TypeASIO = 2;
  538. inline constexpr SoundDevice::Legacy::ID TypePORTAUDIO_WASAPI = 3;
  539. inline constexpr SoundDevice::Legacy::ID TypePORTAUDIO_WDMKS = 4;
  540. inline constexpr SoundDevice::Legacy::ID TypePORTAUDIO_WMME = 5;
  541. inline constexpr SoundDevice::Legacy::ID TypePORTAUDIO_DS = 6;
  542. } // namespace Legacy
  543. } // namespace SoundDevice
  544. class TrackerSettings
  545. {
  546. private:
  547. SettingsContainer &conf;
  548. public:
  549. // Version
  550. Setting<mpt::ustring> IniVersion;
  551. const bool FirstRun;
  552. const Version PreviousSettingsVersion;
  553. Setting<mpt::UUID> VersionInstallGUID;
  554. // Display
  555. Setting<bool> m_ShowSplashScreen;
  556. Setting<bool> gbMdiMaximize;
  557. Setting<bool> highResUI;
  558. Setting<LONG> glTreeSplitRatio;
  559. Setting<LONG> glTreeWindowWidth;
  560. Setting<LONG> glGeneralWindowHeight;
  561. Setting<LONG> glPatternWindowHeight;
  562. Setting<LONG> glSampleWindowHeight;
  563. Setting<LONG> glInstrumentWindowHeight;
  564. Setting<LONG> glCommentsWindowHeight;
  565. Setting<LONG> glGraphWindowHeight;
  566. Setting<int32> gnPlugWindowX;
  567. Setting<int32> gnPlugWindowY;
  568. Setting<int32> gnPlugWindowWidth;
  569. Setting<int32> gnPlugWindowHeight;
  570. Setting<int32> gnPlugWindowLast; // Last selected plugin ID
  571. Setting<uint32> gnMsgBoxVisiblityFlags;
  572. Setting<uint32> GUIUpdateInterval;
  573. CachedSetting<uint32> FSUpdateInterval;
  574. CachedSetting<uint32> VuMeterUpdateInterval;
  575. CachedSetting<float> VuMeterDecaySpeedDecibelPerSecond;
  576. CachedSetting<bool> accidentalFlats;
  577. Setting<bool> rememberSongWindows;
  578. Setting<bool> showDirsInSampleBrowser;
  579. Setting<DefaultChannelColors> defaultRainbowChannelColors;
  580. Setting<FontSetting> commentsFont;
  581. // Misc
  582. Setting<MODTYPE> defaultModType;
  583. Setting<NewFileAction> defaultNewFileAction;
  584. Setting<PlugVolumeHandling> DefaultPlugVolumeHandling;
  585. Setting<bool> autoApplySmoothFT2Ramping;
  586. CachedSetting<uint32> MiscITCompressionStereo; // Mask: bit0: IT, bit1: Compat IT, bit2: MPTM
  587. CachedSetting<uint32> MiscITCompressionMono; // Mask: bit0: IT, bit1: Compat IT, bit2: MPTM
  588. CachedSetting<bool> MiscSaveChannelMuteStatus;
  589. CachedSetting<bool> MiscAllowMultipleCommandsPerKey;
  590. CachedSetting<bool> MiscDistinguishModifiers;
  591. Setting<ProcessPriorityClass> MiscProcessPriorityClass;
  592. CachedSetting<bool> MiscFlushFileBuffersOnSave;
  593. CachedSetting<bool> MiscCacheCompleteFileBeforeLoading;
  594. Setting<bool> MiscUseSingleInstance;
  595. // Sound Settings
  596. bool m_SoundShowRecordingSettings;
  597. Setting<bool> m_SoundShowDeprecatedDevices;
  598. Setting<bool> m_SoundDeprecatedDeviceWarningShown;
  599. Setting<std::vector<uint32> > m_SoundSampleRates;
  600. Setting<bool> m_SoundSettingsOpenDeviceAtStartup;
  601. Setting<SoundDeviceStopMode> m_SoundSettingsStopMode;
  602. bool m_SoundDeviceSettingsUseOldDefaults;
  603. SoundDevice::Legacy::ID m_SoundDeviceID_DEPRECATED;
  604. SoundDevice::Settings m_SoundDeviceSettingsDefaults;
  605. SoundDevice::Settings GetSoundDeviceSettingsDefaults() const;
  606. #if defined(MPT_WITH_DIRECTSOUND)
  607. bool m_SoundDeviceDirectSoundOldDefaultIdentifier;
  608. #endif // MPT_WITH_DIRECTSOUND
  609. Setting<SoundDevice::Identifier> m_SoundDeviceIdentifier;
  610. SoundDevice::Identifier GetSoundDeviceIdentifier() const;
  611. void SetSoundDeviceIdentifier(const SoundDevice::Identifier &identifier);
  612. SoundDevice::Settings GetSoundDeviceSettings(const SoundDevice::Identifier &device) const;
  613. void SetSoundDeviceSettings(const SoundDevice::Identifier &device, const SoundDevice::Settings &settings);
  614. Setting<uint32> MixerMaxChannels;
  615. Setting<uint32> MixerDSPMask;
  616. Setting<uint32> MixerFlags;
  617. Setting<uint32> MixerSamplerate;
  618. Setting<uint32> MixerOutputChannels;
  619. Setting<uint32> MixerPreAmp;
  620. Setting<uint32> MixerStereoSeparation;
  621. Setting<uint32> MixerVolumeRampUpMicroseconds;
  622. Setting<uint32> MixerVolumeRampDownMicroseconds;
  623. Setting<uint32> MixerNumInputChannels;
  624. MixerSettings GetMixerSettings() const;
  625. void SetMixerSettings(const MixerSettings &settings);
  626. Setting<ResamplingMode> ResamplerMode;
  627. Setting<uint8> ResamplerSubMode;
  628. Setting<int32> ResamplerCutoffPercent;
  629. Setting<Resampling::AmigaFilter> ResamplerEmulateAmiga;
  630. CResamplerSettings GetResamplerSettings() const;
  631. void SetResamplerSettings(const CResamplerSettings &settings);
  632. Setting<int> SoundBoostedThreadPriority;
  633. Setting<mpt::ustring> SoundBoostedThreadMMCSSClass;
  634. Setting<bool> SoundBoostedThreadRealtimePosix;
  635. Setting<int> SoundBoostedThreadNicenessPosix;
  636. Setting<int> SoundBoostedThreadRtprioPosix;
  637. Setting<bool> SoundMaskDriverCrashes;
  638. Setting<bool> SoundAllowDeferredProcessing;
  639. // MIDI Settings
  640. Setting<UINT> m_nMidiDevice;
  641. Setting<CString> midiDeviceName;
  642. // FIXME: MIDI recording is currently done in its own callback/thread and
  643. // accesses settings framework from in there. Work-around the ASSERTs for
  644. // now by using cached settings.
  645. CachedSetting<uint32> m_dwMidiSetup;
  646. CachedSetting<RecordAftertouchOptions> aftertouchBehaviour;
  647. CachedSetting<uint16> midiVelocityAmp;
  648. CachedSetting<std::bitset<128> > midiIgnoreCCs;
  649. Setting<uint32> midiImportPatternLen;
  650. Setting<uint32> midiImportQuantize;
  651. Setting<uint8> midiImportTicks;
  652. // Pattern Editor
  653. CachedSetting<bool> gbLoopSong;
  654. CachedSetting<UINT> gnPatternSpacing;
  655. CachedSetting<bool> gbPatternVUMeters;
  656. CachedSetting<bool> gbPatternPluginNames;
  657. CachedSetting<bool> gbPatternRecord;
  658. CachedSetting<bool> patternNoEditPopup;
  659. CachedSetting<bool> patternStepCommands;
  660. CachedSetting<uint32> m_dwPatternSetup;
  661. CachedSetting<uint32> m_nRowHighlightMeasures; // primary (measures) and secondary (beats) highlight
  662. CachedSetting<uint32> m_nRowHighlightBeats; // primary (measures) and secondary (beats) highlight
  663. CachedSetting<ROWINDEX> recordQuantizeRows;
  664. CachedSetting<UINT> gnAutoChordWaitTime;
  665. CachedSetting<int32> orderlistMargins;
  666. CachedSetting<int32> rowDisplayOffset;
  667. Setting<FontSetting> patternFont;
  668. Setting<mpt::ustring> patternFontDot;
  669. Setting<int32> effectVisWidth;
  670. Setting<int32> effectVisHeight;
  671. Setting<int32> effectVisX;
  672. Setting<int32> effectVisY;
  673. Setting<CString> patternAccessibilityFormat;
  674. CachedSetting<bool> patternAlwaysDrawWholePatternOnScrollSlow;
  675. CachedSetting<bool> orderListOldDropBehaviour;
  676. // Sample Editor
  677. Setting<SampleUndoBufferSize> m_SampleUndoBufferSize;
  678. Setting<SampleEditorKeyBehaviour> sampleEditorKeyBehaviour;
  679. Setting<SampleEditorDefaultFormat> m_defaultSampleFormat;
  680. Setting<TimelineFormat> sampleEditorTimelineFormat;
  681. Setting<ResamplingMode> sampleEditorDefaultResampler;
  682. Setting<int32> m_nFinetuneStep; // Increment finetune by x cents when using spin control.
  683. Setting<int32> m_FLACCompressionLevel; // FLAC compression level for saving (0...8)
  684. Setting<bool> compressITI;
  685. Setting<bool> m_MayNormalizeSamplesOnLoad;
  686. Setting<bool> previewInFileDialogs;
  687. CachedSetting<bool> cursorPositionInHex;
  688. // Export
  689. Setting<bool> ExportDefaultToSoundcardSamplerate;
  690. StreamEncoderSettingsConf ExportStreamEncoderSettings;
  691. // Components
  692. Setting<bool> ComponentsLoadOnStartup;
  693. Setting<bool> ComponentsKeepLoaded;
  694. bool IsComponentBlocked(const std::string &name);
  695. // Effects
  696. #ifndef NO_REVERB
  697. CReverbSettings m_ReverbSettings;
  698. #endif
  699. #ifndef NO_DSP
  700. CSurroundSettings m_SurroundSettings;
  701. #endif
  702. #ifndef NO_DSP
  703. CMegaBassSettings m_MegaBassSettings;
  704. #endif
  705. #ifndef NO_EQ
  706. EQPreset m_EqSettings;
  707. EQPreset m_EqUserPresets[4];
  708. #endif
  709. #ifndef NO_DSP
  710. BitCrushSettings m_BitCrushSettings;
  711. #endif
  712. // Display (Colors)
  713. std::array<COLORREF, MAX_MODCOLORS> rgbCustomColors;
  714. // AutoSave
  715. CachedSetting<bool> CreateBackupFiles;
  716. CachedSetting<bool> AutosaveEnabled;
  717. CachedSetting<uint32> AutosaveIntervalMinutes;
  718. CachedSetting<uint32> AutosaveHistoryDepth;
  719. CachedSetting<bool> AutosaveUseOriginalPath;
  720. ConfigurableDirectory AutosavePath;
  721. // Paths
  722. ConfigurableDirectory PathSongs;
  723. ConfigurableDirectory PathSamples;
  724. ConfigurableDirectory PathInstruments;
  725. ConfigurableDirectory PathPlugins;
  726. ConfigurableDirectory PathPluginPresets;
  727. ConfigurableDirectory PathExport;
  728. DefaultAndWorkingDirectory PathTunings;
  729. DefaultAndWorkingDirectory PathUserTemplates;
  730. mpt::PathString m_szKbdFile;
  731. // Default template
  732. Setting<mpt::PathString> defaultTemplateFile;
  733. Setting<mpt::ustring> defaultArtist;
  734. Setting<uint32> mruListLength;
  735. std::vector<mpt::PathString> mruFiles;
  736. // Chords
  737. MPTChords Chords;
  738. // Tunings
  739. std::unique_ptr<CTuningCollection> oldLocalTunings;
  740. // Plugins
  741. Setting<bool> bridgeAllPlugins;
  742. Setting<bool> enableAutoSuspend;
  743. CachedSetting<bool> midiMappingInPluginEditor;
  744. Setting<mpt::ustring> pluginProjectPath;
  745. CachedSetting<mpt::lstring> vstHostProductString;
  746. CachedSetting<mpt::lstring> vstHostVendorString;
  747. CachedSetting<int32> vstHostVendorVersion;
  748. // Broken Plugins Workarounds
  749. Setting<bool> BrokenPluginsWorkaroundVSTMaskAllCrashes;
  750. Setting<bool> BrokenPluginsWorkaroundVSTNeverUnloadAnyPlugin;
  751. #if defined(MPT_ENABLE_UPDATE)
  752. // Update
  753. Setting<bool> UpdateEnabled;
  754. Setting<bool> UpdateInstallAutomatically;
  755. Setting<mpt::Date::Unix> UpdateLastUpdateCheck;
  756. Setting<int32> UpdateUpdateCheckPeriod_DEPRECATED;
  757. Setting<int32> UpdateIntervalDays;
  758. Setting<uint32> UpdateChannel;
  759. Setting<mpt::ustring> UpdateUpdateURL_DEPRECATED;
  760. Setting<mpt::ustring> UpdateAPIURL;
  761. Setting<bool> UpdateStatisticsConsentAsked;
  762. Setting<bool> UpdateStatistics;
  763. Setting<bool> UpdateSendGUID_DEPRECATED;
  764. Setting<bool> UpdateShowUpdateHint;
  765. Setting<CString> UpdateIgnoreVersion;
  766. Setting<bool> UpdateSkipSignatureVerificationUNSECURE;
  767. Setting<std::vector<mpt::ustring>> UpdateSigningKeysRootAnchors;
  768. #endif // MPT_ENABLE_UPDATE
  769. // Wine support
  770. Setting<bool> WineSupportEnabled;
  771. Setting<bool> WineSupportAlwaysRecompile;
  772. Setting<bool> WineSupportAskCompile;
  773. Setting<int32> WineSupportCompileVerbosity;
  774. Setting<bool> WineSupportForeignOpenMPT;
  775. Setting<bool> WineSupportAllowUnknownHost;
  776. Setting<int32> WineSupportEnablePulseAudio; // 0==off 1==auto 2==on
  777. Setting<int32> WineSupportEnablePortAudio; // 0==off 1==auto 2==on
  778. Setting<int32> WineSupportEnableRtAudio; // 0==off 1==auto 2==on
  779. public:
  780. TrackerSettings(SettingsContainer &conf);
  781. ~TrackerSettings();
  782. void MigrateOldSoundDeviceSettings(SoundDevice::Manager &manager);
  783. private:
  784. void MigrateTunings(const Version storedVersion);
  785. std::unique_ptr<CTuningCollection> LoadLocalTunings();
  786. public:
  787. void SaveSettings();
  788. static void GetDefaultColourScheme(std::array<COLORREF, MAX_MODCOLORS> &colours);
  789. std::vector<uint32> GetSampleRates() const;
  790. static MPTChords &GetChords() { return Instance().Chords; }
  791. // Get settings object singleton
  792. static TrackerSettings &Instance();
  793. void SetMIDIDevice(UINT id);
  794. UINT GetCurrentMIDIDevice();
  795. protected:
  796. static std::vector<uint32> GetDefaultSampleRates();
  797. #ifndef NO_EQ
  798. void FixupEQ(EQPreset &eqSettings);
  799. #endif // !NO_EQ
  800. void LoadChords(MPTChords &chords);
  801. void SaveChords(MPTChords &chords);
  802. };
  803. OPENMPT_NAMESPACE_END