1 //=========================================================
2 //  MusE
3 //  Linux Music Editor
4 //  $Id: plugin.h,v 1.9.2.13 2009/12/06 01:25:21 terminator356 Exp $
5 //
6 //  (C) Copyright 2000 Werner Schweer (ws@seh.de)
7 //  (C) Copyright 2011-2016 Tim E. Real (terminator356 on sourceforge)
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; version 2 of
12 //  the License, or (at your option) any later version.
13 //
14 //  This program is distributed in the hope that it will be useful,
15 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 //  GNU General Public License for more details.
18 //
19 //  You should have received a copy of the GNU General Public License
20 //  along with this program; if not, write to the Free Software
21 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22 //
23 //=========================================================
24 
25 #ifndef __PLUGIN_H__
26 #define __PLUGIN_H__
27 
28 #include <list>
29 #include <vector>
30 #include <QSet>
31 #include <QMap>
32 #include <QPair>
33 #include <QFileInfo>
34 #include <QMainWindow>
35 #include <QMouseEvent>
36 #include <QUiLoader>
37 #include <QRect>
38 #include <QList>
39 
40 #include <ladspa.h>
41 
42 #include "globaldefs.h"
43 #include "ctrl.h"
44 #include "controlfifo.h"
45 #include "config.h"
46 
47 #ifdef OSC_SUPPORT
48 #include "osc.h"
49 #endif
50 
51 #ifdef DSSI_SUPPORT
52 #include <dssi.h>
53 #endif
54 
55 // BUG I have filed a Qt bug report 64773. If we do NOT
56 //  set a position on a new QWidget, Qt seems to take control
57 //  of the position management such that it will NOT accept
58 //  any new position after that! It seems to decide to
59 //  remain in 'auto-placement' mode forever.
60 // If the bug is ever fixed by Qt, this define should then
61 //  become version-sensitive.         2017/11/28 Tim.
62 #define QT_SHOW_POS_BUG_WORKAROUND 1;
63 
64 
65 // Forward declarations:
66 class QScrollArea;
67 class QShowEvent;
68 class QHideEvent;
69 class QAction;
70 class QSpinBox;
71 class QToolButton;
72 
73 namespace MusEGui {
74 class PluginGui;
75 class DoubleLabel;
76 }
77 
78 namespace MusEPlugin {
79 class PluginScanInfoStruct;
80 }
81 
82 namespace MusECore {
83 class AudioTrack;
84 class Xml;
85 
86 class PluginI;
87 
88 //---------------------------------------------------------
89 //   Plugin
90 //---------------------------------------------------------
91 
92 class Plugin {
93 
94    protected:
95    friend class PluginI;
96 
97       void* _handle;
98       int _references;
99       int _instNo;
100       QFileInfo fi;
101       // Universal resource identifier, for plugins that use it (LV2).
102       // If this exists, it should be used INSTEAD of file info, for comparison etc.
103       // Never rely on the file info if a uri exists.
104       QString _uri;
105       LADSPA_Descriptor_Function ladspa;
106       const LADSPA_Descriptor *plugin;
107       unsigned long _uniqueID;
108       QString _label;
109       QString _name;
110       QString _maker;
111       QString _copyright;
112 
113       bool _isDssiSynth;
114       bool _isDssi;
115       bool _isLV2Synth;
116       bool _isLV2Plugin;
117       // Hack: Special flag required.
118       bool _isDssiVst;
119       bool _isVstNativeSynth;
120       bool _isVstNativePlugin;
121 
122       #ifdef DSSI_SUPPORT
123       const DSSI_Descriptor* dssi_descr;
124       #endif
125 
126       unsigned long _portCount;
127       unsigned long _inports;
128       unsigned long _outports;
129       unsigned long _controlInPorts;
130       unsigned long _controlOutPorts;
131       std::vector<unsigned long> rpIdx; // Port number to control input index. Item is -1 if it's not a control input.
132 
133       bool _usesTimePosition;
134 
135       PluginFeatures_t _requiredFeatures;
136 
137    public:
Plugin()138       Plugin() {} //empty constructor for LV2PluginWrapper
139       Plugin(QFileInfo* f, const LADSPA_Descriptor* d, const QString& uri,
140              bool isDssi = false, bool isDssiSynth = false, bool isDssiVst = false,
141              PluginFeatures_t reqFeatures = PluginNoFeatures);
142       Plugin(const MusEPlugin::PluginScanInfoStruct&);
143       virtual ~Plugin();
requiredFeatures()144       virtual PluginFeatures_t requiredFeatures() const { return _requiredFeatures; }
uri()145       QString uri() const                          { return _uri; }
label()146       virtual QString label() const                        { return _label; }
name()147       QString name() const                         { return _name; }
id()148       unsigned long id() const                     { return _uniqueID; }
maker()149       QString maker() const                        { return _maker; }
copyright()150       QString copyright() const                    { return _copyright; }
151       QString lib(bool complete = true) const      { return complete ? fi.completeBaseName() : fi.baseName(); } // ddskrjo const
152       QString dirPath(bool complete = true) const  { return complete ? fi.absolutePath() : fi.path(); }
filePath()153       QString filePath() const                     { return fi.filePath(); }
fileName()154       QString fileName() const                     { return fi.fileName(); }
155 
references()156       int references() const                       { return _references; }
157       virtual int incReferences(int);
instNo()158       int instNo()                                 { return _instNo++;        }
159 
isDssiPlugin()160       bool isDssiPlugin() const { return _isDssi; }
isDssiSynth()161       bool isDssiSynth() const  { return _isDssiSynth; }
isLV2Plugin()162       inline bool isLV2Plugin() const { return _isLV2Plugin; } //inline it to use in RT audio thread
isLV2Synth()163       bool isLV2Synth() const { return _isLV2Synth; }
isVstNativePlugin()164       inline bool isVstNativePlugin() const { return _isVstNativePlugin; } //inline it to use in RT audio thread
isVstNativeSynth()165       bool isVstNativeSynth() const { return _isVstNativeSynth; }
166 
167       virtual LADSPA_Handle instantiate(PluginI *);
activate(LADSPA_Handle handle)168       virtual void activate(LADSPA_Handle handle) {
169             if (plugin && plugin->activate)
170                   plugin->activate(handle);
171             }
deactivate(LADSPA_Handle handle)172       virtual void deactivate(LADSPA_Handle handle) {
173             if (plugin && plugin->deactivate)
174                   plugin->deactivate(handle);
175             }
cleanup(LADSPA_Handle handle)176       virtual void cleanup(LADSPA_Handle handle) {
177             if (plugin && plugin->cleanup)
178                   plugin->cleanup(handle);
179             }
connectPort(LADSPA_Handle handle,unsigned long port,float * value)180       virtual void connectPort(LADSPA_Handle handle, unsigned long port, float* value) {
181             if(plugin)
182               plugin->connect_port(handle, port, value);
183             }
184       virtual void apply(LADSPA_Handle handle, unsigned long n, float /*latency_corr*/ = 0.0f) {
185             if(plugin)
186               plugin->run(handle, n);
187             }
188 
189       #ifdef OSC_SUPPORT
190       int oscConfigure(LADSPA_Handle handle, const char* key, const char* value);
191       #endif
192 
ports()193       unsigned long ports() { return _portCount; }
194 
portd(unsigned long k)195       virtual LADSPA_PortDescriptor portd(unsigned long k) const {
196             return plugin ? plugin->PortDescriptors[k] : 0;
197             }
198 
range(unsigned long i)199       virtual LADSPA_PortRangeHint range(unsigned long i) {
200             // FIXME:
201             //return plugin ? plugin->PortRangeHints[i] : 0; DELETETHIS
202             return plugin->PortRangeHints[i];
203             }
204 
205       virtual double defaultValue(unsigned long port) const;
206       virtual void range(unsigned long i, float*, float*) const;
207       virtual CtrlValueType ctrlValueType(unsigned long i) const;
208       virtual CtrlList::Mode ctrlMode(unsigned long i) const;
209       virtual CtrlEnumValues* ctrlEnumValues ( unsigned long ) const;
210 
portName(unsigned long i)211       virtual const char* portName(unsigned long i) {
212             return plugin ? plugin->PortNames[i] : 0;
213             }
214 
usesTimePosition()215       bool usesTimePosition() const         { return _usesTimePosition; }
inports()216       unsigned long inports() const         { return _inports; }
outports()217       unsigned long outports() const        { return _outports; }
controlInPorts()218       unsigned long controlInPorts() const  { return _controlInPorts; }
controlOutPorts()219       unsigned long controlOutPorts() const { return _controlOutPorts; }
220 
getRpIdx()221       const std::vector<unsigned long>* getRpIdx() { return &rpIdx; }
222       };
223 
224 typedef std::list<Plugin *>::iterator iPlugin;
225 typedef std::list<Plugin *>::const_iterator ciPlugin;
226 
227 
228 class PluginGroups : public QMap< QPair<QString, QString>, QSet<int> >
229 {
230   public:
get(QString a,QString b)231     QSet<int>& get(QString a, QString b) { return (*this)[(QPair<QString,QString>(a,b))]; }
get(const Plugin * p)232     QSet<int>& get(const Plugin *p)
233       { return (*this)[(QPair<QString,QString>(p->uri().isEmpty() ? p->lib() : p->uri(), p->label()))]; }
234 
235     void shift_left(int first, int last);
236     void shift_right(int first, int last);
237     void erase(int index);
238 
239   private:
240     void replace_group(int old, int now);
241 };
242 
243 
244 //---------------------------------------------------------
245 //   PluginList
246 //---------------------------------------------------------
247 
248 class PluginList : public std::list<Plugin *> {
249    public:
250       void add(QFileInfo* fi, const LADSPA_Descriptor* d, const QString& uri,
251                bool isDssi = false, bool isDssiSynth = false, bool isDssiVst = false,
252                PluginFeatures_t reqFeatures = PluginNoFeatures)
253       {
254         push_back(new Plugin(fi, d, uri, isDssi, isDssiSynth, isDssiVst, reqFeatures));
255       }
256 
add(const MusEPlugin::PluginScanInfoStruct & scan_info)257       void add(const MusEPlugin::PluginScanInfoStruct& scan_info)
258       { push_back(new Plugin(scan_info)); }
259 
260       // Each argument optional, can be empty.
261       // If uri is not empty, the search is based solely on it, the other arguments are ignored.
262       Plugin* find(const QString& file, const QString& uri, const QString& label) const;
PluginList()263       PluginList() {}
264       };
265 
266 //---------------------------------------------------------
267 //   Port
268 //---------------------------------------------------------
269 
270 struct Port {
271       unsigned long idx;
272 
273       //   NOTE: These values represent the lowest level of control value storage.
274       //         The choice of float or double depends on the underlying system using this struct.
275       //         For example plugins and synthesizers usually use floats to represent control values
276       //          and they are directly pointed to this float, while our own track controls
277       //          (volume, pan etc.) take advantage of the double precision.
278       //         Double precision is preferred if possible because above this lowest level all other
279       //          controller usage is in double precision. Thus our very own track controllers are
280       //          perfectly matched double precision throughout the system.
281       union {
282         float val;
283         double dval;
284         };
285       union {
286         float tmpVal; // TODO Try once again and for all to remove this, was it really required?
287         //double dtmpVal; // Not used, should not be required.
288         };
289 
290       bool enCtrl;  // Enable controller stream.
291       CtrlInterpolate interp;
292       };
293 
294 //---------------------------------------------------------
295 //   PluginQuirks
296 //    An ugly but necessary class due to differences in plugin behaviour.
297 //---------------------------------------------------------
298 
299 class PluginQuirks
300 {
301 public:
302     enum NatUISCaling {GLOBAL, ON, OFF};
303     // Whether the LV2 'speed' timePosition property switches to 0.0 in stop mode, or remains
304     //  fixed at 1.0 regardless of play or stop mode. Fixes plugins like TAL NoiseMak3r
305     //  stuck repeating small modulator segment at speed = 0.0.
306     bool _fixedSpeed;
307     // If the plugin uses our transport (ex. as an LV2 timePosition), sets whether the timePosition
308     //  affects actual audio latency (not just say, beat or sequencer or arpeggiator latency).
309     // Example: LV2 Example Metronome.
310     bool _transportAffectsAudioLatency;
311     // Override the plugin's reported latency. Some plugins get it wrong or not quite right.
312     bool _overrideReportedLatency;
313     // Value to override the reported latency.
314     int _latencyOverrideValue;
315 
PluginQuirks()316   PluginQuirks() :
317     _fixedSpeed(false),
318     _transportAffectsAudioLatency(false),
319     _overrideReportedLatency(false),
320     _latencyOverrideValue(0),
321     _fixNativeUIScaling(NatUISCaling::GLOBAL)
322     { }
323 
324   void write(int level, Xml& xml) const;
325   // Return true on error.
326   bool read(Xml& xml);
327   bool fixNativeUIScaling() const;
setFixNativeUIScaling(NatUISCaling fixScaling)328   void setFixNativeUIScaling(NatUISCaling fixScaling) { _fixNativeUIScaling = fixScaling; };
getFixNativeUIScaling()329   NatUISCaling getFixNativeUIScaling() const { return _fixNativeUIScaling; };
330 
331 private:
332   // Reverse scaling of native UI windows on HiDPI
333   NatUISCaling _fixNativeUIScaling;
334 };
335 
336 typedef enum {
337     PROP_NONE = -1, PROP_INT = 0, PROP_LONG, PROP_FLOAT, PROP_DOUBLE, PROP_BOOL, PROP_STRING, PROP_PATH
338 } PropType;
339 
340 //---------------------------------------------------------
341 //   PluginIBase
342 //---------------------------------------------------------
343 
344 class PluginIBase
345 {
346    protected:
347       ControlFifo _controlFifo;
348       MusEGui::PluginGui* _gui;
349       QRect _guiGeometry;
350       QRect _nativeGuiGeometry;
351       PluginQuirks _quirks;
352 
353       void makeGui();
354 
355    public:
356       PluginIBase();
357       virtual ~PluginIBase();
358       virtual PluginFeatures_t requiredFeatures() const = 0;
359       virtual bool hasBypass() const = 0;
360       virtual bool on() const = 0;
361       virtual void setOn(bool val) = 0;
362       virtual unsigned long pluginID() = 0;
363       virtual int id() = 0;
364       virtual QString pluginLabel() const = 0;
365       virtual QString name() const = 0;
366       virtual QString uri() const = 0;
367       virtual QString lib() const = 0;
368       virtual QString dirPath() const = 0;
369       virtual QString fileName() const = 0;
370       virtual QString titlePrefix() const = 0;
371 
372       virtual AudioTrack* track() = 0;
373 
374       virtual void enableController(unsigned long i, bool v = true) = 0;
375       virtual bool controllerEnabled(unsigned long i) const = 0;
376       virtual void enableAllControllers(bool v = true) = 0;
377       virtual void updateControllers() = 0;
378 
379       virtual void activate() = 0;
380       virtual void deactivate() = 0;
381 
382       virtual void writeConfiguration(int level, Xml& xml) = 0;
383       virtual bool readConfiguration(Xml& xml, bool readPreset=false) = 0;
384 
385       virtual bool addScheduledControlEvent(unsigned long i, double val, unsigned frame);    // returns true if event cannot be delivered
386       virtual unsigned long parameters() const = 0;
387       virtual unsigned long parametersOut() const = 0;
388       virtual void setParam(unsigned long i, double val) = 0;
389       virtual double param(unsigned long i) const = 0;
390       virtual double paramOut(unsigned long i) const = 0;
391       virtual const char* paramName(unsigned long i) = 0;
392       virtual const char* paramOutName(unsigned long i) = 0;
393       // FIXME TODO: Either find a way to agnosticize these two ranges, or change them from ladspa ranges to a new MusE range class.
394       virtual LADSPA_PortRangeHint range(unsigned long i) = 0;
395       virtual LADSPA_PortRangeHint rangeOut(unsigned long i) = 0;
396 
397       virtual bool usesTransportSource() const = 0;
398       virtual bool hasLatencyOutPort() const = 0;
399       virtual unsigned long latencyOutPortIndex() const = 0;
400       virtual float latency() const = 0;
cquirks()401       const PluginQuirks& cquirks() const { return _quirks; }
quirks()402       PluginQuirks& quirks() { return _quirks; }
403 
setCustomData(const std::vector<QString> &)404       virtual void setCustomData(const std::vector<QString> &) {/* Do nothing by default */}
405       virtual CtrlValueType ctrlValueType(unsigned long i) const = 0;
406       virtual CtrlList::Mode ctrlMode(unsigned long i) const = 0;
407       virtual CtrlEnumValues *ctrlEnumValues(unsigned long i) const;
408       virtual QString portGroup(long unsigned int i) const;
409       virtual bool ctrlIsTrigger(long unsigned int i) const;
410       virtual bool ctrlNotOnGui(long unsigned int i) const;
411 
412       QString dssi_ui_filename() const;
413 
gui()414       MusEGui::PluginGui* gui() const { return _gui; }
415       void deleteGui();
416 
417       virtual void showGui();
418       virtual void showGui(bool);
419       virtual bool guiVisible() const;
420       // Sets the gui's geometry. Also updates the saved geometry.
421       virtual void setGeometry(int x, int y, int w, int h);
422       // Returns the current geometry of the gui, or if the gui does not exist,
423       //  the saved gui geometry.
424       virtual void getGeometry(int *x, int *y, int *w, int *h) const;
425       // Saves the current gui geometry.
426       virtual void saveGeometry(int x, int y, int w, int h);
427       // Returns the saved gui geometry.
428       virtual void savedGeometry(int *x, int *y, int *w, int *h) const;
429 
showNativeGui()430       virtual void showNativeGui() { }
showNativeGui(bool)431       virtual void showNativeGui(bool) { }
nativeGuiVisible()432       virtual bool nativeGuiVisible() const { return false; }
433       // Sets the gui's geometry. Also updates the saved geometry.
434       virtual void setNativeGeometry(int x, int y, int w, int h);
435       // Returns the current geometry of the gui, or if the gui does not exist,
436       //  the saved gui geometry.
437       virtual void getNativeGeometry(int *x, int *y, int *w, int *h) const;
438       // Saves the current gui geometry.
439       virtual void saveNativeGeometry(int x, int y, int w, int h);
440       // Returns the saved gui geometry.
441       virtual void savedNativeGeometry(int *x, int *y, int *w, int *h) const;
442 };
443 
444 //---------------------------------------------------------
445 //   PluginI
446 //    plugin instance
447 //---------------------------------------------------------
448 
449 #define IS_AUDIO_IN (LADSPA_PORT_AUDIO  | LADSPA_PORT_INPUT)
450 #define IS_AUDIO_OUT (LADSPA_PORT_AUDIO | LADSPA_PORT_OUTPUT)
451 
452 class PluginI : public PluginIBase {
453 #ifdef LV2_SUPPORT
454     friend class LV2PluginWrapper;
455     friend class LV2Synth;
456 #endif
457 #ifdef VST_NATIVE_SUPPORT
458     friend class VstNativeSynth;
459     friend class VstNativePluginWrapper;
460 #endif
461       Plugin* _plugin;
462       int channel;
463       int instances;
464       AudioTrack* _track;
465       int _id;
466 
467       LADSPA_Handle* handle;         // per instance
468       Port* controls;
469       Port* controlsOut;
470       Port* controlsOutDummy;
471 
472       unsigned long controlPorts;
473       unsigned long controlOutPorts;
474 
475       bool          _hasLatencyOutPort;
476       unsigned long _latencyOutPort;
477 
478       float *_audioInSilenceBuf; // Just all zeros all the time, so we don't have to clear for silence.
479       float *_audioOutDummyBuf;  // A place to connect unused outputs.
480 
481       bool _on;
482       bool initControlValues;
483       QString _name;
484       QString _label;
485 
486       #ifdef OSC_SUPPORT
487       OscEffectIF _oscif;
488       #endif
489       bool _showNativeGuiPending;
490 
491       void init();
492 
493    public:
494       PluginI();
495       virtual ~PluginI();
496 
plugin()497       Plugin* plugin() const { return _plugin; }
498 
requiredFeatures()499       virtual PluginFeatures_t requiredFeatures() const { return _plugin->requiredFeatures(); }
500 
hasBypass()501       bool hasBypass() const  { return true; };
on()502       bool on() const        { return _on; }
setOn(bool val)503       void setOn(bool val)   { _on = val; }
504 
setTrack(AudioTrack * t)505       void setTrack(AudioTrack* t)  { _track = t; }
track()506       AudioTrack* track()           { return _track; }
pluginID()507       unsigned long pluginID()      { return _plugin->id(); }
508       void setID(int i);
id()509       int id()                      { return _id; }
510       void updateControllers();
511 
512       bool initPluginInstance(Plugin*, int channels);
513       void setChannels(int);
514       void connect(unsigned long ports, unsigned long offset, float** src, float** dst);
515       void apply(unsigned pos, unsigned long n,
516                  unsigned long ports, float** bufIn, float** bufOut, float latency_corr_offset = 0.0f);
517 
518       void enableController(unsigned long i, bool v = true)   { controls[i].enCtrl = v; }
controllerEnabled(unsigned long i)519       bool controllerEnabled(unsigned long i) const           { return controls[i].enCtrl; }
520       void enableAllControllers(bool v = true);
521 
522       void activate();
523       void deactivate();
pluginLabel()524       QString pluginLabel() const    { return _plugin->label(); }
label()525       QString label() const          { return _label; }
name()526       QString name() const           { return _name; }
lib()527       QString lib() const            { return _plugin->lib(); }
uri()528       QString uri() const            { return _plugin->uri(); }
dirPath()529       QString dirPath() const        { return _plugin->dirPath(); }
fileName()530       QString fileName() const       { return _plugin->fileName(); }
531       QString titlePrefix() const;
532 
533       #ifdef OSC_SUPPORT
oscIF()534       OscEffectIF& oscIF() { return _oscif; }
535 
536       int oscControl(unsigned long dssiPort, float val);
537       int oscConfigure(const char *key, const char *val);
538       int oscUpdate();
539       #endif
540 
541       void writeConfiguration(int level, Xml& xml);
542       bool readConfiguration(Xml& xml, bool readPreset=false);
543       bool loadControl(Xml& xml);
544       bool setControl(const QString& s, double val);
545       void showGui();
546       void showGui(bool);
isDssiPlugin()547       bool isDssiPlugin() const { return _plugin->isDssiPlugin(); }
isLV2Plugin()548       bool isLV2Plugin() const { return _plugin->isLV2Plugin(); }
isVstNativePlugin()549       bool isVstNativePlugin() const { return _plugin->isVstNativePlugin(); }
550       void showNativeGui();
551       void showNativeGui(bool);
isShowNativeGuiPending()552       bool isShowNativeGuiPending() { return _showNativeGuiPending; }
553       bool nativeGuiVisible() const;
554 
parameters()555       unsigned long parameters() const           { return controlPorts; }
parametersOut()556       unsigned long parametersOut() const           { return controlOutPorts; }
557       void setParam(unsigned long i, double val);
putParam(unsigned long i,double val)558       void putParam(unsigned long i, double val) { controls[i].val = controls[i].tmpVal = val; }
param(unsigned long i)559       double param(unsigned long i) const        { return controls[i].val; }
paramOut(unsigned long i)560       double paramOut(unsigned long i) const        { return controlsOut[i].val; }
561       double defaultValue(unsigned long param) const;
paramName(unsigned long i)562       const char* paramName(unsigned long i)     { return _plugin->portName(controls[i].idx); }
paramOutName(unsigned long i)563       const char* paramOutName(unsigned long i)     { return _plugin->portName(controlsOut[i].idx); }
portd(unsigned long i)564       LADSPA_PortDescriptor portd(unsigned long i) const { return _plugin->portd(controls[i].idx); }
range(unsigned long i,float * min,float * max)565       void range(unsigned long i, float* min, float* max) const { _plugin->range(controls[i].idx, min, max); }
isAudioIn(unsigned long k)566       bool isAudioIn(unsigned long k) { return (_plugin->portd(k) & IS_AUDIO_IN) == IS_AUDIO_IN; }
isAudioOut(unsigned long k)567       bool isAudioOut(unsigned long k) { return (_plugin->portd(k) & IS_AUDIO_OUT) == IS_AUDIO_OUT; }
range(unsigned long i)568       LADSPA_PortRangeHint range(unsigned long i) { return _plugin->range(controls[i].idx); }
rangeOut(unsigned long i)569       LADSPA_PortRangeHint rangeOut(unsigned long i) { return _plugin->range(controlsOut[i].idx); }
usesTransportSource()570       bool usesTransportSource() const { return _plugin->usesTimePosition(); };
hasLatencyOutPort()571       bool hasLatencyOutPort() const { return _hasLatencyOutPort; }
latencyOutPortIndex()572       unsigned long latencyOutPortIndex() const { return _latencyOutPort; }
573       float latency() const;
ctrlValueType(unsigned long i)574       CtrlValueType ctrlValueType(unsigned long i) const { return _plugin->ctrlValueType(controls[i].idx); }
ctrlEnumValues(unsigned long i)575       CtrlEnumValues* ctrlEnumValues( unsigned long i) const { return _plugin->ctrlEnumValues(controls[i].idx); }
ctrlMode(unsigned long i)576       CtrlList::Mode ctrlMode(unsigned long i) const { return _plugin->ctrlMode(controls[i].idx); }
577       virtual void setCustomData(const std::vector<QString> &customParams);
578       };
579 
580 //---------------------------------------------------------
581 //   Pipeline
582 //    chain of connected efx inserts
583 //---------------------------------------------------------
584 
585 class Pipeline : public std::vector<PluginI*> {
586    private:
587       float* buffer[MusECore::MAX_CHANNELS];
588       void initBuffers();
589    public:
590       Pipeline();
591       Pipeline(const Pipeline&, AudioTrack*);
592       ~Pipeline();
593       void insert(PluginI* p, int index);
594       void remove(int index);
595       void removeAll();
596       bool isOn(int idx) const;
597       void setOn(int, bool);
598       QString label(int idx) const;
599       QString name(int idx) const;
600       QString uri(int idx) const;
601       void showGui(int, bool);
602       bool isDssiPlugin(int) const;
603       bool isLV2Plugin(int idx) const;
604       bool isVstNativePlugin(int idx) const;
605       bool has_dssi_ui(int idx) const;
606       void showNativeGui(int, bool);
607       void deleteGui(int idx);
608       void deleteAllGuis();
609       bool guiVisible(int);
610       bool nativeGuiVisible(int);
611       void apply(unsigned pos, unsigned long ports, unsigned long nframes, float** buffer);
612       void move(int idx, bool up);
613       bool empty(int idx) const;
614       void setChannels(int);
615       bool addScheduledControlEvent(int track_ctrl_id, double val, unsigned frame); // returns true if event cannot be delivered
616       void enableController(int track_ctrl_id, bool en);
617       bool controllerEnabled(int track_ctrl_id);
618       float latency() const;
619       };
620 
621 typedef Pipeline::iterator iPluginI;
622 typedef Pipeline::const_iterator ciPluginI;
623 
624 extern void initPlugins();
625 
626 extern bool ladspaDefaultValue(const LADSPA_Descriptor* plugin, unsigned long port, float* val);
627 extern void ladspaControlRange(const LADSPA_Descriptor* plugin, unsigned long port, float* min, float* max);
628 extern bool ladspa2MidiControlValues(const LADSPA_Descriptor* plugin, unsigned long port, int ctlnum, int* min, int* max, int* def);
629 extern float midi2LadspaValue(const LADSPA_Descriptor* plugin, unsigned long port, int ctlnum, int val);
630 extern CtrlValueType ladspaCtrlValueType(const LADSPA_Descriptor* plugin, int port);
631 extern CtrlList::Mode ladspaCtrlMode(const LADSPA_Descriptor* plugin, int port);
632 
633 } // namespace MusECore
634 
635 
636 namespace MusEGui {
637 class DoubleLabel;
638 
639 //   PluginLoader
640 //---------------------------------------------------------
641 
642 class PluginLoader : public QUiLoader
643 {
644    public:
645       virtual QWidget* createWidget(const QString & className, QWidget * parent = 0, const QString & name = QString());
QUiLoader(parent)646       PluginLoader(QObject * parent = 0) : QUiLoader(parent) {}
647 };
648 
649 //---------------------------------------------------------
650 //   GuiParam
651 //---------------------------------------------------------
652 
653 struct GuiParam {
654       enum {
655             GUI_SLIDER, GUI_SWITCH, GUI_METER, GUI_ENUM
656             };
657       int type;
658       int hint;
659       bool pressed;
660 
661       MusEGui::DoubleLabel* label;
662       QWidget* actuator;  // Slider or Toggle Button (SWITCH)
663       };
664 
665 //---------------------------------------------------------
666 //   GuiWidgets
667 //---------------------------------------------------------
668 
669 struct GuiWidgets {
670       enum {
671             SLIDER, DOUBLE_LABEL, QCHECKBOX, QCOMBOBOX
672             };
673       QWidget* widget;
674       int type;
675       unsigned long param;
676       bool pressed;
677       };
678 
679 //---------------------------------------------------------
680 //   PluginGui
681 //---------------------------------------------------------
682 
683 class PluginGui : public QMainWindow {
684       Q_OBJECT
685 
686       MusECore::PluginIBase* plugin;        // plugin instance
687 
688       GuiParam* params;
689       GuiParam* paramsOut;
690       unsigned long nobj;             // number of widgets in gw
691       GuiWidgets* gw;
692 
693       QAction* onOff;
694 //      QAction* transpGovLatencyAct;
695 //      QAction* fixedSpeedAct;
696 //      QAction* overrideLatencyAct;
697 //      QSpinBox* latencyOverrideEntry;
698       QWidget* mw;            // main widget
699       QScrollArea* view;
700 //      QToolButton* fixNativeUIScalingTB;
701 //      QString fixScalingTooltip[3];
702 
703       void updateControls();
704       void getPluginConvertedValues(LADSPA_PortRangeHint range,
705                      double &lower, double &upper, double &dlower, double &dupper, double &dval);
706       void constructGUIFromFile(QFile& uifile);
707       void constructGUIFromPluginMetadata();
708 
709    protected:
710       virtual void showEvent(QShowEvent *e);
711       virtual void hideEvent(QHideEvent *e);
712 
713    private slots:
714       void load();
715       void save();
716       void bypassToggled(bool);
717       void showSettings();
718 //      void transportGovernsLatencyToggled(bool);
719 //      void fixNativeUIScalingTBClicked();
720 //      void fixedSpeedToggled(bool);
721 //      void overrideReportedLatencyToggled(bool);
722 //      void latencyOverrideValueChanged(int);
723       void sliderChanged(double value, int id, int scrollMode);
724       void labelChanged(double, int);
725       void comboChanged(unsigned long);
726       void guiParamChanged(unsigned long int);
727       void sliderPressed(double, int);
728       void sliderReleased(double, int);
729       void switchPressed(int);
730       void switchReleased(int);
731       void guiParamPressed(unsigned long int);
732       void guiParamReleased(unsigned long int);
733       void guiSliderPressed(double, unsigned long int);
734       void guiSliderReleased(double, unsigned long int);
735       void ctrlRightClicked(const QPoint &, int);
736       void guiSliderRightClicked(const QPoint &, unsigned long int);
737       void guiContextMenuReq(unsigned long int idx);
738 
739    protected slots:
740       virtual void heartBeat();
741 
742    public:
743       PluginGui(MusECore::PluginIBase*);
744 
745       ~PluginGui();
746       void setOn(bool);
747       void updateValues();
748       void updateWindowTitle();
749       };
750 
751 
752 } // namespace MusEGui
753 
754 namespace MusEGlobal {
755 extern MusECore::PluginList plugins;
756 extern MusECore::PluginGroups plugin_groups;
757 extern QList<QString> plugin_group_names;
758 
759 void writePluginGroupConfiguration(int level, MusECore::Xml& xml);
760 void readPluginGroupConfiguration(MusECore::Xml& xml);
761 }
762 #endif
763 
764