Merge branch 'master' of https://scm.cri.ensmp.fr/git/Faustine
[Faustine.git] / interpretor / faust-0.9.47mr3 / architecture / jack-internal.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) 2003-2011 GRAME, Centre National de Creation Musicale
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 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <limits.h>
42 #include <math.h>
43 #include <errno.h>
44 #include <time.h>
45 #include <vector>
46 #include <stack>
47 #include <string>
48 #include <map>
49 #include <list>
50 #include <iostream>
51 #include <assert.h>
52
53 #include <libgen.h>
54 #include <jack/jack.h>
55 #include <jack/jslist.h>
56
57 using namespace std;
58
59 // On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
60 // flags to avoid costly denormals
61 #ifdef __SSE__
62 #include <xmmintrin.h>
63 #ifdef __SSE2__
64 #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
65 #else
66 #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
67 #endif
68 #else
69 #define AVOIDDENORMALS
70 #endif
71
72 struct Meta : map<const char*, const char*>
73 {
74 void declare (const char* key, const char* value) { (*this)[key]=value; }
75 };
76
77 #define max(x,y) (((x)>(y)) ? (x) : (y))
78 #define min(x,y) (((x)<(y)) ? (x) : (y))
79
80 // abs is now predefined
81 //template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
82
83 inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); }
84
85 /******************************************************************************
86 *******************************************************************************
87
88 VECTOR INTRINSICS
89
90 *******************************************************************************
91 *******************************************************************************/
92
93 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
94 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
95
96 <<includeIntrinsic>>
97
98
99 /******************************************************************************
100 *******************************************************************************
101
102 GRAPHIC USER INTERFACE (v2)
103 abstract interfaces
104
105 *******************************************************************************
106 *******************************************************************************/
107
108 using namespace std;
109
110
111 struct uiItem;
112 typedef void (*uiCallback)(float val, void* data);
113
114 /**
115 * Graphic User Interface : abstract definition
116 */
117
118 class UI
119 {
120 typedef list<uiItem*> clist;
121 typedef map<float*, clist*> zmap;
122
123 private:
124 static list<UI*> fGuiList;
125 zmap fZoneMap;
126 bool fStopped;
127
128 public:
129
130 UI() : fStopped(false) {
131 fGuiList.push_back(this);
132 }
133
134 virtual ~UI() {
135 // suppression de this dans fGuiList
136 }
137
138 // -- zone management
139
140 void registerZone(float* z, uiItem* c)
141 {
142 if (fZoneMap.find(z) == fZoneMap.end()) fZoneMap[z] = new clist();
143 fZoneMap[z]->push_back(c);
144 }
145
146 void updateAllZones();
147
148 void updateZone(float* z);
149
150 static void updateAllGuis()
151 {
152 list<UI*>::iterator g;
153 for (g = fGuiList.begin(); g != fGuiList.end(); g++) {
154 (*g)->updateAllZones();
155 }
156 }
157
158 // -- active widgets
159
160 virtual void addButton(const char* label, float* zone) = 0;
161 virtual void addToggleButton(const char* label, float* zone) = 0;
162 virtual void addCheckButton(const char* label, float* zone) = 0;
163 virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
164 virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
165 virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
166
167 // -- passive widgets
168
169 virtual void addNumDisplay(const char* label, float* zone, int precision) = 0;
170 virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0;
171 virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
172 virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
173
174 void addCallback(float* zone, uiCallback foo, void* data);
175
176 // -- widget's layouts
177
178 virtual void openFrameBox(const char* label) = 0;
179 virtual void openTabBox(const char* label) = 0;
180 virtual void openHorizontalBox(const char* label) = 0;
181 virtual void openVerticalBox(const char* label) = 0;
182 virtual void closeBox() = 0;
183
184 virtual void declare(float* zone, const char* key, const char* value) {}
185 };
186
187 class OSCUI : public UI
188 {
189 public:
190
191 OSCUI() : UI()
192 {}
193
194 virtual ~OSCUI() {
195 // suppression de this dans fGuiList
196 }
197
198
199 // -- active widgets
200
201 virtual void addButton(const char* label, float* zone) {}
202 virtual void addToggleButton(const char* label, float* zone) {}
203 virtual void addCheckButton(const char* label, float* zone) {}
204 virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) {}
205 virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) {}
206 virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) {}
207
208 // -- passive widgets
209
210 virtual void addNumDisplay(const char* label, float* zone, int precision) {}
211 virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) {}
212 virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) {}
213 virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) {}
214
215 void addCallback(float* zone, uiCallback foo, void* data);
216
217 // -- widget's layouts
218
219 virtual void openFrameBox(const char* label) {}
220 virtual void openTabBox(const char* label) {}
221 virtual void openHorizontalBox(const char* label) {}
222 virtual void openVerticalBox(const char* label) {}
223 virtual void closeBox() {}
224
225 virtual void declare(float* zone, const char* key, const char* value) {}
226 };
227
228 list<UI*> UI::fGuiList;
229
230 /**
231 * User Interface Item: abstract definition
232 */
233
234 class uiItem
235 {
236 protected :
237
238 UI* fGUI;
239 float* fZone;
240 float fCache;
241
242 uiItem (UI* ui, float* zone) : fGUI(ui), fZone(zone), fCache(-123456.654321)
243 {
244 ui->registerZone(zone, this);
245 }
246
247 public :
248
249 virtual ~uiItem() {}
250
251 void modifyZone(float v)
252 {
253 fCache = v;
254 if (*fZone != v) {
255 *fZone = v;
256 fGUI->updateZone(fZone);
257 }
258 }
259
260 float cache() { return fCache; }
261 virtual void reflectZone() = 0;
262 };
263
264
265 /**
266 * Callback Item
267 */
268
269 struct uiCallbackItem : public uiItem
270 {
271 uiCallback fCallback;
272 void* fData;
273
274 uiCallbackItem(UI* ui, float* zone, uiCallback foo, void* data)
275 : uiItem(ui, zone), fCallback(foo), fData(data) {}
276
277 virtual void reflectZone() {
278 float v = *fZone;
279 fCache = v;
280 fCallback(v, fData);
281 }
282 };
283
284 /**
285 * Update all user items reflecting zone z
286 */
287
288 inline void UI::updateZone(float* z)
289 {
290 float v = *z;
291 clist* l = fZoneMap[z];
292 for (clist::iterator c = l->begin(); c != l->end(); c++) {
293 if ((*c)->cache() != v) (*c)->reflectZone();
294 }
295 }
296
297 /**
298 * Update all user items not up to date
299 */
300
301 inline void UI::updateAllZones()
302 {
303 for (zmap::iterator m = fZoneMap.begin(); m != fZoneMap.end(); m++) {
304 float* z = m->first;
305 clist* l = m->second;
306 float v = *z;
307 for (clist::iterator c = l->begin(); c != l->end(); c++) {
308 if ((*c)->cache() != v) (*c)->reflectZone();
309 }
310 }
311 }
312
313 inline void UI::addCallback(float* zone, uiCallback foo, void* data)
314 {
315 new uiCallbackItem(this, zone, foo, data);
316 };
317
318 //----------------------------------------------------------------
319 // definition du processeur de signal
320 //----------------------------------------------------------------
321
322 class dsp {
323 protected:
324 int fSamplingFreq;
325 public:
326 dsp() {}
327 virtual ~dsp() {}
328
329 virtual int getNumInputs() = 0;
330 virtual int getNumOutputs() = 0;
331 virtual void buildUserInterface(UI* interface) = 0;
332 virtual void init(int samplingRate) = 0;
333 virtual void compute(int len, float** inputs, float** outputs) = 0;
334 virtual void conclude() {}
335 };
336
337
338 /********************END ARCHITECTURE SECTION (part 1/2)****************/
339
340 /**************************BEGIN USER SECTION **************************/
341
342 <<includeclass>>
343
344 /***************************END USER SECTION ***************************/
345
346 /*******************BEGIN ARCHITECTURE SECTION (part 2/2)***************/
347
348
349 /******************************************************************************
350 *******************************************************************************
351
352 JACK AUDIO INTERFACE
353
354 *******************************************************************************
355 *******************************************************************************/
356
357 #define JACK_DRIVER_NAME_MAX 15
358 #define JACK_DRIVER_PARAM_NAME_MAX 15
359 #define JACK_DRIVER_PARAM_STRING_MAX 63
360 #define JACK_DRIVER_PARAM_DESC 255
361 #define JACK_PATH_MAX 511
362
363 /** Driver parameter types */
364 typedef enum
365 {
366 JackDriverParamInt = 1,
367 JackDriverParamUInt,
368 JackDriverParamChar,
369 JackDriverParamString,
370 JackDriverParamBool
371 } jack_driver_param_type_t;
372
373 /** Driver parameter value */
374 typedef union
375 {
376 uint32_t ui;
377 int32_t i;
378 char c;
379 char str[JACK_DRIVER_PARAM_STRING_MAX + 1];
380 } jack_driver_param_value_t;
381
382
383 /** A driver parameter descriptor */
384 typedef struct {
385 char name[JACK_DRIVER_NAME_MAX + 1]; /**< The parameter's name */
386 char character; /**< The parameter's character (for getopt, etc) */
387 jack_driver_param_type_t type; /**< The parameter's type */
388 jack_driver_param_value_t value; /**< The parameter's (default) value */
389 char short_desc[64]; /**< A short (~30 chars) description for the user */
390 char long_desc[1024]; /**< A longer description for the user */
391 }
392 jack_driver_param_desc_t;
393
394 /** A driver parameter */
395 typedef struct {
396 char character;
397 jack_driver_param_value_t value;
398 }
399 jack_driver_param_t;
400
401 /** A struct for describing a jack driver */
402 typedef struct {
403 char name[JACK_DRIVER_NAME_MAX + 1]; /**< The driver's canonical name */
404 char desc[JACK_DRIVER_PARAM_DESC + 1]; /**< The driver's extended description */
405 char file[JACK_PATH_MAX + 1]; /**< The filename of the driver's shared object file */
406 uint32_t nparams; /**< The number of parameters the driver has */
407 jack_driver_param_desc_t * params; /**< An array of parameter descriptors */
408 }
409 jack_driver_desc_t;
410
411 // class JackArgParser ***************************************************
412 class JackArgParser
413 {
414 private:
415
416 std::string fArgString;
417 int fArgc;
418 std::vector<std::string> fArgv;
419
420 public:
421
422 JackArgParser (const char* arg);
423 ~JackArgParser();
424 std::string GetArgString();
425 int GetNumArgv();
426 int GetArgc();
427 int GetArgv (std::vector<std::string>& argv);
428 int GetArgv (char** argv);
429 void DeleteArgv (const char** argv);
430 void ParseParams (jack_driver_desc_t* desc, JSList** param_list);
431 void FreeParams (JSList* param_list);
432 };
433
434 JackArgParser::JackArgParser (const char* arg)
435 {
436 printf ("JackArgParser::JackArgParser, arg_string : '%s' \n", arg);
437
438 fArgc = 0;
439 //if empty string
440 if (strlen(arg) == 0)
441 return;
442 fArgString = string(arg);
443 //else parse the arg string
444 const size_t arg_len = fArgString.length();
445 unsigned int i = 0;
446 size_t pos = 0;
447 size_t start = 0;
448 size_t copy_start = 0;
449 size_t copy_length = 0;
450 //we need a 'space terminated' string
451 fArgString += " ";
452 //first fill a vector with args
453 do {
454 //find the first non-space character from the actual position
455 start = fArgString.find_first_not_of (' ', start);
456 //get the next quote or space position
457 pos = fArgString.find_first_of (" \"" , start);
458 //no more quotes or spaces, consider the end of the string
459 if (pos == string::npos)
460 pos = arg_len;
461 //if double quote
462 if (fArgString[pos] == '\"') {
463 //first character : copy the substring
464 if (pos == start) {
465 copy_start = start + 1;
466 pos = fArgString.find ('\"', ++pos);
467 copy_length = pos - copy_start;
468 start = pos + 1;
469 }
470 //else there is someting before the quote, first copy that
471 else {
472 copy_start = start;
473 copy_length = pos - copy_start;
474 start = pos;
475 }
476 }
477 //if space
478 if (fArgString[pos] == ' ') {
479 //short option descriptor
480 if ((fArgString[start] == '-') && (fArgString[start + 1] != '-')) {
481 copy_start = start;
482 copy_length = 2;
483 start += copy_length;
484 }
485 //else copy all the space delimitated string
486 else {
487 copy_start = start;
488 copy_length = pos - copy_start;
489 start = pos + 1;
490 }
491 }
492 //then push the substring to the args vector
493 fArgv.push_back (fArgString.substr (copy_start, copy_length));
494 printf("JackArgParser::JackArgParser, add : '%s' \n", (*fArgv.rbegin()).c_str());
495 } while (start < arg_len);
496
497 //finally count the options
498 for (i = 0; i < fArgv.size(); i++)
499 if (fArgv[i].at(0) == '-')
500 fArgc++;
501 }
502
503 JackArgParser::~JackArgParser()
504 {}
505
506 string JackArgParser::GetArgString()
507 {
508 return fArgString;
509 }
510
511 int JackArgParser::GetNumArgv()
512 {
513 return fArgv.size();
514 }
515
516 int JackArgParser::GetArgc()
517 {
518 return fArgc;
519 }
520
521 int JackArgParser::GetArgv(vector<string>& argv)
522 {
523 argv = fArgv;
524 return 0;
525 }
526
527 int JackArgParser::GetArgv(char** argv)
528 {
529 //argv must be NULL
530 if (argv)
531 return -1;
532 //else allocate and fill it
533 argv = (char**)calloc(fArgv.size(), sizeof(char*));
534 for (unsigned int i = 0; i < fArgv.size(); i++) {
535 argv[i] = (char*)calloc(fArgv[i].length(), sizeof(char));
536 fill_n(argv[i], fArgv[i].length() + 1, 0);
537 fArgv[i].copy(argv[i], fArgv[i].length());
538 }
539 return 0;
540 }
541
542 void JackArgParser::DeleteArgv(const char** argv)
543 {
544 unsigned int i;
545 for (i = 0; i < fArgv.size(); i++)
546 free((void*)argv[i]);
547 free((void*)argv);
548 }
549
550 void JackArgParser::ParseParams(jack_driver_desc_t* desc, JSList** param_list)
551 {
552 string options_list;
553 unsigned long i = 0;
554 unsigned int param = 0;
555 size_t param_id = 0;
556 JSList* params = NULL;
557 jack_driver_param_t* intclient_param;
558
559 for (i = 0; i < desc->nparams; i++)
560 options_list += desc->params[i].character;
561
562 for (param = 0; param < fArgv.size(); param++)
563 {
564 if (fArgv[param][0] == '-')
565 {
566 //valid option
567 if ((param_id = options_list.find_first_of(fArgv[param].at(1))) != string::npos)
568 {
569 intclient_param = static_cast<jack_driver_param_t*>(calloc(1, sizeof(jack_driver_param_t)));
570 intclient_param->character = desc->params[param_id].character;
571
572 switch (desc->params[param_id].type)
573 {
574 case JackDriverParamInt:
575 if (param + 1 < fArgv.size()) // something to parse
576 intclient_param->value.i = atoi(fArgv[param + 1].c_str());
577 break;
578
579 case JackDriverParamUInt:
580 if (param + 1 < fArgv.size()) // something to parse
581 intclient_param->value.ui = strtoul(fArgv[param + 1].c_str(), NULL, 10);
582 break;
583
584 case JackDriverParamChar:
585 if (param + 1 < fArgv.size()) // something to parse
586 intclient_param->value.c = fArgv[param + 1][0];
587 break;
588
589 case JackDriverParamString:
590 if (param + 1 < fArgv.size()) // something to parse
591 fArgv[param + 1].copy(intclient_param->value.str, min(static_cast<int>(fArgv[param + 1].length()), JACK_DRIVER_PARAM_STRING_MAX));
592 break;
593
594 case JackDriverParamBool:
595 intclient_param->value.i = true;
596 break;
597 }
598 //add to the list
599 params = jack_slist_append(params, intclient_param);
600 }
601 //invalid option
602 else
603 printf("Invalid option '%c'\n", fArgv[param][1]);
604 }
605 }
606
607 assert(param_list);
608 *param_list = params;
609 }
610
611 void JackArgParser::FreeParams(JSList* param_list)
612 {
613 JSList *node_ptr = param_list;
614 JSList *next_node_ptr;
615
616 while (node_ptr) {
617 next_node_ptr = node_ptr->next;
618 free(node_ptr->data);
619 free(node_ptr);
620 node_ptr = next_node_ptr;
621 }
622 }
623
624 struct JackFaustInternal {
625
626 //----------------------------------------------------------------------------
627 // number of input and output channels
628 //----------------------------------------------------------------------------
629
630 int fNumInChans;
631 int fNumOutChans;
632
633 //----------------------------------------------------------------------------
634 // Jack ports
635 //----------------------------------------------------------------------------
636
637 jack_port_t* fInputPorts[256];
638 jack_port_t* fOutputPorts[256];
639
640 //----------------------------------------------------------------------------
641 // tables of noninterleaved input and output channels for FAUST
642 //----------------------------------------------------------------------------
643
644 float* fInChannel[256];
645 float* fOutChannel[256];
646
647 jack_client_t* fClient;
648 UI* fInterface;
649 mydsp fDSP;
650
651 JackFaustInternal(jack_client_t* client, const JSList* params)
652 :fClient(client)
653 {}
654
655 ~JackFaustInternal()
656 {
657 delete fInterface;
658 }
659
660 int Open()
661 {
662 char** physicalInPorts;
663 char** physicalOutPorts;
664
665 fInterface = new OSCUI();
666 fDSP.buildUserInterface(fInterface);
667
668 jack_set_process_callback(fClient, process, this);
669 jack_set_sample_rate_callback(fClient, srate, this);
670
671 fNumInChans = fDSP.getNumInputs();
672 fNumOutChans = fDSP.getNumOutputs();
673
674 for (int i = 0; i < fNumInChans; i++) {
675 char buf[256];
676 snprintf(buf, 256, "in_%d", i);
677 fInputPorts[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
678 }
679 for (int i = 0; i < fNumOutChans; i++) {
680 char buf[256];
681 snprintf(buf, 256, "out_%d", i);
682 fOutputPorts[i] = jack_port_register(fClient, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
683 }
684
685 fDSP.init(jack_get_sample_rate(fClient));
686
687 physicalInPorts = (char **)jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
688 physicalOutPorts = (char **)jack_get_ports(fClient, NULL, NULL, JackPortIsPhysical|JackPortIsOutput);
689
690 if (jack_activate(fClient)) {
691 fprintf(stderr, "cannot activate client");
692 return -1;
693 }
694
695 if (physicalOutPorts != NULL) {
696 for (int i = 0; i < fNumInChans && physicalOutPorts[i]; i++) {
697 jack_connect(fClient, physicalOutPorts[i], jack_port_name(fInputPorts[i]));
698 }
699 }
700
701 if (physicalInPorts != NULL) {
702 for (int i = 0; i < fNumOutChans && physicalInPorts[i]; i++) {
703 jack_connect(fClient, jack_port_name(fOutputPorts[i]), physicalInPorts[i]);
704 }
705 }
706
707 return 0;
708 }
709
710 //----------------------------------------------------------------------------
711 // Jack Callbacks
712 //----------------------------------------------------------------------------
713
714 static int srate(jack_nframes_t nframes, void *arg)
715 {
716 printf("the sample rate is now %u/sec\n", nframes);
717 return 0;
718 }
719
720 static int process(jack_nframes_t nframes, void *arg)
721 {
722 JackFaustInternal* obj = (JackFaustInternal*)arg;
723 AVOIDDENORMALS;
724
725 for (int i = 0; i < obj->fNumInChans; i++) {
726 obj->fInChannel[i] = (float *)jack_port_get_buffer(obj->fInputPorts[i], nframes);
727 }
728 for (int i = 0; i < obj->fNumOutChans; i++) {
729 obj->fOutChannel[i] = (float *)jack_port_get_buffer(obj->fOutputPorts[i], nframes);
730 }
731 obj->fDSP.compute(nframes, obj->fInChannel, obj->fOutChannel);
732
733 return 0;
734 }
735
736 };
737
738 #ifdef __cplusplus
739 extern "C"
740 {
741 #endif
742
743 jack_driver_desc_t* jack_get_descriptor()
744 {
745 jack_driver_desc_t *desc;
746 unsigned int i;
747 desc = (jack_driver_desc_t*)calloc(1, sizeof(jack_driver_desc_t));
748
749 strcpy(desc->name, "faust"); // size MUST be less then JACK_DRIVER_NAME_MAX + 1
750 strcpy(desc->desc, " Faust generated internal"); // size MUST be less then JACK_DRIVER_PARAM_DESC + 1
751
752 desc->nparams = 0;
753 /*
754 desc->nparams = 2;
755 desc->params = (jack_driver_param_desc_t*)calloc(desc->nparams, sizeof(jack_driver_param_desc_t));
756
757 i = 0;
758 strcpy(desc->params[i].name, "channels");
759 desc->params[i].character = 'c';
760 desc->params[i].type = JackDriverParamInt;
761 desc->params[i].value.ui = 0;
762 strcpy(desc->params[i].short_desc, "Maximum number of channels");
763 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
764
765 i++;
766 strcpy(desc->params[i].name, "inchannels");
767 desc->params[i].character = 'i';
768 desc->params[i].type = JackDriverParamInt;
769 desc->params[i].value.ui = 0;
770 strcpy(desc->params[i].short_desc, "Maximum number of input channels");
771 strcpy(desc->params[i].long_desc, desc->params[i].short_desc);
772 */
773
774 return desc;
775 }
776
777 int jack_internal_initialize(jack_client_t* client, const JSList* params)
778 {
779 try {
780
781 JackFaustInternal* internal = new JackFaustInternal(client, params);
782 if (internal->Open() == 0) {
783 return 0;
784 } else {
785 delete internal;
786 return 1;
787 }
788
789 } catch (...) {
790 return 1;
791 }
792 }
793
794 int jack_initialize(jack_client_t* client, const char* load_init)
795 {
796 JSList* params = NULL;
797 jack_driver_desc_t *desc = jack_get_descriptor();
798
799 JackArgParser parser(load_init);
800 if (parser.GetArgc() > 0)
801 parser.ParseParams(desc, &params);
802
803 int res = jack_internal_initialize(client, params);
804 parser.FreeParams(params);
805 return res;
806 }
807
808 void jack_finish(void* arg)
809 {
810 JackFaustInternal* internal = static_cast<JackFaustInternal*>(arg);
811
812 if (internal) {
813 printf("Unloading internal\n");
814 delete internal;
815 }
816 }
817
818 #ifdef __cplusplus
819 }
820 #endif
821
822
823 /********************END ARCHITECTURE SECTION (part 2/2)****************/
824
825