zynaddsubfx

ZynAddSubFX open source synthesizer
Log | Files | Refs | Submodules | LICENSE

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 };