Bug fixed for unix error "readlink /proc/self/fd/0" on MacOS.
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / architecture / csound.cpp
1 /************************************************************************
2
3 IMPORTANT NOTE : this file contains two clearly delimited sections :
4 the ARCHITECTURE section (in two parts) and the USER section. Each section
5 is governed by its own copyright and license. Please check individually
6 each section for license and copyright information.
7 *************************************************************************/
8
9 /*******************BEGIN ARCHITECTURE SECTION (part 1/2)****************/
10
11 /************************************************************************
12 FAUST Architecture File
13 Copyright (C) 2010-2011 V. Lazzarini and GRAME
14 ---------------------------------------------------------------------
15 This Architecture section is free software; you can redistribute it
16 and/or modify it under the terms of the GNU General Public License
17 as published by the Free Software Foundation; either version 3 of
18 the License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; If not, see <http://www.gnu.org/licenses/>.
27
28 EXCEPTION : As a special exception, you may create a larger work
29 that contains this FAUST architecture section and distribute
30 that work under terms of your choice, so long as this FAUST
31 architecture section is not modified.
32
33
34 ************************************************************************
35 ************************************************************************/
36
37 //==============================================================================
38 //
39 // CSOUND architecture file for FAUST
40 // Y. Orlarey & V. Lazzarini
41 //
42 // Usage : faust -uim -a csound.cpp <myfx>.dsp -o <myfx>.cpp
43 // g++ -O3 -DOPCODE_NAME=<myfx> -c <myfx>.cpp -o <myfx>.o
44 // ld -E --shared <myfx>.o -o <myfx>.so
45 //
46 // History :
47 // - 28/04/09 : first version
48 // - 29/04/09 : dynamic allocation
49 //
50 //==============================================================================
51
52 #include <new>
53 #include <vector>
54 #include "csdl.h" /* CSOUND plugin API header */
55
56 // used to transform a symbol in a string
57 #define sym(name) xsym(name)
58 #define xsym(name) #name
59
60 // make sure we use csound floats
61 #define FAUSTFLOAT MYFLT
62
63 // we require macro declarations
64 #define FAUST_UIMACROS
65
66 // but we will ignore most of them
67 #define FAUST_ADDBUTTON(l,f)
68 #define FAUST_ADDCHECKBOX(l,f)
69 #define FAUST_ADDVERTICALSLIDER(l,f,i,a,b,s)
70 #define FAUST_ADDHORIZONTALSLIDER(l,f,i,a,b,s)
71 #define FAUST_ADDNUMENTRY(l,f,i,a,b,s)
72 #define FAUST_ADDVERTICALBARGRAPH(l,f,a,b)
73 #define FAUST_ADDHORIZONTALBARGRAPH(l,f,a,b)
74
75 #define max(x,y) (((x)>(y)) ? (x) : (y))
76 #define min(x,y) (((x)<(y)) ? (x) : (y))
77
78 using namespace std;
79
80 // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
81 // flags to avoid costly denormals
82 #ifdef __SSE__
83 #include <xmmintrin.h>
84 #ifdef __SSE2__
85 #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
86 #else
87 #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
88 #endif
89 #else
90 #define AVOIDDENORMALS
91 #endif
92
93
94
95
96 /******************************************************************************
97 *******************************************************************************
98
99 VECTOR INTRINSICS
100
101 *******************************************************************************
102 *******************************************************************************/
103
104
105 <<includeIntrinsic>>
106
107
108
109 /**
110 * We will ignore metadata declarations
111 */
112 struct Meta
113 {
114 void declare (const char* key, const char* value) { }
115 };
116
117 /**
118 * Abstract Definition of a user interface
119 */
120 class UI
121 {
122 public:
123
124 virtual ~UI() {}
125
126 // -- active widgets
127
128 virtual void addButton(const char* label, FAUSTFLOAT* zone) = 0;
129 virtual void addToggleButton(const char* label, FAUSTFLOAT* zone) = 0;
130 virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) = 0;
131 virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
132 virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
133 virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) = 0;
134
135 // -- passive widgets
136
137 virtual void addNumDisplay(const char* label, FAUSTFLOAT* zone, int precision) {}
138 virtual void addTextDisplay(const char* label, FAUSTFLOAT* zone, char* names[], FAUSTFLOAT min, FAUSTFLOAT max) {}
139 virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) {}
140 virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max) {}
141
142 // -- widget's layouts
143
144 virtual void openFrameBox(const char* label) {}
145 virtual void openTabBox(const char* label) {}
146 virtual void openHorizontalBox(const char* label) {}
147 virtual void openVerticalBox(const char* label) {}
148 virtual void closeBox() {}
149
150 virtual void declare(FAUSTFLOAT* zone, const char* key, const char* value) {}
151 };
152
153 /**
154 * A UI that simply collects the active zones in a vector
155 * and provides a method to copy the csound controls
156 */
157 class CSUI : public UI
158 {
159 vector<FAUSTFLOAT*> vZone;
160
161 public:
162 // -- active widgets
163
164 virtual void addButton(const char* label, FAUSTFLOAT* zone) { vZone.push_back(zone); }
165 virtual void addToggleButton(const char* label, FAUSTFLOAT* zone) { vZone.push_back(zone); }
166 virtual void addCheckButton(const char* label, FAUSTFLOAT* zone) { vZone.push_back(zone); }
167 virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { vZone.push_back(zone); }
168 virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { vZone.push_back(zone); }
169 virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step) { vZone.push_back(zone); }
170
171 void copyfrom(MYFLT* mem[]) {
172 for (unsigned int i=0; i<vZone.size(); i++) { *vZone[i] = *(mem[i]); }
173 }
174
175 int size() { return vZone.size(); }
176 };
177
178
179
180 /**
181 * Abstract Definition of a DSP
182 */
183
184 class dsp {
185 protected:
186 int fSamplingFreq;
187 public:
188 virtual int getNumInputs() = 0;
189 virtual int getNumOutputs() = 0;
190 virtual void instanceInit(int samplingFreq) = 0;
191 virtual void init(int samplingFreq)= 0;
192 virtual void buildUserInterface(UI* interface) = 0;
193 virtual void compute (int count, FAUSTFLOAT** input, FAUSTFLOAT** output) = 0;
194 };
195
196
197 /********************END ARCHITECTURE SECTION (part 1/2)****************/
198
199 /**************************BEGIN USER SECTION **************************/
200
201 <<includeclass>>
202
203 /***************************END USER SECTION ***************************/
204
205 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
206
207
208
209 struct dataspace {
210 OPDS h; /* basic attributes */
211 MYFLT* aout[FAUST_OUTPUTS]; /* output buffers */
212 MYFLT* ain[FAUST_INPUTS]; /* input buffers */
213 MYFLT* ktl[FAUST_ACTIVES]; /* controls */
214 dsp* DSP; /* the Faust generated object */
215 CSUI* interface; /* do the mapping between CSound controls and DSP fields */
216 AUXCH dspmem; /* aux memory allocated once to store the DSP object */
217 AUXCH intmem; /* aux memory allocated once to store the interface object */
218 };
219
220
221 /**
222 * Creates a "aaakkkk" CSound description string. Note that
223 * these string will never be released. Potential memory leak
224 */
225 static char* makeDescription(int numa, int numk=0)
226 {
227 char* str = (char*)malloc(numa+numk+1); // NEED TO BE CHANGED ?
228 if (str) {
229 for (int i=0; i<numa; i++) str[i] = 'a';
230 for (int i=0; i<numk; i++) str[numa+i] = 'k';
231 str[numa+numk] = 0;
232 }
233 return str;
234 }
235
236
237 /**
238 * CSOUND callback that allocates and initializes
239 * the FAUST generated DSP object and it's CSound interface
240 */
241 static int init(CSOUND *csound, dataspace *p)
242 {
243 if (p->dspmem.auxp == NULL)
244 csound->AuxAlloc(csound, sizeof(mydsp), &p->dspmem);
245
246 if(p->intmem.auxp == NULL)
247 csound->AuxAlloc(csound, sizeof(CSUI), &p->intmem);
248
249
250 p->DSP = new (p->dspmem.auxp) mydsp;
251 p->interface = new (p->intmem.auxp) CSUI;
252
253 if ((p->DSP == 0) | (p->interface == 0)) return NOTOK;
254
255 p->DSP->init((int)csound->GetSr(csound));
256 p->DSP->buildUserInterface(p->interface);
257
258 return OK;
259 }
260
261
262 /**
263 * CSound callback that process the samples by updating
264 * the controls values and calling the compute() method
265 * of the DSP object. (Assume MYFLT = FAUSTFLOAT)
266 */
267 static int process32bits(CSOUND *csound, dataspace *p)
268 {
269 AVOIDDENORMALS;
270
271 // update all the control values
272 p->interface->copyfrom(p->ktl);
273
274 p->DSP->compute(csound->GetKsmps(csound), p->ain, p->aout);
275 return OK;
276 }
277
278 extern "C" {
279
280 static OENTRY localops[] = {
281 {(char*)sym(OPCODE_NAME), sizeof(dataspace),5,makeDescription(FAUST_OUTPUTS), makeDescription(FAUST_INPUTS,FAUST_ACTIVES),
282 (SUBR)init, NULL,(SUBR)process32bits }
283 };
284 LINKAGE
285 }
286
287
288 /********************END ARCHITECTURE SECTION (part 2/2)****************/
289
290
291