-/* link with : "" */
-#include <stdlib.h>
-#include <libgen.h>
-#include <stdio.h>
-#include <string.h>
-#include <limits.h>
-#include <math.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <pwd.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <assert.h>
-#include <gtk/gtk.h>
-#include <pthread.h>
-#include <sys/wait.h>
-#include <list>
-
-#include <iostream>
-#include <fstream>
-#include <vector>
-#include <algorithm>
-
-#include <AudioToolbox/AudioConverter.h>
-#include <CoreAudio/CoreAudio.h>
-#include <AudioUnit/AudioUnit.h>
-#include <CoreServices/CoreServices.h>
-
-
-using namespace std;
-
-// handle 32/64 bits int size issues
-
-#ifdef __x86_64__
-
-#define uint32 unsigned int
-#define uint64 unsigned long int
-
-#define int32 int
-#define int64 long int
-
-#else
-
-#define uint32 unsigned int
-#define uint64 unsigned long long int
-
-#define int32 int
-#define int64 long long int
-#endif
-
-// check 32/64 bits issues are correctly handled
-
-#define CHECKINTSIZE \
- assert(sizeof(int32)==4);\
- assert(sizeof(int64)==8);
-
-
-
-
-// On Intel set FZ (Flush to Zero) and DAZ (Denormals Are Zero)
-// flags to avoid costly denormals
-#ifdef __SSE__
- #include <xmmintrin.h>
- #ifdef __SSE2__
- #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8040)
- #else
- #define AVOIDDENORMALS _mm_setcsr(_mm_getcsr() | 0x8000)
- #endif
-#else
- #define AVOIDDENORMALS
-#endif
-
-//#define BENCHMARKMODE
-
-// g++ -Wall -O3 -lm -lpthread -lasound `gtk-config --cflags --libs` test.cpp -o test
-
-#define check_error(err) if (err) { printf("%s:%d, alsa error %d : %s\n", __FILE__, __LINE__, err, snd_strerror(err)); exit(1); }
-#define check_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); exit(1); }
-#define display_error_msg(err,msg) if (err) { fprintf(stderr, "%s:%d, %s : %s(%d)\n", __FILE__, __LINE__, msg, snd_strerror(err), err); }
-
-#define max(x,y) (((x)>(y)) ? (x) : (y))
-#define min(x,y) (((x)<(y)) ? (x) : (y))
-
-// abs is now predefined
-//template<typename T> T abs (T a) { return (a<T(0)) ? -a : a; }
-
-
-inline int lsr (int x, int n) { return int(((unsigned int)x) >> n); }
-
-
-inline int int2pow2 (int x) { int r=0; while ((1<<r)<x) r++; return r; }
-
-
-/******************************************************************************
-*******************************************************************************
-
- VECTOR INTRINSICS
-
-*******************************************************************************
-*******************************************************************************/
-
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((unsigned)(calloc((nmemb*size)+15,sizeof(char)))+15 & 0xfffffff0); }
-//inline void *aligned_calloc(size_t nmemb, size_t size) { return (void*)((size_t)(calloc((nmemb*size)+15,sizeof(char)))+15 & ~15); }
-
-
-<<includeIntrinsic>>
-
-#define BENCHMARKMODE
-
-#ifdef BENCHMARKMODE
-
-/**
- * Returns the number of clock cycles elapsed since the last reset
- * of the processor
- */
-static __inline__ uint64 rdtsc(void)
-{
- union {
- uint32 i32[2];
- uint64 i64;
- } count;
-
- __asm__ __volatile__("rdtsc" : "=a" (count.i32[0]), "=d" (count.i32[1]));
-
- return count.i64;
-}
-
-#define KSKIP 20
-#define KMESURE 600
-
-int mesure = 0;
-
-// these values are used to determine the number of clocks in a second
-uint64 firstRDTSC;
-uint64 lastRDTSC;
-
-// these tables contains the last KMESURE in clocks
-uint64 starts[KMESURE];
-uint64 stops [KMESURE];
-
-#define STARTMESURE starts[mesure%KMESURE] = rdtsc();
-#define STOPMESURE stops[mesure%KMESURE] = rdtsc(); mesure = mesure+1;
-
-struct timeval tv1;
-struct timeval tv2;
-
-void openMesure()
-{
- struct timezone tz;
- gettimeofday(&tv1, &tz);
- firstRDTSC = rdtsc();
-}
-
-void closeMesure()
-{
- struct timezone tz;
- gettimeofday(&tv2, &tz);
- lastRDTSC = rdtsc();
-}
-
-/**
- * return the number of RDTSC clocks per seconds
- */
-int64 rdtscpersec()
-{
- // If the environment variable CLOCKSPERSEC is defined
- // we use it instead of our own measurement
- char* str = getenv("CLOCKSPERSEC");
- if (str) {
- int64 cps = (int64) atoll(str);
- if (cps > 1000000000) {
- return cps;
- } else {
- return (lastRDTSC-firstRDTSC) / (tv2.tv_sec - tv1.tv_sec) ;
- }
- } else {
- return (lastRDTSC-firstRDTSC) / (tv2.tv_sec - tv1.tv_sec) ;
- }
-}
-
-
-/**
- * Converts a duration, expressed in RDTSC clocks, into seconds
- */
-double rdtsc2sec( uint64 clk)
-{
- return double(clk) / double(rdtscpersec());
-}
-
-double rdtsc2sec( double clk)
-{
- return clk / double(rdtscpersec());
-}
-
-
-/**
- * Converts RDTSC clocks into Megabytes/seconds according to the
- * number of frames processed during the period, the number of channels
- * and 4 bytes samples.
- */
-double megapersec(int frames, int chans, uint64 clk)
-{
- return double(frames*chans*4)/double(1024*1024*rdtsc2sec(clk));
-}
-
-
-/**
- * Compute the mean value of a vector of measures
- */
-static uint64 meanValue( vector<uint64>::const_iterator a, vector<uint64>::const_iterator b)
-{
- uint64 r = 0;
- unsigned int n = 0;
- while (a!=b) { r += *a++; n++; }
- return (n>0) ? r/n : 0;
-}
-
-/**
- * Print the median value (in Megabytes/second) of KMESURE
- * throughputs measurements
- */
-void printstats(const char* applname, int bsize, int ichans, int ochans)
-{
- assert(mesure > KMESURE);
- vector<uint64> V(KMESURE);
-
- for (int i = 0; i<KMESURE; i++) {
- V[i] = stops[i] - starts[i];
- }
-
- sort(V.begin(), V.end());
-
- // Mean of 10 best values (gives relatively stable results)
- uint64 meavalx = meanValue(V.begin(), V.begin() + 10);
-
- //printing
- cout << megapersec(bsize, ichans+ochans, meavalx) << "\tMB/s"
- << '\t' << applname
- << '\t' << "(clocks/sec : " << rdtscpersec() << ")"
- << endl;
-
-}
-
-#else
-
-#define STARTMESURE
-#define STOPMESURE
-
-#endif
-
-
-
-/******************************************************************************
-*******************************************************************************
-
- GRAPHIC USER INTERFACE (v2)
- abstract interfaces
-
-*******************************************************************************
-*******************************************************************************/
-
-#include <map>
-#include <list>
-
-using namespace std;
-
-struct Meta : map<const char*, const char*>
-{
- void declare (const char* key, const char* value) { (*this)[key]=value; }
-};
-
-
-struct uiItem;
-typedef void (*uiCallback)(float val, void* data);
-
-/**
- * Graphic User Interface : abstract definition
- */
-
-class UI
-{
- typedef list<uiItem*> clist;
- typedef map<float*, clist*> zmap;
-
- private:
- static list<UI*> fGuiList;
- zmap fZoneMap;
- bool fStopped;
-
- public:
-
- UI() : fStopped(false) {
- fGuiList.push_back(this);
- }
-
- virtual ~UI() {
- // suppression de this dans fGuiList
- }
-
- // -- zone management
-
- void registerZone(float* z, uiItem* c)
- {
- if (fZoneMap.find(z) == fZoneMap.end()) fZoneMap[z] = new clist();
- fZoneMap[z]->push_back(c);
- }
-
- // -- saveState(filename) : save the value of every zone to a file
-
- void saveState(const char* filename)
- {
- ofstream f(filename);
-
- for (zmap::iterator i=fZoneMap.begin(); i!=fZoneMap.end(); i++) {
- f << *(i->first) << ' ';
- }
-
- f << endl;
- f.close();
- }
-
- // -- recallState(filename) : load the value of every zone from a file
-
- void recallState(const char* filename)
- {
- ifstream f(filename);
- if (f.good()) {
- for (zmap::iterator i=fZoneMap.begin(); i!=fZoneMap.end(); i++) {
- f >> *(i->first);
- }
- }
- f.close();
- }
-
- void updateAllZones();
-
- void updateZone(float* z);
-
- static void updateAllGuis()
- {
- list<UI*>::iterator g;
- for (g = fGuiList.begin(); g != fGuiList.end(); g++) {
- (*g)->updateAllZones();
- }
- }
-
- // -- active widgets
-
- virtual void addButton(const char* label, float* zone) = 0;
- virtual void addToggleButton(const char* label, float* zone) = 0;
- virtual void addCheckButton(const char* label, float* zone) = 0;
- virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
- virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) = 0;
- virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) = 0;
-
- // -- passive widgets
-
- virtual void addNumDisplay(const char* label, float* zone, int precision) = 0;
- virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max) = 0;
- virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max) = 0;
- virtual void addVerticalBargraph(const char* label, float* zone, float min, float max) = 0;
-
- void addCallback(float* zone, uiCallback foo, void* data);
-
- // -- widget's layouts
-
- virtual void openFrameBox(const char* label) = 0;
- virtual void openTabBox(const char* label) = 0;
- virtual void openHorizontalBox(const char* label) = 0;
- virtual void openVerticalBox(const char* label) = 0;
- virtual void closeBox() = 0;
-
- virtual void show() = 0;
- virtual void run() = 0;
-
- void stop() { fStopped = true; }
- bool stopped() { return fStopped; }
-
- virtual void declare(float* zone, const char* key, const char* value) {}
-};
-
-
-/**
- * User Interface Item: abstract definition
- */
-
-class uiItem
-{
- protected :
-
- UI* fGUI;
- float* fZone;
- float fCache;
-
- uiItem (UI* ui, float* zone) : fGUI(ui), fZone(zone), fCache(-123456.654321)
- {
- ui->registerZone(zone, this);
- }
-
-
- public :
-
- virtual ~uiItem() {}
-
- void modifyZone(float v)
- {
- fCache = v;
- if (*fZone != v) {
- *fZone = v;
- fGUI->updateZone(fZone);
- }
- }
-
- float cache() { return fCache; }
- virtual void reflectZone() = 0;
-};
-
-
-/**
- * Callback Item
- */
-
-struct uiCallbackItem : public uiItem
-{
- uiCallback fCallback;
- void* fData;
-
- uiCallbackItem(UI* ui, float* zone, uiCallback foo, void* data)
- : uiItem(ui, zone), fCallback(foo), fData(data) {}
-
- virtual void reflectZone() {
- float v = *fZone;
- fCache = v;
- fCallback(v, fData);
- }
-};
-
-/**
- * Update all user items reflecting zone z
- */
-
-inline void UI::updateZone(float* z)
-{
- float v = *z;
- clist* l = fZoneMap[z];
- for (clist::iterator c = l->begin(); c != l->end(); c++) {
- if ((*c)->cache() != v) (*c)->reflectZone();
- }
-}
-
-
-/**
- * Update all user items not up to date
- */
-
-inline void UI::updateAllZones()
-{
- for (zmap::iterator m = fZoneMap.begin(); m != fZoneMap.end(); m++) {
- float* z = m->first;
- clist* l = m->second;
- float v = *z;
- for (clist::iterator c = l->begin(); c != l->end(); c++) {
- if ((*c)->cache() != v) (*c)->reflectZone();
- }
- }
-}
-
-inline void UI::addCallback(float* zone, uiCallback foo, void* data)
-{
- new uiCallbackItem(this, zone, foo, data);
-};
-
-
-/******************************************************************************
-*******************************************************************************
-
- GRAPHIC USER INTERFACE
- gtk interface
-
-*******************************************************************************
-*******************************************************************************/
-
-#include <gtk/gtk.h>
-
-#define stackSize 256
-
-// Insertion modes
-
-#define kSingleMode 0
-#define kBoxMode 1
-#define kTabMode 2
-
-
-class GTKUI : public UI
-{
- private :
- static bool fInitialized;
- static list<UI*> fGuiList;
-
- protected :
- GtkWidget* fWindow;
- int fTop;
- GtkWidget* fBox[stackSize];
- int fMode[stackSize];
- bool fStopped;
-
- GtkWidget* addWidget(const char* label, GtkWidget* w);
- virtual void pushBox(int mode, GtkWidget* w);
-
-
- public :
-
- static const gboolean expand = TRUE;
- static const gboolean fill = TRUE;
- static const gboolean homogene = FALSE;
-
- GTKUI(char * name, int* pargc, char*** pargv);
-
- // -- layout groups
-
- virtual void openFrameBox(const char* label);
- virtual void openTabBox(const char* label = "");
- virtual void openHorizontalBox(const char* label = "");
- virtual void openVerticalBox(const char* label = "");
-
- virtual void closeBox();
-
- // -- active widgets
-
- virtual void addButton(const char* label, float* zone);
- virtual void addToggleButton(const char* label, float* zone);
- virtual void addCheckButton(const char* label, float* zone);
- virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step);
- virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step);
- virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step);
-
- // -- passive display widgets
-
- virtual void addNumDisplay(const char* label, float* zone, int precision);
- virtual void addTextDisplay(const char* label, float* zone, char* names[], float min, float max);
- virtual void addHorizontalBargraph(const char* label, float* zone, float min, float max);
- virtual void addVerticalBargraph(const char* label, float* zone, float min, float max);
-
- virtual void show();
- virtual void run();
-
-};
-
-
-
-/******************************************************************************
-*******************************************************************************
-
- GRAPHIC USER INTERFACE (v2)
- gtk implementation
-
-*******************************************************************************
-*******************************************************************************/
-
-// global static fields
-
-bool GTKUI::fInitialized = false;
-list<UI*> UI::fGuiList;
-
-
-
-static gint delete_event( GtkWidget *widget, GdkEvent *event, gpointer data )
-{
- return FALSE;
-}
-
-static void destroy_event( GtkWidget *widget, gpointer data )
-{
- gtk_main_quit ();
-}
-
-
-GTKUI::GTKUI(char * name, int* pargc, char*** pargv)
-{
- if (!fInitialized) {
- gtk_init(pargc, pargv);
- fInitialized = true;
- }
-
- fWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- //gtk_container_set_border_width (GTK_CONTAINER (fWindow), 10);
- gtk_window_set_title (GTK_WINDOW (fWindow), name);
- gtk_signal_connect (GTK_OBJECT (fWindow), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL);
- gtk_signal_connect (GTK_OBJECT (fWindow), "destroy", GTK_SIGNAL_FUNC (destroy_event), NULL);
-
- fTop = 0;
- fBox[fTop] = gtk_vbox_new (homogene, 4);
- fMode[fTop] = kBoxMode;
- gtk_container_add (GTK_CONTAINER (fWindow), fBox[fTop]);
- fStopped = false;
-}
-
-// empilement des boites
-
-void GTKUI::pushBox(int mode, GtkWidget* w)
-{
- assert(++fTop < stackSize);
- fMode[fTop] = mode;
- fBox[fTop] = w;
-}
-
-void GTKUI::closeBox()
-{
- assert(--fTop >= 0);
-}
-
-
-// les differentes boites
-
-void GTKUI::openFrameBox(const char* label)
-{
- GtkWidget * box = gtk_frame_new (label);
- //gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-
- pushBox(kSingleMode, addWidget(label, box));
-}
-
-void GTKUI::openTabBox(const char* label)
-{
- pushBox(kTabMode, addWidget(label, gtk_notebook_new ()));
-}
-
-void GTKUI::openHorizontalBox(const char* label)
-{
- GtkWidget * box = gtk_hbox_new (homogene, 4);
- gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-
- if (fMode[fTop] != kTabMode && label[0] != 0) {
- GtkWidget * frame = addWidget(label, gtk_frame_new (label));
- gtk_container_add (GTK_CONTAINER(frame), box);
- gtk_widget_show(box);
- pushBox(kBoxMode, box);
- } else {
- pushBox(kBoxMode, addWidget(label, box));
- }
-}
-
-void GTKUI::openVerticalBox(const char* label)
-{
- GtkWidget * box = gtk_vbox_new (homogene, 4);
- gtk_container_set_border_width (GTK_CONTAINER (box), 10);
-
- if (fMode[fTop] != kTabMode && label[0] != 0) {
- GtkWidget * frame = addWidget(label, gtk_frame_new (label));
- gtk_container_add (GTK_CONTAINER(frame), box);
- gtk_widget_show(box);
- pushBox(kBoxMode, box);
- } else {
- pushBox(kBoxMode, addWidget(label, box));
- }
-}
-
-GtkWidget* GTKUI::addWidget(const char* label, GtkWidget* w)
-{
- switch (fMode[fTop]) {
- case kSingleMode : gtk_container_add (GTK_CONTAINER(fBox[fTop]), w); break;
- case kBoxMode : gtk_box_pack_start (GTK_BOX(fBox[fTop]), w, expand, fill, 0); break;
- case kTabMode : gtk_notebook_append_page (GTK_NOTEBOOK(fBox[fTop]), w, gtk_label_new(label)); break;
- }
- gtk_widget_show (w);
- return w;
-}
-
-// --------------------------- Press button ---------------------------
-
-struct uiButton : public uiItem
-{
- GtkButton* fButton;
-
- uiButton (UI* ui, float* zone, GtkButton* b) : uiItem(ui, zone), fButton(b) {}
-
- static void pressed( GtkWidget *widget, gpointer data )
- {
- uiItem* c = (uiItem*) data;
- c->modifyZone(1.0);
- }
-
- static void released( GtkWidget *widget, gpointer data )
- {
- uiItem* c = (uiItem*) data;
- c->modifyZone(0.0);
- }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- if (v > 0.0) gtk_button_pressed(fButton); else gtk_button_released(fButton);
- }
-};
-
-void GTKUI::addButton(const char* label, float* zone)
-{
- *zone = 0.0;
- GtkWidget* button = gtk_button_new_with_label (label);
- addWidget(label, button);
-
- uiButton* c = new uiButton(this, zone, GTK_BUTTON(button));
-
- gtk_signal_connect (GTK_OBJECT (button), "pressed", GTK_SIGNAL_FUNC (uiButton::pressed), (gpointer) c);
- gtk_signal_connect (GTK_OBJECT (button), "released", GTK_SIGNAL_FUNC (uiButton::released), (gpointer) c);
-
-}
-
-// --------------------------- Toggle Buttons ---------------------------
-
-struct uiToggleButton : public uiItem
-{
- GtkToggleButton* fButton;
-
- uiToggleButton(UI* ui, float* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {}
-
- static void toggled (GtkWidget *widget, gpointer data)
- {
- float v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0;
- ((uiItem*)data)->modifyZone(v);
- }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- gtk_toggle_button_set_active(fButton, v > 0.0);
- }
-};
-
-void GTKUI::addToggleButton(const char* label, float* zone)
-{
- *zone = 0.0;
- GtkWidget* button = gtk_toggle_button_new_with_label (label);
- addWidget(label, button);
-
- uiToggleButton* c = new uiToggleButton(this, zone, GTK_TOGGLE_BUTTON(button));
- gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC (uiToggleButton::toggled), (gpointer) c);
-}
-
-
-// --------------------------- Check Button ---------------------------
-
-struct uiCheckButton : public uiItem
-{
- GtkToggleButton* fButton;
-
- uiCheckButton(UI* ui, float* zone, GtkToggleButton* b) : uiItem(ui, zone), fButton(b) {}
-
- static void toggled (GtkWidget *widget, gpointer data)
- {
- float v = (GTK_TOGGLE_BUTTON (widget)->active) ? 1.0 : 0.0;
- ((uiItem*)data)->modifyZone(v);
- }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- gtk_toggle_button_set_active(fButton, v > 0.0);
- }
-};
-
-void GTKUI::addCheckButton(const char* label, float* zone)
-{
- *zone = 0.0;
- GtkWidget* button = gtk_check_button_new_with_label (label);
- addWidget(label, button);
-
- uiCheckButton* c = new uiCheckButton(this, zone, GTK_TOGGLE_BUTTON(button));
- gtk_signal_connect (GTK_OBJECT (button), "toggled", GTK_SIGNAL_FUNC(uiCheckButton::toggled), (gpointer) c);
-}
-
-
-// --------------------------- Adjustmenty based widgets ---------------------------
-
-struct uiAdjustment : public uiItem
-{
- GtkAdjustment* fAdj;
-
- uiAdjustment(UI* ui, float* zone, GtkAdjustment* adj) : uiItem(ui, zone), fAdj(adj) {}
-
- static void changed (GtkWidget *widget, gpointer data)
- {
- float v = GTK_ADJUSTMENT (widget)->value;
- ((uiItem*)data)->modifyZone(v);
- }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- gtk_adjustment_set_value(fAdj, v);
- }
-};
-
-static int precision(double n)
-{
- if (n < 0.009999) return 3;
- else if (n < 0.099999) return 2;
- else if (n < 0.999999) return 1;
- else return 0;
-}
-
-// -------------------------- Vertical Slider -----------------------------------
-
-void GTKUI::addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step)
-{
- *zone = init;
- GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
-
- uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
- gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-
- GtkWidget* slider = gtk_vscale_new (GTK_ADJUSTMENT(adj));
- gtk_range_set_inverted (GTK_RANGE(slider), TRUE);
- gtk_scale_set_digits(GTK_SCALE(slider), precision(step));
- gtk_widget_set_usize(slider, -1, 160);
-
- openFrameBox(label);
- addWidget(label, slider);
- closeBox();
-}
-
-// -------------------------- Horizontal Slider -----------------------------------
-
-void GTKUI::addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step)
-{
- *zone = init;
- GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, 0);
-
- uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
- gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-
- GtkWidget* slider = gtk_hscale_new (GTK_ADJUSTMENT(adj));
- gtk_scale_set_digits(GTK_SCALE(slider), precision(step));
- gtk_widget_set_usize(slider, 160, -1);
-
- openFrameBox(label);
- addWidget(label, slider);
- closeBox();
-}
-
-
-// ------------------------------ Num Entry -----------------------------------
-
-void GTKUI::addNumEntry(const char* label, float* zone, float init, float min, float max, float step)
-{
- *zone = init;
- GtkObject* adj = gtk_adjustment_new(init, min, max, step, 10*step, step);
-
- uiAdjustment* c = new uiAdjustment(this, zone, GTK_ADJUSTMENT(adj));
-
- gtk_signal_connect (GTK_OBJECT (adj), "value-changed", GTK_SIGNAL_FUNC (uiAdjustment::changed), (gpointer) c);
-
- GtkWidget* spinner = gtk_spin_button_new (GTK_ADJUSTMENT(adj), 0.005, precision(step));
-
- //gtk_widget_set_usize(slider, 160, -1);
- openFrameBox(label);
- addWidget(label, spinner);
- closeBox();
-}
-
-
-// ========================== passive widgets ===============================
-
-
-// ------------------------------ Progress Bar -----------------------------------
-
-struct uiBargraph : public uiItem
-{
- GtkProgressBar* fProgressBar;
- float fMin;
- float fMax;
-
- uiBargraph(UI* ui, float* zone, GtkProgressBar* pbar, float lo, float hi)
- : uiItem(ui, zone), fProgressBar(pbar), fMin(lo), fMax(hi) {}
-
- float scale(float v) { return (v-fMin)/(fMax-fMin); }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- gtk_progress_bar_set_fraction(fProgressBar, scale(v));
- }
-};
-
-
-
-void GTKUI::addVerticalBargraph(const char* label, float* zone, float lo, float hi)
-{
- GtkWidget* pb = gtk_progress_bar_new();
- gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_BOTTOM_TO_TOP);
- gtk_widget_set_size_request(pb, 8, -1);
- new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi);
- openFrameBox(label);
- addWidget(label, pb);
- closeBox();
-}
-
-
-void GTKUI::addHorizontalBargraph(const char* label, float* zone, float lo, float hi)
-{
- GtkWidget* pb = gtk_progress_bar_new();
- gtk_progress_bar_set_orientation(GTK_PROGRESS_BAR(pb), GTK_PROGRESS_LEFT_TO_RIGHT);
- gtk_widget_set_size_request(pb, -1, 8);
- new uiBargraph(this, zone, GTK_PROGRESS_BAR(pb), lo, hi);
- openFrameBox(label);
- addWidget(label, pb);
- closeBox();
-}
-
-
-// ------------------------------ Num Display -----------------------------------
-
-struct uiNumDisplay : public uiItem
-{
- GtkLabel* fLabel;
- int fPrecision;
-
- uiNumDisplay(UI* ui, float* zone, GtkLabel* label, int precision)
- : uiItem(ui, zone), fLabel(label), fPrecision(precision) {}
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
- char s[64];
- if (fPrecision <= 0) {
- snprintf(s, 63, "%d", int(v));
- } else if (fPrecision>3) {
- snprintf(s, 63, "%f", v);
- } else {
- const char* format[] = {"%.1f", "%.2f", "%.3f"};
- snprintf(s, 63, format[fPrecision-1], v);
- }
- gtk_label_set_text(fLabel, s);
- }
-};
-
-
-void GTKUI::addNumDisplay(const char* label, float* zone, int precision )
-{
- GtkWidget* lw = gtk_label_new("");
- new uiNumDisplay(this, zone, GTK_LABEL(lw), precision);
- openFrameBox(label);
- addWidget(label, lw);
- closeBox();
-}
-
-
-// ------------------------------ Text Display -----------------------------------
-
-struct uiTextDisplay : public uiItem
-{
- GtkLabel* fLabel;
- char** fNames;
- float fMin;
- float fMax;
- int fNum;
-
-
- uiTextDisplay (UI* ui, float* zone, GtkLabel* label, char* names[], float lo, float hi)
- : uiItem(ui, zone), fLabel(label), fNames(names), fMin(lo), fMax(hi)
- {
- fNum = 0;
- while (fNames[fNum] != 0) fNum++;
- }
-
- virtual void reflectZone()
- {
- float v = *fZone;
- fCache = v;
-
- int idx = int(fNum*(v-fMin)/(fMax-fMin));
-
- if (idx < 0) idx = 0;
- else if (idx >= fNum) idx = fNum-1;
-
- gtk_label_set_text(fLabel, fNames[idx]);
- }
-};
-
-
-void GTKUI::addTextDisplay(const char* label, float* zone, char* names[], float lo, float hi )
-{
- GtkWidget* lw = gtk_label_new("");
- new uiTextDisplay (this, zone, GTK_LABEL(lw), names, lo, hi);
- openFrameBox(label);
- addWidget(label, lw);
- closeBox();
-}
-
-
-
-void GTKUI::show()
-{
- assert(fTop == 0);
- gtk_widget_show (fBox[0]);
- gtk_widget_show (fWindow);
-}
-
-
-/**
- * Update all user items reflecting zone z
- */
-
-static gboolean callUpdateAllGuis(gpointer)
-{
- UI::updateAllGuis();
- return TRUE;
-}
-
-
-void GTKUI::run()
-{
- assert(fTop == 0);
- gtk_widget_show (fBox[0]);
- gtk_widget_show (fWindow);
- gtk_timeout_add(40, callUpdateAllGuis, 0);
- gtk_main ();
- stop();
-}
-
-
-/******************************************************************************
-*******************************************************************************
-
- DSP
-
-*******************************************************************************
-*******************************************************************************/
-
-
-//----------------------------------------------------------------
-// Definition of a Faust Digital Signal Processor
-//----------------------------------------------------------------
-
-class dsp {
- protected:
- int fSamplingFreq;
- int fThreadNum;
- public:
- dsp() {}
- virtual ~dsp() {}
-
- virtual int getNumInputs() = 0;
- virtual int getNumOutputs() = 0;
- virtual void buildUserInterface(UI* interface) = 0;
- virtual void init(int samplingRate) = 0;
- virtual void compute(int len, float** inputs, float** outputs) = 0;
- virtual void conclude() {}
-};
-
-
-<<includeclass>>
-
-
-mydsp DSP;
-
-
-
-/******************************************************************************
- *******************************************************************************
-
- COREAUDIO INTERFACE
-
- *******************************************************************************
- *******************************************************************************/
-
-
-//----------------------------------------------------------------------------
-// number of physical input and output channels of the CA device
-//----------------------------------------------------------------------------
-
-int gDevNumInChans;
-int gDevNumOutChans;
-
-bool running = true;
-
-//----------------------------------------------------------------------------
-// tables of noninterleaved input and output channels for FAUST
-//----------------------------------------------------------------------------
-
-float* gInChannel[256];
-float* gOutChannel[256];
-
-#define OPEN_ERR -1
-#define NO_ERR 0
-
-class TCoreAudioRenderer
-{
-
- private:
-
- AudioBufferList* fInputData;
- AudioDeviceID fDeviceID;
- AudioUnit fAUHAL;
-
- OSStatus GetDefaultDevice(int inChan, int outChan, AudioDeviceID* id);
-
- static OSStatus Render(void *inRefCon,
- AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp,
- UInt32 inBusNumber,
- UInt32 inNumberFrames,
- AudioBufferList *ioData);
-
- public:
-
- TCoreAudioRenderer()
- {}
- virtual ~TCoreAudioRenderer()
- {}
-
- long OpenDefault(long inChan, long outChan, long bufferSize, long sampleRate);
- long Close();
-
- long Start();
- long Stop();
-
-};
-
-typedef TCoreAudioRenderer * TCoreAudioRendererPtr;
-
-static void PrintStreamDesc(AudioStreamBasicDescription *inDesc)
-{
- printf("- - - - - - - - - - - - - - - - - - - -\n");
- printf(" Sample Rate:%f\n", inDesc->mSampleRate);
- printf(" Format ID:%.*s\n", (int) sizeof(inDesc->mFormatID), (char*)&inDesc->mFormatID);
- printf(" Format Flags:%lX\n", inDesc->mFormatFlags);
- printf(" Bytes per Packet:%ld\n", inDesc->mBytesPerPacket);
- printf(" Frames per Packet:%ld\n", inDesc->mFramesPerPacket);
- printf(" Bytes per Frame:%ld\n", inDesc->mBytesPerFrame);
- printf(" Channels per Frame:%ld\n", inDesc->mChannelsPerFrame);
- printf(" Bits per Channel:%ld\n", inDesc->mBitsPerChannel);
- printf("- - - - - - - - - - - - - - - - - - - -\n");
-}
-
-static void printError(OSStatus err)
-{
- switch (err) {
- case kAudioHardwareNoError:
- printf("error code : kAudioHardwareNoError\n");
- break;
- case kAudioConverterErr_FormatNotSupported:
- printf("error code : kAudioConverterErr_FormatNotSupported\n");
- break;
- case kAudioConverterErr_OperationNotSupported:
- printf("error code : kAudioConverterErr_OperationNotSupported\n");
- break;
- case kAudioConverterErr_PropertyNotSupported:
- printf("error code : kAudioConverterErr_PropertyNotSupported\n");
- break;
- case kAudioConverterErr_InvalidInputSize:
- printf("error code : kAudioConverterErr_InvalidInputSize\n");
- break;
- case kAudioConverterErr_InvalidOutputSize:
- printf("error code : kAudioConverterErr_InvalidOutputSize\n");
- break;
- case kAudioConverterErr_UnspecifiedError:
- printf("error code : kAudioConverterErr_UnspecifiedError\n");
- break;
- case kAudioConverterErr_BadPropertySizeError:
- printf("error code : kAudioConverterErr_BadPropertySizeError\n");
- break;
- case kAudioConverterErr_RequiresPacketDescriptionsError:
- printf("error code : kAudioConverterErr_RequiresPacketDescriptionsError\n");
- break;
- case kAudioConverterErr_InputSampleRateOutOfRange:
- printf("error code : kAudioConverterErr_InputSampleRateOutOfRange\n");
- break;
- case kAudioConverterErr_OutputSampleRateOutOfRange:
- printf("error code : kAudioConverterErr_OutputSampleRateOutOfRange\n");
- break;
- case kAudioHardwareNotRunningError:
- printf("error code : kAudioHardwareNotRunningError\n");
- break;
- case kAudioHardwareUnknownPropertyError:
- printf("error code : kAudioHardwareUnknownPropertyError\n");
- break;
- case kAudioHardwareIllegalOperationError:
- printf("error code : kAudioHardwareIllegalOperationError\n");
- break;
- case kAudioHardwareBadDeviceError:
- printf("error code : kAudioHardwareBadDeviceError\n");
- break;
- case kAudioHardwareBadStreamError:
- printf("error code : kAudioHardwareBadStreamError\n");
- break;
- case kAudioDeviceUnsupportedFormatError:
- printf("error code : kAudioDeviceUnsupportedFormatError\n");
- break;
- case kAudioDevicePermissionsError:
- printf("error code : kAudioDevicePermissionsError\n");
- break;
- default:
- printf("error code : unknown\n");
- break;
- }
-}
-
-OSStatus TCoreAudioRenderer::Render(void *inRefCon,
- AudioUnitRenderActionFlags *ioActionFlags,
- const AudioTimeStamp *inTimeStamp,
- UInt32,
- UInt32 inNumberFrames,
- AudioBufferList *ioData)
-{
- TCoreAudioRendererPtr renderer = (TCoreAudioRendererPtr)inRefCon;
- AudioUnitRender(renderer->fAUHAL, ioActionFlags, inTimeStamp, 1, inNumberFrames, renderer->fInputData);
- for (int i = 0; i < gDevNumInChans; i++) {
- gInChannel[i] = (float*)renderer->fInputData->mBuffers[i].mData;
- }
- for (int i = 0; i < gDevNumOutChans; i++) {
- gOutChannel[i] = (float*)ioData->mBuffers[i].mData;
- }
- STARTMESURE
- DSP.compute((int)inNumberFrames, gInChannel, gOutChannel);
- STOPMESURE
- running = mesure <= (KMESURE + KSKIP);
- return 0;
-}
-
-OSStatus TCoreAudioRenderer::GetDefaultDevice(int inChan, int outChan, AudioDeviceID* id)
-{
- UInt32 theSize = sizeof(UInt32);
- AudioDeviceID inDefault;
- AudioDeviceID outDefault;
- OSStatus res;
-
- if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultInputDevice,
- &theSize, &inDefault)) != noErr)
- return res;
-
- if ((res = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
- &theSize, &outDefault)) != noErr)
- return res;
-
- // Duplex mode
- if (inChan > 0 && outChan > 0) {
- // Get the device only if default input and output are the same
- if (inDefault == outDefault) {
- *id = inDefault;
- return noErr;
- } else {
- printf("GetDefaultDevice : error input = %ld and output = %ld are not the same\n", inDefault, outDefault);
- return kAudioHardwareBadDeviceError;
- }
- } else if (inChan > 0) {
- *id = inDefault;
- return noErr;
- } else if (outChan > 0) {
- *id = outDefault;
- return noErr;
- } else {
- return kAudioHardwareBadDeviceError;
- }
-
- return noErr;
-}
-
-long TCoreAudioRenderer::OpenDefault(long inChan, long outChan, long bufferSize, long samplerate)
-{
- OSStatus err = noErr;
- ComponentResult err1;
- UInt32 outSize;
- UInt32 enableIO;
- Boolean isWritable;
- AudioStreamBasicDescription srcFormat, dstFormat, sampleRate;
- long in_nChannels, out_nChannels;
-
- printf("OpenDefault inChan = %ld outChan = %ld bufferSize = %ld samplerate = %ld\n", inChan, outChan, bufferSize, samplerate);
-
- if (GetDefaultDevice(inChan, outChan, &fDeviceID) != noErr) {
- printf("Cannot open default device\n");
- return OPEN_ERR;
- }
-
- // Setting buffer size
- outSize = sizeof(UInt32);
- err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyBufferFrameSize, outSize, &bufferSize);
- if (err != noErr) {
- printf("Cannot set buffer size %ld\n", bufferSize);
- printError(err);
- return OPEN_ERR;
- }
-
- // Setting sample rate
- outSize = sizeof(AudioStreamBasicDescription);
- err = AudioDeviceGetProperty(fDeviceID, 0, false, kAudioDevicePropertyStreamFormat, &outSize, &sampleRate);
- if (err != noErr) {
- printf("Cannot get current sample rate\n");
- printError(err);
- return OPEN_ERR;
- }
-
- if (samplerate != long(sampleRate.mSampleRate)) {
- sampleRate.mSampleRate = (Float64)(samplerate);
- err = AudioDeviceSetProperty(fDeviceID, NULL, 0, false, kAudioDevicePropertyStreamFormat, outSize, &sampleRate);
- if (err != noErr) {
- printf("Cannot set sample rate = %ld\n", samplerate);
- printError(err);
- return OPEN_ERR;
- }
- }
-
- // AUHAL
- ComponentDescription cd = {kAudioUnitType_Output, kAudioUnitSubType_HALOutput, kAudioUnitManufacturer_Apple, 0, 0};
- Component HALOutput = FindNextComponent(NULL, &cd);
-
- err1 = OpenAComponent(HALOutput, &fAUHAL);
- if (err1 != noErr) {
- printf("Error calling OpenAComponent\n");
- printError(err1);
- goto error;
- }
-
- err1 = AudioUnitInitialize(fAUHAL);
- if (err1 != noErr) {
- printf("Cannot initialize AUHAL unit\n");
- printError(err1);
- goto error;
- }
-
- enableIO = 1;
- err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO));
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output\n");
- printError(err1);
- goto error;
- }
-
- enableIO = 1;
- err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input\n");
- printError(err1);
- goto error;
- }
-
- err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &fDeviceID, sizeof(AudioDeviceID));
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_CurrentDevice\n");
- printError(err1);
- goto error;
- }
-
- err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, (UInt32*)&bufferSize, sizeof(UInt32));
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
- printError(err1);
- goto error;
- }
-
- err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 0, (UInt32*)&bufferSize, sizeof(UInt32));
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_MaximumFramesPerSlice\n");
- printError(err1);
- goto error;
- }
-
- err1 = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Input, 1, &outSize, &isWritable);
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 1\n");
- printError(err1);
- }
-
- in_nChannels = (err1 == noErr) ? outSize / sizeof(SInt32) : 0;
- printf("in_nChannels = %ld\n", in_nChannels);
-
- err1 = AudioUnitGetPropertyInfo(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, &outSize, &isWritable);
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap-INFO 0\n");
- printError(err1);
- }
-
- out_nChannels = (err1 == noErr) ? outSize / sizeof(SInt32) : 0;
- printf("out_nChannels = %ld\n", out_nChannels);
-
- /*
- Just ignore this case : seems to work without any further change...
-
- if (outChan > out_nChannels) {
- printf("This device hasn't required output channels\n");
- goto error;
- }
- if (inChan > in_nChannels) {
- printf("This device hasn't required input channels\n");
- goto error;
- }
- */
-
- if (outChan < out_nChannels) {
- SInt32 chanArr[out_nChannels];
- for (int i = 0; i < out_nChannels; i++) {
- chanArr[i] = -1;
- }
- for (int i = 0; i < outChan; i++) {
- chanArr[i] = i;
- }
- err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap, kAudioUnitScope_Output, 0, chanArr, sizeof(SInt32) * out_nChannels);
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 0\n");
- printError(err1);
- }
- }
-
- if (inChan < in_nChannels) {
- SInt32 chanArr[in_nChannels];
- for (int i = 0; i < in_nChannels; i++) {
- chanArr[i] = -1;
- }
- for (int i = 0; i < inChan; i++) {
- chanArr[i] = i;
- }
- AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_ChannelMap , kAudioUnitScope_Input, 1, chanArr, sizeof(SInt32) * in_nChannels);
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioOutputUnitProperty_ChannelMap 1\n");
- printError(err1);
- }
- }
-
- if (inChan > 0) {
- outSize = sizeof(AudioStreamBasicDescription);
- err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, &outSize);
- if (err1 != noErr) {
- printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
- printError(err1);
- }
- PrintStreamDesc(&srcFormat);
-
- srcFormat.mSampleRate = samplerate;
- srcFormat.mFormatID = kAudioFormatLinearPCM;
- srcFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
- srcFormat.mBytesPerPacket = sizeof(float);
- srcFormat.mFramesPerPacket = 1;
- srcFormat.mBytesPerFrame = sizeof(float);
- srcFormat.mChannelsPerFrame = inChan;
- srcFormat.mBitsPerChannel = 32;
-
- PrintStreamDesc(&srcFormat);
-
- err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &srcFormat, sizeof(AudioStreamBasicDescription));
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
- printError(err1);
- }
- }
-
- if (outChan > 0) {
- outSize = sizeof(AudioStreamBasicDescription);
- err1 = AudioUnitGetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, &outSize);
- if (err1 != noErr) {
- printf("Error calling AudioUnitGetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
- printError(err1);
- }
- PrintStreamDesc(&dstFormat);
-
- dstFormat.mSampleRate = samplerate;
- dstFormat.mFormatID = kAudioFormatLinearPCM;
- dstFormat.mFormatFlags = kAudioFormatFlagsNativeFloatPacked | kLinearPCMFormatFlagIsNonInterleaved;
- dstFormat.mBytesPerPacket = sizeof(float);
- dstFormat.mFramesPerPacket = 1;
- dstFormat.mBytesPerFrame = sizeof(float);
- dstFormat.mChannelsPerFrame = outChan;
- dstFormat.mBitsPerChannel = 32;
-
- PrintStreamDesc(&dstFormat);
-
- err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &dstFormat, sizeof(AudioStreamBasicDescription));
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_StreamFormat kAudioUnitScope_Output\n");
- printError(err1);
- }
- }
-
- if (inChan > 0 && outChan == 0) {
- AURenderCallbackStruct output;
- output.inputProc = Render;
- output.inputProcRefCon = this;
- err1 = AudioUnitSetProperty(fAUHAL, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 0, &output, sizeof(output));
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 1\n");
- printError(err1);
- goto error;
- }
- } else {
- AURenderCallbackStruct output;
- output.inputProc = Render;
- output.inputProcRefCon = this;
- err1 = AudioUnitSetProperty(fAUHAL, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &output, sizeof(output));
- if (err1 != noErr) {
- printf("Error calling AudioUnitSetProperty - kAudioUnitProperty_SetRenderCallback 0\n");
- printError(err1);
- goto error;
- }
- }
-
- fInputData = (AudioBufferList*)malloc(sizeof(UInt32) + inChan * sizeof(AudioBuffer));
- if (fInputData == 0) {
- printf("Cannot allocate memory for input buffers\n");
- goto error;
- }
- fInputData->mNumberBuffers = inChan;
-
- // Prepare buffers
- for (int i = 0; i < inChan; i++) {
- fInputData->mBuffers[i].mNumberChannels = 1;
- fInputData->mBuffers[i].mData = malloc(bufferSize * sizeof(float));
- fInputData->mBuffers[i].mDataByteSize = bufferSize * sizeof(float);
- }
-
- return NO_ERR;
-
-error:
- AudioUnitUninitialize(fAUHAL);
- CloseComponent(fAUHAL);
- return OPEN_ERR;
-}
-
-long TCoreAudioRenderer::Close()
-{
- for (int i = 0; i < gDevNumInChans; i++) {
- free(fInputData->mBuffers[i].mData);
- }
- free(fInputData);
- AudioUnitUninitialize(fAUHAL);
- CloseComponent(fAUHAL);
- return NO_ERR;
-}
-
-long TCoreAudioRenderer::Start()
-{
- OSStatus err = AudioOutputUnitStart(fAUHAL);
-
- if (err != noErr) {
- printf("Error while opening device : device open error \n");
- return OPEN_ERR;
- } else {
- return NO_ERR;
- }
-}
-
-long TCoreAudioRenderer::Stop()
-{
- OSStatus err = AudioOutputUnitStop(fAUHAL);
-
- if (err != noErr) {
- printf("Error while closing device : device close error \n");
- return OPEN_ERR;
- } else {
- return NO_ERR;
- }
-}
-
-
-/******************************************************************************
-*******************************************************************************
-
- MAIN PLAY THREAD
-
-*******************************************************************************
-*******************************************************************************/
-
-// lopt : Scan Command Line long int Arguments
-
-/*
-long lopt (int argc, char *argv[], const char* longname, const char* shortname, long def)
-{
- for (int i=2; i<argc; i++)
- if ( strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0 )
- return atoi(argv[i]);
- return def;
-}
-*/
-
-long lopt (char *argv[], const char *name, long def)
-{
- int i;
- for (i=0; argv[i]; i++) if (!strcmp(argv[i], name)) return atoi(argv[i+1]);
- return def;
-}
-
-// sopt : Scan Command Line string Arguments
-
-const char* sopt (int argc, char *argv[], const char* longname, const char* shortname, const char* def)
-{
- for (int i=2; i<argc; i++)
- if ( strcmp(argv[i-1], shortname) == 0 || strcmp(argv[i-1], longname) == 0 )
- return argv[i];
- return def;
-}
-
-// fopt : Scan Command Line flag option (without argument), return true if the flag
-
-bool fopt (int argc, char *argv[], const char* longname, const char* shortname)
-{
- for (int i=1; i<argc; i++)
- if ( strcmp(argv[i], shortname) == 0 || strcmp(argv[i], longname) == 0 )
- return true;
- return false;
-}
-
-
-//-------------------------------------------------------------------------
-// MAIN
-//-------------------------------------------------------------------------
-
-pthread_t guithread;
-
-void* run_ui(void* ptr)
-{
- UI* interface = (UI*) ptr;
- interface->run();
- pthread_exit(0);
- return 0;
-}
-
-int main(int argc, char *argv[] )
-{
- CHECKINTSIZE;
-
- UI* interface = new GTKUI(argv[0], &argc, &argv);
-
- // compute rcfilename to (re)store application state
- char rcfilename[256];
- char* home = getenv("HOME");
- snprintf(rcfilename, 255, "%s/.%src", home, basename(argv[0]));
-
- TCoreAudioRenderer audio_device;
-
- long srate = (long)lopt(argv, "--frequency", 44100);
- int fpb = lopt(argv, "--buffer", 512);
-
- AVOIDDENORMALS;
-
- DSP.init(srate);
- DSP.buildUserInterface(interface);
-
- gDevNumInChans = DSP.getNumInputs();
- gDevNumOutChans = DSP.getNumOutputs();
-
- interface->recallState(rcfilename);
-
- pthread_create(&guithread, NULL, run_ui, interface);
-
- openMesure();
-
- if (audio_device.OpenDefault(gDevNumInChans, gDevNumOutChans, fpb, srate) < 0) {
- printf("Cannot open CoreAudio device\n");
- return 0;
- }
-
- if (audio_device.Start() < 0) {
- printf("Cannot start CoreAudio device\n");
- return 0;
- }
- while(running) {
- usleep(100000);
- }
- closeMesure();
- interface->saveState(rcfilename);
-
-#ifdef BENCHMARKMODE
- printstats(argv[0], fpb, DSP.getNumInputs(), DSP.getNumOutputs());
-#endif
-
- return 0;
-}