1 /*
2     SynthEngine.h
3 
4     Original ZynAddSubFX author Nasca Octavian Paul
5     Copyright (C) 2002-2005 Nasca Octavian Paul
6     Copyright 2009-2011, Alan Calvert
7     Copyright 2014-2021, Will Godfrey & others
8 
9     This file is part of yoshimi, which is free software: you can redistribute
10     it and/or modify it under the terms of the GNU Library General Public
11     License as published by the Free Software Foundation; either version 2 of
12     the License, or (at your option) any later version.
13 
14     yoshimi is distributed in the hope that it will be useful, but WITHOUT ANY
15     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16     FOR A PARTICULAR PURPOSE.   See the GNU General Public License (version 2 or
17     later) for more details.
18 
19     You should have received a copy of the GNU General Public License along with
20     yoshimi; if not, write to the Free Software Foundation, Inc., 51 Franklin
21     Street, Fifth Floor, Boston, MA  02110-1301, USA.
22 
23     This file is derivative of ZynAddSubFX original code.
24 
25 */
26 
27 #ifndef SYNTHENGINE_H
28 #define SYNTHENGINE_H
29 
30 #include <sys/types.h>
31 #include <limits.h>
32 #include <cstdlib>
33 #include <semaphore.h>
34 #include <string>
35 #include <vector>
36 #include <list>
37 #include <map>
38 
39 #include "Misc/RandomGen.h"
40 #include "Misc/Microtonal.h"
41 #include "Misc/Bank.h"
42 #include "Interface/InterChange.h"
43 #include "Interface/MidiLearn.h"
44 #include "Interface/MidiDecode.h"
45 #include "Misc/Config.h"
46 #include "Params/PresetsStore.h"
47 #include "Params/UnifiedPresets.h"
48 #include "globals.h"
49 
50 class Part;
51 class EffectMgr;
52 class XMLwrapper;
53 class Controller;
54 class TextMsgBuffer;
55 
56 #ifdef GUI_FLTK
57 class MasterUI;
58 #endif
59 
60 using std::string;
61 
62 enum LV2PluginType
63 {
64     LV2PluginTypeNone,
65     LV2PluginTypeSingle,
66     LV2PluginTypeMulti
67 };
68 
69 class SynthEngine
70 {
71     private:
72         unsigned int uniqueId;
73         LV2PluginType lv2PluginType;
74         bool needsSaving;
75     public:
76         std::atomic <uint8_t> audioOut;
77         Bank bank;
78         InterChange interchange;
79         MidiLearn midilearn;
80         MidiDecode mididecode;
81         UnifiedPresets unifiedpresets;
82     private:
83         Config Runtime;
84         PresetsStore presetsstore;
85     public:
86         TextMsgBuffer& textMsgBuffer;
87         SynthEngine(std::list<string>& allArgs, LV2PluginType _lv2PluginType = LV2PluginTypeNone, unsigned int forceId = 0);
88         ~SynthEngine();
89         bool Init(unsigned int audiosrate, int audiobufsize);
90 
91         bool savePatchesXML(string filename);
92         void add2XML(XMLwrapper *xml);
93         string manualname();
94         void defaults(void);
95 
96         bool loadXML(const string& filename);
97         bool loadStateAndUpdate(const string& filename);
98         bool saveState(const string& filename);
99         bool loadPatchSetAndUpdate(string filename);
100         bool loadMicrotonal(const string& fname);
101         bool saveMicrotonal(const string& fname);
102         bool installBanks(void);
103         bool saveBanks(void);
104         void newHistory(string name, int group);
105         void addHistory(const string& name, int group);
106         std::vector<string> *getHistory(int group);
107         void setHistoryLock(int group, bool status);
108         bool getHistoryLock(int group);
109         string lastItemSeen(int group);
110         bool loadHistory(void);
111         bool saveHistory(void);
112         unsigned char loadVectorAndUpdate(unsigned char baseChan, const string& name);
113         unsigned char loadVector(unsigned char baseChan, const string& name, bool full);
114         unsigned char extractVectorData(unsigned char baseChan, XMLwrapper *xml, const string& name);
115         unsigned char saveVector(unsigned char baseChan, const string& name, bool full);
116         bool insertVectorData(unsigned char baseChan, bool full, XMLwrapper *xml, const string& name);
117 
118         bool getfromXML(XMLwrapper *xml);
119 
120         int getalldata(char **data);
121         void putalldata(const char *data, int size);
122 
123         void NoteOn(unsigned char chan, unsigned char note, unsigned char velocity);
124         void NoteOff(unsigned char chan, unsigned char note);
125         int RunChannelSwitch(unsigned char chan, int value);
126         void SetController(unsigned char chan, int CCtype, short int par);
127         void SetZynControls(bool in_place);
128         int setRootBank(int root, int bank, bool notinplace = true);
129         int setProgramByName(CommandBlock *getData);
130         int setProgramFromBank(CommandBlock *getData, bool notinplace = true);
131         bool setProgram(const string& fname, int npart);
132         int ReadBankRoot(void);
133         int ReadBank(void);
134         void SetPartChan(unsigned char npart, unsigned char nchan);
135         void SetPartPortamento(int npart, bool state);
136         bool ReadPartPortamento(int npart);
137         void SetPartKeyMode(int npart, int mode);
138         int  ReadPartKeyMode(int npart);
139         void cliOutput(std::list<string>& msg_buf, unsigned int lines);
140         void ListPaths(std::list<string>& msg_buf);
141         void ListBanks(int rootNum, std::list<string>& msg_buf);
142         void ListInstruments(int bankNum, std::list<string>& msg_buf);
143         void ListVectors(std::list<string>& msg_buf);
144         bool SingleVector(std::list<string>& msg_buf, int chan);
145         void ListSettings(std::list<string>& msg_buf);
146         int SetSystemValue(int type, int value);
147         int LoadNumbered(unsigned char group, unsigned char entry);
148         bool vectorInit(int dHigh, unsigned char chan, int par);
149         void vectorSet(int dHigh, unsigned char chan, int par);
150         void ClearNRPNs(void);
151         void resetAll(bool andML);
152         void ShutUp(void);
153         int MasterAudio(float *outl [NUM_MIDI_PARTS + 1], float *outr [NUM_MIDI_PARTS + 1], int to_process = 0);
154         void partonoffLock(int npart, int what);
155         void partonoffWrite(int npart, int what);
156         char partonoffRead(int npart);
157         sem_t partlock;
158         unsigned char legatoPart;
159         void setPartMap(int npart);
160         void setAllPartMaps(void);
161 
162         bool masterMono;
163         bool fileCompatible;
164         bool usingYoshiType;
165 
166         float getLimits(CommandBlock *getData);
167         float getVectorLimits(CommandBlock *getData);
168         float getConfigLimits(CommandBlock *getData);
169 
170         Part *part[NUM_MIDI_PARTS];
171         unsigned int fadeAll;
172         // Per sample change in gain calculated whenever samplerate changes (which
173         // is currently only on init). fadeStep is used in SynthEngine, while
174         // fadeStepShort is used directly by notes, currently only for legato.
175         float fadeStep;
176         float fadeStepShort;
177         float fadeLevel;
178 
179         // parameters
180         unsigned int samplerate;
181         float samplerate_f;
182         float halfsamplerate_f;
183         int buffersize;
184         float buffersize_f;
185         int bufferbytes;
186         int oscilsize;
187         float oscilsize_f;
188         int halfoscilsize;
189         float halfoscilsize_f;
190         float oscil_sample_step_f;
191         float oscil_norm_factor_pm;
192         float oscil_norm_factor_fm;
193 
194         // Reference values used for normalization
195         static constexpr float samplerate_ref_f = 44100.0f;
196         static constexpr float oscilsize_ref_f = float(1024 * 256);
197 
198         int           sent_buffersize; //used for variable length runs
199         int           sent_bufferbytes; //used for variable length runs
200         float         sent_buffersize_f; //used for variable length runs
201         float         fixed_sample_step_f;
202         float         TransVolume;
203         float         Pvolume;
204         float         ControlStep;
205         int           Paudiodest;
206         int           Pkeyshift;
207         unsigned char Psysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS];
208         unsigned char Psysefxsend[NUM_SYS_EFX][NUM_SYS_EFX];
209 
210         // parameters control
211         void setPvolume(float value);
212         void setPkeyshift(int Pkeyshift_);
213         void setPsysefxvol(int Ppart, int Pefx, char Pvol);
214         void setPsysefxsend(int Pefxfrom, int Pefxto, char Pvol);
215         void setPaudiodest(int value);
216 
217         // effects
218         unsigned char  syseffnum;
219         bool syseffEnable[NUM_SYS_EFX];
220         unsigned char  inseffnum;
221         EffectMgr *sysefx[NUM_SYS_EFX]; // system
222         EffectMgr *insefx[NUM_INS_EFX]; // insertion
223 
224         // part that's apply the insertion effect; -1 to disable
225         short int Pinsparts[NUM_INS_EFX];
226 
227         // others ...
228         Controller *ctl;
229         Microtonal microtonal;
230         FFTwrapper *fft;
231 
232         // peaks for VU-meters
233         union VUtransfer{
234             struct{
235                 float vuOutPeakL;
236                 float vuOutPeakR;
237                 float vuRmsPeakL;
238                 float vuRmsPeakR;
239                 float parts[NUM_MIDI_PARTS];
240                 float partsR[NUM_MIDI_PARTS];
241                 int buffersize;
242             } values;
243             char bytes [sizeof(values)];
244         };
245         VUtransfer VUpeak, VUcopy, VUdata;
246         unsigned int VUcount;
247         bool VUready;
248         void fetchMeterData(void);
249 
getLV2PluginType()250         inline LV2PluginType getLV2PluginType() {return lv2PluginType;}
getIsLV2Plugin()251         inline bool getIsLV2Plugin() {return lv2PluginType != LV2PluginTypeNone; }
getRuntime()252         inline Config &getRuntime() {return Runtime;}
getPresetsStore()253         inline PresetsStore &getPresetsStore() {return presetsstore;}
getUniqueId()254         unsigned int getUniqueId() {return uniqueId;}
255         SynthEngine *getSynthFromId(unsigned int uniqueId);
256         void guiClosed(bool stopSynth);
setGuiClosedCallback(void (* _guiClosedCallback)(void *),void * arg)257         void setGuiClosedCallback(void( *_guiClosedCallback)(void*), void *arg)
258         {
259             guiClosedCallback = _guiClosedCallback;
260             guiCallbackArg = arg;
261         }
262         void closeGui();
getLFOtime()263         int64_t getLFOtime() {return LFOtime;}
getSongBeat()264         float getSongBeat() {return songBeat;}
getMonotonicBeat()265         float getMonotonicBeat() {return monotonicBeat;}
getBPM()266         float getBPM() { return bpm; }
isBPMAccurate()267         bool isBPMAccurate() { return bpmAccurate; }
setBPMAccurate(bool value)268         void setBPMAccurate(bool value) { bpmAccurate = value; }
setBeatValues(float songBeat,float monotonicBeat,float bpm)269         void setBeatValues(float songBeat, float monotonicBeat, float bpm) {
270             this->songBeat = songBeat;
271             this->monotonicBeat = monotonicBeat;
272             this->bpm = bpm;
273         }
274         string makeUniqueName(const string& name);
275 
getBankRef()276         Bank &getBankRef() {return bank;}
getBankPtr()277         Bank *getBankPtr() {return &bank;}
278 
getWindowTitle()279         string getWindowTitle() {return windowTitle;}
280         void setWindowTitle(const string& _windowTitle = "");
setNeedsSaving(bool ns)281         void setNeedsSaving(bool ns) { needsSaving = ns; }
getNeedsSaving()282         bool getNeedsSaving() { return needsSaving; }
283     private:
284         float volume;
285         float sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS];
286         float sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX];
287 
288         int keyshift;
289 
290     public:
291 #ifdef GUI_FLTK
292         MasterUI *guiMaster; // need to read this in InterChange::returns
293         MasterUI *getGuiMaster(bool createGui = true);
294 #endif
295     private:
296         void( *guiClosedCallback)(void*);
297         void *guiCallbackArg;
298 
299         int CHtimer;
300 
301         int64_t LFOtime; // used by Pcontinous without Pbpm
302         float songBeat; // used by Pbpm without Pcontinous
303         float monotonicBeat; // used by Pbpm
304         float bpm; // used by Echo Effect
305         bool bpmAccurate; // Set to false by engines that can't provide an
306                           // accurate BPM value.
307 
308         string windowTitle;
309         //MusicClient *musicClient;
310 
311         RandomGen prng;
312     public:
numRandom()313         float numRandom()   { return prng.numRandom(); }
randomINT()314         uint32_t randomINT(){ return prng.randomINT(); }   // random number in the range 0...INT_MAX
315         void setReproducibleState(int value);
316 };
317 
318 #endif
319