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.

mainwin.cc 7.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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. 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. x_map ();
  92. set_time (0);
  93. inc_time (500000);
  94. }
  95. Mainwin::~Mainwin (void)
  96. {
  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::setchan_ui (int chan)
  112. {
  113. char s [16];
  114. _midich = chan;
  115. if (_midich)
  116. {
  117. sprintf (s, "Ch %d\n", _midich);
  118. _bchan->set_text (s, 0);
  119. }
  120. else _bchan->set_text ("Omni", 0);
  121. }
  122. void Mainwin::handle_event (XEvent *E)
  123. {
  124. switch (E->type)
  125. {
  126. case Expose:
  127. expose ((XExposeEvent *) E);
  128. break;
  129. case ClientMessage:
  130. clmesg ((XClientMessageEvent *) E);
  131. break;
  132. }
  133. }
  134. void Mainwin::expose (XExposeEvent *E)
  135. {
  136. if (E->count) return;
  137. redraw ();
  138. }
  139. void Mainwin::clmesg (XClientMessageEvent *E)
  140. {
  141. if (E->message_type == _atom) _stop = true;
  142. }
  143. void Mainwin::handle_time (void)
  144. {
  145. int i, k, s;
  146. float v;
  147. v = _jclient->retuner ()->get_error ();
  148. _tmeter->update (v, v);
  149. k = _jclient->retuner ()->get_noteset ();
  150. for (i = 0; i < 12; i++)
  151. {
  152. s = _bnote [i]->state ();
  153. if (k & 1) s |= 2;
  154. else s &= ~2;
  155. _bnote [i]->set_state (s);
  156. k >>= 1;
  157. }
  158. k = _jclient->get_midiset();
  159. if (k) _bmidi->set_state (_bmidi->state () | 1);
  160. else _bmidi->set_state (_bmidi->state () & ~1);
  161. if (_ttimer)
  162. {
  163. if (--_ttimer == 0) _textln->x_unmap ();
  164. }
  165. inc_time (50000);
  166. XFlush (dpy ());
  167. }
  168. void Mainwin::handle_stop (void)
  169. {
  170. put_event (EV_EXIT, 1);
  171. }
  172. void Mainwin::handle_callb (int type, X_window *W, XEvent *E)
  173. {
  174. PushButton *B;
  175. RotaryCtl *R;
  176. int k;
  177. float v;
  178. switch (type)
  179. {
  180. case X_callback::BUTTON | X_button::PRESS:
  181. {
  182. X_button *Z = (X_button *) W;
  183. XButtonEvent *X = (XButtonEvent *) E;
  184. switch (Z->cbid ())
  185. {
  186. case B_CHAN:
  187. switch (X->button)
  188. {
  189. case 1:
  190. case 4:
  191. setchan (1);
  192. break;
  193. case 3:
  194. case 5:
  195. setchan (-1);
  196. break;
  197. }
  198. break;
  199. }
  200. break;
  201. }
  202. case PushButton::PRESS:
  203. B = (PushButton *) W;
  204. k = B->cbind ();
  205. if (k < B_MIDI)
  206. {
  207. k = 1 << k;
  208. if (B->state () & 1) _notes |= k;
  209. else _notes &= ~k;
  210. _jclient->set_notemask (_notes);
  211. }
  212. else if (k == B_MIDI)
  213. {
  214. _jclient->clr_midimask ();
  215. }
  216. break;
  217. case RotaryCtl::PRESS:
  218. R = (RotaryCtl *) W;
  219. k = R->cbind ();
  220. switch (k)
  221. {
  222. case R_TUNE:
  223. case R_OFFS:
  224. showval (k);
  225. break;
  226. }
  227. break;
  228. case RotaryCtl::DELTA:
  229. R = (RotaryCtl *) W;
  230. k = R->cbind ();
  231. switch (k)
  232. {
  233. case R_TUNE:
  234. v = _rotary [R_TUNE]->value ();
  235. _jclient->retuner ()->set_refpitch (v);
  236. _valuecb->valueChangedCallback (R_TUNE, v);
  237. showval (k);
  238. break;
  239. case R_BIAS:
  240. v = _rotary [R_BIAS]->value ();
  241. _jclient->retuner ()->set_notebias (v);
  242. _valuecb->valueChangedCallback (R_BIAS, v);
  243. break;
  244. case R_FILT:
  245. v = _rotary [R_FILT]->value ();
  246. _jclient->retuner ()->set_corrfilt (v);
  247. _valuecb->valueChangedCallback (R_FILT, v);
  248. break;
  249. case R_CORR:
  250. v = _rotary [R_CORR]->value ();
  251. _jclient->retuner ()->set_corrgain (v);
  252. _valuecb->valueChangedCallback (R_CORR, v);
  253. break;
  254. case R_OFFS:
  255. v = _rotary [R_OFFS]->value ();
  256. _jclient->retuner ()->set_corroffs (v);
  257. _valuecb->valueChangedCallback (R_OFFS, v);
  258. showval (k);
  259. break;
  260. }
  261. break;
  262. }
  263. }
  264. void Mainwin::setchan (int d)
  265. {
  266. char s [16];
  267. _midich += d;
  268. if (_midich < 0) _midich = 0;
  269. if (_midich > 16) _midich = 16;
  270. if (_midich)
  271. {
  272. sprintf (s, "Ch %d\n", _midich);
  273. _bchan->set_text (s, 0);
  274. }
  275. else _bchan->set_text ("Omni", 0);
  276. _jclient->set_midichan (_midich - 1);
  277. _valuecb->valueChangedCallback (NROTARY, _midich);
  278. }
  279. void Mainwin::showval (int k)
  280. {
  281. char s [16];
  282. switch (k)
  283. {
  284. case R_TUNE:
  285. sprintf (s, "%5.1lf", _rotary [R_TUNE]->value ());
  286. _textln->x_move (222, 58);
  287. break;
  288. case R_OFFS:
  289. sprintf (s, "%5.2lf", _rotary [R_OFFS]->value ());
  290. _textln->x_move (463, 58);
  291. break;
  292. }
  293. _textln->set_text (s);
  294. _textln->x_map ();
  295. _ttimer = 40;
  296. }
  297. void Mainwin::redraw (void)
  298. {
  299. int x;
  300. x = 80;
  301. XPutImage (dpy (), win (), dgc (), notesect_img, 0, 0, x, 0, 190, 75);
  302. x += 190;
  303. XPutImage (dpy (), win (), dgc (), ctrlsect_img, 0, 0, x, 0, 315, 75);
  304. }
  305. }