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.

147 lines
4.6KB

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