#include #include #include #include #include "../globals.h" #include "Fl_Osc_Widget.H" #include "Fl_Osc_Interface.h" class PADnoteOvertonePosition: public Fl_Box, public Fl_Osc_Widget { public: PADnoteOvertonePosition(int x,int y, int w, int h, const char *label=0) :Fl_Box(x,y,w,h,label), nsamples(0), spc(0), nhr(0), spectrum(new float[w]), mode(0), osc(NULL) { memset(spectrum, 0, w*sizeof(float)); } ~PADnoteOvertonePosition(void) { osc->removeLink("/oscilsize", (Fl_Osc_Widget*) this); osc->removeLink(base_path + "oscilgen/spectrum", (Fl_Osc_Widget*) this); osc->removeLink(base_path + "nhr", (Fl_Osc_Widget*) this); osc->removeLink(base_path + "Pmode", (Fl_Osc_Widget*) this); delete [] spc; delete [] nhr; delete [] spectrum; } void init(void) { Fl_Osc_Pane *og = fetch_osc_pane(this); assert(og); base_path = og->base; osc = og->osc; assert(osc); osc->createLink("/oscilsize", (Fl_Osc_Widget*) this); osc->requestValue("/oscilsize"); osc->createLink(base_path + "nhr", (Fl_Osc_Widget*) this); osc->createLink(base_path + "oscilgen/spectrum", (Fl_Osc_Widget*) this); osc->createLink(base_path + "Pmode", (Fl_Osc_Widget*) this); update(); } void update(void) { osc->requestValue(base_path + "nhr"); osc->requestValue(base_path + "oscilgen/spectrum"); osc->requestValue(base_path + "Pmode"); } virtual void OSC_value(unsigned N, void *data, const char *name) override { if(N/4 != nsamples) { nsamples = N/4; delete [] spc; delete [] nhr; spc = new float[nsamples]; nhr = new float[nsamples]; memset(spc, 0, nsamples*sizeof(float)); memset(nhr, 0, nsamples*sizeof(float)); } assert(N==(4*nsamples)); float *d = (float*)data; if(!strcmp(name, "spectrum")) updateSpectrum(d); else if(!strcmp(name, "nhr")) updateHarmonicPos(d); else assert(false); } virtual void OSC_value(int x, const char *name) override { if(!strcmp(name, "Pmode")) { mode = x; regenerateOvertones(); } else if(!strcmp(name, "oscilsize")) { if(x/2 != (int)nsamples) { nsamples = x/2; delete [] spc; delete [] nhr; spc = new float[nsamples]; nhr = new float[nsamples]; memset(spc, 0, nsamples*sizeof(float)); memset(nhr, 0, nsamples*sizeof(float)); } } } private: void updateSpectrum(float *data) { //normalize float max=0; for (unsigned i=0; i=lx)) continue; spectrum[kx]=spc[i-1]+1e-9; } if(mode==2) { int old=0; for (int i=1;i1e-10)||(i==(lx-1))){ const int delta=i-old; const float val1=spectrum[old]; const float val2=spectrum[i]; const float idelta=1.0/delta; for (int j=0;jdB2rap(-maxdb)) x=rap2dB(x)/maxdb+1; else continue; int yy=(int)(x*ly); fl_line(ox+i,oy+ly-1-yy,ox+i,oy+ly-1); } } private: size_t nsamples; float *spc; float *nhr; float *spectrum; char mode; std::string base_path; Fl_Osc_Interface *osc; };