Fl_OscilSpectrum.h (3663B)
1 /* 2 ZynAddSubFX - a software synthesizer 3 4 Fl_OscilSpectrum.h - OSC Controlled Spectrum 5 Copyright (C) 2016 Mark McCurry 6 7 This program is free software; you can redistribute it and/or 8 modify it under the terms of the GNU General Public License 9 as published by the Free Software Foundation; either version 2 10 of the License, or (at your option) any later version. 11 */ 12 #include <cassert> 13 #include <FL/Fl_Box.H> 14 #include <FL/Fl.H> 15 #include "Fl_Osc_Widget.H" 16 17 //consider merging with Fl_Oscilloscope 18 class Fl_OscilSpectrum : public Fl_Box, public Fl_Osc_Widget 19 { 20 public: 21 Fl_OscilSpectrum(int x,int y, int w, int h, const char *label=0) 22 :Fl_Box(x,y,w,h,label), nsamples(0), spc(NULL) 23 {} 24 25 ~Fl_OscilSpectrum(void) 26 { 27 delete[] spc; 28 osc->removeLink(loc, (Fl_Osc_Widget*) this); 29 } 30 31 void init(bool base_spectrum_p) 32 { 33 Fl_Osc_Pane *og = fetch_osc_pane(this); 34 assert(og); 35 36 loc = og->base + (base_spectrum_p ? "base-spectrum": "spectrum"); 37 osc = og->osc; 38 assert(osc); 39 40 osc->createLink(loc, (Fl_Osc_Widget*) this); 41 update(); 42 } 43 44 void update(void) 45 { 46 osc->requestValue(loc); 47 } 48 49 virtual void OSC_value(unsigned N, void *data) override 50 { 51 assert(!(N%4)); 52 const size_t new_samples = N / 4; 53 54 //resize buffer if needed 55 if(new_samples != nsamples) { 56 delete [] spc; 57 spc = new float[new_samples]; 58 nsamples = new_samples; 59 } 60 61 memcpy(spc, data, N); 62 63 //normalize 64 float max=0; 65 for (unsigned i=0; i<nsamples; i++){ 66 float x=fabsf(spc[i]); 67 if (max<x) max=x; 68 } 69 if (max<0.000001) max=1.0; 70 max=max*1.05; 71 72 for(unsigned i=0; i<nsamples; ++i) 73 spc[i]/=max; 74 75 //Get widget to redraw new data 76 redraw(); 77 } 78 79 void draw(void) 80 { 81 const int ox=x(),oy=y(),lx=w(),ly=h(); 82 const int maxdb=60;//must be multiple of 10 83 const int GX=2; 84 int n=lx/GX-1; 85 if (n>(int)nsamples) 86 n=nsamples; 87 88 fl_rectf(ox,oy,lx,ly,0,0,0); 89 90 //draw 91 if(this->active_r()) 92 fl_color(0,0,255); 93 else 94 fl_color(this->parent()->color()); 95 fl_line_style(FL_DOT); 96 97 for(int i=1; i<maxdb/10; i++){ 98 const int ky=((int)((float)i*ly*10.0/maxdb)/2)*2; 99 fl_line(ox,oy+ky-1,ox+lx-2,oy+ky-1); 100 } 101 102 for(int i=2; i<n; i++){ 103 int tmp=i*GX-2; 104 if(i%10==1) 105 fl_line_style(0); 106 else 107 fl_line_style(FL_DOT); 108 fl_line(ox+tmp,oy+2,ox+tmp,oy+ly-2); 109 } 110 111 if (this->active_r()) 112 fl_color(0,255,0); 113 else 114 fl_color(this->parent()->color()); 115 fl_line_style(0); 116 117 if(!spc) 118 return; 119 //draws the spectrum 120 for(int i=1; i<n; i++){ 121 int tmp=(i-1)*GX+2; 122 float x=spc[i]; 123 124 if (x>dB2rap(-maxdb)) x=rap2dB(x)/maxdb+1; 125 else x=0; 126 127 int val=(int) ((ly-2)*x); 128 if (val>0) fl_line(ox+tmp,oy+ly-2-val,ox+tmp,oy+ly-2); 129 } 130 } 131 private: 132 133 size_t nsamples; 134 float *spc; 135 };