X-Git-Url: https://scm.cri.ensmp.fr/git/Faustine.git/blobdiff_plain/c7f552fd8888da2f0d8cfb228fe0f28d3df3a12c..b4b6f2ea75b9f0f3ca918f5b84016610bf7a4d4f:/interpretor/preprocessor/faust-0.9.47mr3/architecture/matlabplot.cpp diff --git a/interpretor/preprocessor/faust-0.9.47mr3/architecture/matlabplot.cpp b/interpretor/preprocessor/faust-0.9.47mr3/architecture/matlabplot.cpp new file mode 100644 index 0000000..2a8a829 --- /dev/null +++ b/interpretor/preprocessor/faust-0.9.47mr3/architecture/matlabplot.cpp @@ -0,0 +1,545 @@ +/************************************************************************ + ************************************************************************ + FAUST Architecture File + Copyright (C) 2007-2011 Julius O. Smith III + --------------------------------------------------------------------- + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. + ************************************************************************ + ************************************************************************/ + +/* matlabplot.cpp = simple variation of plot.cpp */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +// g++ -O3 -lm -lsndfile myfx.cpp + +using namespace std; + +struct Meta : map +{ + void declare (const char* key, const char* value) { (*this)[key]=value; } +}; + + +//------------------------------------------------------------------- +// Generic min and max using c++ inline +//------------------------------------------------------------------- + +inline int max (unsigned int a, unsigned int b) { return (a>b) ? a : b; } +inline int max (int a, int b) { return (a>b) ? a : b; } + +inline long max (long a, long b) { return (a>b) ? a : b; } +inline long max (int a, long b) { return (a>b) ? a : b; } +inline long max (long a, int b) { return (a>b) ? a : b; } + +inline float max (float a, float b) { return (a>b) ? a : b; } +inline float max (int a, float b) { return (a>b) ? a : b; } +inline float max (float a, int b) { return (a>b) ? a : b; } +inline float max (long a, float b) { return (a>b) ? a : b; } +inline float max (float a, long b) { return (a>b) ? a : b; } + +inline double max (double a, double b) { return (a>b) ? a : b; } +inline double max (int a, double b) { return (a>b) ? a : b; } +inline double max (double a, int b) { return (a>b) ? a : b; } +inline double max (long a, double b) { return (a>b) ? a : b; } +inline double max (double a, long b) { return (a>b) ? a : b; } +inline double max (float a, double b) { return (a>b) ? a : b; } +inline double max (double a, float b) { return (a>b) ? a : b; } + + +inline int min (int a, int b) { return (a> n); } + +template T abs (T a) { return (a> + + + + +/****************************************************************************** +******************************************************************************* + + USER INTERFACE + +******************************************************************************* +*******************************************************************************/ + +class UI +{ + bool fStopped; +public: + + UI() : fStopped(false) {} + virtual ~UI() {} + + // -- 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; + + // -- frames and labels + + 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) {} +}; + +struct param { + float* fZone; + float fMin; + float fMax; + param(float* z, float init, float a, float b) : fZone(z), fMin(a), fMax(b) { *z = init; } +}; + + +class CMDUI : public UI +{ + int fArgc; + char** fArgv; + vector fFiles; + stack fPrefix; + map fKeyParam; + + void openAnyBox(const char* label) + { + string prefix; + + if (label && label[0]) { + prefix = fPrefix.top() + "-" + label; + } else { + prefix = fPrefix.top(); + } + fPrefix.push(prefix); + } + + string simplify(const string& src) + { + int i=0; + int level=0; + string dst; + + while (src[i] ) { + + switch (level) { + + case 0 : + case 1 : + case 2 : + // Skip the begin of the label "--foo-" + // until 3 '-' have been read + if (src[i]=='-') { level++; } + break; + + case 3 : + // copy the content, but skip non alphnum + // and content in parenthesis + switch (src[i]) { + case '(' : + case '[' : + level++; + break; + + case '-' : + dst += '-'; + break; + + default : + if (isalnum(src[i])) { + dst+= tolower(src[i]); + } + + } + break; + + default : + // here we are inside parenthesis and + // we skip the content until we are back to + // level 3 + switch (src[i]) { + + case '(' : + case '[' : + level++; + break; + + case ')' : + case ']' : + level--; + break; + + default : + break; + } + + } + i++; + } + return dst; + } + + +public: + + CMDUI(int argc, char *argv[]) : UI(), fArgc(argc), fArgv(argv) { fPrefix.push("-"); } + virtual ~CMDUI() {} + + + void addOption(const char* label, float* zone, float init, float min, float max) + { + string fullname = "-" + simplify(fPrefix.top() + "-" + label); + fKeyParam.insert(make_pair(fullname, param(zone, init, min, max))); + } + + + virtual void addButton(const char* label, float* zone) + { + addOption(label,zone,0,0,1); + } + + virtual void addToggleButton(const char* label, float* zone) + { + addOption(label,zone,0,0,1); + } + + virtual void addCheckButton(const char* label, float* zone) + { + addOption(label,zone,0,0,1); + } + + virtual void addVerticalSlider(const char* label, float* zone, float init, float min, float max, float step) + { + addOption(label,zone,init,min,max); + } + + virtual void addHorizontalSlider(const char* label, float* zone, float init, float min, float max, float step) + { + addOption(label,zone,init,min,max); + } + + virtual void addNumEntry(const char* label, float* zone, float init, float min, float max, float step) + { + addOption(label,zone,init,min,max); + } + + // -- passive 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 openFrameBox(const char* label) { openAnyBox(label); } + virtual void openTabBox(const char* label) { openAnyBox(label); } + virtual void openHorizontalBox(const char* label) { openAnyBox(label); } + virtual void openVerticalBox(const char* label) { openAnyBox(label); } + + virtual void closeBox() { fPrefix.pop(); } + + virtual void show() {} + virtual void run() {} + + void printhelp() + { + map::iterator i; + cout << fArgc << "\n"; + cout << fArgv[0] << " option list : "; + for (i = fKeyParam.begin(); i != fKeyParam.end(); i++) { + cout << "[ " << i->first << " " << i->second.fMin << ".." << i->second.fMax <<" ] "; + } + cout << " infile outfile\n"; + } + + void process_command() + { + map::iterator p; + for (int i = 1; i < fArgc; i++) { + if (fArgv[i][0] == '-') { + if ( (strcmp(fArgv[i], "-help") == 0) + || (strcmp(fArgv[i], "-h") == 0) + || (strcmp(fArgv[i], "--help") == 0) ) { + printhelp(); + exit(1); + } + p = fKeyParam.find(fArgv[i]); + if (p == fKeyParam.end()) { + cout << fArgv[0] << " : unrecognized option " << fArgv[i] << "\n"; + printhelp(); + exit(1); + } + char* end; + *(p->second.fZone) = float(strtod(fArgv[i+1], &end)); + i++; + } else { + fFiles.push_back(fArgv[i]); + } + } + } + + int files() { return fFiles.size(); } + char* file (int n) { return fFiles[n]; } + +}; + +//---------------------------------------------------------------- +// d�inition du processeur de signal +//---------------------------------------------------------------- + +class dsp { +protected: + int fSamplingFreq; +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() {} +}; + + +//---------------------------------------------------------------------------- +// FAUST generated code +//---------------------------------------------------------------------------- + +<> + + +mydsp DSP; + + +class channels +{ + int fNumFrames; + int fNumChannels; + float* fBuffers[256]; + +public: + + channels(int nframes, int nchannels) + { + assert(nchannels < 256); + + fNumFrames = nframes; + fNumChannels = nchannels; + + // allocate audio channels + for (int i = 0; i < fNumChannels; i++) { + fBuffers[i] = (float*) calloc (fNumFrames, sizeof(float)); + } + } + + void zero() + { + // allocate audio channels + for (int i = 0; i < fNumChannels; i++) { + for (int f = 0; f < fNumFrames; f++) { + fBuffers[i][f] = 0.0; + } + } + } + + void impulse() + { + // allocate audio channels + for (int i = 0; i < fNumChannels; i++) { + fBuffers[i][0] = 1.0; + for (int f = 1; f < fNumFrames; f++) { + fBuffers[i][f] = 0.0; + } + } + } + + ~channels() + { + // free separate input channels + for (int i = 0; i < fNumChannels; i++) { + free(fBuffers[i]); + } + } + + float** buffers() { return fBuffers; } +}; + + + +#define kFrames 512 + +int main(int argc, char *argv[] ) +{ + float fStartAtSample; + float fnbsamples; + + + CMDUI* interface = new CMDUI(argc, argv); + DSP.buildUserInterface(interface); + + interface->addOption("-s", &fStartAtSample, 0, 0.0, 100000000.0); + interface->addOption("-n", &fnbsamples, 16, 0.0, 100000000.0); + +// if (DSP.getNumInputs() > 0) { +// fprintf(stderr, +// "*** input signals not supported by architecture file matlab.cpp\n"); +// exit(1); +// } + + // init signal processor and the user interface values: + DSP.init(44100); + + // modify the UI values according to the command-line options: + interface->process_command(); + + // prepare input channels (if any) with an impulse + int nins = DSP.getNumInputs(); + channels inchan (kFrames, nins); + inchan.impulse(); // after each compute we will zero them + + // prepare output channels + int nouts = DSP.getNumOutputs(); + channels outchan (kFrames, nouts); + + // print usage info: + printf("%% Usage: octave --persist thisfile.m\n\n"); + + // print matlab-compatible matrix syntax followed by a plot command: + printf("faustout = [ ...\n"); + + + // skip samples + int start = int(fStartAtSample); + while (start > kFrames) { + DSP.compute(kFrames, inchan.buffers(), outchan.buffers()); + inchan.zero(); + start -= kFrames; + } + if (start > 0) { + DSP.compute(start, inchan.buffers(), outchan.buffers()); + } + // end skip + + + int nbsamples = int(fnbsamples); + while (nbsamples > kFrames) { + + DSP.compute(kFrames, inchan.buffers(), outchan.buffers()); + inchan.zero(); + for (int i = 0; i < kFrames; i++) { + for (int c = 0; c < nouts; c++) { + printf(" %g", outchan.buffers()[c][i]); + } + if (i < kFrames-1) { + printf("; ...\n"); + } else { + printf("; ...\n%%---- Chunk Boundary ----\n"); + } + } + nbsamples -= kFrames; + } + + if (nbsamples) { // Write out partial-chunk buffer: + + DSP.compute(nbsamples, inchan.buffers(), outchan.buffers()); + inchan.zero(); + for (int i = 0; i < nbsamples; i++) { + for (int c = 0; c < nouts; c++) { + printf(" %g", outchan.buffers()[c][i]); + } + printf("; ...\n"); + } + } + printf("];\n\n"); + printf("plot(faustout);\n"); + printf("title('Plot generated by %s made using ''faust -a matlabplot.cpp ...''');\n",argv[0]); + printf("xlabel('Time (samples)');\n"); + printf("ylabel('Amplitude');\n"); + if (nouts>1) { + printf("legend("); + for (int c = 0; c < nouts; c++) { + printf("'channel %d'", c+1); + if (c