zynaddsubfx

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

VuMasterMeter.h (4675B)


      1 /*
      2   ZynAddSubFX - a software synthesizer
      3 
      4   VuMasterMeter.h - OSC Controlled VU Meter
      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 "VuMeter.h"
     13 #include "Fl_Osc_Interface.h"
     14 #define MIN_DB (-48)
     15 using namespace zyn;
     16 
     17 class VuMasterMeter: public VuMeter
     18 {
     19     public:
     20         VuMasterMeter(int x,int y, int w, int h, const char *label=0)
     21         :VuMeter(x,y,w,h,label),
     22         olddbl(0.0f),olddbr(0.0f),
     23         oldrmsdbl(0.0f),oldrmsdbr(0.0f),
     24         dbl(0.0f),dbr(0.0f),rmsdbl(0.0f),rmsdbr(0.0f),maxdbl(0.0f),maxdbr(0.0f),
     25         clipped(0),osc(NULL)
     26         {}
     27 
     28         void init(Fl_Osc_Interface *_osc)
     29         {
     30             osc = _osc;
     31         }
     32 
     33         int handle(int event)
     34         {
     35             switch(event){
     36                 case FL_SHOW:
     37                     Fl::add_timeout(1.0/18.0,tick,osc);
     38                     break;
     39                 case FL_HIDE:
     40                     Fl::remove_timeout(tick,osc);
     41                     break;
     42                 case FL_PUSH:
     43                     osc->requestValue("/reset-vu");
     44                     return 1;
     45             }
     46 
     47             return 0;
     48         }
     49 
     50         static void tick(void *v)
     51         {
     52             Fl::repeat_timeout(1.0/18.0,tick,v);//18 fps
     53             Fl_Osc_Interface *osc = (Fl_Osc_Interface*)v;
     54             osc->requestValue("/get-vu");
     55         }
     56 
     57         void draw(void)
     58         {
     59             const int X = x(), Y = y(), W = w(), H = h();
     60 
     61 #define VULENX (W-35)
     62 #define VULENY (H/2-3)
     63 
     64             const int idbl    = dbl*VULENX;
     65             const int idbr    = dbr*VULENX;
     66             const int irmsdbl = rmsdbl*VULENX;
     67             const int irmsdbr = rmsdbr*VULENX;
     68 
     69             //draw the vu-meter lines
     70             //dB
     71             fl_rectf(X,Y,idbr,VULENY,0,200,255);
     72             fl_rectf(X,Y+H/2,idbl,VULENY,0,200,255);
     73             //black
     74             fl_rectf(X+idbr,Y,VULENX-idbr,VULENY,0,0,0);
     75             fl_rectf(X+idbl,Y+H/2,VULENX-idbl,VULENY,0,0,0);
     76 
     77             //draw the scales
     78             const float  tmp=VULENX*1.0/MIN_DB;
     79             for (int i=1;i<1-MIN_DB;i++){
     80                 const int tx=VULENX+(int) (tmp*i);
     81                 fl_rectf(X+tx,Y,1,VULENY+H/2,0,160,200);
     82                 if (i%5==0) fl_rectf(X+tx,Y,1,VULENY+H/2,0,230,240);
     83                 if (i%10==0) fl_rectf(X+tx-1,Y,2,VULENY+H/2,0,225,255);
     84             }
     85 
     86             //rms
     87             if (irmsdbr>2) fl_rectf(X+irmsdbr-1,Y,3,VULENY,255,255,0);
     88             if (irmsdbl>2) fl_rectf(X+irmsdbl-1,Y+H/2,3,VULENY,255,255,0);
     89 
     90 
     91             //draw the red box if clipping has occurred
     92             if (clipped==0) fl_rectf(X+VULENX+2,Y+1,W-VULENX-3,H-4,0,0,10);
     93             else fl_rectf(X+VULENX+2,Y+1,W-VULENX-3,H-4,250,10,10);
     94 
     95             //draw the maxdB
     96             fl_font(FL_HELVETICA|FL_BOLD,10);
     97             fl_color(255,255,255);
     98 
     99             char tmpstr[10];
    100             if(maxdbl>MIN_DB-20){
    101                 snprintf((char *)&tmpstr,10,"%ddB",(int)maxdbr);
    102                 fl_draw(tmpstr,X+VULENX+1,Y+1,W-VULENX-1,VULENY,FL_ALIGN_RIGHT,NULL,0);
    103             }
    104             if(maxdbr>MIN_DB-20){
    105                 snprintf((char *)&tmpstr,10,"%ddB",(int)maxdbl);
    106                 fl_draw(tmpstr,X+VULENX+1,Y+H/2+1,W-VULENX-1,VULENY,FL_ALIGN_RIGHT,NULL,0);
    107             }
    108         }
    109 
    110         void update(vuData *d)
    111         {
    112             //Update properties
    113             dbl     = limit((MIN_DB-rap2dB(d->outpeakl))/MIN_DB);
    114             dbr     = limit((MIN_DB-rap2dB(d->outpeakr))/MIN_DB);
    115             rmsdbl  = limit((MIN_DB-rap2dB(d->rmspeakl))/MIN_DB);
    116             rmsdbr  = limit((MIN_DB-rap2dB(d->rmspeakr))/MIN_DB);
    117             maxdbl  = rap2dB(d->maxoutpeakl);
    118             maxdbr  = rap2dB(d->maxoutpeakr);
    119             clipped = d->clipped;
    120 
    121             //interpolate
    122             dbl    = 0.4 * dbl    + 0.6 * olddbl;
    123             dbr    = 0.4 * dbr    + 0.6 * olddbr;
    124 
    125             rmsdbl = 0.4 * rmsdbl + 0.6 * oldrmsdbl;
    126             rmsdbr = 0.4 * rmsdbr + 0.6 * oldrmsdbr;
    127 
    128             //only update when values appear to be different
    129             if(olddbl == dbl && olddbr == dbr)
    130                 return;
    131 
    132             olddbl    = dbl;
    133             olddbr    = dbr;
    134             oldrmsdbl = rmsdbl;
    135             oldrmsdbr = rmsdbr;
    136 
    137             damage(FL_DAMAGE_USER1);
    138         }
    139     private:
    140         float olddbl,olddbr;
    141         float oldrmsdbl,oldrmsdbr;
    142         float dbl,dbr,rmsdbl,rmsdbr,maxdbl,maxdbr;
    143         int clipped;
    144 
    145         Fl_Osc_Interface *osc;
    146 };