Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
4.5KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. VuMasterMeter.h - OSC Controlled VU Meter
  4. Copyright (C) 2016 Mark McCurry
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. */
  10. #include "VuMeter.h"
  11. #include "Fl_Osc_Interface.h"
  12. #define MIN_DB (-48)
  13. class VuMasterMeter: public VuMeter
  14. {
  15. public:
  16. VuMasterMeter(int x,int y, int w, int h, const char *label=0)
  17. :VuMeter(x,y,w,h,label),
  18. olddbl(0.0f),olddbr(0.0f),
  19. oldrmsdbl(0.0f),oldrmsdbr(0.0f),
  20. dbl(0.0f),dbr(0.0f),rmsdbl(0.0f),rmsdbr(0.0f),maxdbl(0.0f),maxdbr(0.0f),
  21. clipped(0),osc(NULL)
  22. {}
  23. void init(Fl_Osc_Interface *_osc)
  24. {
  25. osc = _osc;
  26. }
  27. int handle(int event)
  28. {
  29. switch(event){
  30. case FL_SHOW:
  31. Fl::add_timeout(1.0/18.0,tick,osc);
  32. break;
  33. case FL_HIDE:
  34. Fl::remove_timeout(tick,osc);
  35. break;
  36. case FL_PUSH:
  37. osc->requestValue("/reset-vu");
  38. return 1;
  39. }
  40. return 0;
  41. }
  42. static void tick(void *v)
  43. {
  44. Fl::repeat_timeout(1.0/18.0,tick,v);//18 fps
  45. Fl_Osc_Interface *osc = (Fl_Osc_Interface*)v;
  46. osc->requestValue("/get-vu");
  47. }
  48. void draw(void)
  49. {
  50. const int X = x(), Y = y(), W = w(), H = h();
  51. #define VULENX (W-35)
  52. #define VULENY (H/2-3)
  53. const int idbl = dbl*VULENX;
  54. const int idbr = dbr*VULENX;
  55. const int irmsdbl = rmsdbl*VULENX;
  56. const int irmsdbr = rmsdbr*VULENX;
  57. //draw the vu-meter lines
  58. //dB
  59. fl_rectf(X,Y,idbr,VULENY,0,200,255);
  60. fl_rectf(X,Y+H/2,idbl,VULENY,0,200,255);
  61. //black
  62. fl_rectf(X+idbr,Y,VULENX-idbr,VULENY,0,0,0);
  63. fl_rectf(X+idbl,Y+H/2,VULENX-idbl,VULENY,0,0,0);
  64. //draw the scales
  65. const float tmp=VULENX*1.0/MIN_DB;
  66. for (int i=1;i<1-MIN_DB;i++){
  67. const int tx=VULENX+(int) (tmp*i);
  68. fl_rectf(X+tx,Y,1,VULENY+H/2,0,160,200);
  69. if (i%5==0) fl_rectf(X+tx,Y,1,VULENY+H/2,0,230,240);
  70. if (i%10==0) fl_rectf(X+tx-1,Y,2,VULENY+H/2,0,225,255);
  71. }
  72. //rms
  73. if (irmsdbr>2) fl_rectf(X+irmsdbr-1,Y,3,VULENY,255,255,0);
  74. if (irmsdbl>2) fl_rectf(X+irmsdbl-1,Y+H/2,3,VULENY,255,255,0);
  75. //draw the red box if clipping has occured
  76. if (clipped==0) fl_rectf(X+VULENX+2,Y+1,W-VULENX-3,H-4,0,0,10);
  77. else fl_rectf(X+VULENX+2,Y+1,W-VULENX-3,H-4,250,10,10);
  78. //draw the maxdB
  79. fl_font(FL_HELVETICA|FL_BOLD,10);
  80. fl_color(255,255,255);
  81. char tmpstr[10];
  82. if(maxdbl>MIN_DB-20){
  83. snprintf((char *)&tmpstr,10,"%ddB",(int)maxdbr);
  84. fl_draw(tmpstr,X+VULENX+1,Y+1,W-VULENX-1,VULENY,FL_ALIGN_RIGHT,NULL,0);
  85. }
  86. if(maxdbr>MIN_DB-20){
  87. snprintf((char *)&tmpstr,10,"%ddB",(int)maxdbl);
  88. fl_draw(tmpstr,X+VULENX+1,Y+H/2+1,W-VULENX-1,VULENY,FL_ALIGN_RIGHT,NULL,0);
  89. }
  90. }
  91. void update(vuData *d)
  92. {
  93. //Update properties
  94. dbl = limit((MIN_DB-rap2dB(d->outpeakl))/MIN_DB);
  95. dbr = limit((MIN_DB-rap2dB(d->outpeakr))/MIN_DB);
  96. rmsdbl = limit((MIN_DB-rap2dB(d->rmspeakl))/MIN_DB);
  97. rmsdbr = limit((MIN_DB-rap2dB(d->rmspeakr))/MIN_DB);
  98. maxdbl = rap2dB(d->maxoutpeakl);
  99. maxdbr = rap2dB(d->maxoutpeakr);
  100. clipped = d->clipped;
  101. //interpolate
  102. dbl = 0.4 * dbl + 0.6 * olddbl;
  103. dbr = 0.4 * dbr + 0.6 * olddbr;
  104. rmsdbl = 0.4 * rmsdbl + 0.6 * oldrmsdbl;
  105. rmsdbr = 0.4 * rmsdbr + 0.6 * oldrmsdbr;
  106. //only update when values appear to be different
  107. if(olddbl == dbl && olddbr == dbr)
  108. return;
  109. olddbl = dbl;
  110. olddbr = dbr;
  111. oldrmsdbl = rmsdbl;
  112. oldrmsdbr = rmsdbr;
  113. damage(FL_DAMAGE_USER1);
  114. }
  115. private:
  116. float olddbl,olddbr;
  117. float oldrmsdbl,oldrmsdbr;
  118. float dbl,dbr,rmsdbl,rmsdbr,maxdbl,maxdbr;
  119. int clipped;
  120. Fl_Osc_Interface *osc;
  121. };