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.

136 lines
3.6KB

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