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.

360 lines
7.8KB

  1. // ----------------------------------------------------------------------
  2. //
  3. // Copyright (C) 2010-2014 Fons Adriaensen <fons@linuxaudio.org>
  4. // Modified by falkTX on Jan 2015 for inclusion in Carla
  5. //
  6. // This program is free software; you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation; either version 2 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // This program is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU General Public License
  17. // along with this program; if not, write to the Free Software
  18. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. //
  20. // ----------------------------------------------------------------------
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include <math.h>
  24. #include "styles.h"
  25. #include "global.h"
  26. #include "mainwin.h"
  27. namespace AT1 {
  28. Mainwin::Mainwin (X_rootwin *parent, X_resman *xres, int xp, int yp, Jclient *jclient, ValueChangedCallback* valuecb) :
  29. A_thread ("Main"),
  30. X_window (parent, xp, yp, XSIZE, YSIZE, XftColors [C_MAIN_BG]->pixel),
  31. _stop (false),
  32. _xres (xres),
  33. _jclient (jclient),
  34. _valuecb (valuecb)
  35. {
  36. X_hints H;
  37. char s [256];
  38. int i, j, x, y;
  39. _atom = XInternAtom (dpy (), "WM_DELETE_WINDOW", True);
  40. XSetWMProtocols (dpy (), win (), &_atom, 1);
  41. _atom = XInternAtom (dpy (), "WM_PROTOCOLS", True);
  42. sprintf (s, "%s", jclient->jname ());
  43. x_set_title (s);
  44. H.position (xp, yp);
  45. H.minsize (XSIZE, YSIZE);
  46. H.maxsize (XSIZE, YSIZE);
  47. H.rname (xres->rname ());
  48. H.rclas (xres->rclas ());
  49. x_apply (&H);
  50. x = 20;
  51. _bmidi = new Pbutt0 (this, this, &b_midi_img, x, 12, B_MIDI);
  52. _bmidi->x_map ();
  53. bstyle1.size.x = 50;
  54. bstyle1.size.y = 20;
  55. _bchan = new X_tbutton (this, this, &bstyle1, x - 5, 40, "Omni", 0, B_CHAN);
  56. _bchan->x_map ();
  57. _midich = 0;
  58. x = 100;
  59. y = 23;
  60. _tmeter = new Tmeter (this, x - 20, 53);
  61. _tmeter->x_map ();
  62. for (i = j = 0; i < 12; i++, j++)
  63. {
  64. _bnote [i] = new Pbutt1 (this, this, &b_note_img, x, y, i);
  65. _bnote [i]->set_state (1);
  66. _bnote [i]->x_map ();
  67. if (j == 4)
  68. {
  69. x += 20;
  70. j++;
  71. }
  72. else
  73. {
  74. x += 10;
  75. if (j & 1) y += 18;
  76. else y -= 18;
  77. }
  78. }
  79. RotaryCtl::init (disp ());
  80. x = 270;
  81. _rotary [R_TUNE] = new Rlinctl (this, this, R_TUNE, &r_tune_geom, x, 0, 400, 5, 400.0, 480.0, 440.0);
  82. _rotary [R_BIAS] = new Rlinctl (this, this, R_BIAS, &r_bias_geom, x, 0, 270, 5, 0.0, 1.0, 0.5);
  83. _rotary [R_FILT] = new Rlogctl (this, this, R_FILT, &r_filt_geom, x, 0, 200, 5, 0.50, 0.02, 0.1);
  84. _rotary [R_CORR] = new Rlinctl (this, this, R_CORR, &r_corr_geom, x, 0, 270, 5, 0.0, 1.0, 1.0);
  85. _rotary [R_OFFS] = new Rlinctl (this, this, R_OFFS, &r_offs_geom, x, 0, 400, 10, -2.0, 2.0, 0.0);
  86. for (i = 0; i < NROTARY; i++) _rotary [i]->x_map ();
  87. _textln = new X_textip (this, 0, &tstyle1, 0, 0, 50, 15, 15);
  88. _textln->set_align (0);
  89. _ttimer = 0;
  90. _notes = 0xFFF;
  91. x_add_events (ExposureMask);
  92. x_map ();
  93. set_time (0);
  94. inc_time (500000);
  95. }
  96. Mainwin::~Mainwin (void)
  97. {
  98. RotaryCtl::fini ();
  99. }
  100. int Mainwin::process (void)
  101. {
  102. int e;
  103. if (_stop) handle_stop ();
  104. e = get_event_timed ();
  105. switch (e)
  106. {
  107. case EV_TIME:
  108. handle_time ();
  109. break;
  110. }
  111. return e;
  112. }
  113. void Mainwin::setchan_ui (int chan)
  114. {
  115. char s [16];
  116. _midich = chan;
  117. if (_midich)
  118. {
  119. sprintf (s, "Ch %d\n", _midich);
  120. _bchan->set_text (s, 0);
  121. }
  122. else _bchan->set_text ("Omni", 0);
  123. }
  124. void Mainwin::handle_event (XEvent *E)
  125. {
  126. switch (E->type)
  127. {
  128. case Expose:
  129. expose ((XExposeEvent *) E);
  130. break;
  131. case ClientMessage:
  132. clmesg ((XClientMessageEvent *) E);
  133. break;
  134. }
  135. }
  136. void Mainwin::expose (XExposeEvent *E)
  137. {
  138. if (E->count) return;
  139. redraw ();
  140. }
  141. void Mainwin::clmesg (XClientMessageEvent *E)
  142. {
  143. if (E->message_type == _atom) _stop = true;
  144. }
  145. void Mainwin::handle_time (void)
  146. {
  147. int i, k, s;
  148. float v;
  149. v = _jclient->retuner ()->get_error ();
  150. _tmeter->update (v, v);
  151. k = _jclient->retuner ()->get_noteset ();
  152. for (i = 0; i < 12; i++)
  153. {
  154. s = _bnote [i]->state ();
  155. if (k & 1) s |= 2;
  156. else s &= ~2;
  157. _bnote [i]->set_state (s);
  158. k >>= 1;
  159. }
  160. k = _jclient->get_midiset();
  161. if (k) _bmidi->set_state (_bmidi->state () | 1);
  162. else _bmidi->set_state (_bmidi->state () & ~1);
  163. if (_ttimer)
  164. {
  165. if (--_ttimer == 0) _textln->x_unmap ();
  166. }
  167. inc_time (50000);
  168. XFlush (dpy ());
  169. }
  170. void Mainwin::handle_stop (void)
  171. {
  172. put_event (EV_EXIT, 1);
  173. }
  174. void Mainwin::handle_callb (int type, X_window *W, XEvent *E)
  175. {
  176. PushButton *B;
  177. RotaryCtl *R;
  178. int k;
  179. float v;
  180. switch (type)
  181. {
  182. case X_callback::BUTTON | X_button::PRESS:
  183. {
  184. X_button *Z = (X_button *) W;
  185. XButtonEvent *X = (XButtonEvent *) E;
  186. switch (Z->cbid ())
  187. {
  188. case B_CHAN:
  189. switch (X->button)
  190. {
  191. case 1:
  192. case 4:
  193. setchan (1);
  194. break;
  195. case 3:
  196. case 5:
  197. setchan (-1);
  198. break;
  199. }
  200. break;
  201. }
  202. break;
  203. }
  204. case PushButton::PRESS:
  205. B = (PushButton *) W;
  206. k = B->cbind ();
  207. if (k < B_MIDI)
  208. {
  209. k = 1 << k;
  210. if (B->state () & 1) _notes |= k;
  211. else _notes &= ~k;
  212. _jclient->set_notemask (_notes);
  213. }
  214. else if (k == B_MIDI)
  215. {
  216. _jclient->clr_midimask ();
  217. }
  218. break;
  219. case RotaryCtl::PRESS:
  220. R = (RotaryCtl *) W;
  221. k = R->cbind ();
  222. switch (k)
  223. {
  224. case R_TUNE:
  225. case R_OFFS:
  226. showval (k);
  227. break;
  228. }
  229. break;
  230. case RotaryCtl::DELTA:
  231. R = (RotaryCtl *) W;
  232. k = R->cbind ();
  233. switch (k)
  234. {
  235. case R_TUNE:
  236. v = _rotary [R_TUNE]->value ();
  237. _jclient->retuner ()->set_refpitch (v);
  238. _valuecb->valueChangedCallback (R_TUNE, v);
  239. showval (k);
  240. break;
  241. case R_BIAS:
  242. v = _rotary [R_BIAS]->value ();
  243. _jclient->retuner ()->set_notebias (v);
  244. _valuecb->valueChangedCallback (R_BIAS, v);
  245. break;
  246. case R_FILT:
  247. v = _rotary [R_FILT]->value ();
  248. _jclient->retuner ()->set_corrfilt (v);
  249. _valuecb->valueChangedCallback (R_FILT, v);
  250. break;
  251. case R_CORR:
  252. v = _rotary [R_CORR]->value ();
  253. _jclient->retuner ()->set_corrgain (v);
  254. _valuecb->valueChangedCallback (R_CORR, v);
  255. break;
  256. case R_OFFS:
  257. v = _rotary [R_OFFS]->value ();
  258. _jclient->retuner ()->set_corroffs (v);
  259. _valuecb->valueChangedCallback (R_OFFS, v);
  260. showval (k);
  261. break;
  262. }
  263. break;
  264. }
  265. }
  266. void Mainwin::setchan (int d)
  267. {
  268. char s [16];
  269. _midich += d;
  270. if (_midich < 0) _midich = 0;
  271. if (_midich > 16) _midich = 16;
  272. if (_midich)
  273. {
  274. sprintf (s, "Ch %d\n", _midich);
  275. _bchan->set_text (s, 0);
  276. }
  277. else _bchan->set_text ("Omni", 0);
  278. _jclient->set_midichan (_midich - 1);
  279. _valuecb->valueChangedCallback (NROTARY, _midich);
  280. }
  281. void Mainwin::showval (int k)
  282. {
  283. char s [16];
  284. switch (k)
  285. {
  286. case R_TUNE:
  287. sprintf (s, "%5.1lf", _rotary [R_TUNE]->value ());
  288. _textln->x_move (222, 58);
  289. break;
  290. case R_OFFS:
  291. sprintf (s, "%5.2lf", _rotary [R_OFFS]->value ());
  292. _textln->x_move (463, 58);
  293. break;
  294. }
  295. _textln->set_text (s);
  296. _textln->x_map ();
  297. _ttimer = 40;
  298. }
  299. void Mainwin::redraw (void)
  300. {
  301. int x;
  302. x = 80;
  303. XPutImage (dpy (), win (), dgc (), notesect_img, 0, 0, x, 0, 190, 75);
  304. x += 190;
  305. XPutImage (dpy (), win (), dgc (), ctrlsect_img, 0, 0, x, 0, 315, 75);
  306. }
  307. }