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.

Fl_Resonance_Graph.cpp 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include "Fl_Resonance_Graph.H"
  2. #include <FL/Fl.H>
  3. #include <FL/fl_draw.H>
  4. #include <FL/Fl_Value_Output.H>
  5. #include <rtosc/rtosc.h>
  6. Fl_Resonance_Graph::Fl_Resonance_Graph(int x,int y, int w, int h, const char *label)
  7. :Fl_Box(x,y,w,h,label), Fl_Osc_Widget(this), khzvalue(NULL), dbvalue(NULL),
  8. oldx(-1), oldy(-1), cbwidget(NULL), applybutton(NULL), Pcenterfreq(0), Poctavesfreq(0),
  9. PmaxdB(0)
  10. {
  11. memset(Prespoints, 64, N_RES_POINTS);
  12. //Get values
  13. oscRegister("Prespoints");
  14. oscRegister("Pcenterfreq");
  15. oscRegister("Poctavesfreq");
  16. oscRegister("PmaxdB");
  17. cbwidget=NULL;
  18. applybutton=NULL;
  19. }
  20. Fl_Resonance_Graph::~Fl_Resonance_Graph(void)
  21. {
  22. }
  23. void Fl_Resonance_Graph::init(Fl_Value_Output *khzvalue_,Fl_Value_Output *dbvalue_)
  24. {
  25. khzvalue=khzvalue_;
  26. dbvalue=dbvalue_;
  27. oldx=-1;
  28. khzval=-1;
  29. }
  30. void Fl_Resonance_Graph::draw_freq_line(float freq,int type)
  31. {
  32. const float freqx=getfreqpos(freq);//XXX
  33. switch(type){
  34. case 0:fl_line_style(FL_SOLID);break;
  35. case 1:fl_line_style(FL_DOT);break;
  36. case 2:fl_line_style(FL_DASH);break;
  37. }
  38. if ((freqx>0.0)&&(freqx<1.0))
  39. fl_line(x()+(int) (freqx*w()),y(),
  40. x()+(int) (freqx*w()),y()+h());
  41. }
  42. void Fl_Resonance_Graph::draw()
  43. {
  44. const int ox=x(),oy=y(),lx=w(),ly=h();
  45. fl_color(FL_DARK1);
  46. fl_rectf(ox,oy,lx,ly);
  47. //draw the lines
  48. fl_color(FL_GRAY);
  49. fl_line_style(FL_SOLID);
  50. fl_line(ox+2,oy+ly/2,ox+lx-2,oy+ly/2);
  51. //Draw 1kHz line
  52. const float freqx=getfreqpos(1000.0);//XXX
  53. if ((freqx>0.0)&&(freqx<1.0))
  54. fl_line(ox+(int) (freqx*lx),oy,
  55. ox+(int) (freqx*lx),oy+ly);
  56. //Draw other frequency lines
  57. for (int i=1; i<10; ++i){
  58. if(i==1) {
  59. draw_freq_line(i*100.0,0);
  60. draw_freq_line(i*1000.0,0);
  61. } else
  62. if (i==5) {
  63. draw_freq_line(i*100.0,2);
  64. draw_freq_line(i*1000.0,2);
  65. } else {
  66. draw_freq_line(i*100.0,1);
  67. draw_freq_line(i*1000.0,1);
  68. }
  69. }
  70. draw_freq_line(10000.0,0);
  71. draw_freq_line(20000.0,1);
  72. //Draw dotted grid
  73. fl_line_style(FL_DOT);
  74. int GY=10;if (ly<GY*3) GY=-1;
  75. for (int i=1; i<GY; ++i){
  76. int tmp=(int)(ly/(float)GY*i);
  77. fl_line(ox+2,oy+tmp,ox+lx-2,oy+tmp);
  78. }
  79. //draw the data
  80. fl_color(FL_RED);
  81. fl_line_style(FL_SOLID,2);
  82. fl_begin_line();
  83. int oiy = ly*Prespoints[0]/128.0;//XXX easy
  84. for (int i=1; i<N_RES_POINTS; ++i){
  85. const int ix=(i*1.0/N_RES_POINTS*lx);
  86. const int iy= ly*Prespoints[i]/128.0;//XXX easy
  87. fl_vertex(ox+ix,oy+ly-oiy);
  88. oiy=iy;
  89. }
  90. fl_end_line();
  91. fl_line_style(FL_SOLID,0);
  92. }
  93. int Fl_Resonance_Graph::handle(int event)
  94. {
  95. int x_=Fl::event_x()-x();
  96. int y_=Fl::event_y()-y();
  97. if((x_>=0)&&(x_<w()) && (y_>=0)&&(y_<h())){
  98. khzvalue->value(getfreqx(x_*1.0/w())/1000.0);//XXX
  99. dbvalue->value((1.0-y_*2.0/h())*PmaxdB);//XXX
  100. }
  101. if((event==FL_PUSH)||(event==FL_DRAG)){
  102. const bool leftbutton = Fl::event_button() == FL_LEFT_MOUSE;
  103. if (x_<0) x_=0;if (y_<0) y_=0;
  104. if (x_>=w()) x_=w();if (y_>=h()-1) y_=h()-1;
  105. if ((oldx<0)||(oldx==x_)){
  106. int sn=(int)(x_*1.0/w()*N_RES_POINTS);
  107. int sp=127-(int)(y_*1.0/h()*127);
  108. if(leftbutton)
  109. setPoint(sn,sp);
  110. //oscWrite("setpoint", "ii", sn, sp);//respar->setpoint(sn,sp);//XXX easy
  111. else
  112. setPoint(sn,sp);
  113. //oscWrite("setpoint", "ii", sn, 64);//respar->setpoint(sn,64);//XXX easy
  114. } else {
  115. int x1=oldx;
  116. int x2=x_;
  117. int y1=oldy;
  118. int y2=y_;
  119. if (oldx>x_){
  120. x1=x_;y1=y_;
  121. x2=oldx;y2=oldy;
  122. }
  123. for (int i=0;i<x2-x1;i++){
  124. int sn=(int)((i+x1)*1.0/w()*N_RES_POINTS);
  125. float yy=(y2-y1)*1.0/(x2-x1)*i;
  126. int sp=127-(int)((y1+yy)/h()*127);
  127. if(leftbutton) //respar->setpoint(sn,sp);//XXX easy
  128. setPoint(sn, sp);
  129. //oscWrite("setpoint", "ii", sn, sp);
  130. else //respar->setpoint(sn,64);//XXX easy
  131. setPoint(sn, sp);
  132. //oscWrite("setpoint", "ii", sn, sp);
  133. }
  134. }
  135. oldx=x_;oldy=y_;
  136. redraw();
  137. }
  138. if(event==FL_RELEASE) {
  139. oldx=-1;
  140. if(cbwidget) {
  141. cbwidget->do_callback();
  142. if(applybutton) {
  143. applybutton->color(FL_RED);
  144. applybutton->redraw();
  145. }
  146. }
  147. }
  148. return 1;
  149. }
  150. void Fl_Resonance_Graph::setcbwidget(Fl_Widget *cbwidget,Fl_Widget *applybutton)
  151. {
  152. this->cbwidget=cbwidget;
  153. this->applybutton=applybutton;
  154. }
  155. void Fl_Resonance_Graph::update(void)
  156. {
  157. oscWrite("Prespoints");
  158. oscWrite("Pcenterfreq");
  159. oscWrite("Poctavesfreq");
  160. oscWrite("PmaxdB");
  161. }
  162. void Fl_Resonance_Graph::OSC_raw(const char *msg)
  163. {
  164. //TODO check the types (OSC regex)
  165. if(strstr(msg, "Prespoints")) {
  166. rtosc_blob_t arg = rtosc_argument(msg, 0).b;
  167. assert(arg.len == N_RES_POINTS);
  168. memcpy(Prespoints, arg.data, N_RES_POINTS);
  169. } else if(strstr(msg, "Pcenterfreq"))
  170. Pcenterfreq = rtosc_argument(msg, 0).i;
  171. else if(strstr(msg, "Poctavesfreq"))
  172. Poctavesfreq = rtosc_argument(msg, 0).i;
  173. else if(strstr(msg, "PmaxdB"))
  174. PmaxdB = rtosc_argument(msg, 0).i;
  175. else
  176. puts("I got an unknown message...");
  177. redraw();
  178. }
  179. float Fl_Resonance_Graph::getfreqx(float x) const
  180. {
  181. const float octf = powf(2.0f, getoctavesfreq());
  182. return getcenterfreq() / sqrt(octf) * powf(octf, limit(x, 0.0f, 1.0f));
  183. }
  184. /*
  185. * Get the x coordinate from frequency (used by the UI)
  186. */
  187. float Fl_Resonance_Graph::getfreqpos(float freq) const
  188. {
  189. return (logf(freq) - logf(getfreqx(0.0f))) / logf(2.0f) / getoctavesfreq();
  190. }
  191. /*
  192. * Get the center frequency of the resonance graph
  193. */
  194. float Fl_Resonance_Graph::getcenterfreq() const
  195. {
  196. return 10000.0f * powf(10, -(1.0f - Pcenterfreq / 127.0f) * 2.0f);
  197. }
  198. /*
  199. * Get the number of octave that the resonance functions applies to
  200. */
  201. float Fl_Resonance_Graph::getoctavesfreq() const
  202. {
  203. return 0.25f + 10.0f * Poctavesfreq / 127.0f;
  204. }
  205. void Fl_Resonance_Graph::setPoint(int idx, int val)
  206. {
  207. Prespoints[idx] = val;
  208. oscWrite(std::string("Prespoints")+to_s(idx), "c", val);
  209. redraw();
  210. }