Implement stdin, stdout and stderr to Faustine.
[Faustine.git] / interpreter / preprocessor / faust-0.9.47mr3 / architecture / unsupported-arch / jack-wx.cpp
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <limits.h>
5 #include <math.h>
6 #include <errno.h>
7 #include <time.h>
8 #include <sys/ioctl.h>
9 #include <unistd.h>
10 #include <fcntl.h>
11 //#include <sys/soundcard.h>
12 #include <pwd.h>
13 #include <sys/types.h>
14 #include <assert.h>
15 #include <pthread.h>
16 #include <sys/wait.h>
17 #include <list>
18 #include <vector>
19 #include <stack>
20
21 #include "wx/wx.h"
22 #include "wx/statbox.h"
23 #include "wx/notebook.h"
24 #include "wx/spinctrl.h"
25
26
27 #include <libgen.h>
28 #include <jack/jack.h>
29
30 // linux : g++ -O3 -lm -ljack `wx-config --cflags --libs` ex2.cpp
31 // macosx: g++ karplus-strong.cpp -D__WXMAC__ -DWXMAKINGDLL -lwx_mac-2.4 -ljack -o karplus
32
33 using namespace std ;
34
35
36 #ifdef __GNUC__
37
38 //-------------------------------------------------------------------
39 // Generic min and max using gcc extensions
40 //-------------------------------------------------------------------
41
42 #define max(x,y) ((x)>?(y))
43 #define min(x,y) ((x)<?(y))
44
45 //abs(x) should be already predefined
46
47 #else
48
49 //-------------------------------------------------------------------
50 // Generic min and max using c++ inline
51 //-------------------------------------------------------------------
52
53 inline int max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
54 inline int max (int a, int b) { return (a>b) ? a : b; }
55
56 inline long max (long a, long b) { return (a>b) ? a : b; }
57 inline long max (int a, long b) { return (a>b) ? a : b; }
58 inline long max (long a, int b) { return (a>b) ? a : b; }
59
60 inline float max (float a, float b) { return (a>b) ? a : b; }
61 inline float max (int a, float b) { return (a>b) ? a : b; }
62 inline float max (float a, int b) { return (a>b) ? a : b; }
63 inline float max (long a, float b) { return (a>b) ? a : b; }
64 inline float max (float a, long b) { return (a>b) ? a : b; }
65
66 inline double max (double a, double b) { return (a>b) ? a : b; }
67 inline double max (int a, double b) { return (a>b) ? a : b; }
68 inline double max (double a, int b) { return (a>b) ? a : b; }
69 inline double max (long a, double b) { return (a>b) ? a : b; }
70 inline double max (double a, long b) { return (a>b) ? a : b; }
71 inline double max (float a, double b) { return (a>b) ? a : b; }
72 inline double max (double a, float b) { return (a>b) ? a : b; }
73
74
75 inline int min (int a, int b) { return (a<b) ? a : b; }
76
77 inline long min (long a, long b) { return (a<b) ? a : b; }
78 inline long min (int a, long b) { return (a<b) ? a : b; }
79 inline long min (long a, int b) { return (a<b) ? a : b; }
80
81 inline float min (float a, float b) { return (a<b) ? a : b; }
82 inline float min (int a, float b) { return (a<b) ? a : b; }
83 inline float min (float a, int b) { return (a<b) ? a : b; }
84 inline float min (long a, float b) { return (a<b) ? a : b; }
85 inline float min (float a, long b) { return (a<b) ? a : b; }
86
87 inline double min (double a, double b) { return (a<b) ? a : b; }
88 inline double min (int a, double b) { return (a<b) ? a : b; }
89 inline double min (double a, int b) { return (a<b) ? a : b; }
90 inline double min (long a, double b) { return (a<b) ? a : b; }
91 inline double min (double a, long b) { return (a<b) ? a : b; }
92 inline double min (float a, double b) { return (a<b) ? a : b; }
93 inline double min (double a, float b) { return (a<b) ? a : b; }
94
95 #endif
96
97 // abs is now predefined
98 //template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
99
100
101 inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); }
102
103 inline int int2pow2 (int x) { int r=0; while ((1<<r)<x) r++; return r; }
104
105
106 /******************************************************************************
107 *******************************************************************************
108
109 VECTOR INTRINSICS
110
111 *******************************************************************************
112 *******************************************************************************/
113
114 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
115 //inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
116
117 <<includeIntrinsic>>
118
119
120 /******************************************************************************
121 *******************************************************************************
122
123 USER INTERFACE
124
125 *******************************************************************************
126 *******************************************************************************/
127
128 class UI
129 {
130 bool fStopped;
131 public:
132
133 UI() : fStopped(false) {}
134 virtual ~UI() {}
135
136 virtual void addButton(char* label, float* zone) = 0;
137 virtual void addToggleButton(char* label, float* zone) = 0;
138 virtual void addCheckButton(char* label, float* zone) = 0;
139 virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
140 virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
141 virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step) = 0;
142
143 virtual void openFrameBox(char* label) = 0;
144 virtual void openTabBox(char* label) = 0;
145 virtual void openHorizontalBox(char* label) = 0;
146 virtual void openVerticalBox(char* label) = 0;
147 virtual void closeBox() = 0;
148
149 virtual void run() {};
150
151 void stop() { fStopped = true; }
152 bool stopped() { return fStopped; }
153 };
154
155
156
157 /******************************************************************************
158 *******************************************************************************
159
160 FAUST DSP
161
162 *******************************************************************************
163 *******************************************************************************/
164
165
166
167 //----------------------------------------------------------------
168 // définition du processeur de signal
169 //----------------------------------------------------------------
170
171 class dsp {
172 protected:
173 int fSamplingFreq;
174 public:
175 dsp() {}
176 virtual int getNumInputs() = 0;
177 virtual int getNumOutputs() = 0;
178 virtual void buildUserInterface(UI* interface) = 0;
179 virtual void init(int samplingRate) = 0;
180 virtual void compute(int len, float** inputs, float** outputs) = 0;
181 };
182
183
184 <<includeclass>>
185
186
187 mydsp DSP;
188
189
190
191 /******************************************************************************
192 *******************************************************************************
193
194 JACK AUDIO INTERFACE
195
196 *******************************************************************************
197 *******************************************************************************/
198
199
200
201 //----------------------------------------------------------------------------
202 // number of input and output channels
203 //----------------------------------------------------------------------------
204
205 int gNumInChans;
206 int gNumOutChans;
207
208
209 //----------------------------------------------------------------------------
210 // Jack ports
211 //----------------------------------------------------------------------------
212
213 jack_port_t *input_ports[256];
214 jack_port_t *output_ports[256];
215
216 //----------------------------------------------------------------------------
217 // tables of noninterleaved input and output channels for FAUST
218 //----------------------------------------------------------------------------
219
220 float* gInChannel[256];
221 float* gOutChannel[256];
222
223
224 //----------------------------------------------------------------------------
225 // Jack Callbacks
226 //----------------------------------------------------------------------------
227
228 int srate(jack_nframes_t nframes, void *arg)
229 {
230 printf("the sample rate is now %lu/sec\n", nframes);
231 return 0;
232 }
233
234 void jack_shutdown(void *arg)
235 {
236 exit(1);
237 }
238
239 int process (jack_nframes_t nframes, void *arg)
240 {
241 // ATTENTION: en vectoriel il faut s'assurer que gInChannel et gOutChannel soit align�s sur une fronti�re de 128 bits
242
243 for (int i = 0; i < gNumInChans; i++) {
244 gInChannel[i] = (float *)jack_port_get_buffer(input_ports[i], nframes);
245 }
246 for (int i = 0; i < gNumOutChans; i++) {
247 gOutChannel[i] = (float *)jack_port_get_buffer(output_ports[i], nframes);
248 }
249 DSP.compute(nframes, gInChannel, gOutChannel);
250 return 0;
251 }
252
253
254 /******************************************************************************
255 *******************************************************************************
256
257 WXWINDOWS USER INTERFACE
258
259 *******************************************************************************
260 *******************************************************************************/
261
262
263 // les modes d'insertion
264
265 #define kNormalState 0
266 #define kNotebookState 1
267 #define kAutoPageState 2
268
269 #define kProp 0
270 #define kBorder 5
271 #define kFlag wxALL|wxGROW
272
273
274 // faustButton : a wxButton for FAUST.
275 class faustButton : public wxButton
276 {
277 float* fZone;
278 public :
279 faustButton(wxWindow* parent, const wxString& label, float* zone)
280 : wxButton(parent, -1, label, wxPoint(-1, -1)), fZone(zone)
281 {
282 *fZone = 0.0;
283 }
284
285 #ifdef MACOSX
286 void clickdown (wxCommandEvent& ev) { *fZone = 1.0; /*printf("click down : zone (at %p) = %f\n", fZone, *fZone); ev.Skip();*/}
287 void clickup (wxCommandEvent& ev) { *fZone = 0.0; /*printf("click up : zone (at %p) = %f\n", fZone, *fZone);ev.Skip();*/ }
288 #else
289 void clickdown (wxCommandEvent& ev) { *fZone = 1.0; /*printf("click down : zone (at %p) = %f\n", fZone, *fZone);*/ ev.Skip();}
290 void clickup (wxCommandEvent& ev) { *fZone = 0.0; /*printf("click up : zone (at %p) = %f\n", fZone, *fZone);*/ ev.Skip(); }
291 #endif
292 private:
293 DECLARE_EVENT_TABLE()
294 };
295
296 BEGIN_EVENT_TABLE(faustButton, wxButton)
297 EVT_LEFT_DOWN(faustButton::clickdown)
298 EVT_LEFT_UP(faustButton::clickup)
299 END_EVENT_TABLE()
300
301
302 class faustCheckBox : public wxCheckBox
303 {
304 float* fZone;
305 public :
306 faustCheckBox(wxWindow* parent, const wxString& label, float* zone)
307 : wxCheckBox(parent, -1, label, wxPoint(-1, -1)), fZone(zone)
308 {
309 *fZone = 0.0;
310 }
311
312 void toggle (wxCommandEvent& ev) {
313 *fZone = (ev.IsChecked()) ? 1.0 : 0.0;
314 //printf("toogle : zone (at %p) = %f\n", fZone, *fZone);
315 }
316
317 private:
318 DECLARE_EVENT_TABLE()
319 };
320
321 BEGIN_EVENT_TABLE(faustCheckBox, wxCheckBox)
322 EVT_CHECKBOX(-1, faustCheckBox::toggle)
323 END_EVENT_TABLE()
324
325
326 class faustHorizontalSlider : public wxSlider
327 {
328 float fStep;
329 float* fZone;
330 public :
331 faustHorizontalSlider(wxWindow* parent, float* zone, float init , float min, float max, float step)
332 : wxSlider(parent, -1, int(init/step), int(min/step), int(max/step), wxDefaultPosition, wxSize(120,30), wxSL_HORIZONTAL), fStep(step), fZone(zone)
333 {
334 *fZone = init;
335 }
336
337 void update (wxCommandEvent& ev) {
338 *fZone = GetValue()*fStep;
339 //printf("horizontal slider update : zone (at %p) = %f\n", fZone, *fZone);
340 }
341
342 private:
343 DECLARE_EVENT_TABLE()
344 };
345
346 BEGIN_EVENT_TABLE(faustHorizontalSlider, wxSlider)
347 EVT_SLIDER (-1, faustHorizontalSlider::update)
348 END_EVENT_TABLE()
349
350
351 class faustVerticalSlider : public wxSlider
352 {
353 float fStep;
354 float* fZone;
355 public :
356 faustVerticalSlider(wxWindow* parent, float* zone, float init , float min, float max, float step)
357 : wxSlider(parent, -1, int((max+min-init)/step), int(min/step), int(max/step), wxDefaultPosition, wxSize(30,120), wxSL_VERTICAL), fStep(step), fZone(zone)
358 {
359 *fZone = init;
360 }
361
362 void update (wxCommandEvent& ev) {
363 *fZone = (GetMin()+GetMax()-GetValue())*fStep;
364 //printf("vertical slider update : zone (at %p) = %f\n", fZone, *fZone);
365 }
366
367 private:
368 DECLARE_EVENT_TABLE()
369 };
370
371 BEGIN_EVENT_TABLE(faustVerticalSlider, wxSlider)
372 EVT_SLIDER (-1, faustVerticalSlider::update)
373 END_EVENT_TABLE()
374
375
376 //--------------------------------
377 // faustSpinCtrl* b = new faustSpinCtrl(topPanel(), zone, init, min, max, step);
378 // wxSpinCtrl* b = new wxSpinCtrl( topPanel(), -1, "", wxPoint(200, 160), wxSize(80, -1) );
379 // b->SetRange(int(min),int(max));
380 // b->SetValue(int(init));
381
382
383 class faustSpinCtrl : public wxSpinCtrl
384 {
385 float fStep;
386 float* fZone;
387 public :
388 faustSpinCtrl(wxWindow* parent, float* zone, float init , float min, float max, float step)
389 : wxSpinCtrl(parent), fStep(step), fZone(zone)
390 {
391 SetRange(int(min),int(max));
392 SetValue(int(init));
393 *fZone = init;
394 }
395
396 void update (wxCommandEvent& ev) { *fZone = GetValue(); printf("spin ctrl update : zone (at %p) = %f\n", fZone, *fZone); }
397
398 private:
399 DECLARE_EVENT_TABLE()
400 };
401
402 BEGIN_EVENT_TABLE(faustSpinCtrl, wxSpinCtrl)
403 EVT_SPINCTRL (-1, faustSpinCtrl::update)
404 END_EVENT_TABLE()
405
406
407
408 class WXUI : public UI // user interface
409 {
410
411 class State
412 {
413 int const fType;
414 wxWindow* const fPanel;
415 wxSizer* const fSizer;
416
417 public:
418 State (int t, wxWindow* p, wxSizer* z) : fType(t), fPanel(p), fSizer(z) {}
419 int type() const { return fType; }
420 wxWindow* panel() const { return fPanel; }
421 wxSizer* sizer() const { return fSizer; }
422 };
423
424 stack<State> lState;
425 wxFrame* frame;
426 wxSizer* fSizer;
427
428 // gestion de l'etat courant du constructeur
429
430 void push (int t, wxWindow* p, wxSizer* z)
431 {
432 printf("push %d of %d, %p, %p\n", lState.size(), t, p, z);
433 lState.push(State(t,p,z));
434 }
435
436 int topType() { return lState.top().type(); }
437 wxWindow* topPanel() { return lState.top().panel(); }
438 wxSizer* topSizer() { return lState.top().sizer(); }
439
440 void pop ()
441 {
442 printf("pop %d", lState.size()-1);
443 lState.pop();
444 printf(" ok\n");
445 }
446
447 void openAutoPage(char* label)
448 {
449 if (topType() == kNotebookState) {
450
451 if (!label) label = "";
452
453 wxNotebook* nb = (wxNotebook*) topPanel();
454 wxPanel* p = new wxPanel( nb, -1 );
455 wxBoxSizer* z = new wxBoxSizer( wxVERTICAL );
456
457 nb->AddPage(p, label);
458 p->SetAutoLayout(TRUE);
459 p->SetSizer(z);
460
461 push(kAutoPageState, p, z);
462 }
463 }
464
465 void closeAutoPage()
466 {
467 if (topType() == kAutoPageState) pop();
468 }
469
470 void openOrientedBox(char* label, int orientation)
471 {
472 openAutoPage(label);
473
474 wxSizer* z = (label == 0) ? new wxBoxSizer(orientation)
475 : new wxStaticBoxSizer(new wxStaticBox(topPanel(), -1, label), orientation);
476
477 topSizer()->Add(z, 1, kFlag, kBorder);
478 push(kNormalState, topPanel(), z);
479 }
480
481 public:
482
483
484 WXUI(){}
485
486 virtual ~WXUI() {}
487
488 void openFrame(wxFrame* f)
489 {
490 frame = f;
491 fSizer = new wxBoxSizer(wxVERTICAL);
492 frame->SetSizer(fSizer);
493 push(kNormalState, frame, fSizer);
494 }
495
496 wxFrame* closeFrame()
497 {
498 fSizer->Fit(frame);
499 fSizer->SetSizeHints(frame);
500 return frame;
501 }
502
503 virtual void openHorizontalBox(char* label) { openOrientedBox(label, wxHORIZONTAL); }
504 virtual void openVerticalBox(char* label) { openOrientedBox(label, wxVERTICAL); }
505
506 virtual void openTabBox(char* label)
507 {
508 openAutoPage(label);
509
510 wxNotebook* nb = new wxNotebook( topPanel(), -1 );
511 wxNotebookSizer* z = new wxNotebookSizer( nb );
512
513 topSizer()->Add(z, 1, kFlag, kBorder);
514 push(kNotebookState, nb, z);
515 }
516
517 virtual void closeBox()
518 {
519 pop();
520 closeAutoPage();
521 }
522
523 //--------------------------------- les elements ------------------------------------------
524
525 virtual void addButton(char* label, float* zone)
526 {
527 openAutoPage(label);
528 faustButton* b = new faustButton(topPanel(), label, zone);
529 topSizer()->Add(b, kProp, kFlag, kBorder);
530 closeAutoPage();
531 }
532
533 virtual void addCheckButton(char* label, float* zone)
534 {
535 openAutoPage(label);
536 faustCheckBox* b = new faustCheckBox(topPanel(), label, zone);
537 topSizer()->Add(b, kProp, kFlag, kBorder);
538 closeAutoPage();
539 }
540
541 virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step)
542 {
543 openAutoPage(label);
544 if (label) {
545 wxSizer* z = new wxStaticBoxSizer(new wxStaticBox(topPanel(), -1, label), wxHORIZONTAL);
546 topSizer()->Add(z, 1, kFlag, kBorder);
547 faustVerticalSlider* b = new faustVerticalSlider(topPanel(), zone, init, min, max, step);
548 b->SetToolTip(label);
549 z->Add(b, 1, kFlag|wxALIGN_CENTER_VERTICAL, kBorder);
550 } else {
551 faustVerticalSlider* b = new faustVerticalSlider(topPanel(), zone, init, min, max, step);
552 topSizer()->Add(b, kProp, kFlag, kBorder);
553 }
554 closeAutoPage();
555 }
556
557 virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step)
558 {
559 openAutoPage(label);
560 if (label) {
561 wxSizer* z = new wxStaticBoxSizer(new wxStaticBox(topPanel(), -1, label), wxVERTICAL);
562 topSizer()->Add(z, 1, kFlag, kBorder);
563 faustHorizontalSlider* b = new faustHorizontalSlider(topPanel(), zone, init, min, max, step);
564 b->SetToolTip(label);
565 z->Add(b, 1, kFlag|wxALIGN_CENTER_HORIZONTAL, kBorder);
566 } else {
567 faustHorizontalSlider* b = new faustHorizontalSlider(topPanel(), zone, init, min, max, step);
568 topSizer()->Add(b, kProp, kFlag, kBorder);
569 }
570 closeAutoPage();
571 }
572
573 virtual void addToggleButton(char* label, float* zone) {}
574 virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step)
575 {
576 openAutoPage(label);
577 if (label) {
578 wxSizer* z = new wxStaticBoxSizer(new wxStaticBox(topPanel(), -1, label), wxVERTICAL);
579 topSizer()->Add(z, 0, kFlag, kBorder);
580 faustSpinCtrl* b = new faustSpinCtrl(topPanel(), zone, init, min, max, step);
581 // wxSpinCtrl* b = new wxSpinCtrl( topPanel(), -1, "", wxPoint(200, 160), wxSize(80, -1) );
582 // b->SetRange(int(min),int(max));
583 // b->SetValue(int(init));
584 b->SetToolTip(label);
585 z->Add(b, 0, kFlag, kBorder);
586 } else {
587 faustSpinCtrl* b = new faustSpinCtrl(topPanel(), zone, init, min, max, step);
588 // wxSpinCtrl* b = new wxSpinCtrl( topPanel(), -1, "", wxPoint(200, 160), wxSize(80, -1) );
589 // b->SetRange(int(min),int(max));
590 // b->SetValue(int(init));
591 topSizer()->Add(b, kProp, kFlag, kBorder);
592 }
593 closeAutoPage();
594 }
595 virtual void openFrameBox(char* label) {}
596 };
597
598
599
600 /******************************************************************************
601 *******************************************************************************
602
603 WXWINDOWS TOP FRAME
604
605 *******************************************************************************
606 *******************************************************************************/
607
608
609 enum { ID_QUIT=1, ID_ABOUT };
610
611
612 class MyFrame : public wxFrame
613 {
614 public:
615 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
616 : wxFrame(0, -1, title, pos, size)
617 {
618 wxMenu* m = new wxMenu;
619 m->Append(ID_ABOUT, "&About...");
620 m->AppendSeparator();
621 m->Append(ID_QUIT, "E&xit");
622
623 wxMenuBar* b = new wxMenuBar;
624 b->Append(m, "&File");
625 SetMenuBar(b);
626 CreateStatusBar();
627 SetStatusText("hello...");
628 }
629
630 void OnQuit(wxCommandEvent& event)
631 {
632 Close(TRUE);
633 }
634
635 void OnAbout(wxCommandEvent& event)
636 {
637 wxMessageBox("message 1", "message 2", wxOK|wxICON_INFORMATION);
638 }
639
640 private:
641 DECLARE_EVENT_TABLE()
642 };
643
644
645 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
646 EVT_MENU(ID_QUIT, MyFrame::OnQuit)
647 EVT_MENU(ID_ABOUT, MyFrame::OnAbout)
648 END_EVENT_TABLE()
649
650
651
652 /******************************************************************************
653 *******************************************************************************
654
655 WXWINDOWS MAIN APPLICATION
656
657 *******************************************************************************
658 *******************************************************************************/
659
660 // Scan Command Line Arguments
661
662 class MyApp : public wxApp
663 {
664 jack_client_t* client;
665 char jackname[256];
666 char** physicalInPorts;
667 char** physicalOutPorts;
668
669 virtual bool OnInit()
670 {
671 MyFrame* frame = new MyFrame(argv[0], wxPoint(50,50), wxSize(-1, -1));
672 /*
673 wxMenu* m = new wxMenu;
674 m->Append(ID_ABOUT, "&About...");
675 m->AppendSeparator();
676 m->Append(ID_QUIT, "E&xit");
677
678 wxMenuBar* b = new wxMenuBar;
679 b->Append(m, "&File");
680
681 frame->SetMenuBar(b);
682 frame->CreateStatusBar();
683 frame->SetStatusText("Faust dsp...");
684 */
685 WXUI* ui = new WXUI();
686 ui->openFrame(frame);
687 DSP.buildUserInterface((UI*)ui);
688 ui->closeFrame();
689
690 frame->Show(TRUE);
691 SetTopWindow(frame);
692
693 snprintf(jackname, 256, "faust_%s", basename(argv[0]));
694
695 if ((client = jack_client_open(jackname, JackNullOption, NULL)) == 0) {
696 fprintf(stderr, "jack server not running?\n");
697 return 1;
698 }
699
700 jack_set_process_callback(client, process, 0);
701 jack_set_sample_rate_callback(client, srate, 0);
702 jack_on_shutdown(client, jack_shutdown, 0);
703
704 gNumInChans = DSP.getNumInputs();
705 gNumOutChans = DSP.getNumOutputs();
706
707 for (int i = 0; i < gNumInChans; i++) {
708 char buf[256];
709 snprintf(buf, 256, "in_%d", i);
710 input_ports[i] = jack_port_register(client, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
711 }
712 for (int i = 0; i < gNumOutChans; i++) {
713 char buf[256];
714 snprintf(buf, 256, "out_%d", i);
715 output_ports[i] = jack_port_register(client, buf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
716 }
717
718 DSP.init(jack_get_sample_rate(client));
719
720 physicalInPorts = (char **)jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsInput);
721 physicalOutPorts = (char **)jack_get_ports(client, NULL, NULL, JackPortIsPhysical|JackPortIsOutput);
722
723 if (jack_activate(client)) {
724 fprintf(stderr, "cannot activate client");
725 return 1;
726 }
727
728 if (physicalOutPorts != NULL) {
729 for (int i = 0; i < gNumInChans && physicalOutPorts[i]; i++) {
730 jack_connect(client, physicalOutPorts[i], jack_port_name(input_ports[i]));
731 }
732 free(physicalOutPorts);
733 }
734
735 if (physicalInPorts != NULL) {
736 for (int i = 0; i < gNumOutChans && physicalInPorts[i]; i++) {
737 jack_connect(client, jack_port_name(output_ports[i]), physicalInPorts[i]);
738 }
739 free(physicalInPorts);
740 }
741
742 return TRUE;
743 }
744
745 virtual int OnExit()
746 {
747 jack_deactivate(client);
748
749 for (int i = 0; i < gNumInChans; i++) {
750 jack_port_unregister(client, input_ports[i]);
751 }
752 for (int i = 0; i < gNumOutChans; i++) {
753 jack_port_unregister(client, output_ports[i]);
754 }
755
756 jack_client_close(client);
757 return 0;
758 }
759 };
760
761
762 IMPLEMENT_APP(MyApp)
763