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.

169 lines
4.6KB

  1. /*
  2. ZynAddSubFX - a software synthesizer
  3. Fl_Oscilloscope.h - OSC Waveform View
  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. #pragma once
  11. #include "Fl_Osc_Pane.H"
  12. #include <FL/Fl_Box.H>
  13. #include <FL/fl_draw.H>
  14. #include "Fl_Osc_Widget.H"
  15. #include "Fl_Osc_Pane.H"
  16. #include "Fl_Osc_Interface.h"
  17. #include "common.H"
  18. #include <cassert>
  19. #include <cstdio>
  20. #include "../globals.h"
  21. class Fl_Osc_Group;
  22. //Consider merging in Fl_OscilSpectrum
  23. class Fl_Oscilloscope : public Fl_Box, public Fl_Osc_Widget
  24. {
  25. public:
  26. Fl_Oscilloscope(int x,int y, int w, int h, const char *label=0)
  27. :Fl_Box(x,y,w,h,label), Fl_Osc_Widget(this), smps(0), oscilsize(0),
  28. Overlay(NULL)
  29. {
  30. phase=64;
  31. box(FL_FLAT_BOX);
  32. bkgnd = fl_color_average( FL_BLACK, FL_BACKGROUND_COLOR, 0.5 );
  33. }
  34. ~Fl_Oscilloscope(void)
  35. {
  36. delete[] smps;
  37. }
  38. void init(bool base_waveform_p)
  39. {
  40. ext = (base_waveform_p ? "base-waveform": "waveform");
  41. osc->createLink("/oscilsize", this);
  42. osc->requestValue("/oscilsize");
  43. assert(osc);
  44. oscRegister(ext.c_str());
  45. }
  46. void update(void)
  47. {
  48. oscWrite(ext);
  49. }
  50. virtual void OSC_value(int smp)
  51. {
  52. if(smp == oscilsize)
  53. return;
  54. oscilsize = smp;
  55. delete []smps;
  56. smps = new float[oscilsize];
  57. memset(smps, 0, oscilsize*sizeof(float));
  58. }
  59. virtual void OSC_value(unsigned N, void *data) override
  60. {
  61. if(oscilsize == 0)
  62. OSC_value((int)N/4);
  63. assert(N==(unsigned)(oscilsize*4));
  64. memcpy(smps, data, N);
  65. //normalize
  66. float max=0;
  67. for (int i=0;i<oscilsize;i++)
  68. if(max<fabs(smps[i]))
  69. max=fabs(smps[i]);
  70. if (max<0.00001) max=1.0;
  71. max *= -1.05;
  72. for(int i=0; i < oscilsize; ++i)
  73. smps[i] /= max;
  74. //Get widget to redraw new data
  75. redraw();
  76. }
  77. void draw(void)
  78. {
  79. int ox=x(),oy=y(),lx=w(),ly=h()-1;
  80. if (damage()!=1) {
  81. fl_color(bkgnd);
  82. fl_rectf(ox,oy,lx,ly);
  83. }
  84. //draw
  85. fl_line_style(FL_DASH);
  86. if (this->active_r()) fl_color(this->parent()->labelcolor());
  87. else fl_color(this->parent()->color());
  88. int GX=16;if (lx<GX*3) GX=-1;
  89. for (int i=1;i<GX;i++){
  90. int tmp=(int)(lx/(float)GX*i);
  91. fl_line(ox+tmp,oy+2,ox+tmp,oy+ly-2);
  92. }
  93. int GY=8; if (ly<GY*3) GY=-1;
  94. for (int i=1;i<GY;i++){
  95. int tmp=(int)(ly/(float)GY*i);
  96. fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp);
  97. }
  98. //draw the function
  99. fl_line_style(0,1);
  100. fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2);
  101. if (this->active_r()) fl_color(this->parent()->selection_color());
  102. else fl_color(this->parent()->labelcolor());
  103. fl_color( fl_color_add_alpha( fl_color(), 127 ) );
  104. if(smps) {
  105. int lw=2;
  106. fl_line_style(FL_SOLID,lw);
  107. fl_begin_line();
  108. double ph=((phase-64.0)/128.0*oscilsize+oscilsize);
  109. for (int i=1;i<lx;i++){
  110. int k2=(oscilsize*i/lx)+ph;
  111. fl_vertex(i+ox,(smps[k2%oscilsize]+1)*(ly-1)/2+oy+0.5);
  112. }
  113. fl_end_line();
  114. }
  115. // Erase stray pixels on margin
  116. fl_color(bkgnd);
  117. fl_line_style(FL_SOLID,1);
  118. fl_rect(ox-1,oy-1,lx+2,ly+2);
  119. fl_line_style(FL_SOLID,0);
  120. if (Overlay)
  121. Overlay->redraw();
  122. }
  123. //allows UI to manipuate phase of displayed waveform
  124. int phase;
  125. private:
  126. Fl_Osc_Pane *fetch_osc_pane(Fl_Widget *w)
  127. {
  128. if(!w)
  129. return NULL;
  130. Fl_Osc_Pane *pane = dynamic_cast<Fl_Osc_Pane*>(w->parent());
  131. if(pane)
  132. return pane;
  133. return fetch_osc_pane(w->parent());
  134. }
  135. float *smps;
  136. int oscilsize;
  137. Fl_Color bkgnd;
  138. public:
  139. Fl_Box *Overlay;
  140. };