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