zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

Master.h (10221B)


      1 /*
      2   ZynAddSubFX - a software synthesizer
      3 
      4   Master.h - It sends Midi Messages to Parts, receives samples from parts,
      5              process them with system/insertion effects and mix them
      6   Copyright (C) 2002-2005 Nasca Octavian Paul
      7   Author: Nasca Octavian Paul
      8 
      9   This program is free software; you can redistribute it and/or
     10   modify it under the terms of the GNU General Public License
     11   as published by the Free Software Foundation; either version 2
     12   of the License, or (at your option) any later version.
     13 */
     14 
     15 #ifndef MASTER_H
     16 #define MASTER_H
     17 #include "../globals.h"
     18 #include "Microtonal.h"
     19 #include <atomic>
     20 #include <set>
     21 #include <rtosc/automations.h>
     22 #include <rtosc/miditable.h>
     23 #include <rtosc/savefile.h>
     24 
     25 #include "Time.h"
     26 #include "Bank.h"
     27 #include "Recorder.h"
     28 
     29 #include "../Params/Controller.h"
     30 #include "../Synth/WatchPoint.h"
     31 #include "../DSP/Value_Smoothing_Filter.h"
     32 
     33 namespace zyn {
     34 
     35 class Allocator;
     36 
     37 struct vuData {
     38     vuData(void);
     39     float outpeakl, outpeakr, maxoutpeakl, maxoutpeakr,
     40           rmspeakl, rmspeakr;
     41     int clipped;
     42 };
     43 
     44 
     45 /** It sends Midi Messages to Parts, receives samples from parts,
     46  *  process them with system/insertion effects and mix them */
     47 class Master
     48 {
     49     public:
     50         Master(const Master& other) = delete;
     51         Master(Master&& other) = delete;
     52 
     53         /** Constructor TODO make private*/
     54         Master(const SYNTH_T &synth, class Config *config);
     55         /** Destructor*/
     56         ~Master();
     57 
     58         char last_xmz[XMZ_PATH_MAX];
     59 
     60         //applyOscEvent overlays
     61         bool applyOscEvent(const char *event, float *outl, float *outr,
     62                            bool offline, bool nio = true, int msg_id = -1);
     63         bool applyOscEvent(const char *event, bool nio = true, int msg_id = -1);
     64 
     65         /**Saves all settings to a XML file
     66          * @return 0 for ok or <0 if there is an error*/
     67         int saveXML(const char *filename);
     68 
     69         /**This adds the parameters to the XML data*/
     70         void add2XML(XMLwrapper& xml);
     71 
     72         static void saveAutomation(XMLwrapper &xml, const rtosc::AutomationMgr &midi);
     73         static void loadAutomation(XMLwrapper &xml,       rtosc::AutomationMgr &midi);
     74 
     75         void defaults();
     76 
     77         /**loads all settings from a XML file
     78          * @return 0 for ok or -1 if there is an error*/
     79         int loadXML(const char *filename);
     80 
     81         /**Append all settings to an OSC savefile (as specified by RT OSC)*/
     82         std::string saveOSC(std::string savefile, std::set<std::string>& alreadyWritten);
     83         /**loads all settings from an OSC file (as specified by RT OSC)
     84          * @param dispatcher Message dispatcher and modifier
     85          * @return 0 for ok or <0 if there is an error*/
     86         int loadOSC(const char *filename,
     87                     rtosc::savefile_dispatcher_t* dispatcher);
     88 
     89         /**Regenerate PADsynth and other non-RT parameters
     90          * It is NOT SAFE to call this from a RT context*/
     91         void applyparameters(void) NONREALTIME;
     92 
     93         //This must be called prior-to/at-the-time-of RT insertion
     94         void initialize_rt(void) REALTIME;
     95 
     96         void getfromXML(XMLwrapper& xml);
     97 
     98         /**get all data to a newly allocated array (used for plugin)
     99          * @return the datasize*/
    100         int getalldata(char **data) NONREALTIME;
    101         /**put all data from the *data array to zynaddsubfx parameters (used for plugin)*/
    102         void putalldata(const char *data);
    103 
    104         //Midi IN
    105         void noteOn(char chan, note_t note, char velocity) {
    106             noteOn(chan, note, velocity, note / 12.0f);
    107         };
    108         void noteOn(char chan, note_t note, char velocity, float note_log2_freq);
    109         void noteOff(char chan, note_t note);
    110         void polyphonicAftertouch(char chan, note_t note, char velocity);
    111         void setController(char chan, int type, int par);
    112         void setController(char chan, int type, note_t note, float value);
    113         //void NRPN...
    114 
    115 
    116         void ShutUp();
    117         int shutup;
    118 
    119         void vuUpdate(const float *outl, const float *outr);
    120 
    121         //Process a set of OSC events in the bToU buffer
    122         //This may be called by MiddleWare if we are offline
    123         //(in this case, the param offline is true)
    124         bool runOSC(float *outl, float *outr, bool offline=false,
    125                     Master* master_from_mw = nullptr);
    126 
    127         //For debugging OSC issues
    128         void setUnknownAddressCallback(void(*cb)(void*,bool,rtosc::msg_t), void* ptr) {
    129             unknown_address_cb = cb;
    130             unknown_address_cb_ptr = ptr;
    131         }
    132 
    133         /**Audio Output*/
    134         bool AudioOut(float *outl, float *outr) REALTIME;
    135         /**Audio Output (for callback mode).
    136          * This allows the program to be controlled by an external program*/
    137         void GetAudioOutSamples(size_t nsamples,
    138                                 unsigned samplerate,
    139                                 float *outl,
    140                                 float *outr,
    141                                 int bar=0,
    142                                 int beat=0,
    143                                 float beatsPerBar=0.0f,
    144                                 float beatType=0.0f,
    145                                 float tick=0.0f,
    146                                 float bpm=0.0f,
    147                                 float PPQ=0.0f,
    148                                 bool playing=false,
    149                                 size_t frames=0) REALTIME;
    150 
    151 
    152         void partonoff(int npart, int what);
    153 
    154         //Set callback to run when master changes
    155         void setMasterChangedCallback(void(*cb)(void*,Master*),void *ptr);
    156         //Copy callback to other master
    157         void copyMasterCbTo(Master* dest);
    158         bool hasMasterCb() const;
    159         void setMasterSwitchUpcoming() { masterSwitchUpcoming = true; }
    160         bool isMasterSwitchUpcoming() const { return masterSwitchUpcoming; }
    161         void setAudioCompressor(bool enabled);
    162 
    163         /**parts \todo see if this can be made to be dynamic*/
    164         class Part * part[NUM_MIDI_PARTS];
    165 
    166         //parameters
    167         unsigned char Pkeyshift;
    168         unsigned char Psysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS];
    169         unsigned char Psysefxsend[NUM_SYS_EFX][NUM_SYS_EFX];
    170 
    171         //parameters control
    172         static float volume127ToFloat(unsigned char volume_);
    173         void setPkeyshift(char Pkeyshift_);
    174         void setPsysefxvol(int Ppart, int Pefx, char Pvol);
    175         void setPsysefxsend(int Pefxfrom, int Pefxto, char Pvol);
    176 
    177         //effects
    178         class EffectMgr * sysefx[NUM_SYS_EFX]; //system
    179         class EffectMgr * insefx[NUM_INS_EFX]; //insertion
    180 //      void swapcopyeffects(int what,int type,int neff1,int neff2);
    181 
    182         //HDD recorder
    183         Recorder HDDRecorder;
    184 
    185         //part that's apply the insertion effect; -1 to disable
    186         short int Pinsparts[NUM_INS_EFX];
    187 
    188 
    189         //peaks for VU-meter
    190         void vuresetpeaks();
    191 
    192         //peaks for part VU-meters
    193         float vuoutpeakpartl[NUM_MIDI_PARTS];
    194         float vuoutpeakpartr[NUM_MIDI_PARTS];
    195         unsigned char fakepeakpart[NUM_MIDI_PARTS]; //this is used to compute the "peak" when the part is disabled
    196 
    197         AbsTime time;
    198         Sync* sync;
    199         Controller ctl;
    200         bool       swaplr; //if L and R are swapped
    201 
    202         //other objects
    203         Microtonal microtonal;
    204 
    205         //Strictly Non-RT instrument bank object
    206         Bank bank;
    207 
    208         class FFTwrapper * fft;
    209 
    210         static const rtosc::Ports &ports;
    211         float  Volume;
    212 
    213         //Statistics on output levels
    214         vuData vu;
    215 
    216         //Display info on midi notes
    217         bool activeNotes[128];
    218 
    219         //Other watchers
    220         WatchManager watcher;
    221 
    222         //Midi Learn
    223         rtosc::AutomationMgr automate;
    224         rtosc::MidiMapperRT midi;
    225 
    226         bool   frozenState;//read-only parameters for threadsafe actions
    227         Allocator *memory;
    228         rtosc::ThreadLink *bToU;
    229         rtosc::ThreadLink *uToB;
    230         bool pendingMemory;
    231         const SYNTH_T &synth;
    232         const int& gzip_compression; //!< value from config
    233         bool SaveFullXml; // value from config
    234 
    235         //Heartbeat for identifying plugin offline modes
    236         //in units of 10 ms (done s.t. overflow is in 497 days)
    237         uint32_t last_beat = 0;
    238         uint32_t last_ack = 0;
    239 
    240         //Buffer to contain the OSC path to the last GUI element
    241         //on which a drag and drop operation ended
    242         constexpr static std::size_t dnd_buffer_size = 1024;
    243         char dnd_buffer[dnd_buffer_size] = {0};
    244 
    245         //Return XML data as string. Must be freed.
    246         char* getXMLData();
    247         //Load OSC from OSC savefile
    248         //Returns 0 if OK, <0 in case of failure
    249         int loadOSCFromStr(const char *file_content,
    250                            rtosc::savefile_dispatcher_t* dispatcher);
    251 
    252     private:
    253         std::atomic<bool> run_osc_in_use = { false };
    254         void (*unknown_address_cb)(void*,bool,rtosc::msg_t) = nullptr;
    255         void* unknown_address_cb_ptr;
    256 
    257         float  sysefxvol[NUM_SYS_EFX][NUM_MIDI_PARTS];
    258         float  sysefxsend[NUM_SYS_EFX][NUM_SYS_EFX];
    259         int    keyshift;
    260 
    261         //information relevant to generating plugin audio samples
    262         float *bufl;
    263         float *bufr;
    264         off_t  off;
    265         size_t smps;
    266 
    267         //Callback When Master changes
    268         void(*mastercb)(void*,Master*);
    269         void* mastercb_ptr;
    270         std::atomic<bool> masterSwitchUpcoming = { false };
    271 
    272         //! apply an OSC event with a DataObj parameter
    273         //! @note This may be called by MiddleWare if we are offline
    274         //!   (in this case, the param offline is true)
    275         //! @return false iff master has been changed
    276         bool applyOscEvent(const char *event, float *outl, float *outr,
    277                            bool offline, bool nio,
    278                            class DataObj& d, int msg_id = -1,
    279                            Master* master_from_mw = nullptr);
    280 
    281         Value_Smoothing_Filter smoothing;
    282 
    283         Value_Smoothing_Filter smoothing_part_l[NUM_MIDI_PARTS];
    284         Value_Smoothing_Filter smoothing_part_r[NUM_MIDI_PARTS];
    285 };
    286 
    287 class master_dispatcher_t : public rtosc::savefile_dispatcher_t
    288 {
    289     virtual void vUpdateMaster(Master* m) = 0;
    290 public:
    291     void updateMaster(Master* m) { vUpdateMaster(m); }
    292 };
    293 
    294 }
    295 
    296 #endif