1 /************************************************************************
2  ************************************************************************
3     FAUST Architecture File
4     Copyright (C) 2009-2016 Albert Graef <aggraef@gmail.com>
5     ---------------------------------------------------------------------
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU Lesser General Public License as
8     published by the Free Software Foundation; either version 3 of the
9     License, or (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU Lesser General Public License for more details.
15 
16     You should have received a copy of the GNU Lesser General Public
17     License along with the GNU C Library; if not, write to the Free
18     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19     02111-1307 USA.
20  ************************************************************************
21  ************************************************************************/
22 
23 /* LV2 architecture for Faust synths. */
24 
25 /* NOTE: This requires one of the Boost headers (boost/circular_buffer.hpp),
26    so to compile Faust programs created with this architecture you need to
27    have at least the Boost headers installed somewhere on your include path
28    (the Boost libraries aren't needed). */
29 
30 #include <stdlib.h>
31 #include <string.h>
32 #include <math.h>
33 #include <list>
34 #include <map>
35 #include <set>
36 
37 // generic Faust dsp and UI classes
38 #include <faust/dsp/dsp.h>
39 #include <faust/gui/UI.h>
40 
41 using namespace std;
42 
43 typedef pair<const char*,const char*> strpair;
44 
45 struct Meta : std::map<const char*, const char*>
46 {
declareMeta47   void declare(const char *key, const char *value)
48   {
49     (*this)[key] = value;
50   }
getMeta51   const char* get(const char *key, const char *def)
52   {
53     if (this->find(key) != this->end())
54       return (*this)[key];
55     else
56       return def;
57   }
58 };
59 
60 /******************************************************************************
61 *******************************************************************************
62 
63 		       VECTOR INTRINSICS
64 
65 *******************************************************************************
66 *******************************************************************************/
67 
68 <<includeIntrinsic>>
69 
70 /***************************************************************************
71    LV2 UI interface
72  ***************************************************************************/
73 
74 enum ui_elem_type_t {
75   UI_BUTTON, UI_CHECK_BUTTON,
76   UI_V_SLIDER, UI_H_SLIDER, UI_NUM_ENTRY,
77   UI_V_BARGRAPH, UI_H_BARGRAPH,
78   UI_END_GROUP, UI_V_GROUP, UI_H_GROUP, UI_T_GROUP
79 };
80 
81 struct ui_elem_t {
82   ui_elem_type_t type;
83   const char *label;
84   int port;
85   float *zone;
86   void *ref;
87   float init, min, max, step;
88 };
89 
90 class LV2UI : public UI
91 {
92 public:
93   bool is_instr;
94   int nelems, nports;
95   ui_elem_t *elems;
96   map< int, list<strpair> > metadata;
97 
98   LV2UI(int maxvoices = 0);
99   virtual ~LV2UI();
100 
101 protected:
102   void add_elem(ui_elem_type_t type, const char *label = NULL);
103   void add_elem(ui_elem_type_t type, const char *label, float *zone);
104   void add_elem(ui_elem_type_t type, const char *label, float *zone,
105 		float init, float min, float max, float step);
106   void add_elem(ui_elem_type_t type, const char *label, float *zone,
107 		float min, float max);
108 
109   bool have_freq, have_gain, have_gate;
110   bool is_voice_ctrl(const char *label);
111 
112 public:
113   virtual void addButton(const char* label, float* zone);
114   virtual void addCheckButton(const char* label, float* zone);
115   virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);
116   virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);
117   virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
118 
119   virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
120   virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
121 
addSoundfile(const char * label,const char * filename,Soundfile ** sf_zone)122   virtual void addSoundfile(const char* label, const char* filename, Soundfile** sf_zone) {}
123 
124   virtual void openTabBox(const char* label);
125   virtual void openHorizontalBox(const char* label);
126   virtual void openVerticalBox(const char* label);
127   virtual void closeBox();
128 
129   virtual void run();
130 
131   virtual void declare(float* zone, const char* key, const char* value);
132 };
133 
LV2UI(int maxvoices)134 LV2UI::LV2UI(int maxvoices)
135 {
136   is_instr = maxvoices>0;
137   have_freq = have_gain = have_gate = false;
138   nelems = nports = 0;
139   elems = NULL;
140 }
141 
~LV2UI()142 LV2UI::~LV2UI()
143 {
144   if (elems) free(elems);
145 }
146 
declare(float * zone,const char * key,const char * value)147 void LV2UI::declare(float* zone, const char* key, const char* value)
148 {
149   map< int, list<strpair> >::iterator it = metadata.find(nelems);
150   if (it != metadata.end())
151     it->second.push_back(strpair(key, value));
152   else
153     metadata[nelems] = list<strpair>(1, strpair(key, value));
154 }
155 
add_elem(ui_elem_type_t type,const char * label)156 inline void LV2UI::add_elem(ui_elem_type_t type, const char *label)
157 {
158   ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
159   if (elems1)
160     elems = elems1;
161   else
162     return;
163   elems[nelems].type = type;
164   elems[nelems].label = label;
165   elems[nelems].port = -1;
166   elems[nelems].zone = NULL;
167   elems[nelems].ref = NULL;
168   elems[nelems].init = 0.0;
169   elems[nelems].min = 0.0;
170   elems[nelems].max = 0.0;
171   elems[nelems].step = 0.0;
172   nelems++;
173 }
174 
175 #define portno(label) (is_voice_ctrl(label)?-1:nports++)
176 
add_elem(ui_elem_type_t type,const char * label,float * zone)177 inline void LV2UI::add_elem(ui_elem_type_t type, const char *label, float *zone)
178 {
179   ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
180   if (elems1)
181     elems = elems1;
182   else
183     return;
184   elems[nelems].type = type;
185   elems[nelems].label = label;
186   elems[nelems].port = portno(label);
187   elems[nelems].zone = zone;
188   elems[nelems].ref = NULL;
189   elems[nelems].init = 0.0;
190   elems[nelems].min = 0.0;
191   elems[nelems].max = 0.0;
192   elems[nelems].step = 0.0;
193   nelems++;
194 }
195 
add_elem(ui_elem_type_t type,const char * label,float * zone,float init,float min,float max,float step)196 inline void LV2UI::add_elem(ui_elem_type_t type, const char *label, float *zone,
197 			     float init, float min, float max, float step)
198 {
199   ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
200   if (elems1)
201     elems = elems1;
202   else
203     return;
204   elems[nelems].type = type;
205   elems[nelems].label = label;
206   elems[nelems].port = portno(label);
207   elems[nelems].zone = zone;
208   elems[nelems].ref = NULL;
209   elems[nelems].init = init;
210   elems[nelems].min = min;
211   elems[nelems].max = max;
212   elems[nelems].step = step;
213   nelems++;
214 }
215 
add_elem(ui_elem_type_t type,const char * label,float * zone,float min,float max)216 inline void LV2UI::add_elem(ui_elem_type_t type, const char *label, float *zone,
217 			     float min, float max)
218 {
219   ui_elem_t *elems1 = (ui_elem_t*)realloc(elems, (nelems+1)*sizeof(ui_elem_t));
220   if (elems1)
221     elems = elems1;
222   else
223     return;
224   elems[nelems].type = type;
225   elems[nelems].label = label;
226   elems[nelems].port = portno(label);
227   elems[nelems].zone = zone;
228   elems[nelems].ref = NULL;
229   elems[nelems].init = 0.0;
230   elems[nelems].min = min;
231   elems[nelems].max = max;
232   elems[nelems].step = 0.0;
233   nelems++;
234 }
235 
is_voice_ctrl(const char * label)236 inline bool LV2UI::is_voice_ctrl(const char *label)
237 {
238   if (!is_instr)
239     return false;
240   else if (!have_freq && !strcmp(label, "freq"))
241     return (have_freq = true);
242   else if (!have_gain && !strcmp(label, "gain"))
243     return (have_gain = true);
244   else if (!have_gate && !strcmp(label, "gate"))
245     return (have_gate = true);
246   else
247     return false;
248 }
249 
addButton(const char * label,float * zone)250 void LV2UI::addButton(const char* label, float* zone)
251 { add_elem(UI_BUTTON, label, zone); }
addCheckButton(const char * label,float * zone)252 void LV2UI::addCheckButton(const char* label, float* zone)
253 { add_elem(UI_CHECK_BUTTON, label, zone); }
addVerticalSlider(const char * label,float * zone,float init,float min,float max,float step)254 void LV2UI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
255 { add_elem(UI_V_SLIDER, label, zone, init, min, max, step); }
addHorizontalSlider(const char * label,float * zone,float init,float min,float max,float step)256 void LV2UI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
257 { add_elem(UI_H_SLIDER, label, zone, init, min, max, step); }
addNumEntry(const char * label,float * zone,float init,float min,float max,float step)258 void LV2UI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
259 { add_elem(UI_NUM_ENTRY, label, zone, init, min, max, step); }
260 
addHorizontalBargraph(const char * label,float * zone,float min,float max)261 void LV2UI::addHorizontalBargraph(const char* label, float* zone, float min, float max)
262 { add_elem(UI_H_BARGRAPH, label, zone, min, max); }
addVerticalBargraph(const char * label,float * zone,float min,float max)263 void LV2UI::addVerticalBargraph(const char* label, float* zone, float min, float max)
264 { add_elem(UI_V_BARGRAPH, label, zone, min, max); }
265 
openTabBox(const char * label)266 void LV2UI::openTabBox(const char* label)
267 { add_elem(UI_T_GROUP, label); }
openHorizontalBox(const char * label)268 void LV2UI::openHorizontalBox(const char* label)
269 { add_elem(UI_H_GROUP, label); }
openVerticalBox(const char * label)270 void LV2UI::openVerticalBox(const char* label)
271 { add_elem(UI_V_GROUP, label); }
closeBox()272 void LV2UI::closeBox()
273 { add_elem(UI_END_GROUP); }
274 
run()275 void LV2UI::run() {}
276 
277 //----------------------------------------------------------------------------
278 //  FAUST generated signal processor
279 //----------------------------------------------------------------------------
280 
281 <<includeclass>>
282 
283 //----------------------------------------------------------------------------
284 //  LV2 interface
285 //----------------------------------------------------------------------------
286 
287 #line 286 "lv2.cpp"
288 
289 #include <assert.h>
290 #include <stdio.h>
291 #include <stdlib.h>
292 
293 #include <bitset>
294 #include <boost/circular_buffer.hpp>
295 
296 #include <lv2/lv2plug.in/ns/lv2core/lv2.h>
297 #include <lv2/lv2plug.in/ns/ext/dynmanifest/dynmanifest.h>
298 #include <lv2/lv2plug.in/ns/ext/atom/util.h>
299 #include <lv2/lv2plug.in/ns/ext/urid/urid.h>
300 
301 // Set this to the proper shared library extension for your system
302 #ifndef DLLEXT
303 #define DLLEXT ".so"
304 #endif
305 
306 #ifndef URI_PREFIX
307 #define URI_PREFIX "https://faustlv2.bitbucket.io"
308 #endif
309 
310 #ifndef PLUGIN_URI
311 #define PLUGIN_URI URI_PREFIX "/mydsp"
312 #endif
313 
314 #define MIDI_EVENT_URI "http://lv2plug.in/ns/ext/midi#MidiEvent"
315 
316 /* Setting NVOICES at compile time overrides meta data in the Faust source. If
317    set, this must be an integer value >= 0. A nonzero value indicates an
318    instrument (VSTi) plugin with the given maximum number of voices. Use 1 for
319    a monophonic synthesizer, and 0 for a simple effect plugin. If NVOICES
320    isn't defined at compile time then the number of voices of an instrument
321    plugin can also be set with the global "nvoices" meta data key in the Faust
322    source. This setting also adds a special "polyphony" control to the plugin
323    which can be used to dynamically adjust the actual number of voices in the
324    range 1..NVOICES. */
325 //#define NVOICES 16
326 
327 /* This enables a special "tuning" control for instruments which lets you
328    select the MTS tuning to be used for the synth. In order to use this, you
329    just drop some sysex (.syx) files with MTS octave-based tunings in 1- or
330    2-byte format into the ~/.fautvst/tuning directory (these can be generated
331    with the author's sclsyx program, https://bitbucket.org/agraef/sclsyx).
332    The control will only be shown if any .syx files were found at startup. 0
333    selects the default tuning (standard 12-tone equal temperament), i>0 the
334    tuning in the ith sysex file (in alphabetic order). */
335 #ifndef FAUST_MTS
336 #define FAUST_MTS 1
337 #endif
338 
339 /* This allows various manifest data to be generated from the corresponding
340    metadata (author, name, description, license) in the Faust source. */
341 #ifndef FAUST_META
342 #define FAUST_META 1
343 #endif
344 
345 /* This enables automatic MIDI controller mapping based on the midi:ctrl
346    attributes in the Faust source. We have this enabled by default, but you
347    may have to disable it if the custom controller mapping gets in the way of
348    the automation facilities that the host provides. (But then again if the
349    host wants to do its own controller mapping then it probably won't, or at
350    least shouldn't, send us the MIDI controllers in the first place.) */
351 #ifndef FAUST_MIDICC
352 #define FAUST_MIDICC 1
353 #endif
354 
355 /* This enables or disables the plugin's custom Qt GUI (cf. lv2ui.cpp). Note
356    that this only affects the plugin manifest, the GUI code itself is in a
357    separate module created with the lv2ui.cpp architecture. Also, you'll have
358    to use the alternative lv2ui manifest templates to tell the LV2 host about
359    the GUI. */
360 #ifndef FAUST_UI
361 #define FAUST_UI 0
362 #endif
363 
364 // You can define these for various debugging output items.
365 //#define DEBUG_META 1 // recognized MIDI controller metadata
366 //#define DEBUG_VOICES 1 // triggering of synth voices
367 //#define DEBUG_VOICE_ALLOC 1 // voice allocation
368 //#define DEBUG_MIDI 1 // incoming MIDI messages
369 //#define DEBUG_NOTES 1 // note messages
370 //#define DEBUG_MIDICC 1 // controller messages
371 //#define DEBUG_RPN 1 // RPN messages (pitch bend range, master tuning)
372 //#define DEBUG_MTS 1 // MTS messages (octave/scale tuning)
373 
374 // Note and voice data structures.
375 
376 struct NoteInfo {
377   uint8_t ch;
378   int8_t note;
379 };
380 
381 struct VoiceData {
382   // Octave tunings (offsets in semitones) per MIDI channel.
383   float tuning[16][12];
384   // Allocated voices per MIDI channel and note.
385   int8_t notes[16][128];
386   // Free and used voices.
387   int n_free, n_used;
388   boost::circular_buffer<int> free_voices;
389   boost::circular_buffer<int> used_voices;
390   NoteInfo *note_info;
391   // Voices queued for note-offs (zero-length notes).
392   set<int> queued;
393   // Last gate value during run() for each voice. We need to keep track of
394   // these so that we can force the Faust synth to retrigger a note when
395   // needed.
396   float *lastgate;
397   // Current pitch bend and pitch bend range on each MIDI channel, in semitones.
398   float bend[16], range[16];
399   // Current coarse, fine and total master tuning on each MIDI channel (tuning
400   // offset relative to A4 = 440 Hz, in semitones).
401   float coarse[16], fine[16], tune[16];
VoiceDataVoiceData402   VoiceData(int n) : free_voices(n), used_voices(n) { }
403 };
404 
405 #if FAUST_MTS
406 
407 // Helper classes to read and store MTS tunings.
408 
409 #include <sys/types.h>
410 #include <sys/stat.h>
411 #include <dirent.h>
412 
413 #include <string>
414 #include <vector>
415 
416 struct MTSTuning {
417   char *name; // name of the tuning
418   int len; // length of sysex data in bytes
419   unsigned char *data; // sysex data
MTSTuningMTSTuning420   MTSTuning() : name(0), len(0), data(0) {}
operator =MTSTuning421   MTSTuning& operator=(const MTSTuning &t)
422   {
423     if (this == &t) return *this;
424     if (name) free(name); if (data) free(data);
425     name = 0; data = 0; len = t.len;
426     if (t.name) {
427       name = strdup(t.name); assert(name);
428     }
429     if (t.data) {
430       data = (unsigned char*)malloc(len); assert(data);
431       memcpy(data, t.data, len);
432     }
433     return *this;
434   }
MTSTuningMTSTuning435   MTSTuning(const MTSTuning& t) : name(0), len(0), data(0)
436   { *this = t; }
437   MTSTuning(const char *filename);
~MTSTuningMTSTuning438   ~MTSTuning()
439   { if (name) free(name); if (data) free(data); }
440 };
441 
MTSTuning(const char * filename)442 MTSTuning::MTSTuning(const char *filename)
443 {
444   FILE *fp = fopen(filename, "rb");
445   name = 0; len = 0; data = 0;
446   if (!fp) return;
447   struct stat st;
448   if (fstat(fileno(fp), &st)) return;
449   len = st.st_size;
450   data = (unsigned char*)calloc(len, 1);
451   if (!data) {
452     len = 0; fclose(fp);
453     return;
454   }
455   assert(len > 0);
456   if (fread(data, 1, len, fp) < len) {
457     free(data); len = 0; data = 0; fclose(fp);
458     return;
459   }
460   fclose(fp);
461   // Do some basic sanity checks.
462   if (data[0] != 0xf0 || data[len-1] != 0xf7 || // not a sysex message
463       (data[1] != 0x7e && data[1] != 0x7f) || data[3] != 8 || // not MTS
464       !((len == 21 && data[4] == 8) ||
465 	(len == 33 && data[4] == 9))) { // no 1- or 2-byte tuning
466     free(data); len = 0; data = 0;
467     return;
468   }
469   // Name of the tuning is the basename of the file, without the trailing .syx
470   // suffix.
471   string nm = filename;
472   size_t p = nm.rfind(".syx");
473   if (p != string::npos) nm.erase(p);
474   p = nm.rfind('/');
475   if (p != string::npos) nm.erase(0, p+1);
476   name = strdup(nm.c_str());
477   assert(name);
478 }
479 
480 struct MTSTunings {
481   vector<MTSTuning> tuning;
MTSTuningsMTSTunings482   MTSTunings() {}
483   MTSTunings(const char *path);
484 };
485 
compareByName(const MTSTuning & a,const MTSTuning & b)486 static bool compareByName(const MTSTuning &a, const MTSTuning &b)
487 {
488   return strcmp(a.name, b.name) < 0;
489 }
490 
MTSTunings(const char * path)491 MTSTunings::MTSTunings(const char *path)
492 {
493   DIR *dp = opendir(path);
494   if (!dp) return;
495   struct dirent *d;
496   while ((d = readdir(dp))) {
497     string nm = d->d_name;
498     if (nm.length() > 4 && nm.substr(nm.length()-4) == ".syx") {
499       string pathname = path;
500       pathname += "/";
501       pathname += nm;
502       MTSTuning t(pathname.c_str());
503       if (t.data) tuning.push_back(t);
504     }
505   }
506   closedir(dp);
507   // sort found tunings by name
508   sort(tuning.begin(), tuning.end(), compareByName);
509 }
510 
511 #endif
512 
513 #if FAUST_MIDICC
ctrlval(const ui_elem_t & el,uint8_t v)514 static float ctrlval(const ui_elem_t &el, uint8_t v)
515 {
516   // Translate the given MIDI controller value to the range and stepsize
517   // indicated by the Faust control.
518   switch (el.type) {
519   case UI_BUTTON: case UI_CHECK_BUTTON:
520     return (float)(v>=64);
521   default:
522     /* Continuous controllers. The problem here is that the range 0..127 is
523        not symmetric. We'd like to map 64 to the center of the range
524        (max-min)/2 and at the same time retain the full control range
525        min..max. So let's just pretend that there are 128 controller values
526        and map value 127 to the max value anyway. */
527     if (v==127)
528       return el.max;
529     else
530       // XXXFIXME: We might want to add proper quantization according to
531       // el.step here.
532       return el.min+(el.max-el.min)*v/128;
533   }
534 }
535 #endif
536 
537 /***************************************************************************/
538 
539 /* Polyphonic Faust plugin data structure. XXXTODO: At present this is just a
540    big struct which exposes all requisite data. Some more work is needed to
541    make the interface a bit more abstract and properly encapsulate the
542    internal data structures, so that implementation details can be changed
543    more easily. */
544 
545 struct LV2Plugin {
546   const int maxvoices;	// maximum number of voices (zero if not an instrument)
547   const int ndsps;	// number of dsp instances (1 if maxvoices==0)
548   bool active;		// activation status
549   int rate;		// sampling rate
550   int nvoices;		// current number of voices (<= maxvoices)
551   int tuning_no;	// current tuning number (<= n_tunings)
552   mydsp **dsp;		// the dsps
553   LV2UI **ui;		// their Faust interface descriptions
554   int n_in, n_out;	// number of input and output control ports
555   int *ctrls;		// Faust ui elements (indices into ui->elems)
556   float **ports;	// corresponding LV2 data
557   float *portvals;	// cached port data from the last run
558   float *midivals[16];	// per-midi channel data
559   int *inctrls, *outctrls;	// indices for active and passive controls
560   float **inputs, **outputs;	// audio buffers
561   int freq, gain, gate;	// indices of voice controls
562   unsigned n_samples;	// current block size
563   float **outbuf;	// audio buffers for mixing down the voices
564   float **inbuf;	// dummy input buffer
565   LV2_Atom_Sequence* event_port; // midi input
566   float *poly, *tuning;	// polyphony and tuning ports
567   std::map<uint8_t,int> ctrlmap; // MIDI controller map
568   // Needed host features.
569   LV2_URID_Map* map;	// the urid extension
570   LV2_URID midi_event;	// midi event uri
571   // Current RPN MSB and LSB numbers, as set with controllers 101 and 100.
572   uint8_t rpn_msb[16], rpn_lsb[16];
573   // Current data entry MSB and LSB numbers, as set with controllers 6 and 38.
574   uint8_t data_msb[16], data_lsb[16];
575   // Synth voice data (instruments only).
576   VoiceData *vd;
577 
578   // Static methods. These all use static data so they can be invoked before
579   // instantiating a plugin.
580 
581   // Global meta data (dsp name, author, etc.).
582   static Meta *meta;
init_metaLV2Plugin583   static void init_meta()
584   {
585     if (!meta && (meta = new Meta)) {
586       // We allocate the temporary dsp object on the heap here, to prevent
587       // large dsp objects from running out of stack in environments where
588       // stack space is precious (e.g., Reaper). Note that if any of these
589       // allocations fail then no meta data will be available, but at least we
590       // won't make the host crash and burn.
591       mydsp* tmp_dsp = new mydsp();
592       if (tmp_dsp) {
593 	tmp_dsp->metadata(meta);
594 	delete tmp_dsp;
595       }
596     }
597   }
meta_getLV2Plugin598   static const char *meta_get(const char *key, const char *deflt)
599   {
600     init_meta();
601     return meta?meta->get(key, deflt):deflt;
602   }
603 
pluginNameLV2Plugin604   static const char *pluginName()
605   {
606     return meta_get("name", "mydsp");
607   }
608 
pluginAuthorLV2Plugin609   static const char *pluginAuthor()
610   {
611     return meta_get("author", "");
612   }
613 
pluginDescriptionLV2Plugin614   static const char *pluginDescription()
615   {
616     return meta_get("description", "");
617   }
618 
pluginLicenseLV2Plugin619   static const char *pluginLicense()
620   {
621     return meta_get("license", "");
622   }
623 
pluginVersionLV2Plugin624   static const char *pluginVersion()
625   {
626     return meta_get("version", "");
627   }
628 
629   // Load a collection of sysex files with MTS tunings in ~/.faust/tuning.
630   static int n_tunings;
631 #if FAUST_MTS
632   static MTSTunings *mts;
633 
load_sysex_dataLV2Plugin634   static MTSTunings *load_sysex_data()
635   {
636     if (!mts) {
637       string mts_path;
638       // Look for FAUST_HOME. If that isn't set, try $HOME/.faust. If HOME
639       // isn't set either, just assume a .faust subdir of the cwd.
640       const char *home = getenv("FAUST_HOME");
641       if (home)
642 	mts_path = home;
643       else {
644 	home = getenv("HOME");
645 	if (home) {
646 	  mts_path = home;
647 	  mts_path += "/.faust";
648 	} else
649 	  mts_path = ".faust";
650       }
651       // MTS tunings are looked for in this subdir.
652       mts_path += "/tuning";
653       mts = new MTSTunings(mts_path.c_str());
654 #ifdef __APPLE__
655       if (!mts || mts->tuning.size() == 0) {
656 	// Also check ~/Library/Faust/Tuning on the Mac.
657 	home = getenv("HOME");
658 	if (home) {
659 	  if (mts) delete mts;
660 	  mts_path = home;
661 	  mts_path += "/Library/Faust/Tuning";
662 	  mts = new MTSTunings(mts_path.c_str());
663 	}
664       }
665 #endif
666       n_tunings = mts->tuning.size();
667     }
668     return mts;
669   }
670 #endif
671 
672   // The number of voices of an instrument plugin. We get this information
673   // from the global meta data (nvoices key) of the dsp module if present, and
674   // you can also override this setting at compile time by defining the
675   // NVOICES macro. If neither is defined or the value is zero then the plugin
676   // becomes a simple audio effect instead.
numVoicesLV2Plugin677   static int numVoices()
678   {
679 #ifdef NVOICES
680     return NVOICES;
681 #else
682     const char *numVoices = meta_get("nvoices", "0");
683     int nvoices = atoi(numVoices);
684     if (nvoices < 0 ) nvoices = 0;
685     return nvoices;
686 #endif
687   }
688 
689   // Instance methods.
690 
LV2PluginLV2Plugin691   LV2Plugin(const int num_voices, const int sr)
692     : maxvoices(num_voices), ndsps(num_voices<=0?1:num_voices),
693       vd(num_voices>0?new VoiceData(num_voices):0)
694   {
695     // Initialize static data.
696     init_meta();
697 #if FAUST_MTS
698     // Synth: load tuning sysex data if present.
699     if (num_voices>0) load_sysex_data();
700 #endif
701     // Allocate data structures and set some reasonable defaults.
702     dsp = (mydsp**)calloc(ndsps, sizeof(mydsp*));
703     ui = (LV2UI**)calloc(ndsps, sizeof(LV2UI*));
704     assert(dsp && ui);
705     if (vd) {
706       vd->note_info = (NoteInfo*)calloc(ndsps, sizeof(NoteInfo));
707       vd->lastgate = (float*)calloc(ndsps, sizeof(float));
708       assert(vd->note_info && vd->lastgate);
709     }
710     active = false;
711     rate = sr;
712     nvoices = maxvoices;
713     tuning_no = 0;
714     n_in = n_out = 0;
715     map = NULL;
716     midi_event = -1;
717     event_port = NULL;
718     poly = tuning = NULL;
719     freq = gain = gate = -1;
720     if (vd) {
721       vd->n_free = maxvoices;
722       for (int i = 0; i < maxvoices; i++) {
723 	vd->free_voices.push_back(i);
724 	vd->lastgate[i] = 0.0f;
725       }
726       for (int i = 0; i < 16; i++) {
727 	vd->bend[i] = 0.0f;
728 	vd->range[i] = 2.0f;
729 	vd->coarse[i] = vd->fine[i] = vd->tune[i] = 0.0f;
730 	for (int j = 0; j < 12; j++)
731 	  vd->tuning[i][j] = 0.0f;
732       }
733       vd->n_used = 0;
734       memset(vd->notes, 0xff, sizeof(vd->notes));
735     }
736     n_samples = 0;
737     ctrls = inctrls = outctrls = NULL;
738     ports = inputs = outputs = inbuf = outbuf = NULL;
739     portvals = NULL;
740     memset(midivals, 0, sizeof(midivals));
741     // Initialize the Faust DSPs.
742     for (int i = 0; i < ndsps; i++) {
743       dsp[i] = new mydsp();
744       ui[i] = new LV2UI(num_voices);
745       dsp[i]->init(rate);
746       dsp[i]->buildUserInterface(ui[i]);
747     }
748     // The ports are numbered as follows: 0..k-1 are the control ports, then
749     // come the n audio input ports, then the m audio output ports, and
750     // finally the midi input port and the polyphony and tuning controls.
751     int k = ui[0]->nports, p = 0, q = 0;
752     int n = dsp[0]->getNumInputs(), m = dsp[0]->getNumOutputs();
753     // Allocate tables for the built-in control elements and their ports.
754     ctrls = (int*)calloc(k, sizeof(int));
755     inctrls = (int*)calloc(k, sizeof(int));
756     outctrls = (int*)calloc(k, sizeof(int));
757     ports = (float**)calloc(k, sizeof(float*));
758     portvals = (float*)calloc(k, sizeof(float));
759     assert(k == 0 || (ctrls && inctrls && outctrls && ports && portvals));
760     for (int ch = 0; ch < 16; ch++) {
761       midivals[ch] = (float*)calloc(k, sizeof(float));
762       assert(k == 0 || midivals[ch]);
763     }
764     // Scan the Faust UI for active and passive controls which become the
765     // input and output control ports of the plugin, respectively.
766     for (int i = 0, j = 0; i < ui[0]->nelems; i++) {
767       switch (ui[0]->elems[i].type) {
768       case UI_T_GROUP: case UI_H_GROUP: case UI_V_GROUP: case UI_END_GROUP:
769 	// control groups (ignored right now)
770 	break;
771       case UI_H_BARGRAPH: case UI_V_BARGRAPH:
772 	// passive controls (output ports)
773 	ctrls[j++] = i;
774 	outctrls[q++] = i;
775 	break;
776       default:
777 	// active controls (input ports)
778 	if (maxvoices == 0)
779 	  goto noinstr;
780 	else if (freq == -1 &&
781 		 !strcmp(ui[0]->elems[i].label, "freq"))
782 	  freq = i;
783 	else if (gain == -1 &&
784 		 !strcmp(ui[0]->elems[i].label, "gain"))
785 	  gain = i;
786 	else if (gate == -1 &&
787 		 !strcmp(ui[0]->elems[i].label, "gate"))
788 	  gate = i;
789 	else {
790 	noinstr:
791 #if FAUST_MIDICC
792 	  std::map< int, list<strpair> >::iterator it =
793 	    ui[0]->metadata.find(i);
794 	  if (it != ui[0]->metadata.end()) {
795 	    // Scan for controller mappings.
796 	    for (std::list<strpair>::iterator jt = it->second.begin();
797 		 jt != it->second.end(); jt++) {
798 	      const char *key = jt->first, *val = jt->second;
799 #if DEBUG_META
800 	      fprintf(stderr, "ctrl '%s' meta: '%s' -> '%s'\n",
801 		      ui[0]->elems[i].label, key, val);
802 #endif
803 	      if (strcmp(key, "midi") == 0) {
804 		unsigned num;
805 		if (sscanf(val, "ctrl %u", &num) < 1) continue;
806 #if 0 // enable this to get feedback about controller assignments
807 		fprintf(stderr, "%s: cc %d -> %s\n", PLUGIN_URI, num,
808 			ui[0]->elems[i].label);
809 #endif
810 		ctrlmap.insert(std::pair<uint8_t,int>(num, p));
811 	      }
812 	    }
813 	  }
814 #endif
815 	  ctrls[j++] = i;
816 	  inctrls[p++] = i;
817 	  int p = ui[0]->elems[i].port;
818 	  float val = ui[0]->elems[i].init;
819 	  assert(p>=0);
820 	  portvals[p] = val;
821 	  for (int ch = 0; ch < 16; ch++)
822 	    midivals[ch][p] = val;
823 	}
824 	break;
825       }
826     }
827     // Realloc the inctrls and outctrls vectors to their appropriate sizes.
828     inctrls = (int*)realloc(inctrls, p*sizeof(int));
829     assert(p == 0 || inctrls);
830     outctrls = (int*)realloc(outctrls, q*sizeof(int));
831     assert(q == 0 || outctrls);
832     n_in = p; n_out = q;
833     // Allocate vectors for the audio input and output ports. Like
834     // ports, these will be initialized in the connect_port callback.
835     inputs = (float**)calloc(n, sizeof(float*));
836     assert(n == 0 || inputs);
837     outputs = (float**)calloc(m, sizeof(float*));
838     assert(m == 0 || outputs);
839     if (maxvoices > 0) {
840       // Initialize the mixdown buffer.
841       outbuf = (float**)calloc(m, sizeof(float*));
842       assert(m == 0 || outbuf);
843       // We start out with a blocksize of 512 samples here. Hopefully this is
844       // enough for most realtime hosts so that we can avoid reallocations
845       // later when we know what the actual blocksize is.
846       n_samples = 512;
847       for (int i = 0; i < m; i++) {
848 	outbuf[i] = (float*)malloc(n_samples*sizeof(float));
849 	assert(outbuf[i]);
850       }
851       // Initialize a 1-sample dummy input buffer used for retriggering notes.
852       inbuf = (float**)calloc(n, sizeof(float*));
853       assert(n == 0 || inbuf);
854       for (int i = 0; i < m; i++) {
855 	inbuf[i] = (float*)malloc(sizeof(float));
856 	assert(inbuf[i]);
857 	*inbuf[i] = 0.0f;
858       }
859     }
860   }
861 
~LV2PluginLV2Plugin862   ~LV2Plugin()
863   {
864     const int n = dsp[0]->getNumInputs();
865     const int m = dsp[0]->getNumOutputs();
866     for (int i = 0; i < ndsps; i++) {
867       delete dsp[i];
868       delete ui[i];
869     }
870     free(ctrls); free(inctrls); free(outctrls);
871     free(ports); free(portvals);
872     free(inputs); free(outputs);
873     for (int ch = 0; ch < 16; ch++)
874       free(midivals[ch]);
875     if (inbuf) {
876       for (int i = 0; i < n; i++)
877 	free(inbuf[i]);
878       free(inbuf);
879     }
880     if (outbuf) {
881       for (int i = 0; i < m; i++)
882 	free(outbuf[i]);
883       free(outbuf);
884     }
885     free(dsp); free(ui);
886     if (vd) {
887       free(vd->note_info);
888       free(vd->lastgate);
889       delete vd;
890     }
891   }
892   // Voice allocation.
893 
894 #if DEBUG_VOICE_ALLOC
print_voicesLV2Plugin895   void print_voices(const char *msg)
896   {
897     fprintf(stderr, "%s: notes =", msg);
898     for (uint8_t ch = 0; ch < 16; ch++)
899       for (int note = 0; note < 128; note++)
900 	if (vd->notes[ch][note] >= 0)
901 	  fprintf(stderr, " [%d] %d(#%d)", ch, note, vd->notes[ch][note]);
902     fprintf(stderr, "\nqueued (%d):", vd->queued.size());
903     for (int i = 0; i < nvoices; i++)
904       if (vd->queued.find(i) != vd->queued.end()) fprintf(stderr, " #%d", i);
905     fprintf(stderr, "\nused (%d):", vd->n_used);
906     for (boost::circular_buffer<int>::iterator it = vd->used_voices.begin();
907 	 it != vd->used_voices.end(); it++)
908       fprintf(stderr, " #%d->%d", *it, vd->note_info[*it].note);
909     fprintf(stderr, "\nfree (%d):", vd->n_free);
910     for (boost::circular_buffer<int>::iterator it = vd->free_voices.begin();
911 	 it != vd->free_voices.end(); it++)
912       fprintf(stderr, " #%d", *it);
913     fprintf(stderr, "\n");
914   }
915 #endif
916 
alloc_voiceLV2Plugin917   int alloc_voice(uint8_t ch, int8_t note, int8_t vel)
918   {
919     int i = vd->notes[ch][note];
920     if (i >= 0) {
921       // note already playing on same channel, retrigger it
922       voice_off(i);
923       voice_on(i, note, vel, ch);
924       // move this voice to the end of the used list
925       for (boost::circular_buffer<int>::iterator it =
926 	     vd->used_voices.begin();
927 	   it != vd->used_voices.end(); it++) {
928 	if (*it == i) {
929 	  vd->used_voices.erase(it);
930 	  vd->used_voices.push_back(i);
931 	  break;
932 	}
933       }
934 #if DEBUG_VOICE_ALLOC
935       print_voices("retrigger");
936 #endif
937       return i;
938     } else if (vd->n_free > 0) {
939       // take voice from free list
940       int i = vd->free_voices.front();
941       vd->free_voices.pop_front();
942       vd->n_free--;
943       vd->used_voices.push_back(i);
944       vd->note_info[i].ch = ch;
945       vd->note_info[i].note = note;
946       vd->n_used++;
947       voice_on(i, note, vel, ch);
948       vd->notes[ch][note] = i;
949 #if DEBUG_VOICE_ALLOC
950       print_voices("alloc");
951 #endif
952       return i;
953     } else {
954       // steal a voice
955       assert(vd->n_used > 0);
956       // FIXME: Maybe we should look for the oldest note on the *current*
957       // channel here, but this is faster.
958       int i = vd->used_voices.front();
959       int oldch = vd->note_info[i].ch;
960       int oldnote = vd->note_info[i].note;
961       voice_off(i);
962       vd->notes[oldch][oldnote] = -1;
963       vd->queued.erase(i);
964       vd->used_voices.pop_front();
965       vd->used_voices.push_back(i);
966       vd->note_info[i].ch = ch;
967       vd->note_info[i].note = note;
968       voice_on(i, note, vel, ch);
969       vd->notes[ch][note] = i;
970 #if DEBUG_VOICE_ALLOC
971       print_voices("steal");
972 #endif
973       return i;
974     }
975   }
976 
dealloc_voiceLV2Plugin977   int dealloc_voice(uint8_t ch, int8_t note, int8_t vel)
978   {
979     int i = vd->notes[ch][note];
980     if (i >= 0) {
981       if (vd->lastgate[i] == 0.0f && gate >= 0) {
982 	// zero-length note, queued for later
983 	vd->queued.insert(i);
984 	vd->notes[ch][note] = -1;
985 #if DEBUG_VOICE_ALLOC
986 	print_voices("dealloc (queued)");
987 #endif
988 	return i;
989       }
990       assert(vd->n_free < nvoices);
991       vd->free_voices.push_back(i);
992       vd->n_free++;
993       voice_off(i);
994       vd->notes[ch][note] = -1;
995       // erase this voice from the used list
996       for (boost::circular_buffer<int>::iterator it =
997 	     vd->used_voices.begin();
998 	   it != vd->used_voices.end(); it++) {
999 	if (*it == i) {
1000 	  vd->used_voices.erase(it);
1001 	  vd->n_used--;
1002 	  break;
1003 	}
1004       }
1005 #if DEBUG_VOICE_ALLOC
1006       print_voices("dealloc");
1007 #endif
1008       return i;
1009     }
1010     return -1;
1011   }
1012 
1013 
midicpsLV2Plugin1014   float midicps(int8_t note, uint8_t chan)
1015   {
1016     float pitch = note + vd->tune[chan] +
1017       vd->tuning[chan][note%12] + vd->bend[chan];
1018     return 440.0*pow(2, (pitch-69.0)/12.0);
1019   }
1020 
voice_onLV2Plugin1021   void voice_on(int i, int8_t note, int8_t vel, uint8_t ch)
1022   {
1023     if (vd->lastgate[i] == 1.0f && gate >= 0) {
1024       // Make sure that the synth sees the 0.0f gate so that the voice is
1025       // properly retriggered.
1026       *ui[i]->elems[gate].zone = 0.0f;
1027       dsp[i]->compute(1, inbuf, outbuf);
1028     }
1029 #if DEBUG_VOICES
1030     fprintf(stderr, "voice on: %d %d (%g Hz) %d (%g)\n", i,
1031 	    note, midicps(note, ch), vel, vel/127.0);
1032 #endif
1033     if (freq >= 0)
1034       *ui[i]->elems[freq].zone = midicps(note, ch);
1035     if (gate >= 0)
1036       *ui[i]->elems[gate].zone = 1.0f;
1037     if (gain >= 0)
1038       *ui[i]->elems[gain].zone = vel/127.0;
1039     // reinitialize the per-channel control data for this voice
1040     for (int idx = 0; idx < n_in; idx++) {
1041       int j = inctrls[idx], k = ui[0]->elems[j].port;
1042       *ui[i]->elems[j].zone = midivals[ch][k];
1043     }
1044   }
1045 
voice_offLV2Plugin1046   void voice_off(int i)
1047   {
1048 #if DEBUG_VOICES
1049     fprintf(stderr, "voice off: %d\n", i);
1050 #endif
1051     if (gate >= 0)
1052       *ui[i]->elems[gate].zone = 0.0f;
1053   }
1054 
update_voicesLV2Plugin1055   void update_voices(uint8_t chan)
1056   {
1057     // update running voices on the given channel after tuning or pitch bend
1058     // changes
1059     for (boost::circular_buffer<int>::iterator it =
1060 	   vd->used_voices.begin();
1061 	 it != vd->used_voices.end(); it++) {
1062       int i = *it;
1063       if (vd->note_info[i].ch == chan && freq >= 0) {
1064 	int note = vd->note_info[i].note;
1065 	*ui[i]->elems[freq].zone = midicps(note, chan);
1066       }
1067     }
1068   }
1069 
all_notes_offLV2Plugin1070   void all_notes_off()
1071   {
1072     for (int i = 0; i < nvoices; i++)
1073       voice_off(i);
1074     for (int i = 0; i < 16; i++)
1075       vd->bend[i] = 0.0f;
1076     memset(vd->notes, 0xff, sizeof(vd->notes));
1077     vd->free_voices.clear();
1078     vd->n_free = nvoices;
1079     for (int i = 0; i < nvoices; i++)
1080       vd->free_voices.push_back(i);
1081     vd->queued.clear();
1082     vd->used_voices.clear();
1083     vd->n_used = 0;
1084   }
1085 
all_notes_offLV2Plugin1086   void all_notes_off(uint8_t chan)
1087   {
1088     for (boost::circular_buffer<int>::iterator it =
1089 	   vd->used_voices.begin();
1090 	 it != vd->used_voices.end(); ) {
1091       int i = *it;
1092       if (vd->note_info[i].ch == chan) {
1093 	assert(vd->n_free < nvoices);
1094 	vd->free_voices.push_back(i);
1095 	vd->n_free++;
1096 	voice_off(i);
1097 	vd->notes[vd->note_info[i].ch][vd->note_info[i].note] = -1;
1098 	vd->queued.erase(i);
1099 	// erase this voice from the used list
1100 	it = vd->used_voices.erase(it);
1101 	vd->n_used--;
1102 #if DEBUG_VOICE_ALLOC
1103 	print_voices("dealloc (all-notes-off)");
1104 #endif
1105       } else
1106 	it++;
1107     }
1108     vd->bend[chan] = 0.0f;
1109   }
1110 
queued_notes_offLV2Plugin1111   void queued_notes_off()
1112   {
1113     if (vd->queued.empty()) return;
1114     for (int i = 0; i < nvoices; i++)
1115       if (vd->queued.find(i) != vd->queued.end()) {
1116 	assert(vd->n_free < nvoices);
1117 	vd->free_voices.push_back(i);
1118 	vd->n_free++;
1119 	voice_off(i);
1120 	vd->notes[vd->note_info[i].ch][vd->note_info[i].note] = -1;
1121 	vd->queued.erase(i);
1122 	// erase this voice from the used list
1123 	for (boost::circular_buffer<int>::iterator it =
1124 	       vd->used_voices.begin();
1125 	     it != vd->used_voices.end(); it++) {
1126 	  if (*it == i) {
1127 	    vd->used_voices.erase(it);
1128 	    vd->n_used--;
1129 	    break;
1130 	  }
1131 	}
1132 #if DEBUG_VOICE_ALLOC
1133 	print_voices("dealloc (unqueued)");
1134 #endif
1135       }
1136   }
1137 
1138   // Plugin activation status. suspend() deactivates a plugin (disables audio
1139   // processing), resume() reactivates it. Also, set_rate() changes the sample
1140   // rate. Note that the audio and MIDI process functions (see below) can
1141   // still be called in deactivated state, but this is optional. The plugin
1142   // tries to do some reasonable processing in either case, no matter whether
1143   // the host plugin architecture actually executes callbacks in suspended
1144   // state or not.
1145 
suspendLV2Plugin1146   void suspend()
1147   {
1148     active = false;
1149     if (maxvoices > 0) all_notes_off();
1150   }
1151 
resumeLV2Plugin1152   void resume()
1153   {
1154     for (int i = 0; i < ndsps; i++)
1155       dsp[i]->init(rate);
1156     for (int i = 0, j = 0; i < ui[0]->nelems; i++) {
1157       int p = ui[0]->elems[i].port;
1158       if (p >= 0) {
1159 	float val = ui[0]->elems[i].init;
1160 	portvals[p] = val;
1161       }
1162     }
1163     active = true;
1164   }
1165 
set_rateLV2Plugin1166   void set_rate(int sr)
1167   {
1168     rate = sr;
1169     for (int i = 0; i < ndsps; i++)
1170       dsp[i]->init(rate);
1171   }
1172 
1173   // Audio and MIDI process functions. The plugin should run these in the
1174   // appropriate real-time callbacks.
1175 
process_audioLV2Plugin1176   void process_audio(int blocksz, float **inputs, float **outputs)
1177   {
1178     int n = dsp[0]->getNumInputs(), m = dsp[0]->getNumOutputs();
1179     AVOIDDENORMALS;
1180     if (maxvoices > 0) queued_notes_off();
1181     if (!active) {
1182       // Depending on the plugin architecture and host, this code might never
1183       // be invoked, since the plugin is deactivitated at this point. But
1184       // let's do something reasonable here anyway.
1185       if (n == m) {
1186 	// copy inputs to outputs
1187 	for (int i = 0; i < m; i++)
1188 	  for (unsigned j = 0; j < blocksz; j++)
1189 	    outputs[i][j] = inputs[i][j];
1190       } else {
1191 	// silence
1192 	for (int i = 0; i < m; i++)
1193 	  for (unsigned j = 0; j < blocksz; j++)
1194 	    outputs[i][j] = 0.0f;
1195       }
1196       return;
1197     }
1198     // Handle changes in the polyphony and tuning controls.
1199     bool is_instr = maxvoices > 0;
1200     if (is_instr) {
1201       if (!poly)
1202 	; // this shouldn't happen but...
1203       else if (nvoices != (int)*poly &&
1204 	       (int)*poly > 0 && (int)*poly <= maxvoices) {
1205 	for (int i = 0; i < nvoices; i++)
1206 	  voice_off(i);
1207         nvoices = (int)*poly;
1208 	// Reset the voice allocation.
1209 	memset(vd->notes, 0xff, sizeof(vd->notes));
1210 	vd->free_voices.clear();
1211 	vd->n_free = nvoices;
1212 	for (int i = 0; i < nvoices; i++)
1213 	  vd->free_voices.push_back(i);
1214 	vd->used_voices.clear();
1215 	vd->n_used = 0;
1216       } else
1217 	*poly = nvoices;
1218 #if FAUST_MTS
1219       if (tuning && tuning_no != (int)*tuning) change_tuning((int)*tuning);
1220 #endif
1221     }
1222     // Only update the controls (of all voices simultaneously) if a port value
1223     // actually changed. This is necessary to allow MIDI controllers to modify
1224     // the values for individual MIDI channels (see processEvents below). Also
1225     // note that this will be done *after* processing the MIDI controller data
1226     // for the current audio block, so manual inputs can still override these.
1227     for (int i = 0; i < n_in; i++) {
1228       int j = inctrls[i], k = ui[0]->elems[j].port;
1229       float &oldval = portvals[k], newval = *ports[k];
1230       if (newval != oldval) {
1231 	if (is_instr) {
1232 	  // instrument: update running voices
1233 	  for (boost::circular_buffer<int>::iterator it =
1234 		 vd->used_voices.begin();
1235 	       it != vd->used_voices.end(); it++) {
1236 	    int i = *it;
1237 	    *ui[i]->elems[j].zone = newval;
1238 	  }
1239 	} else {
1240 	  // simple effect: here we only have a single dsp instance
1241 	  *ui[0]->elems[j].zone = newval;
1242 	}
1243 	// also update the MIDI controller data for all channels (manual
1244 	// control input is always omni)
1245 	for (int ch = 0; ch < 16; ch++)
1246 	  midivals[ch][k] = newval;
1247 	// record the new value
1248 	oldval = newval;
1249       }
1250     }
1251     // Initialize the output buffers.
1252     if (n_samples < blocksz) {
1253       // We need to enlarge the buffers. We're not officially allowed to do
1254       // this here (presumably in the realtime thread), but since we usually
1255       // don't know the hosts's block size beforehand, there's really nothing
1256       // else that we can do. Let's just hope that doing this once suffices,
1257       // then hopefully noone will notice.
1258       if (outbuf) {
1259 	for (int i = 0; i < m; i++) {
1260 	  outbuf[i] = (float*)realloc(outbuf[i],
1261 				      blocksz*sizeof(float));
1262 	  assert(outbuf[i]);
1263 	}
1264       }
1265       n_samples = blocksz;
1266     }
1267     if (outbuf) {
1268       // Polyphonic instrument: Mix the voices down to one signal.
1269       for (int i = 0; i < m; i++)
1270 	for (unsigned j = 0; j < blocksz; j++)
1271 	  outputs[i][j] = 0.0f;
1272       for (int l = 0; l < nvoices; l++) {
1273 	// Let Faust do all the hard work.
1274 	dsp[l]->compute(blocksz, inputs, outbuf);
1275 	for (int i = 0; i < m; i++)
1276 	  for (unsigned j = 0; j < blocksz; j++)
1277 	    outputs[i][j] += outbuf[i][j];
1278       }
1279     } else {
1280       // Simple effect: We can write directly to the output buffer.
1281       dsp[0]->compute(blocksz, inputs, outputs);
1282     }
1283     // Finally grab the passive controls and write them back to the
1284     // corresponding control ports. NOTE: Depending on the plugin
1285     // architecture, this might require a host call to get the control GUI
1286     // updated in real-time (if the host supports this at all).
1287     // FIXME: It's not clear how to aggregate the data of the different
1288     // voices. We compute the maximum of each control for now.
1289     for (int i = 0; i < n_out; i++) {
1290       int j = outctrls[i], k = ui[0]->elems[j].port;
1291       float *z = ui[0]->elems[j].zone;
1292       *ports[k] = *z;
1293       for (int l = 1; l < nvoices; l++) {
1294 	float *z = ui[l]->elems[j].zone;
1295 	if (*ports[k] < *z)
1296 	  *ports[k] = *z;
1297       }
1298     }
1299     // Keep track of the last gates set for each voice, so that voices can be
1300     // forcibly retriggered if needed.
1301     if (gate >= 0)
1302       for (int i = 0; i < nvoices; i++)
1303 	vd->lastgate[i] =
1304 	  *ui[i]->elems[gate].zone;
1305   }
1306 
1307   // This processes just a single MIDI message, so to process an entire series
1308   // of MIDI events you'll have to loop over the event data in the plugin's
1309   // MIDI callback. XXXTODO: Sample-accurate processing of MIDI events.
1310 
process_midiLV2Plugin1311   void process_midi(unsigned char *data, int sz)
1312   {
1313 #if DEBUG_MIDI
1314     fprintf(stderr, "midi ev (%d bytes):", sz);
1315     for (int i = 0; i < sz; i++)
1316       fprintf(stderr, " 0x%0x", data[i]);
1317     fprintf(stderr, "\n");
1318 #endif
1319     uint8_t status = data[0] & 0xf0, chan = data[0] & 0x0f;
1320     bool is_instr = maxvoices > 0;
1321     switch (status) {
1322     case 0x90: {
1323       if (!is_instr) break;
1324       // note on
1325 #if DEBUG_NOTES
1326       fprintf(stderr, "note-on  chan %d, note %d, vel %d\n", chan+1,
1327 	      data[1], data[2]);
1328 #endif
1329       if (data[2] == 0) goto note_off;
1330       alloc_voice(chan, data[1], data[2]);
1331       break;
1332     }
1333     case 0x80: {
1334       if (!is_instr) break;
1335       // note off
1336 #if DEBUG_NOTES
1337       fprintf(stderr, "note-off chan %d, note %d, vel %d\n", chan+1,
1338 	      data[1], data[2]);
1339 #endif
1340       note_off:
1341       dealloc_voice(chan, data[1], data[2]);
1342       break;
1343     }
1344     case 0xe0: {
1345       if (!is_instr) break;
1346       // pitch bend
1347       // data[1] is LSB, data[2] MSB, range is 0..0x3fff (which maps to
1348       // -2..+2 semitones by default), center point is 0x2000 = 8192
1349       int val = data[1] | (data[2]<<7);
1350       vd->bend[chan] =
1351 	(val-0x2000)/8192.0f*vd->range[chan];
1352 #if DEBUG_MIDICC
1353       fprintf(stderr, "pitch-bend (chan %d): %g cent\n", chan+1,
1354 	      vd->bend[chan]*100.0);
1355 #endif
1356       update_voices(chan);
1357       break;
1358     }
1359     case 0xb0: {
1360       // controller change
1361       switch (data[1]) {
1362       case 120: case 123:
1363 	if (!is_instr) break;
1364 	// all-sound-off and all-notes-off controllers (these are treated
1365 	// the same in the current implementation)
1366 	all_notes_off(chan);
1367 #if DEBUG_MIDICC
1368 	fprintf(stderr, "all-notes-off (chan %d)\n", chan+1);
1369 #endif
1370 	break;
1371       case 121:
1372 	// all-controllers-off (in the current implementation, this just
1373 	// resets the RPN-related controllers)
1374 	data_msb[chan] = data_lsb[chan] = 0;
1375 	rpn_msb[chan] = rpn_lsb[chan] = 0x7f;
1376 #if DEBUG_MIDICC
1377 	fprintf(stderr, "all-controllers-off (chan %d)\n", chan+1);
1378 #endif
1379 	break;
1380       case 101: case 100:
1381 	// RPN MSB/LSB
1382 	if (data[1] == 101)
1383 	  rpn_msb[chan] = data[2];
1384 	else
1385 	  rpn_lsb[chan] = data[2];
1386 	break;
1387       case 6: case 38:
1388 	// data entry coarse/fine
1389 	if (data[1] == 6)
1390 	  data_msb[chan] = data[2];
1391 	else
1392 	  data_lsb[chan] = data[2];
1393 	goto rpn;
1394       case 96: case 97:
1395 	// data increment/decrement
1396 	/* NOTE: The specification of these controllers is a complete
1397 	   mess. Originally, the MIDI specification didn't have anything
1398 	   to say about their exact behaviour at all. Nowadays, the
1399 	   behaviour depends on which RPN or NRPN is being modified, which
1400 	   is also rather confusing. Fortunately, as we only handle RPNs
1401 	   0..2 here anyway, it's sufficient to assume the MSB for RPN #2
1402 	   (channel coarse tuning) and the LSB otherwise. */
1403 	if (rpn_msb[chan] == 0 && rpn_lsb[chan] == 2) {
1404 	  // modify the MSB
1405 	  if (data[1] == 96 && data_msb[chan] < 0x7f)
1406 	    data_msb[chan]++;
1407 	  else if (data[1] == 97 && data_msb[chan] > 0)
1408 	    data_msb[chan]--;
1409 	} else {
1410 	  // modify the LSB
1411 	  if (data[1] == 96 && data_lsb[chan] < 0x7f)
1412 	    data_lsb[chan]++;
1413 	  else if (data[1] == 97 && data_lsb[chan] > 0)
1414 	    data_lsb[chan]--;
1415 	}
1416       rpn:
1417 	if (!is_instr) break;
1418 	if (rpn_msb[chan] == 0) {
1419 	  switch (rpn_lsb[chan]) {
1420 	  case 0:
1421 	    // pitch bend range, coarse value is in semitones, fine value
1422 	    // in cents
1423 	    vd->range[chan] = data_msb[chan]+
1424 	      data_lsb[chan]/100.0;
1425 #if DEBUG_RPN
1426 	    fprintf(stderr, "pitch-bend-range (chan %d): %g cent\n", chan+1,
1427 		    vd->range[chan]*100.0);
1428 #endif
1429 	    break;
1430 	  case 1:
1431 	    {
1432 	      // channel fine tuning (14 bit value, range -100..+100 cents)
1433 	      int value = (data_msb[chan]<<7) |
1434 		data_lsb[chan];
1435 	      vd->fine[chan] = (value-8192)/8192.0f;
1436 	    }
1437 	    goto master_tune;
1438 	  case 2:
1439 	    // channel coarse tuning (only msb is used, range -64..+63
1440 	    // semitones)
1441 	    vd->coarse[chan] = data_msb[chan]-64;
1442 	  master_tune:
1443 	    vd->tune[chan] = vd->coarse[chan]+
1444 	      vd->fine[chan];
1445 #if DEBUG_RPN
1446 	    fprintf(stderr, "master-tuning (chan %d): %g cent\n", chan+1,
1447 		    vd->tune[chan]*100.0);
1448 #endif
1449 	    update_voices(chan);
1450 	    break;
1451 	  default:
1452 	    break;
1453 	  }
1454 	}
1455 	break;
1456       default: {
1457 #if FAUST_MIDICC
1458 	// interpret all other controller changes according to the MIDI
1459 	// controller map defined in the Faust plugin itself
1460 	std::map<uint8_t,int>::iterator it = ctrlmap.find(data[1]);
1461 	if (it != ctrlmap.end()) {
1462 	  // defined MIDI controller
1463 	  int j = inctrls[it->second],
1464 	    k = ui[0]->elems[j].port;
1465 	  float val = ctrlval(ui[0]->elems[j], data[2]);
1466 	  midivals[chan][k] = val;
1467 	  if (is_instr) {
1468 	    // instrument: update running voices on this channel
1469 	    for (boost::circular_buffer<int>::iterator it =
1470 		   vd->used_voices.begin();
1471 		 it != vd->used_voices.end(); it++) {
1472 	      int i = *it;
1473 	      if (vd->note_info[i].ch == chan)
1474 		*ui[i]->elems[j].zone = val;
1475 	    }
1476 	  } else {
1477 	    // simple effect: here we only have a single dsp instance and
1478 	    // we're operating in omni mode, so we just update the control no
1479 	    // matter what the midi channel is
1480 	    *ui[0]->elems[j].zone = val;
1481 	  }
1482 #if DEBUG_MIDICC
1483 	  fprintf(stderr, "ctrl-change chan %d, ctrl %d, val %d\n", chan+1,
1484 		  data[1], data[2]);
1485 #endif
1486 	}
1487 #endif
1488 	break;
1489       }
1490       }
1491       break;
1492     }
1493     default:
1494       break;
1495     }
1496   }
1497 
1498   // Process an MTS sysex message and update the control values accordingly.
1499 
process_sysexLV2Plugin1500   void process_sysex(uint8_t *data, int sz)
1501   {
1502     if (!data || sz < 2) return;
1503 #if DEBUG_MIDI
1504     fprintf(stderr, "midi sysex (%d bytes):", sz);
1505     for (int i = 0; i < sz; i++)
1506       fprintf(stderr, " 0x%0x", data[i]);
1507     fprintf(stderr, "\n");
1508 #endif
1509     if (data[0] == 0xf0) {
1510       // Skip over the f0 and f7 status bytes in case they are included in the
1511       // dump.
1512       data++; sz--;
1513       if (data[sz-1] == 0xf7) sz--;
1514     }
1515     if ((data[0] == 0x7e || data[0] == 0x7f) && data[2] == 8) {
1516       // MIDI tuning standard
1517       bool realtime = data[0] == 0x7f;
1518       if ((sz == 19 && data[3] == 8) ||
1519 	  (sz == 31 && data[3] == 9)) {
1520 	// MTS scale/octave tuning 1- or 2-byte form
1521 	bool onebyte = data[3] == 8;
1522 	unsigned chanmsk = (data[4]<<14) | (data[5]<<7) | data[6];
1523 	for (int i = 0; i < 12; i++) {
1524 	  float t;
1525 	  if (onebyte)
1526 	    t = (data[i+7]-64)/100.0;
1527 	  else
1528 	    t = (((data[2*i+7]<<7)|data[2*i+8])-8192)/8192.0;
1529 	  for (uint8_t ch = 0; ch < 16; ch++)
1530 	    if (chanmsk & (1<<ch))
1531 	      vd->tuning[ch][i] = t;
1532 	}
1533 	if (realtime) {
1534 	  for (uint8_t ch = 0; ch < 16; ch++)
1535 	    if (chanmsk & (1<<ch)) {
1536 	      // update running voices on this channel
1537 	      update_voices(ch);
1538 	    }
1539 	}
1540 #if DEBUG_MTS
1541 	fprintf(stderr, "octave-tuning-%s (chan ",
1542 		realtime?"realtime":"non-realtime");
1543 	bool first = true;
1544 	for (uint8_t i = 0; i < 16; )
1545 	  if (chanmsk & (1<<i)) {
1546 	    uint8_t j;
1547 	    for (j = i+1; j < 16 && (chanmsk&(1<<j)); )
1548 	      j++;
1549 	    if (first)
1550 	      first = false;
1551 	    else
1552 	      fprintf(stderr, ",");
1553 	    if (j > i+1)
1554 	      fprintf(stderr, "%u-%u", i+1, j);
1555 	    else
1556 	      fprintf(stderr, "%u", i+1);
1557 	    i = j;
1558 	  } else
1559 	    i++;
1560 	fprintf(stderr, "):");
1561 	if (onebyte) {
1562 	  for (int i = 7; i < 19; i++) {
1563 	    int val = data[i];
1564 	    fprintf(stderr, " %d", val-64);
1565 	  }
1566 	} else {
1567 	  for (int i = 7; i < 31; i++) {
1568 	    int val = data[i++] << 7;
1569 	    val |= data[i];
1570 	    fprintf(stderr, " %g", ((double)val-8192.0)/8192.0*100.0);
1571 	  }
1572 	}
1573 	fprintf(stderr, "\n");
1574 #endif
1575       }
1576     }
1577   }
1578 
1579   // Change to a given preloaded tuning. The given tuning number may be in the
1580   // range 1..PFaustPlugin::n_tunings, zero denotes the default tuning (equal
1581   // temperament). This is only supported if FAUST_MTS is defined at compile
1582   // time.
1583 
change_tuningLV2Plugin1584   void change_tuning(int num)
1585   {
1586 #if FAUST_MTS
1587     if (!mts || num == tuning_no) return;
1588     if (num < 0) num = 0;
1589     if (num > mts->tuning.size())
1590       num = mts->tuning.size();
1591     tuning_no = num;
1592     if (tuning_no > 0) {
1593       process_sysex(mts->tuning[tuning_no-1].data,
1594 		    mts->tuning[tuning_no-1].len);
1595     } else {
1596       memset(vd->tuning, 0, sizeof(vd->tuning));
1597 #if DEBUG_MTS
1598       fprintf(stderr,
1599 	      "octave-tuning-default (chan 1-16): equal temperament\n");
1600 #endif
1601     }
1602 #endif
1603   }
1604 
1605 };
1606 
1607 Meta *LV2Plugin::meta = 0;
1608 int LV2Plugin::n_tunings = 0;
1609 #if FAUST_MTS
1610 MTSTunings *LV2Plugin::mts = 0;
1611 #endif
1612 
1613 /* LV2-specific part starts here. ********************************************/
1614 
1615 static LV2_Handle
instantiate(const LV2_Descriptor * descriptor,double rate,const char * bundle_path,const LV2_Feature * const * features)1616 instantiate(const LV2_Descriptor*     descriptor,
1617             double                    rate,
1618             const char*               bundle_path,
1619             const LV2_Feature* const* features)
1620 {
1621   LV2Plugin* plugin =
1622     new LV2Plugin(LV2Plugin::numVoices(), (int)rate);
1623   // Scan host features for URID map.
1624   for (int i = 0; features[i]; i++) {
1625     if (!strcmp(features[i]->URI, LV2_URID_URI "#map")) {
1626       plugin->map = (LV2_URID_Map*)features[i]->data;
1627       plugin->midi_event =
1628 	plugin->map->map(plugin->map->handle, MIDI_EVENT_URI);
1629     }
1630   }
1631   if (!plugin->map) {
1632     fprintf
1633       (stderr, "%s: host doesn't support urid:map, giving up\n",
1634        PLUGIN_URI);
1635     delete plugin;
1636     return 0;
1637   }
1638   return (LV2_Handle)plugin;
1639 }
1640 
1641 static void
cleanup(LV2_Handle instance)1642 cleanup(LV2_Handle instance)
1643 {
1644   LV2Plugin* plugin = (LV2Plugin*)instance;
1645   delete plugin;
1646 }
1647 
1648 static void
connect_port(LV2_Handle instance,uint32_t port,void * data)1649 connect_port(LV2_Handle instance,
1650              uint32_t   port,
1651              void*      data)
1652 {
1653   LV2Plugin* plugin = (LV2Plugin*)instance;
1654   int i = port, k = plugin->ui[0]->nports;
1655   int n = plugin->dsp[0]->getNumInputs(), m = plugin->dsp[0]->getNumOutputs();
1656   if (i < k)
1657     plugin->ports[i] = (float*)data;
1658   else {
1659     i -= k;
1660     if (i < n)
1661       plugin->inputs[i] = (float*)data;
1662     else {
1663       i -= n;
1664       if (i < m)
1665 	plugin->outputs[i] = (float*)data;
1666       else if (i == m)
1667 	plugin->event_port = (LV2_Atom_Sequence*)data;
1668       else if (i == m+1)
1669 	plugin->poly = (float*)data;
1670       else if (i == m+2)
1671 	plugin->tuning = (float*)data;
1672       else
1673 	fprintf(stderr, "%s: bad port number %u\n", PLUGIN_URI, port);
1674     }
1675   }
1676 }
1677 
1678 static void
run(LV2_Handle instance,uint32_t n_samples)1679 run(LV2_Handle instance, uint32_t n_samples)
1680 {
1681   LV2Plugin* plugin = (LV2Plugin*)instance;
1682   // Process incoming MIDI events.
1683   if (plugin->event_port) {
1684     LV2_ATOM_SEQUENCE_FOREACH(plugin->event_port, ev) {
1685       if (ev->body.type == plugin->midi_event) {
1686 	uint8_t *data = (uint8_t*)(ev+1);
1687 #if 0
1688 	// FIXME: Consider doing sample-accurate note onsets here. LV2 keeps
1689 	// track of the exact onset in the frames and subframes fields
1690 	// (http://lv2plug.in/ns/doc/html/structLV2__Atom__Event.html), but we
1691 	// can't use that information at present, since our gate parameter is
1692 	// a control variable which can only change at block boundaries. In
1693 	// the future, the gate could be implemented as an audio signal to get
1694 	// sample-accurate note onsets.
1695 	uint32_t frames = ev->body.frames;
1696 #endif
1697 	if (data[0] == 0xf0)
1698 	  plugin->process_sysex(data, ev->body.size);
1699 	else
1700 	  plugin->process_midi(data, ev->body.size);
1701       }
1702     }
1703   }
1704   // Process audio.
1705   plugin->process_audio(n_samples, plugin->inputs, plugin->outputs);
1706 }
1707 
1708 static void
activate(LV2_Handle instance)1709 activate(LV2_Handle instance)
1710 {
1711   LV2Plugin* plugin = (LV2Plugin*)instance;
1712   plugin->resume();
1713 }
1714 
1715 static void
deactivate(LV2_Handle instance)1716 deactivate(LV2_Handle instance)
1717 {
1718   LV2Plugin* plugin = (LV2Plugin*)instance;
1719   plugin->suspend();
1720 }
1721 
1722 const void*
extension_data(const char * uri)1723 extension_data(const char* uri)
1724 {
1725   return NULL;
1726 }
1727 
1728 static const LV2_Descriptor descriptor = {
1729   PLUGIN_URI,
1730   instantiate,
1731   connect_port,
1732   activate,
1733   run,
1734   deactivate,
1735   cleanup,
1736   extension_data
1737 };
1738 
1739 extern "C"
1740 LV2_SYMBOL_EXPORT
1741 const LV2_Descriptor*
lv2_descriptor(uint32_t index)1742 lv2_descriptor(uint32_t index)
1743 {
1744   switch (index) {
1745   case 0:
1746     return &descriptor;
1747   default:
1748     return NULL;
1749   }
1750 }
1751 
1752 //----------------------------------------------------------------------------
1753 //  Dynamic manifest
1754 //----------------------------------------------------------------------------
1755 
1756 // NOTE: If your LV2 host doesn't offer this extension then you'll have to
1757 // create a static ttl file with the descriptions of the ports. You can do
1758 // this by compiling this code to a standalone executable. Running the
1759 // executable then prints the manifest on stdout.
1760 
1761 extern "C"
1762 LV2_SYMBOL_EXPORT
lv2_dyn_manifest_open(LV2_Dyn_Manifest_Handle * handle,const LV2_Feature * const * features)1763 int lv2_dyn_manifest_open(LV2_Dyn_Manifest_Handle *handle,
1764 			  const LV2_Feature *const *features)
1765 {
1766   LV2Plugin* plugin =
1767     new LV2Plugin(LV2Plugin::numVoices(), 48000);
1768   *handle = (LV2_Dyn_Manifest_Handle)plugin;
1769   return 0;
1770 }
1771 
1772 extern "C"
1773 LV2_SYMBOL_EXPORT
lv2_dyn_manifest_get_subjects(LV2_Dyn_Manifest_Handle handle,FILE * fp)1774 int lv2_dyn_manifest_get_subjects(LV2_Dyn_Manifest_Handle handle,
1775 				  FILE *fp)
1776 {
1777   fprintf(fp, "@prefix lv2:  <http://lv2plug.in/ns/lv2core#> .\n\
1778 <%s> a lv2:Plugin .\n", PLUGIN_URI);
1779   return 0;
1780 }
1781 
1782 #include <string>
1783 #include <ctype.h>
1784 
mangle(const string & s)1785 static string mangle(const string &s)
1786 {
1787   string t = s;
1788   size_t n = s.size();
1789   for (size_t i = 0; i < n; i++)
1790     if ((i == 0 && !isalpha(t[i]) && t[i] != '_') ||
1791 	(!isalnum(t[i]) && t[i] != '_'))
1792       t[i] = '_';
1793   return t;
1794 }
1795 
steps(float min,float max,float step)1796 static unsigned steps(float min, float max, float step)
1797 {
1798   if (step == 0.0) return 1;
1799   int n = (max-min)/step;
1800   if (n < 0) n = -n;
1801   if (n == 0) n = 1;
1802   return n;
1803 }
1804 
1805 #if FAUST_META
is_xmlstring(const char * s)1806 static bool is_xmlstring(const char *s)
1807 {
1808   // This is just a basic sanity check. The string must not contain any
1809   // (unescaped) newlines, carriage returns or double quotes.
1810   return !strchr(s, '\n') && !strchr(s, '\r') && !strchr(s, '"');
1811 }
1812 #endif
1813 
1814 extern "C"
1815 LV2_SYMBOL_EXPORT
lv2_dyn_manifest_get_data(LV2_Dyn_Manifest_Handle handle,FILE * fp,const char * uri)1816 int lv2_dyn_manifest_get_data(LV2_Dyn_Manifest_Handle handle,
1817 			      FILE *fp,
1818 			      const char *uri)
1819 {
1820   LV2Plugin* plugin = (LV2Plugin*)handle;
1821   int k = plugin->ui[0]->nports;
1822   int n = plugin->dsp[0]->getNumInputs(), m = plugin->dsp[0]->getNumOutputs();
1823   bool is_instr = plugin->maxvoices > 0, have_midi = is_instr;
1824   // Scan the global metadata for plugin name, description, license etc.
1825   const char *plugin_name = NULL, *plugin_author = NULL, *plugin_descr = NULL,
1826     *plugin_version = NULL, *plugin_license = NULL;
1827 #if FAUST_META
1828   plugin_name = plugin->pluginName();
1829   plugin_descr = plugin->pluginDescription();
1830   plugin_author = plugin->pluginAuthor();
1831   plugin_version = plugin->pluginVersion();
1832   plugin_license = plugin->pluginLicense();
1833 #endif
1834   if (!plugin_name || !*plugin_name) plugin_name = "mydsp";
1835   fprintf(fp, "@prefix doap:  <http://usefulinc.com/ns/doap#> .\n\
1836 @prefix foaf:  <http://xmlns.com/foaf/0.1/> .\n\
1837 @prefix lv2:   <http://lv2plug.in/ns/lv2core#> .\n\
1838 @prefix ui:    <http://lv2plug.in/ns/extensions/ui#> .\n\
1839 @prefix epp:   <http://lv2plug.in/ns/ext/port-props#> .\n\
1840 @prefix atom:  <http://lv2plug.in/ns/ext/atom#> .\n\
1841 @prefix rdf:   <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\
1842 @prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> .\n\
1843 @prefix units: <http://lv2plug.in/ns/extensions/units#> .\n\
1844 @prefix urid:  <http://lv2plug.in/ns/ext/urid#> .\n\
1845 <%s>\n\
1846        a lv2:Plugin%s ;\n\
1847        doap:name \"%s\" ;\n\
1848        lv2:binary <mydsp%s> ;\n\
1849        lv2:requiredFeature urid:map ;\n\
1850        lv2:optionalFeature epp:supportsStrictBounds ;\n\
1851        lv2:optionalFeature lv2:hardRTCapable ;\n", PLUGIN_URI,
1852 	  is_instr?", lv2:InstrumentPlugin":"",
1853 	  plugin_name, DLLEXT);
1854   if (plugin_author && *plugin_author)
1855     fprintf(fp, "\
1856        doap:maintainer [ foaf:name \"%s\" ] ;\n", plugin_author);
1857   // doap:description just seems to be ignored by all LV2 hosts anyway, so we
1858   // rather use rdfs:comment now which works with Ardour at least.
1859   if (plugin_descr && *plugin_descr)
1860     fprintf(fp, "\
1861        rdfs:comment \"%s\" ;\n", plugin_descr);
1862   if (plugin_version && *plugin_version)
1863     fprintf(fp, "\
1864        doap:revision \"%s\" ;\n", plugin_version);
1865   if (plugin_license && *plugin_license)
1866     fprintf(fp, "\
1867        doap:license \"%s\" ;\n", plugin_license);
1868 #if FAUST_UI
1869     fprintf(fp, "\
1870        ui:ui <%sui> ;\n", PLUGIN_URI);
1871 #endif
1872   int idx = 0;
1873   // control ports
1874   for (int i = 0; i < k; i++, idx++) {
1875     int j = plugin->ctrls[i];
1876     assert(idx == plugin->ui[0]->elems[j].port);
1877     fprintf(fp, "%s [\n", idx==0?"    lv2:port":" ,");
1878     const char *label = plugin->ui[0]->elems[j].label;
1879     assert(label);
1880     string sym = mangle(plugin->ui[0]->elems[j].label);
1881     switch (plugin->ui[0]->elems[j].type) {
1882     // active controls (input ports)
1883     case UI_BUTTON: case UI_CHECK_BUTTON:
1884     fprintf(fp, "\
1885 	a lv2:InputPort ;\n\
1886 	a lv2:ControlPort ;\n\
1887 	lv2:index %d ;\n\
1888 	lv2:symbol \"%s_%d\" ;\n\
1889 	lv2:name \"%s\" ;\n\
1890         lv2:portProperty epp:hasStrictBounds ;\n\
1891         lv2:portProperty lv2:toggled ;\n\
1892 	lv2:default 0.00000 ;\n\
1893 	lv2:minimum 0.00000 ;\n\
1894 	lv2:maximum 1.00000 ;\n", idx, sym.c_str(), idx, label);
1895       break;
1896     case UI_NUM_ENTRY: case UI_H_SLIDER: case UI_V_SLIDER:
1897     fprintf(fp, "\
1898 	a lv2:InputPort ;\n\
1899 	a lv2:ControlPort ;\n\
1900 	lv2:index %d ;\n\
1901 	lv2:symbol \"%s_%d\" ;\n\
1902 	lv2:name \"%s\" ;\n\
1903         lv2:portProperty epp:hasStrictBounds ;\n\
1904         epp:rangeSteps %u ;\n\
1905 	lv2:default %g ;\n\
1906 	lv2:minimum %g ;\n\
1907 	lv2:maximum %g ;\n", idx, sym.c_str(), idx, label,
1908 	    steps(plugin->ui[0]->elems[j].min,
1909 		  plugin->ui[0]->elems[j].max,
1910 		  plugin->ui[0]->elems[j].step),
1911 	    plugin->ui[0]->elems[j].init,
1912 	    plugin->ui[0]->elems[j].min,
1913 	    plugin->ui[0]->elems[j].max);
1914       break;
1915     // passive controls (output ports)
1916     case UI_H_BARGRAPH: case UI_V_BARGRAPH:
1917     fprintf(fp, "\
1918 	a lv2:OutputPort ;\n\
1919 	a lv2:ControlPort ;\n\
1920 	lv2:index %d ;\n\
1921 	lv2:symbol \"%s_%d\" ;\n\
1922 	lv2:name \"%s\" ;\n\
1923 	lv2:default %g ;\n\
1924 	lv2:minimum %g ;\n\
1925 	lv2:maximum %g ;\n", idx, sym.c_str(), idx, label,
1926 	    plugin->ui[0]->elems[j].min,
1927 	    plugin->ui[0]->elems[j].min,
1928 	    plugin->ui[0]->elems[j].max);
1929       break;
1930     default:
1931       assert(0 && "this can't happen");
1932       break;
1933     }
1934     // Scan for Faust control metadata we understand and add corresponding
1935     // hints to the LV2 description of the port.
1936     std::map< int, list<strpair> >::iterator it =
1937       plugin->ui[0]->metadata.find(j);
1938     if (it != plugin->ui[0]->metadata.end()) {
1939       for (std::list<strpair>::iterator jt = it->second.begin();
1940 	   jt != it->second.end(); jt++) {
1941 	const char *key = jt->first, *val = jt->second;
1942 #if FAUST_MIDICC
1943 	unsigned num;
1944 	if (!strcmp(key, "midi") && sscanf(val, "ctrl %u", &num) == 1)
1945 	  have_midi = true;
1946 #endif
1947 	if (!strcmp(key, "unit"))
1948 	  fprintf(fp, "\
1949 	units:unit [\n\
1950             a            units:Unit ;\n\
1951             units:name   \"%s\" ;\n\
1952             units:symbol \"%s\" ;\n\
1953             units:render \"%%f %s\"\n\
1954 	] ;\n", val, val, val);
1955 	if (strcmp(key, "lv2")) continue;
1956 	if (!strcmp(val, "integer"))
1957 	  fprintf(fp, "\
1958 	lv2:portProperty lv2:integer ;\n");
1959 	else if (!strcmp(val, "reportsLatency"))
1960 	  fprintf(fp, "\
1961 	lv2:portProperty lv2:reportsLatency ;\n\
1962 	lv2:designation lv2:latency ;\n");
1963 	else if (!strcmp(val, "hidden") || !strcmp(val, "notOnGUI"))
1964 	  fprintf(fp, "\
1965 	lv2:portProperty epp:notOnGUI ;\n");
1966 	else if (!strncmp(val, "scalepoint", 10) ||
1967 		 !strncmp(val, "scalePoint", 10)) {
1968 	  val += 10;
1969 	  if (!isspace(*val)) continue;
1970 	  char *label = (char*)malloc(strlen(val)+1);
1971 	  float point;
1972 	  int pos;
1973 	  while (sscanf(val, "%s %g%n", label, &point, &pos) == 2) {
1974 	    fprintf(fp, "\
1975 	lv2:scalePoint [ rdfs:label \"%s\"; rdf:value %g ] ;\n",
1976 		    label, point);
1977 	    val += pos;
1978 	  }
1979 	  free(label);
1980 	} else
1981 	  fprintf(stderr, "%s: bad port property '%s:%s'\n", PLUGIN_URI,
1982 		  key, val);
1983       }
1984     }
1985     fprintf(fp, "    ]");
1986   }
1987   // audio inputs
1988   for (int i = 0; i < n; i++, idx++)
1989     fprintf(fp, "%s [\n\
1990 	a lv2:InputPort ;\n\
1991 	a lv2:AudioPort ;\n\
1992 	lv2:index %d ;\n\
1993 	lv2:symbol \"in%d\" ;\n\
1994 	lv2:name \"in%d\" ;\n\
1995     ]", idx==0?"    lv2:port":" ,", idx, i, i);
1996   // audio outputs
1997   for (int i = 0; i < m; i++, idx++)
1998     fprintf(fp, "%s [\n\
1999 	a lv2:OutputPort ;\n\
2000 	a lv2:AudioPort ;\n\
2001 	lv2:index %d ;\n\
2002 	lv2:symbol \"out%d\" ;\n\
2003 	lv2:name \"out%d\" ;\n\
2004     ]", idx==0?"    lv2:port":" ,", idx, i, i);
2005   if (have_midi) {
2006     // midi input
2007     fprintf(fp, "%s [\n\
2008 	a lv2:InputPort ;\n\
2009 	a atom:AtomPort ;\n\
2010 	atom:bufferType atom:Sequence ;\n\
2011 	atom:supports <http://lv2plug.in/ns/ext/midi#MidiEvent> ;\n\
2012 	lv2:index %d ;\n\
2013 	lv2:symbol \"midiin\" ;\n\
2014 	lv2:name \"midiin\"\n\
2015     ]", idx==0?"    lv2:port":" ,", idx);
2016     idx++;
2017   }
2018   if (is_instr) {
2019     // polyphony control
2020     fprintf(fp, "%s [\n\
2021 	a lv2:InputPort ;\n\
2022 	a lv2:ControlPort ;\n\
2023 	lv2:index %d ;\n\
2024 	lv2:symbol \"polyphony\" ;\n\
2025 	lv2:name \"polyphony\" ;\n\
2026         lv2:portProperty epp:hasStrictBounds ;\n\
2027 #       lv2:portProperty epp:expensive ;\n\
2028         lv2:portProperty lv2:integer ;\n\
2029         epp:rangeSteps %d ;\n\
2030 	lv2:default %d ;\n\
2031 	lv2:minimum 1 ;\n\
2032 	lv2:maximum %d ;\n\
2033     ]", idx==0?"    lv2:port":" ,", idx, plugin->maxvoices-1,
2034       plugin->maxvoices>1?plugin->maxvoices/2:1,
2035       plugin->maxvoices);
2036     idx++;
2037 #if FAUST_MTS
2038     if (plugin->n_tunings > 0) {
2039       // tuning control
2040       fprintf(fp, "%s [\n\
2041 	a lv2:InputPort ;\n\
2042 	a lv2:ControlPort ;\n\
2043 	lv2:index %d ;\n\
2044 	lv2:symbol \"tuning\" ;\n\
2045 	lv2:name \"tuning\" ;\n\
2046         lv2:portProperty epp:hasStrictBounds ;\n\
2047         lv2:portProperty lv2:integer ;\n\
2048         epp:rangeSteps %d ;\n\
2049 	lv2:default 0 ;\n\
2050 	lv2:minimum 0 ;\n\
2051 	lv2:maximum %d ;\n",
2052 	idx==0?"    lv2:port":" ,", idx, plugin->n_tunings, plugin->n_tunings);
2053       for (int i = 0; i <= plugin->n_tunings; i++)
2054 	fprintf(fp, "\
2055 	lv2:scalePoint [ rdfs:label \"%s\"; rdf:value %d ] ;\n",
2056 		(i>0)?plugin->mts->tuning[i-1].name:"default", i);
2057       fprintf(fp, "    ]");
2058       idx++;
2059     }
2060 #endif
2061   }
2062   fprintf(fp, "\n.\n");
2063   return 0;
2064 }
2065 
2066 extern "C"
2067 LV2_SYMBOL_EXPORT
lv2_dyn_manifest_close(LV2_Dyn_Manifest_Handle handle)2068 void lv2_dyn_manifest_close(LV2_Dyn_Manifest_Handle handle)
2069 {
2070   LV2Plugin* plugin = (LV2Plugin*)handle;
2071   delete plugin;
2072 }
2073 
main()2074 int main()
2075 {
2076   LV2_Dyn_Manifest_Handle handle;
2077   LV2_Feature **features = { NULL };
2078   int res = lv2_dyn_manifest_open(&handle, features);
2079   if (res) return res;
2080   res = lv2_dyn_manifest_get_data(handle, stdout, PLUGIN_URI);
2081   return res;
2082 }
2083