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.

369 lines
7.7KB

  1. // ----------------------------------------------------------------------
  2. //
  3. // Copyright (C) 2010-2014 Fons Adriaensen <fons@linuxaudio.org>
  4. // Modified by falkTX on Jan-Apr 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, 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. z_error (0.0f),
  34. z_noteset (0),
  35. z_midiset (0),
  36. _valuecb (valuecb)
  37. {
  38. X_hints H;
  39. int i, j, x, y;
  40. _atom = XInternAtom (dpy (), "WM_DELETE_WINDOW", True);
  41. XSetWMProtocols (dpy (), win (), &_atom, 1);
  42. _atom = XInternAtom (dpy (), "WM_PROTOCOLS", True);
  43. H.position (xp, yp);
  44. H.minsize (XSIZE, YSIZE);
  45. H.maxsize (XSIZE, YSIZE);
  46. H.rname (xres->rname ());
  47. H.rclas (xres->rclas ());
  48. x_apply (&H);
  49. x = 20;
  50. _bmidi = new Pbutt0 (this, this, &b_midi_img, x, 12, B_MIDI);
  51. _bmidi->x_map ();
  52. bstyle1.size.x = 50;
  53. bstyle1.size.y = 20;
  54. _bchan = new X_tbutton (this, this, &bstyle1, x - 5, 40, "Omni", 0, B_CHAN);
  55. _bchan->x_map ();
  56. _midich = 0;
  57. x = 100;
  58. y = 23;
  59. _tmeter = new Tmeter (this, x - 20, 53);
  60. _tmeter->x_map ();
  61. for (i = j = 0; i < 12; i++, j++)
  62. {
  63. _bnote [i] = new Pbutt1 (this, this, &b_note_img, x, y, i);
  64. _bnote [i]->set_state (1);
  65. _bnote [i]->x_map ();
  66. if (j == 4)
  67. {
  68. x += 20;
  69. j++;
  70. }
  71. else
  72. {
  73. x += 10;
  74. if (j & 1) y += 18;
  75. else y -= 18;
  76. }
  77. }
  78. RotaryCtl::init (disp ());
  79. x = 270;
  80. _rotary [R_TUNE] = new Rlinctl (this, this, R_TUNE, &r_tune_geom, x, 0, 400, 5, 400.0, 480.0, 440.0);
  81. _rotary [R_BIAS] = new Rlinctl (this, this, R_BIAS, &r_bias_geom, x, 0, 270, 5, 0.0, 1.0, 0.5);
  82. _rotary [R_FILT] = new Rlogctl (this, this, R_FILT, &r_filt_geom, x, 0, 200, 5, 0.50, 0.02, 0.1);
  83. _rotary [R_CORR] = new Rlinctl (this, this, R_CORR, &r_corr_geom, x, 0, 270, 5, 0.0, 1.0, 1.0);
  84. _rotary [R_OFFS] = new Rlinctl (this, this, R_OFFS, &r_offs_geom, x, 0, 400, 10, -2.0, 2.0, 0.0);
  85. for (i = 0; i < NROTARY; i++) _rotary [i]->x_map ();
  86. _textln = new X_textip (this, 0, &tstyle1, 0, 0, 50, 15, 15);
  87. _textln->set_align (0);
  88. _ttimer = 0;
  89. _notes = 0xFFF;
  90. x_add_events (ExposureMask);
  91. set_time (0);
  92. inc_time (500000);
  93. }
  94. Mainwin::~Mainwin (void)
  95. {
  96. RotaryCtl::fini ();
  97. }
  98. int Mainwin::process (void)
  99. {
  100. int e;
  101. if (_stop) handle_stop ();
  102. e = get_event_timed ();
  103. switch (e)
  104. {
  105. case EV_TIME:
  106. handle_time ();
  107. break;
  108. }
  109. return e;
  110. }
  111. void Mainwin::setdata_ui (float error, int noteset, int midiset)
  112. {
  113. z_error = error;
  114. z_noteset = noteset;
  115. z_midiset = midiset;
  116. }
  117. void Mainwin::setchan_ui (int chan)
  118. {
  119. char s [16];
  120. _midich = chan;
  121. if (_midich)
  122. {
  123. sprintf (s, "Ch %d\n", _midich);
  124. _bchan->set_text (s, 0);
  125. }
  126. else _bchan->set_text ("Omni", 0);
  127. }
  128. void Mainwin::setmask_ui (int mask)
  129. {
  130. _notes = mask;
  131. for (int i = 0; i < 12; i++)
  132. _bnote [i]->set_state ( (_notes & (1 << i)) != 0 ? 1 : 0 );
  133. }
  134. void Mainwin::handle_event (XEvent *E)
  135. {
  136. switch (E->type)
  137. {
  138. case Expose:
  139. expose ((XExposeEvent *) E);
  140. break;
  141. case ClientMessage:
  142. clmesg ((XClientMessageEvent *) E);
  143. break;
  144. }
  145. }
  146. void Mainwin::expose (XExposeEvent *E)
  147. {
  148. if (E->count) return;
  149. redraw ();
  150. }
  151. void Mainwin::clmesg (XClientMessageEvent *E)
  152. {
  153. if (E->message_type == _atom) _stop = true;
  154. }
  155. void Mainwin::handle_time (void)
  156. {
  157. int i, k, s;
  158. float v;
  159. v = z_error;
  160. _tmeter->update (v, v);
  161. k = z_noteset;
  162. for (i = 0; i < 12; i++)
  163. {
  164. s = _bnote [i]->state ();
  165. if (k & 1) s |= 2;
  166. else s &= ~2;
  167. _bnote [i]->set_state (s);
  168. k >>= 1;
  169. }
  170. k = z_midiset;
  171. if (k) _bmidi->set_state (_bmidi->state () | 1);
  172. else _bmidi->set_state (_bmidi->state () & ~1);
  173. if (_ttimer)
  174. {
  175. if (--_ttimer == 0) _textln->x_unmap ();
  176. }
  177. inc_time (5000);
  178. XFlush (dpy ());
  179. }
  180. void Mainwin::handle_stop (void)
  181. {
  182. put_event (EV_EXIT, 1);
  183. }
  184. void Mainwin::handle_callb (int type, X_window *W, XEvent *E)
  185. {
  186. PushButton *B;
  187. RotaryCtl *R;
  188. int k;
  189. float v;
  190. switch (type)
  191. {
  192. case X_callback::BUTTON | X_button::PRESS:
  193. {
  194. X_button *Z = (X_button *) W;
  195. XButtonEvent *X = (XButtonEvent *) E;
  196. switch (Z->cbid ())
  197. {
  198. case B_CHAN:
  199. switch (X->button)
  200. {
  201. case 1:
  202. case 4:
  203. setchan (1);
  204. break;
  205. case 3:
  206. case 5:
  207. setchan (-1);
  208. break;
  209. }
  210. break;
  211. }
  212. break;
  213. }
  214. case PushButton::PRESS:
  215. B = (PushButton *) W;
  216. k = B->cbind ();
  217. if (k < B_MIDI)
  218. {
  219. k = 1 << k;
  220. if (B->state () & 1) _notes |= k;
  221. else _notes &= ~k;
  222. _valuecb->noteMaskChangedCallback (_notes);
  223. }
  224. else if (k == B_MIDI)
  225. {
  226. _valuecb->noteMaskChangedCallback (-1);
  227. }
  228. break;
  229. case RotaryCtl::PRESS:
  230. R = (RotaryCtl *) W;
  231. k = R->cbind ();
  232. switch (k)
  233. {
  234. case R_TUNE:
  235. case R_OFFS:
  236. showval (k);
  237. break;
  238. }
  239. break;
  240. case RotaryCtl::DELTA:
  241. R = (RotaryCtl *) W;
  242. k = R->cbind ();
  243. switch (k)
  244. {
  245. case R_TUNE:
  246. v = _rotary [R_TUNE]->value ();
  247. _valuecb->valueChangedCallback (R_TUNE, v);
  248. showval (k);
  249. break;
  250. case R_BIAS:
  251. v = _rotary [R_BIAS]->value ();
  252. _valuecb->valueChangedCallback (R_BIAS, v);
  253. break;
  254. case R_FILT:
  255. v = _rotary [R_FILT]->value ();
  256. _valuecb->valueChangedCallback (R_FILT, v);
  257. break;
  258. case R_CORR:
  259. v = _rotary [R_CORR]->value ();
  260. _valuecb->valueChangedCallback (R_CORR, v);
  261. break;
  262. case R_OFFS:
  263. v = _rotary [R_OFFS]->value ();
  264. _valuecb->valueChangedCallback (R_OFFS, v);
  265. showval (k);
  266. break;
  267. }
  268. break;
  269. }
  270. }
  271. void Mainwin::setchan (int d)
  272. {
  273. char s [16];
  274. _midich += d;
  275. if (_midich < 0) _midich = 0;
  276. if (_midich > 16) _midich = 16;
  277. if (_midich)
  278. {
  279. sprintf (s, "Ch %d\n", _midich);
  280. _bchan->set_text (s, 0);
  281. }
  282. else _bchan->set_text ("Omni", 0);
  283. _valuecb->valueChangedCallback (NROTARY, _midich);
  284. }
  285. void Mainwin::showval (int k)
  286. {
  287. char s [16];
  288. switch (k)
  289. {
  290. case R_TUNE:
  291. sprintf (s, "%5.1lf", _rotary [R_TUNE]->value ());
  292. _textln->x_move (222, 58);
  293. break;
  294. case R_OFFS:
  295. sprintf (s, "%5.2lf", _rotary [R_OFFS]->value ());
  296. _textln->x_move (463, 58);
  297. break;
  298. }
  299. _textln->set_text (s);
  300. _textln->x_map ();
  301. _ttimer = 40;
  302. }
  303. void Mainwin::redraw (void)
  304. {
  305. int x;
  306. x = 80;
  307. XPutImage (dpy (), win (), dgc (), notesect_img, 0, 0, x, 0, 190, 75);
  308. x += 190;
  309. XPutImage (dpy (), win (), dgc (), ctrlsect_img, 0, 0, x, 0, 315, 75);
  310. }
  311. }