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.

135 lines
4.2KB

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