1 /************************************************************************
2  ************************************************************************
3  Copyright (C) 2021 GRAME, Centre National de Creation Musicale
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation; either version 2.1 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 
19  ************************************************************************
20  ************************************************************************/
21 
22 #include <string>
23 #include <vector>
24 
25 #ifndef LIBFAUSTCOMMON_H
26 #define LIBFAUSTCOMMON_H
27 
28 /*!
29  \addtogroup boxcpp C++ interface for the Box API.
30  @{
31  */
32 
33 /**
34  * Opaque types.
35  */
36 class CTree;
37 typedef std::vector<CTree*> tvec;
38 
39 enum SType { kSInt, kSReal };
40 
41 enum SOperator { kAdd, kSub, kMul, kDiv, kRem, kLsh, kARsh, kLRsh, kGT, kLT, kGE, kLE, kEQ, kNE, kAND, kOR, kXOR };
42 
43 /**
44  * Base class for factories.
45  */
46 struct dsp_factory_base {
47 
~dsp_factory_basedsp_factory_base48     virtual ~dsp_factory_base() {}
49 
50     virtual void write(std::ostream* out, bool binary = false, bool compact = false) {}
51 };
52 
53 #endif
54 
55 #ifndef LIBFAUSTBOX_H
56 #define LIBFAUSTBOX_H
57 
58 /**
59  * Opaque types.
60  */
61 typedef CTree* Box;
62 
63 /**
64  * Create global compilation context, has to be done first.
65  */
66 extern "C" void createLibContext();
67 
68 /**
69  * Destroy global compilation context, has to be done last.
70  */
71 extern "C" void destroyLibContext();
72 
73 /**
74  * Constant integer : for all t, x(t) = n.
75  *
76  * @param n - the integer
77  *
78  * @return the integer box.
79  */
80 
81 Box boxInt(int n);
82 
83 /**
84  * Constant real : for all t, x(t) = n.
85  *
86  * @param n - the float/double value (depends of -single or -double compilation parameter)
87  *
88  * @return the float/double box.
89  */
90 Box boxReal(double n);
91 
92 /**
93  * The identity box, copy its input to its output.
94  *
95  * @return the identity box.
96  */
97 Box boxWire();
98 
99 /**
100 * The cut box, to "stop"/terminate a signal.
101 *
102 * @return the cut box.
103 */
104 Box boxCut();
105 
106 /**
107  * The sequential composition of two blocks (e.g., A:B) expects: outputs(A)=inputs(B)
108  *
109  * @return the seq box.
110  */
111 Box boxSeq(Box x, Box y);
112 
113 /**
114  * The parallel composition of two blocks (e.g., A,B).
115  * It places the two block-diagrams one on top of the other, without connections.
116  *
117  * @return the par box.
118  */
119 Box boxPar(Box x, Box y);
120 
121 Box boxPar3(Box x, Box y, Box z);
122 
123 Box boxPar4(Box a, Box b, Box c, Box d);
124 
125 Box boxPar5(Box a, Box b, Box c, Box d, Box e);
126 
127 /**
128  * The split composition (e.g., A<:B) operator is used to distribute
129  * the outputs of A to the inputs of B.
130  *
131  * For the operation to be valid, the number of inputs of B
132  * must be a multiple of the number of outputs of A: outputs(A).k=inputs(B)
133  *
134  * @return the split box.
135  */
136 Box boxSplit(Box x, Box y);
137 
138 /**
139  * The merge composition (e.g., A:>B) is the dual of the split composition.
140  *
141  * The number of outputs of A must be a multiple of the number of inputs of B: outputs(A)=k.inputs(B)
142  *
143  * @return the merge box.
144  */
145 Box boxMerge(Box x, Box y);
146 
147 /**
148  * The recursive composition (e.g., A~B) is used to create cycles in the block-diagram
149  * in order to express recursive computations.
150  * It is the most complex operation in terms of connections: outputs(A)≥inputs(B) and inputs(A)≥outputs(B)
151  *
152  * @return the rec box.
153  */
154 Box boxRec(Box x, Box y);
155 
156 /**
157  * The route primitive facilitates the routing of signals in Faust.
158  * It has the following syntax: route(A,B,a,b,c,d,...) or route(A,B,(a,b),(c,d),...)
159  *
160  * @param n -  the number of input signals
161  * @param m -  the number of output signals
162  * @param r - the routing description, a 'par' expression of a,b / (a,b) input/output pairs
163 
164  * @return the route box.
165  */
166 Box boxRoute(Box n, Box m, Box r);
167 
168 /**
169  * Create a delayed box.
170  *
171  * @return the delayed box.
172  */
173 Box boxDelay();
174 
175 /**
176  * Create a delayed box.
177  *
178  * @param s - the box to be delayed
179  * @param del - the delay box that doesn't have to be fixed but must be bounded and cannot be negative
180 
181  * @return the delayed box.
182  */
183 Box boxDelay(Box s, Box del);
184 
185 /**
186  * Create a casted box.
187  *
188  * @return the casted box.
189  */
190 Box boxIntCast();
191 
192 /**
193  * Create a casted box.
194  *
195  * @param s - the box to be casted in integer
196  *
197  * @return the casted box.
198  */
199 
200 Box boxIntCast(Box s);
201 
202 /**
203  * Create a casted box.
204  *
205  * @return the casted box.
206  */
207 Box boxFloatCast();
208 
209 /**
210  * Create a casted box.
211  *
212  * @param s - the signal to be casted as float/double value (depends of -single or -double compilation parameter)
213  *
214  * @return the casted box.
215  */
216 Box boxFloatCast(Box s);
217 
218 /**
219  * Create a read only table.
220  *
221  * @return the table box.
222  */
223 Box boxReadOnlyTable();
224 
225 /**
226  * Create a read only table.
227  *
228  * @param n - the table size, a constant numerical expression (see [1])
229  * @param init - the table content
230  * @param ridx - the read index (an int between 0 and n-1)
231  *
232  * @return the table box.
233  */
234 Box boxReadOnlyTable(Box n, Box init, Box ridx);
235 
236 /**
237  * Create a read/write table.
238  *
239  * @return the table box.
240  */
241 Box boxWriteReadTable();
242 
243 /**
244  * Create a read/write table.
245  *
246  * @param n - the table size, a constant numerical expression (see [1])
247  * @param init - the table content
248  * @param widx - the write index (an integer between 0 and n-1)
249  * @param wsig - the input of the table
250  * @param ridx - the read index (an integer between 0 and n-1)
251  *
252  * @return the table box.
253  */
254 Box boxWriteReadTable(Box n, Box init, Box widx, Box wsig, Box ridx);
255 
256 /**
257  * Create a waveform.
258  *
259  * @param wf - the content of the waveform as a vector of boxInt or boxDouble boxes
260  *
261  * @return the waveform box.
262  */
263 Box boxWaveform(const tvec& wf);
264 
265 /**
266  * Create a soundfile block.
267  *
268  * @param label - of form "label[url:{'path1';'path2';'path3'}]" to describe a list of soundfiles
269  * @param chan - the number of outputs channels, a constant numerical expression (see [1])
270  *
271  * @return the soundfile box.
272  */
273 Box boxSoundfile(const std::string& label, Box chan);
274 
275 /**
276  * Create a soundfile block.
277  *
278  * @param label - of form "label[url:{'path1';'path2';'path3'}]" to describe a list of soundfiles
279  * @param chan - the number of outputs channels, a constant numerical expression (see [1])
280  * @param part - in the [0..255] range to select a given sound number, a constant numerical expression (see [1])
281  * @param ridx - the read index (an integer between 0 and the selected sound length)
282  *
283  * @return the soundfile box.
284  */
285 Box boxSoundfile(const std::string& label, Box chan, Box part, Box ridx);
286 
287 /**
288  * Create a selector between two boxes.
289  *
290  * @return the selected box depending of the selector value at each time t.
291  */
292 Box boxSelect2();
293 
294 /**
295  * Create a selector between two boxes.
296  *
297  * @param selector - when 0 at time t returns s1[t], otherwise returns s2[t]
298  * @param s1 - first box to be selected
299  * @param s2 - second box to be selected
300  *
301  * @return the selected box depending of the selector value at each time t.
302  */
303 Box boxSelect2(Box selector, Box s1, Box s2);
304 
305 /**
306  * Create a selector between three boxes.
307  *
308  * @return the selected box depending of the selector value at each time t.
309  */
310 Box boxSelect3();
311 
312 /**
313  * Create a selector between three boxes.
314  *
315  * @param selector - when 0 at time t returns s1[t], when 1 at time t returns s2[t], otherwise returns s3[t]
316  * @param s1 - first box to be selected
317  * @param s2 - second box to be selected
318  * @param s3 - third signal to be selected
319  *
320  * @return the selected box depending of the selector value at each time t.
321  */
322 Box boxSelect3(Box selector, Box s1, Box s2, Box s3);
323 
324 /**
325  * Create a foreign constant box.
326  *
327  * @param type - the foreign constant type of SType
328  * @param name - the foreign constant name
329  * @param file - the include file where the foreign constant is defined
330  *
331  * @return the foreign constant box.
332  */
333 Box boxFConst(SType type, const std::string& name, const std::string& file);
334 
335 /**
336  * Create a foreign variable box.
337  *
338  * @param type - the foreign variable type of SType
339  * @param name - the foreign variable name
340  * @param file - the include file where the foreign variable is defined
341  *
342  * @return the foreign variable box.
343  */
344 Box boxFVar(SType type, const std::string& name, const std::string& file);
345 
346 /**
347  * Generic binary mathematical functions.
348  *
349  * @param op - the operator in SOperator set
350  *
351  * @return the result box of op(x,y).
352  */
353 Box boxBinOp(SOperator op);
354 
355 Box boxBinOp(SOperator op, Box b1, Box b2);
356 
357 /**
358  * Specific binary mathematical functions.
359  *
360  * @return the result box.
361  */
362 Box boxAdd();
363 Box boxAdd(Box b1, Box b2);
364 Box boxSub();
365 Box boxSub(Box b1, Box b2);
366 Box boxMul();
367 Box boxMul(Box b1, Box b2);
368 Box boxDiv();
369 Box boxDiv(Box b1, Box b2);
370 Box boxRem();
371 Box boxRem(Box b1, Box b2);
372 
373 Box boxLeftShift();
374 Box boxLeftShift(Box b1, Box b2);
375 Box boxLRightShift();
376 Box boxLRightShift(Box b1, Box b2);
377 Box boxARightShift();
378 Box boxARightShift(Box b1, Box b2);
379 
380 Box boxGT();
381 Box boxGT(Box b1, Box b2);
382 Box boxLT();
383 Box boxLT(Box b1, Box b2);
384 Box boxGE();
385 Box boxGE(Box b1, Box b2);
386 Box boxLE();
387 Box boxLE(Box b1, Box b2);
388 Box boxEQ();
389 Box boxEQ(Box b1, Box b2);
390 Box boxNE();
391 Box boxNE(Box b1, Box b2);
392 
393 Box boxAND();
394 Box boxAND(Box b1, Box b2);
395 Box boxOR();
396 Box boxOR(Box b1, Box b2);
397 Box boxXOR();
398 Box boxXOR(Box b1, Box b2);
399 
400 /**
401  * Extended unary mathematical functions.
402  */
403 
404 Box boxAbs();
405 Box boxAbs(Box x);
406 Box boxAcos();
407 Box boxAcos(Box x);
408 Box boxTan();
409 Box boxTan(Box x);
410 Box boxSqrt();
411 Box boxSqrt(Box x);
412 Box boxSin();
413 Box boxSin(Box x);
414 Box boxRint();
415 Box boxRint(Box x);
416 Box boxLog();
417 Box boxLog(Box x);
418 Box boxLog10();
419 Box boxLog10(Box x);
420 Box boxFloor();
421 Box boxFloor(Box x);
422 Box boxExp();
423 Box boxExp(Box x);
424 Box boxExp10();
425 Box boxExp10(Box x);
426 Box boxCos();
427 Box boxCos(Box x);
428 Box boxCeil();
429 Box boxCeil(Box x);
430 Box boxAtan();
431 Box boxAtan(Box x);
432 Box boxAsin();
433 Box boxAsin(Box x);
434 
435 /**
436  * Extended binary mathematical functions.
437  */
438 
439 Box boxRemainder();
440 Box boxRemainder(Box b1, Box b2);
441 Box boxPow();
442 Box boxPow(Box b1, Box b2);
443 Box boxMin();
444 Box boxMin(Box b1, Box b2);
445 Box boxMax();
446 Box boxMax(Box b1, Box b2);
447 Box boxFmod();
448 Box boxFmod(Box b1, Box b2);
449 Box boxAtan2();
450 Box boxAtan2(Box b1, Box b2);
451 
452 /**
453  * Create a button box.
454  *
455  * @param label - the label definition (see [2])
456  *
457  * @return the button box.
458  */
459 Box boxButton(const std::string& label);
460 
461 /**
462  * Create a checkbox box.
463  *
464  * @param label - the label definition (see [2])
465  *
466  * @return the checkbox box.
467  */
468 Box boxCheckbox(const std::string& label);
469 
470 /**
471  * Create a vertical slider box.
472  *
473  * @param label - the label definition (see [2])
474  * @param init - the init box, a constant numerical expression (see [1])
475  * @param min - the max box, a constant numerical expression (see [1])
476  * @param max - the min box, a constant numerical expression (see [1])
477  * @param step - the step box, a constant numerical expression (see [1])
478  *
479  * @return the vertical slider box.
480  */
481 Box boxVSlider(const std::string& label, Box init, Box min, Box max, Box step);
482 
483 /**
484  * Create an horizontal slider box.
485  *
486  * @param label - the label definition (see [2])
487  * @param init - the init box, a constant numerical expression (see [1])
488  * @param min - the max box, a constant numerical expression (see [1])
489  * @param max - the min box, a constant numerical expression (see [1])
490  * @param step - the step box, a constant numerical expression (see [1])
491  *
492  * @return the horizontal slider box.
493  */
494 Box boxHSlider(const std::string& label, Box init, Box min, Box max, Box step);
495 
496 /**
497  * Create a num entry box.
498  *
499  * @param label - the label definition (see [2])
500  * @param init - the init box, a constant numerical expression (see [1])
501  * @param min - the max box, a constant numerical expression (see [1])
502  * @param max - the min box, a constant numerical expression (see [1])
503  * @param step - the step box, a constant numerical expression (see [1])
504  *
505  * @return the num entry box.
506  */
507 Box boxNumEntry(const std::string& label, Box init, Box min, Box max, Box step);
508 
509 /**
510  * Create a vertical bargraph box.
511  *
512  * @param label - the label definition (see [2])
513  * @param min - the max box, a constant numerical expression (see [1])
514  * @param max - the min box, a constant numerical expression (see [1])
515  *
516  * @return the vertical bargraph box.
517  */
518 Box boxVBargraph(const std::string& label, Box min, Box max);
519 
520 /**
521  * Create a vertical bargraph box.
522  *
523  * @param label - the label definition (see [2])
524  * @param min - the max box, a constant numerical expression (see [1])
525  * @param max - the min box, a constant numerical expression (see [1])
526  * @param s - the input box
527  *
528  * @return the vertical bargraph box.
529  */
530 Box boxVBargraph(const std::string& label, Box min, Box max, Box x);
531 
532 /**
533  * Create an horizontal bargraph box.
534  *
535  * @param label - the label definition (see [2])
536  * @param min - the max box, a constant numerical expression (see [1])
537  * @param max - the min box, a constant numerical expression (see [1])
538  *
539  * @return the horizontal bargraph box.
540  */
541 Box boxHBargraph(const std::string& label, Box min, Box max);
542 
543 /**
544  * Create a horizontal bargraph box.
545  *
546  * @param label - the label definition (see [2])
547  * @param min - the max box, a constant numerical expression (see [1])
548  * @param max - the min box, a constant numerical expression (see [1])
549  * @param s - the input box
550  *
551  * @return the vertical horizontal box.
552  */
553 Box boxHBargraph(const std::string& label, Box min, Box max, Box x);
554 
555 /**
556  * Create an attach box.
557  *
558  * The attach primitive takes two input boxes and produces one output box
559  * which is a copy of the first input. The role of attach is to force
560  * its second input boxes to be compiled with the first one.
561  *
562  * @return the attach box.
563  */
564 Box boxAttach();
565 
566 /**
567  * Create an attach box.
568  *
569  * The attach primitive takes two input box and produces one output box
570  * which is a copy of the first input. The role of attach is to force
571  * its second input signal to be compiled with the first one.
572  *
573  * @param s1 - the first box
574  * @param s2 - the second box
575  *
576  * @return the attach signal.
577  */
578 Box boxAttach(Box s1, Box s2);
579 
580 /**
581  * Compile a box expression in a list of signals.
582  *
583  * @param box - the box expression
584  * @param error_msg - the error string to be filled
585  *
586  * @return a list of signals on success, otherwise an empty list.
587  */
588 tvec boxesToSignals(Box box, std::string& error_msg);
589 
590 /**
591  * Create a C++ Faust DSP factory from a box expression.
592  *
593  * @param name_app - the name of the Faust program
594  * @param box - the box expression
595  * @param argc - the number of parameters in argv array
596  * @param argv - the array of parameters
597  * @param error_msg - the error string to be filled
598  *
599  * @return a DSP factory on success, otherwise a null pointer.
600  */
601 dsp_factory_base* createCPPDSPFactoryFromBoxes(const std::string& name_app, Box box,
602                                                int argc, const char* argv[],
603                                                std::string& error_msg);
604 
605 /*
606  [1] Constant numerical expression : see https://faustdoc.grame.fr/manual/syntax/#constant-numerical-expressions
607  [2] Label definition : https://faustdoc.grame.fr/manual/syntax/#variable-parts-of-a-label
608  */
609 
610 /*!
611  @}
612  */
613 
614 #endif
615