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.

125 lines
3.2KB

  1. #include <cassert>
  2. #include <FL/Fl_Box.H>
  3. #include <FL/Fl.H>
  4. #include "Fl_Osc_Widget.H"
  5. //consider merging with Fl_Oscilloscope
  6. class Fl_OscilSpectrum : public Fl_Box, public Fl_Osc_Widget
  7. {
  8. public:
  9. Fl_OscilSpectrum(int x,int y, int w, int h, const char *label=0)
  10. :Fl_Box(x,y,w,h,label), nsamples(0), spc(NULL)
  11. {}
  12. ~Fl_OscilSpectrum(void)
  13. {
  14. delete[] spc;
  15. osc->removeLink(loc, (Fl_Osc_Widget*) this);
  16. }
  17. void init(bool base_spectrum_p)
  18. {
  19. Fl_Osc_Pane *og = fetch_osc_pane(this);
  20. assert(og);
  21. loc = og->base + (base_spectrum_p ? "base-spectrum": "spectrum");
  22. osc = og->osc;
  23. assert(osc);
  24. osc->createLink(loc, (Fl_Osc_Widget*) this);
  25. update();
  26. }
  27. void update(void)
  28. {
  29. osc->requestValue(loc);
  30. }
  31. virtual void OSC_value(unsigned N, void *data) override
  32. {
  33. assert(!(N%4));
  34. const size_t new_samples = N / 4;
  35. //resize buffer if needed
  36. if(new_samples != nsamples) {
  37. delete [] spc;
  38. spc = new float[new_samples];
  39. nsamples = new_samples;
  40. }
  41. memcpy(spc, data, N);
  42. //normalize
  43. float max=0;
  44. for (unsigned i=0; i<nsamples; i++){
  45. float x=fabs(spc[i]);
  46. if (max<x) max=x;
  47. }
  48. if (max<0.000001) max=1.0;
  49. max=max*1.05;
  50. for(unsigned i=0; i<nsamples; ++i)
  51. spc[i]/=max;
  52. //Get widget to redraw new data
  53. redraw();
  54. }
  55. void draw(void)
  56. {
  57. const int ox=x(),oy=y(),lx=w(),ly=h();
  58. const int maxdb=60;//must be multiple of 10
  59. const int GX=2;
  60. int n=lx/GX-1;
  61. if (n>(int)nsamples)
  62. n=nsamples;
  63. fl_rectf(ox,oy,lx,ly,0,0,0);
  64. //draw
  65. if(this->active_r())
  66. fl_color(0,0,255);
  67. else
  68. fl_color(this->parent()->color());
  69. fl_line_style(FL_DOT);
  70. for(int i=1; i<maxdb/10; i++){
  71. const int ky=((int)((float)i*ly*10.0/maxdb)/2)*2;
  72. fl_line(ox,oy+ky-1,ox+lx-2,oy+ky-1);
  73. }
  74. for(int i=2; i<n; i++){
  75. int tmp=i*GX-2;
  76. if(i%10==1)
  77. fl_line_style(0);
  78. else
  79. fl_line_style(FL_DOT);
  80. fl_line(ox+tmp,oy+2,ox+tmp,oy+ly-2);
  81. }
  82. if (this->active_r())
  83. fl_color(0,255,0);
  84. else
  85. fl_color(this->parent()->color());
  86. fl_line_style(0);
  87. if(!spc)
  88. return;
  89. //draws the spectrum
  90. for(int i=1; i<n; i++){
  91. int tmp=(i-1)*GX+2;
  92. float x=spc[i];
  93. if (x>dB2rap(-maxdb)) x=rap2dB(x)/maxdb+1;
  94. else x=0;
  95. int val=(int) ((ly-2)*x);
  96. if (val>0) fl_line(ox+tmp,oy+ly-2-val,ox+tmp,oy+ly-2);
  97. }
  98. }
  99. private:
  100. size_t nsamples;
  101. float *spc;
  102. };