Add the output wave files into track list
[Faustine.git] / interpretor / faust-0.9.47mr3 / architecture / unsupported-arch / oss-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 // g++ -O3 -lm `wx-config --cflags --libs` ex2.cpp
27
28 using namespace std ;
29
30
31 #ifdef __GNUC__
32
33 //-------------------------------------------------------------------
34 // Generic min and max using gcc extensions
35 //-------------------------------------------------------------------
36
37 #define max(x,y) ((x)>?(y))
38 #define min(x,y) ((x)<?(y))
39
40 //abs(x) should be already predefined
41
42 #else
43
44 //-------------------------------------------------------------------
45 // Generic min and max using c++ inline
46 //-------------------------------------------------------------------
47
48 inline int max (unsigned int a, unsigned int b) { return (a>b) ? a : b; }
49 inline int max (int a, int b) { return (a>b) ? a : b; }
50
51 inline long max (long a, long b) { return (a>b) ? a : b; }
52 inline long max (int a, long b) { return (a>b) ? a : b; }
53 inline long max (long a, int b) { return (a>b) ? a : b; }
54
55 inline float max (float a, float b) { return (a>b) ? a : b; }
56 inline float max (int a, float b) { return (a>b) ? a : b; }
57 inline float max (float a, int b) { return (a>b) ? a : b; }
58 inline float max (long a, float b) { return (a>b) ? a : b; }
59 inline float max (float a, long b) { return (a>b) ? a : b; }
60
61 inline double max (double a, double b) { return (a>b) ? a : b; }
62 inline double max (int a, double b) { return (a>b) ? a : b; }
63 inline double max (double a, int b) { return (a>b) ? a : b; }
64 inline double max (long a, double b) { return (a>b) ? a : b; }
65 inline double max (double a, long b) { return (a>b) ? a : b; }
66 inline double max (float a, double b) { return (a>b) ? a : b; }
67 inline double max (double a, float b) { return (a>b) ? a : b; }
68
69
70 inline int min (int a, int b) { return (a<b) ? a : b; }
71
72 inline long min (long a, long b) { return (a<b) ? a : b; }
73 inline long min (int a, long b) { return (a<b) ? a : b; }
74 inline long min (long a, int b) { return (a<b) ? a : b; }
75
76 inline float min (float a, float b) { return (a<b) ? a : b; }
77 inline float min (int a, float b) { return (a<b) ? a : b; }
78 inline float min (float a, int b) { return (a<b) ? a : b; }
79 inline float min (long a, float b) { return (a<b) ? a : b; }
80 inline float min (float a, long b) { return (a<b) ? a : b; }
81
82 inline double min (double a, double b) { return (a<b) ? a : b; }
83 inline double min (int a, double b) { return (a<b) ? a : b; }
84 inline double min (double a, int b) { return (a<b) ? a : b; }
85 inline double min (long a, double b) { return (a<b) ? a : b; }
86 inline double min (double a, long b) { return (a<b) ? a : b; }
87 inline double min (float a, double b) { return (a<b) ? a : b; }
88 inline double min (double a, float b) { return (a<b) ? a : b; }
89
90 #endif
91
92 // abs is now predefined
93 //template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
94
95
96 inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); }
97
98 inline int int2pow2 (int x) { int r=0; while ((1<<r)<x) r++; return r; }
99
100
101 void setRealtimePriority ()
102 {
103 struct passwd * pw;
104 int err;
105 uid_t uid;
106 struct sched_param param;
107
108 uid = getuid ();
109 pw = getpwnam ("root");
110 setuid (pw->pw_uid);
111 param.sched_priority = 50; /* 0 to 99 */
112 err = sched_setscheduler(0, SCHED_RR, &param);
113 setuid (uid);
114 if (err != -1) {
115 printf("OK : Running with realtime priority\n");
116 } else {
117 printf("Warning : running with non-realtime priority\n");
118 }
119
120 }
121
122
123 /******************************************************************************
124 *******************************************************************************
125
126 VECTOR INTRINSICS
127
128 *******************************************************************************
129 *******************************************************************************/
130
131
132 <<includeIntrinsic>>
133
134
135
136 /******************************************************************************
137 *******************************************************************************
138
139 AUDIO INTERFACE
140
141 *******************************************************************************
142 *******************************************************************************/
143
144 enum { kRead = 1, kWrite = 2, kReadWrite = 3 };
145
146 // AudioParam : a convenient class to pass parameters to the AudioInterface
147 struct AudioParam
148 {
149 const char* fDeviceName;
150 int fSamplingFrequency;
151 int fRWMode;
152 int fSampleFormat;
153 int fFramesPerBuffer;
154
155 AudioParam() :
156 fDeviceName("/dev/dsp"),
157 fSamplingFrequency(44100),
158 fRWMode(kReadWrite),
159 fSampleFormat(AFMT_S16_LE),
160 fFramesPerBuffer(512)
161 {}
162
163 AudioParam& device(const char * n) { fDeviceName = n; return *this; }
164 AudioParam& frequency(int f) { fSamplingFrequency = f; return *this; }
165 AudioParam& mode(int m) { fRWMode = m; return *this; }
166 AudioParam& format(int f) { fSampleFormat = f; return *this; }
167 AudioParam& buffering(int fpb) { fFramesPerBuffer = fpb; return *this; }
168 };
169
170 class AudioInterface
171 {
172 private :
173 AudioParam fParam;
174 int fOutputDevice ;
175 int fInputDevice ;
176 int fNumOfOutputChannels;
177 int fNumOfInputChannels;
178 int fInputBufferSize;
179 short* fInputBuffer;
180 int fOutputBufferSize;
181 short* fOutputBuffer;
182
183
184 public :
185
186 const char* getDeviceName() { return fParam.fDeviceName; }
187 int getSamplingFrequency() { return fParam.fSamplingFrequency; }
188 int getRWMode() { return fParam.fRWMode; }
189 int getSampleFormat() { return fParam.fSampleFormat; }
190 int getFramesPerBuffer() { return fParam.fFramesPerBuffer; }
191
192 int getNumOutputs() { return fNumOfOutputChannels; }
193 int getNumInputs() { return fNumOfInputChannels; }
194 int getInputBufferSize() { return fInputBufferSize; }
195 int getOutputBufferSize() { return fOutputBufferSize; }
196
197
198 AudioInterface(const AudioParam& ap = AudioParam()) : fParam(ap)
199 {
200 fOutputDevice = -1;
201 fInputDevice = -1;
202 fNumOfOutputChannels = 0;
203 fNumOfInputChannels = 0;
204 fInputBufferSize = 0;
205 fInputBuffer = 0;
206 fOutputBufferSize = 0;
207 fOutputBuffer = 0;
208 }
209
210
211 void openInputAudioDev ()
212 {
213 int err = 0;
214
215 assert( (fInputDevice = ::open(fParam.fDeviceName, O_RDONLY, 0)) > 0);
216 assert( ioctl(fInputDevice, SNDCTL_DSP_SETFMT, &fParam.fSampleFormat) != -1);
217 assert( ioctl(fInputDevice, SNDCTL_DSP_CHANNELS, &fNumOfInputChannels) != -1);
218 assert( ioctl(fInputDevice, SNDCTL_DSP_SPEED, &fParam.fSamplingFrequency) != -1);
219
220 int gFragFormat = (1 << 16) + int2pow2(fParam.fFramesPerBuffer * 2 * fNumOfInputChannels);
221 assert( ioctl(fInputDevice, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) != -1);
222
223 fInputBufferSize = 0;
224 assert( ioctl(fInputDevice, SNDCTL_DSP_GETBLKSIZE, &fInputBufferSize) != -1);
225 assert( fInputBufferSize == fParam.fFramesPerBuffer * 2 * fNumOfInputChannels );
226
227 fInputBuffer = (short*) calloc(fInputBufferSize, 1);
228 }
229
230
231 void openOutputAudioDev ()
232 {
233 int err = 0;
234
235 assert( (fOutputDevice = ::open(fParam.fDeviceName, O_WRONLY, 0)) > 0);
236 assert( ioctl(fOutputDevice, SNDCTL_DSP_SETFMT, &fParam.fSampleFormat) != -1);
237 assert( ioctl(fOutputDevice, SNDCTL_DSP_CHANNELS,&fNumOfOutputChannels)!= -1);
238 assert( ioctl(fOutputDevice, SNDCTL_DSP_SPEED, &fParam.fSamplingFrequency) != -1);
239
240 int gFragFormat = (1 << 16) + int2pow2(fParam.fFramesPerBuffer * 2 * fNumOfOutputChannels);
241 assert( ioctl(fOutputDevice, SNDCTL_DSP_SETFRAGMENT, &gFragFormat) != -1);
242
243 fOutputBufferSize = 0;
244 assert( ioctl(fOutputDevice, SNDCTL_DSP_GETBLKSIZE, &fOutputBufferSize) != -1);
245 assert( fOutputBufferSize == fParam.fFramesPerBuffer * 2 * fNumOfOutputChannels );
246
247 fOutputBuffer = (short*)calloc(fOutputBufferSize, 1);
248 }
249
250
251 void open()
252 {
253 if (fParam.fRWMode & kRead) openInputAudioDev();
254 if (fParam.fRWMode & kWrite) openOutputAudioDev();
255 }
256
257
258 void close()
259 {
260 if (fParam.fRWMode & kRead) ::close(fOutputDevice);
261 if (fParam.fRWMode & kWrite) ::close(fInputDevice);
262 }
263
264
265
266 //----------------------------------------------------------------
267 // allocChanGroup() : allocate a group of audio buffers
268 // chan[] : is an array of buffer pointers
269 // n : is the number of buffers to allocate
270 // len : is the length of each buffer
271 //----------------------------------------------------------------
272
273 void allocChanGroup(float* chan[], int n, int len)
274 {
275 for (int c = 0; c < n; c++) {
276 chan[c] = (float*) calloc (len, sizeof(float));
277 }
278 }
279
280
281 //----------------------------------------------------------------
282 // info() : print information on the audio device
283 //----------------------------------------------------------------
284
285 void info()
286 {
287 audio_buf_info info;
288 int err = 0;
289 int cap;
290 printf("Audio Interface Description :\n");
291 printf("Sampling Frequency : %d, Sample Format : %d, Mode : %d\n", getSamplingFrequency(), getSampleFormat(), getRWMode());
292
293 if (getRWMode() & kWrite) {
294 assert( ioctl(fOutputDevice, SNDCTL_DSP_GETOSPACE, &info) != -1);
295 printf("output space info: fragments=%d, fragstotal=%d, fragsize=%d, bytes=%d\n", info.fragments, info.fragstotal,
296 info.fragsize, info.bytes);
297
298 assert( ioctl(fOutputDevice,SNDCTL_DSP_GETCAPS, &cap) != -1);
299 printf("Output capabilities - %d channels : ", fNumOfOutputChannels);
300
301 if (cap & DSP_CAP_DUPLEX) printf(" DSP_CAP_DUPLEX");
302 if (cap & DSP_CAP_REALTIME) printf(" DSP_CAP_REALTIME");
303 if (cap & DSP_CAP_DUPLEX) printf(" DSP_CAP_DUPLEX");
304 if (cap & DSP_CAP_BATCH) printf(" DSP_CAP_BATCH");
305 if (cap & DSP_CAP_COPROC) printf(" DSP_CAP_COPROC");
306 if (cap & DSP_CAP_TRIGGER) printf(" DSP_CAP_TRIGGER");
307 if (cap & DSP_CAP_MMAP) printf(" DSP_CAP_MMAP");
308 if (cap & DSP_CAP_MULTI) printf(" DSP_CAP_MULTI");
309 if (cap & DSP_CAP_BIND) printf(" DSP_CAP_BIND");
310 printf("\n");
311 printf("Output block size = %d\n", fOutputBufferSize);
312 }
313
314
315 if (getRWMode() & kRead) {
316 assert( ioctl(fInputDevice, SNDCTL_DSP_GETISPACE, &info) != -1);
317 printf("input space info: fragments=%d, fragstotal=%d, fragsize=%d, bytes=%d\n", info.fragments, info.fragstotal,
318 info.fragsize, info.bytes);
319
320
321 assert( ioctl(fInputDevice,SNDCTL_DSP_GETCAPS, &cap) != -1);
322 printf("Input capabilities - %d channels : ", fNumOfInputChannels);
323 if (cap & DSP_CAP_DUPLEX) printf(" DSP_CAP_DUPLEX");
324 if (cap & DSP_CAP_REALTIME) printf(" DSP_CAP_REALTIME");
325 if (cap & DSP_CAP_DUPLEX) printf(" DSP_CAP_DUPLEX");
326 if (cap & DSP_CAP_BATCH) printf(" DSP_CAP_BATCH");
327 if (cap & DSP_CAP_COPROC) printf(" DSP_CAP_COPROC");
328 if (cap & DSP_CAP_TRIGGER) printf(" DSP_CAP_TRIGGER");
329 if (cap & DSP_CAP_MMAP) printf(" DSP_CAP_MMAP");
330 if (cap & DSP_CAP_MULTI) printf(" DSP_CAP_MULTI");
331 if (cap & DSP_CAP_BIND) printf(" DSP_CAP_BIND");
332 printf("\n");
333 printf("Input block size = %d\n", fInputBufferSize);
334 }
335 }
336
337
338 //----------------------------------------------------------------
339 // read() : read
340 //----------------------------------------------------------------
341
342 bool read(int frames, float* channel[])
343 {
344 int bytes = frames * 2 * fNumOfInputChannels; assert(bytes <= fInputBufferSize);
345 int count = ::read(fInputDevice, fInputBuffer, bytes);
346 assert (bytes == count);
347
348 for (int s = 0; s < frames; s++) {
349 for (int c = 0; c < fNumOfInputChannels; c++) {
350 channel[c][s] = float(fInputBuffer[c + s*fNumOfInputChannels])*(1.0/float(SHRT_MAX));
351 }
352 }
353 return bytes == count;
354 }
355
356
357 bool write(int frames, float* channel[])
358 {
359 int bytes = frames * 2 * fNumOfOutputChannels; assert(bytes <= fOutputBufferSize);
360
361 for (int f = 0; f < frames; f++) {
362 for (int c = 0; c < fNumOfOutputChannels; c++) {
363 float x = channel[c][f];
364 fOutputBuffer[c + f*fNumOfOutputChannels] = short( max(min(x,1.0),-1.0) * float(SHRT_MAX) ) ;
365 }
366 }
367
368 int count = ::write(fOutputDevice, fOutputBuffer, bytes);
369 assert (bytes == count);
370
371 return bytes == count;
372 }
373
374
375
376 };
377
378
379
380
381
382
383 /******************************************************************************
384 *******************************************************************************
385
386 USER INTERFACE
387
388 *******************************************************************************
389 *******************************************************************************/
390
391 class UI
392 {
393 bool fStopped;
394 public:
395
396 UI() : fStopped(false) {}
397 virtual ~UI() {}
398
399 virtual void addButton(char* label, float* zone) = 0;
400 virtual void addToggleButton(char* label, float* zone) = 0;
401 virtual void addCheckButton(char* label, float* zone) = 0;
402 virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
403 virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step) = 0;
404 virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step) = 0;
405
406 virtual void openFrameBox(char* label) = 0;
407 virtual void openTabBox(char* label) = 0;
408 virtual void openHorizontalBox(char* label) = 0;
409 virtual void openVerticalBox(char* label) = 0;
410 virtual void closeBox() = 0;
411
412 virtual void run() {};
413
414 void stop() { fStopped = true; }
415 bool stopped() { return fStopped; }
416 };
417
418
419
420 /******************************************************************************
421 *******************************************************************************
422
423 DSP
424
425 *******************************************************************************
426 *******************************************************************************/
427
428
429 //---------------------------------------------------
430 // tableaux de buffers initialis�s par allocChannels
431 //---------------------------------------------------
432
433 float* gInChannel[256];
434 float* gOutChannel[256];
435
436 void allocChannels (int size, int numInChan, int numOutChan)
437 {
438
439 assert (numInChan < 256);
440 assert (numOutChan < 256);
441
442
443 for (int i = 0; i < numInChan; i++) {
444 gInChannel[i] = (float*) calloc (size, sizeof(float));
445 for (int j = 0; j < size; j++) {
446 gInChannel[i][j] = 0.0;
447 }
448 }
449
450 for (int i = 0; i < numOutChan; i++) {
451 gOutChannel[i] = (float*) calloc (size, sizeof(float));
452 for (int j = 0; j < size; j++) {
453 gOutChannel[i][j] = 0.0;
454 }
455 }
456 }
457
458
459
460 //----------------------------------------------------------------
461 // d�finition du processeur de signal
462 //----------------------------------------------------------------
463
464 class dsp {
465 protected:
466 int fSamplingFreq;
467 public:
468 dsp() {}
469 virtual int getNumInputs() = 0;
470 virtual int getNumOutputs() = 0;
471 virtual void buildUserInterface(UI* interface) = 0;
472 virtual void init(int samplingRate) = 0;
473 virtual void compute(int len, float** inputs, float** outputs) = 0;
474 };
475
476
477 <<includeclass>>
478
479
480 mydsp DSP;
481
482
483 /******************************************************************************
484 *******************************************************************************
485
486 WXWINDOWS USER INTERFACE
487
488 *******************************************************************************
489 *******************************************************************************/
490
491
492 // les modes d'insertion
493
494 #define kNormalState 0
495 #define kNotebookState 1
496 #define kAutoPageState 2
497
498 #define kProp 0
499 #define kBorder 5
500 #define kFlag wxALL|wxGROW
501
502
503 // faustButton : a wxButton for FAUST.
504 class faustButton : public wxButton
505 {
506 float* fZone;
507 public :
508 faustButton(wxWindow* parent, const wxString& label, float* zone)
509 : wxButton(parent, -1, label, wxPoint(-1, -1)), fZone(zone)
510 {
511 *fZone = 0.0;
512 }
513
514 void clickdown (wxCommandEvent& ev) { *fZone = 1.0; /*printf("click down : zone (at %p) = %f\n", fZone, *fZone);*/ ev.Skip();}
515 void clickup (wxCommandEvent& ev) { *fZone = 0.0; /*printf("click up : zone (at %p) = %f\n", fZone, *fZone);*/ ev.Skip(); }
516
517 private:
518 DECLARE_EVENT_TABLE()
519 };
520
521 BEGIN_EVENT_TABLE(faustButton, wxButton)
522 EVT_LEFT_DOWN(faustButton::clickdown)
523 EVT_LEFT_UP(faustButton::clickup)
524 END_EVENT_TABLE()
525
526
527 class faustCheckBox : public wxCheckBox
528 {
529 float* fZone;
530 public :
531 faustCheckBox(wxWindow* parent, const wxString& label, float* zone)
532 : wxCheckBox(parent, -1, label, wxPoint(-1, -1)), fZone(zone)
533 {
534 *fZone = 0.0;
535 }
536
537 void toggle (wxCommandEvent& ev) {
538 *fZone = (ev.IsChecked()) ? 1.0 : 0.0;
539 //printf("toogle : zone (at %p) = %f\n", fZone, *fZone);
540 }
541
542 private:
543 DECLARE_EVENT_TABLE()
544 };
545
546 BEGIN_EVENT_TABLE(faustCheckBox, wxCheckBox)
547 EVT_CHECKBOX(-1, faustCheckBox::toggle)
548 END_EVENT_TABLE()
549
550
551 class faustHorizontalSlider : public wxSlider
552 {
553 float fStep;
554 float* fZone;
555 public :
556 faustHorizontalSlider(wxWindow* parent, float* zone, float init , float min, float max, float step)
557 : wxSlider(parent, -1, int(init/step), int(min/step), int(max/step), wxDefaultPosition, wxSize(120,30), wxSL_HORIZONTAL), fStep(step), fZone(zone)
558 {
559 *fZone = init;
560 }
561
562 void update (wxCommandEvent& ev) {
563 *fZone = GetValue()*fStep;
564 //printf("horizontal slider update : zone (at %p) = %f\n", fZone, *fZone);
565 }
566
567 private:
568 DECLARE_EVENT_TABLE()
569 };
570
571 BEGIN_EVENT_TABLE(faustHorizontalSlider, wxSlider)
572 EVT_SLIDER (-1, faustHorizontalSlider::update)
573 END_EVENT_TABLE()
574
575
576 class faustVerticalSlider : public wxSlider
577 {
578 float fStep;
579 float* fZone;
580 public :
581 faustVerticalSlider(wxWindow* parent, float* zone, float init , float min, float max, float step)
582 : wxSlider(parent, -1, int((max+min-init)/step), int(min/step), int(max/step), wxDefaultPosition, wxSize(30,120), wxSL_VERTICAL), fStep(step), fZone(zone)
583 {
584 *fZone = init;
585 }
586
587 void update (wxCommandEvent& ev) {
588 *fZone = (GetMin()+GetMax()-GetValue())*fStep;
589 //printf("vertical slider update : zone (at %p) = %f\n", fZone, *fZone);
590 }
591
592 private:
593 DECLARE_EVENT_TABLE()
594 };
595
596 BEGIN_EVENT_TABLE(faustVerticalSlider, wxSlider)
597 EVT_SLIDER (-1, faustVerticalSlider::update)
598 END_EVENT_TABLE()
599
600
601 //--------------------------------
602 // faustSpinCtrl* b = new faustSpinCtrl(topPanel(), zone, init, min, max, step);
603 // wxSpinCtrl* b = new wxSpinCtrl( topPanel(), -1, "", wxPoint(200, 160), wxSize(80, -1) );
604 // b->SetRange(int(min),int(max));
605 // b->SetValue(int(init));
606
607
608 class faustSpinCtrl : public wxSpinCtrl
609 {
610 float fStep;
611 float* fZone;
612 public :
613 faustSpinCtrl(wxWindow* parent, float* zone, float init , float min, float max, float step)
614 : wxSpinCtrl(parent), fStep(step), fZone(zone)
615 {
616 SetRange(int(min),int(max));
617 SetValue(int(init));
618 *fZone = init;
619 }
620
621 void update (wxCommandEvent& ev) { *fZone = GetValue(); printf("spin ctrl update : zone (at %p) = %f\n", fZone, *fZone); }
622
623 private:
624 DECLARE_EVENT_TABLE()
625 };
626
627 BEGIN_EVENT_TABLE(faustSpinCtrl, wxSlider)
628 EVT_SPINCTRL (-1, faustSpinCtrl::update)
629 END_EVENT_TABLE()
630
631
632
633 class WXUI : public UI // user interface
634 {
635
636 class State
637 {
638 int const fType;
639 wxWindow* const fPanel;
640 wxSizer* const fSizer;
641
642 public:
643 State (int t, wxWindow* p, wxSizer* z) : fType(t), fPanel(p), fSizer(z) {}
644 int type() const { return fType; }
645 wxWindow* panel() const { return fPanel; }
646 wxSizer* sizer() const { return fSizer; }
647 };
648
649 stack<State> lState;
650 wxFrame* frame;
651 wxSizer* fSizer;
652
653 // gestion de l'etat courant du constructeur
654
655 void push (int t, wxWindow* p, wxSizer* z)
656 {
657 printf("push %d of %d, %p, %p\n", lState.size(), t, p, z);
658 lState.push(State(t,p,z));
659 }
660
661 int topType() { return lState.top().type(); }
662 wxWindow* topPanel() { return lState.top().panel(); }
663 wxSizer* topSizer() { return lState.top().sizer(); }
664
665 void pop ()
666 {
667 printf("pop %d", lState.size()-1);
668 lState.pop();
669 printf(" ok\n");
670 }
671
672 void openAutoPage(char* label)
673 {
674 if (topType() == kNotebookState) {
675
676 if (!label) label = "";
677
678 wxNotebook* nb = (wxNotebook*) topPanel();
679 wxPanel* p = new wxPanel( nb, -1 );
680 wxBoxSizer* z = new wxBoxSizer( wxVERTICAL );
681
682 nb->AddPage(p, label);
683 p->SetAutoLayout(TRUE);
684 p->SetSizer(z);
685
686 push(kAutoPageState, p, z);
687 }
688 }
689
690 void closeAutoPage()
691 {
692 if (topType() == kAutoPageState) pop();
693 }
694
695 void openOrientedBox(char* label, int orientation)
696 {
697 openAutoPage(label);
698
699 wxSizer* z = (label == 0) ? new wxBoxSizer(orientation)
700 : new wxStaticBoxSizer(new wxStaticBox(topPanel(), -1, label), orientation);
701
702 topSizer()->Add(z, 1, kFlag, kBorder);
703 push(kNormalState, topPanel(), z);
704 }
705
706 public:
707
708
709 WXUI(){}
710
711 virtual ~WXUI() {}
712
713 void openFrame(wxFrame* f)
714 {
715 frame = f;
716 fSizer = new wxBoxSizer(wxVERTICAL);
717 frame->SetSizer(fSizer);
718 push(kNormalState, frame, fSizer);
719 }
720
721 wxFrame* closeFrame()
722 {
723 fSizer->Fit(frame);
724 fSizer->SetSizeHints(frame);
725 return frame;
726 }
727
728 virtual void openHorizontalBox(char* label) { openOrientedBox(label, wxHORIZONTAL); }
729 virtual void openVerticalBox(char* label) { openOrientedBox(label, wxVERTICAL); }
730
731 virtual void openTabBox(char* label)
732 {
733 openAutoPage(label);
734
735 wxNotebook* nb = new wxNotebook( topPanel(), -1 );
736 wxNotebookSizer* z = new wxNotebookSizer( nb );
737
738 topSizer()->Add(z, 1, kFlag, kBorder);
739 push(kNotebookState, nb, z);
740 }
741
742 virtual void closeBox()
743 {
744 pop();
745 closeAutoPage();
746 }
747
748 //--------------------------------- les elements ------------------------------------------
749
750 virtual void addButton(char* label, float* zone)
751 {
752 openAutoPage(label);
753 faustButton* b = new faustButton(topPanel(), label, zone);
754 topSizer()->Add(b, kProp, kFlag, kBorder);
755 closeAutoPage();
756 }
757
758 virtual void addCheckButton(char* label, float* zone)
759 {
760 openAutoPage(label);
761 faustCheckBox* b = new faustCheckBox(topPanel(), label, zone);
762 topSizer()->Add(b, kProp, kFlag, kBorder);
763 closeAutoPage();
764 }
765
766 virtual void addVerticalSlider(char* label, float* zone, float init, float min, float max, float step)
767 {
768 openAutoPage(label);
769 if (label) {
770 wxSizer* z = new wxStaticBoxSizer(new wxStaticBox(topPanel(), -1, label), wxHORIZONTAL);
771 topSizer()->Add(z, 1, kFlag, kBorder);
772 faustVerticalSlider* b = new faustVerticalSlider(topPanel(), zone, init, min, max, step);
773 b->SetToolTip(label);
774 z->Add(b, 1, kFlag|wxALIGN_CENTER_VERTICAL, kBorder);
775 } else {
776 faustVerticalSlider* b = new faustVerticalSlider(topPanel(), zone, init, min, max, step);
777 topSizer()->Add(b, kProp, kFlag, kBorder);
778 }
779 closeAutoPage();
780 }
781
782 virtual void addHorizontalSlider(char* label, float* zone, float init, float min, float max, float step)
783 {
784 openAutoPage(label);
785 if (label) {
786 wxSizer* z = new wxStaticBoxSizer(new wxStaticBox(topPanel(), -1, label), wxVERTICAL);
787 topSizer()->Add(z, 1, kFlag, kBorder);
788 faustHorizontalSlider* b = new faustHorizontalSlider(topPanel(), zone, init, min, max, step);
789 b->SetToolTip(label);
790 z->Add(b, 1, kFlag|wxALIGN_CENTER_HORIZONTAL, kBorder);
791 } else {
792 faustHorizontalSlider* b = new faustHorizontalSlider(topPanel(), zone, init, min, max, step);
793 topSizer()->Add(b, kProp, kFlag, kBorder);
794 }
795 closeAutoPage();
796 }
797
798 virtual void addToggleButton(char* label, float* zone) {}
799 virtual void addNumEntry(char* label, float* zone, float init, float min, float max, float step)
800 {
801 openAutoPage(label);
802 if (label) {
803 wxSizer* z = new wxStaticBoxSizer(new wxStaticBox(topPanel(), -1, label), wxVERTICAL);
804 topSizer()->Add(z, 0, kFlag, kBorder);
805 faustSpinCtrl* b = new faustSpinCtrl(topPanel(), zone, init, min, max, step);
806 // wxSpinCtrl* b = new wxSpinCtrl( topPanel(), -1, "", wxPoint(200, 160), wxSize(80, -1) );
807 // b->SetRange(int(min),int(max));
808 // b->SetValue(int(init));
809 b->SetToolTip(label);
810 z->Add(b, 0, kFlag, kBorder);
811 } else {
812 faustSpinCtrl* b = new faustSpinCtrl(topPanel(), zone, init, min, max, step);
813 // wxSpinCtrl* b = new wxSpinCtrl( topPanel(), -1, "", wxPoint(200, 160), wxSize(80, -1) );
814 // b->SetRange(int(min),int(max));
815 // b->SetValue(int(init));
816 topSizer()->Add(b, kProp, kFlag, kBorder);
817 }
818 closeAutoPage();
819 }
820 virtual void openFrameBox(char* label) {}
821 };
822
823
824
825 /******************************************************************************
826 *******************************************************************************
827
828 WXWINDOWS APPLICATION
829
830 *******************************************************************************
831 *******************************************************************************/
832
833
834 enum { ID_QUIT=1, ID_ABOUT };
835
836
837 class MyApp : public wxApp
838 {
839 virtual bool OnInit();
840 };
841
842
843 class MyFrame : public wxFrame
844 {
845 public:
846 MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
847 : wxFrame(0, -1, title, pos, size)
848 {
849 wxMenu* m = new wxMenu;
850 m->Append(ID_ABOUT, "&About...");
851 m->AppendSeparator();
852 m->Append(ID_QUIT, "E&xit");
853
854 wxMenuBar* b = new wxMenuBar;
855 b->Append(m, "&File");
856 SetMenuBar(b);
857 CreateStatusBar();
858 SetStatusText("hello...");
859 }
860
861 void OnQuit(wxCommandEvent& event)
862 {
863 Close(TRUE);
864 }
865
866 void OnAbout(wxCommandEvent& event)
867 {
868 wxMessageBox("message 1", "message 2", wxOK|wxICON_INFORMATION);
869 }
870
871 private:
872 DECLARE_EVENT_TABLE()
873 };
874
875
876 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
877 EVT_MENU(ID_QUIT, MyFrame::OnQuit)
878 EVT_MENU(ID_ABOUT, MyFrame::OnAbout)
879 END_EVENT_TABLE()
880
881
882
883 IMPLEMENT_APP(MyApp)
884
885
886 /******************************************************************************
887 *******************************************************************************
888
889 MAIN PLAY THREAD
890
891 *******************************************************************************
892 *******************************************************************************/
893
894 // Scan Command Line Arguments
895
896 long lopt (char *argv[], char *name, long def)
897 {
898 int i;
899 for (i=0; argv[i]; i++) if (!strcmp(argv[i], name)) return atoi(argv[i+1]);
900 return def;
901 }
902
903
904 //-------------------------------------------------------------------------
905 // MAIN
906 //-------------------------------------------------------------------------
907 float* inChannel[256];
908 float* outChannel[256];
909 int fpb;
910
911 pthread_t soundthread;
912
913 void* run_sound(void* ptr)
914 {
915 AudioInterface* audio = (AudioInterface*)ptr;
916
917 setRealtimePriority();
918 // Sound processing loop
919 audio->write(fpb, outChannel);
920 audio->write(fpb, outChannel);
921 while (1) {
922 if ( !audio->write(fpb, outChannel)) printf("w");
923 if ( !audio->read (fpb, inChannel)) printf("r");;
924 DSP.compute(fpb, inChannel, outChannel);
925 }
926
927 audio->close();
928 return 0;
929 }
930
931 bool MyApp::OnInit()
932 {
933 // create and init the audio interface card
934 AudioInterface* audio = new AudioInterface(
935 AudioParam().frequency(lopt(argv, "--frequency", 44100))
936 .buffering(lopt(argv, "--buffer", 128))
937 //.mode( ((DSP.getNumInputs()>0)?kRead:0) | ((DSP.getNumOutputs()>0)?kWrite:0) )
938 );
939 audio->open();
940 audio->info();
941
942
943
944 MyFrame* frame = new MyFrame(argv[0], wxPoint(50,50), wxSize(-1, -1));
945
946 wxMenu* m = new wxMenu;
947 m->Append(ID_ABOUT, "&About...");
948 m->AppendSeparator();
949 m->Append(ID_QUIT, "E&xit");
950
951 wxMenuBar* b = new wxMenuBar;
952 b->Append(m, "&File");
953
954 frame->SetMenuBar(b);
955 frame->CreateStatusBar();
956 frame->SetStatusText("hello...");
957
958 WXUI* ui = new WXUI();
959 ui->openFrame(frame);
960 DSP.buildUserInterface((UI*)ui);
961 ui->closeFrame();
962
963 DSP.init(audio->getSamplingFrequency());
964 fpb = audio->getFramesPerBuffer();
965 audio->allocChanGroup(inChannel, max(audio->getNumInputs(), DSP.getNumInputs()), fpb);
966 audio->allocChanGroup(outChannel, max(audio->getNumOutputs(), DSP.getNumOutputs()), fpb);
967
968 frame->Show(TRUE);
969 SetTopWindow(frame);
970
971 pthread_create(&soundthread, NULL, run_sound, audio);
972
973 return TRUE;
974 }