jack2 codebase
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.

258 lines
6.2KB

  1. /*
  2. Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. // --------------------------------------------------------------------------------
  16. #include <stdlib.h>
  17. #include <stdio.h>
  18. #include <math.h>
  19. #include <unistd.h>
  20. #include <jack/jack.h>
  21. class Freq
  22. {
  23. public:
  24. int p;
  25. int f;
  26. float a;
  27. float xa;
  28. float ya;
  29. float xf;
  30. float yf;
  31. };
  32. class MTDM
  33. {
  34. public:
  35. MTDM (void);
  36. int process (size_t len, float *inp, float *out);
  37. int resolve (void);
  38. void invert (void) { _inv ^= 1; }
  39. int inv (void) { return _inv; }
  40. double del (void) { return _del; }
  41. double err (void) { return _err; }
  42. double _del;
  43. double _err;
  44. int _cnt;
  45. int _inv;
  46. Freq _freq [5];
  47. };
  48. MTDM::MTDM (void) : _cnt (0), _inv (0)
  49. {
  50. int i;
  51. Freq *F;
  52. _freq [0].f = 4096;
  53. _freq [1].f = 512;
  54. _freq [2].f = 1088;
  55. _freq [3].f = 1544;
  56. _freq [4].f = 2049;
  57. _freq [0].a = 0.2f;
  58. _freq [1].a = 0.1f;
  59. _freq [2].a = 0.1f;
  60. _freq [3].a = 0.1f;
  61. _freq [4].a = 0.1f;
  62. for (i = 0, F = _freq; i < 5; i++, F++)
  63. {
  64. F->p = 128;
  65. F->xa = F->ya = 0.0f;
  66. F->xf = F->yf = 0.0f;
  67. }
  68. }
  69. int MTDM::process (size_t len, float *ip, float *op)
  70. {
  71. int i;
  72. float vip, vop, a, c, s;
  73. Freq *F;
  74. while (len--)
  75. {
  76. vop = 0.0f;
  77. vip = *ip++;
  78. for (i = 0, F = _freq; i < 5; i++, F++)
  79. {
  80. a = 2 * (float) M_PI * (F->p & 65535) / 65536.0;
  81. F->p += F->f;
  82. c = cosf (a);
  83. s = -sinf (a);
  84. vop += F->a * s;
  85. F->xa += s * vip;
  86. F->ya += c * vip;
  87. }
  88. *op++ = vop;
  89. if (++_cnt == 16)
  90. {
  91. for (i = 0, F = _freq; i < 5; i++, F++)
  92. {
  93. F->xf += 1e-3f * (F->xa - F->xf + 1e-20);
  94. F->yf += 1e-3f * (F->ya - F->yf + 1e-20);
  95. F->xa = F->ya = 0.0f;
  96. }
  97. _cnt = 0;
  98. }
  99. }
  100. return 0;
  101. }
  102. int MTDM::resolve (void)
  103. {
  104. int i, k, m;
  105. double d, e, f0, p;
  106. Freq *F = _freq;
  107. if (hypot (F->xf, F->yf) < 0.01) return -1;
  108. d = atan2 (F->yf, F->xf) / (2 * M_PI);
  109. if (_inv) d += 0.5f;
  110. if (d > 0.5f) d -= 1.0f;
  111. f0 = _freq [0].f;
  112. m = 1;
  113. _err = 0.0;
  114. for (i = 0; i < 4; i++)
  115. {
  116. F++;
  117. p = atan2 (F->yf, F->xf) / (2 * M_PI) - d * F->f / f0;
  118. if (_inv) p += 0.5f;
  119. p -= floor (p);
  120. p *= 8;
  121. k = (int)(floor (p + 0.5));
  122. e = fabs (p - k);
  123. if (e > _err) _err = e;
  124. if (e > 0.4) return 1;
  125. d += m * (k & 7);
  126. m *= 8;
  127. }
  128. _del = 16 * d;
  129. return 0;
  130. }
  131. // --------------------------------------------------------------------------------
  132. static MTDM mtdm;
  133. static jack_client_t *jack_handle;
  134. static jack_port_t *jack_capt;
  135. static jack_port_t *jack_play;
  136. jack_latency_range_t capture_latency = {-1, -1};
  137. jack_latency_range_t playback_latency = {-1, -1};
  138. void
  139. latency_cb (jack_latency_callback_mode_t mode, void *arg)
  140. {
  141. jack_latency_range_t range;
  142. range.min = range.max = 0;
  143. if (mode == JackCaptureLatency) {
  144. jack_port_set_latency_range (jack_play, mode, &range);
  145. jack_port_get_latency_range (jack_capt, mode, &range);
  146. if ((range.min != capture_latency.min) || (range.max != capture_latency.max)) {
  147. capture_latency = range;
  148. printf ("new capture latency: [%d, %d]\n", range.min, range.max);
  149. }
  150. } else {
  151. jack_port_set_latency_range (jack_capt, mode, &range);
  152. jack_port_get_latency_range (jack_play, mode, &range);
  153. if ((range.min != playback_latency.min) || (range.max != playback_latency.max)) {
  154. playback_latency = range;
  155. printf ("new playback latency: [%d, %d]\n", range.min, range.max);
  156. }
  157. }
  158. }
  159. int jack_callback (jack_nframes_t nframes, void *arg)
  160. {
  161. float *ip, *op;
  162. ip = (float *)(jack_port_get_buffer (jack_capt, nframes));
  163. op = (float *)(jack_port_get_buffer (jack_play, nframes));
  164. mtdm.process (nframes, ip, op);
  165. return 0;
  166. }
  167. int main (int ac, char *av [])
  168. {
  169. float t;
  170. jack_status_t s;
  171. jack_handle = jack_client_open ("jack_delay", JackNoStartServer, &s);
  172. if (jack_handle == 0)
  173. {
  174. fprintf (stderr, "Can't connect to Jack, is the server running ?\n");
  175. exit (1);
  176. }
  177. jack_set_process_callback (jack_handle, jack_callback, 0);
  178. if (jack_set_latency_callback)
  179. jack_set_latency_callback (jack_handle, latency_cb, 0);
  180. jack_capt = jack_port_register (jack_handle, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  181. jack_play = jack_port_register (jack_handle, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  182. t = 1000.0f / jack_get_sample_rate (jack_handle);
  183. if (jack_activate (jack_handle))
  184. {
  185. fprintf(stderr, "Can't activate Jack");
  186. return 1;
  187. }
  188. while (1)
  189. {
  190. #ifdef WIN32
  191. Sleep (250);
  192. #else
  193. usleep (250000);
  194. #endif
  195. if (mtdm.resolve() < 0) printf ("Signal below threshold...\n");
  196. else
  197. {
  198. jack_nframes_t systemic_latency;
  199. if (mtdm.err () > 0.3)
  200. {
  201. mtdm.invert ();
  202. mtdm.resolve ();
  203. }
  204. systemic_latency = (jack_nframes_t) floor (mtdm._del - (capture_latency.max + playback_latency.max));
  205. printf("%10.3lf frames %10.3lf ms total roundtrip latency\n\textra loopback latency: %u frames\n\tuse %u for the backend arguments -I and -O"
  206. , mtdm._del, mtdm._del * t,
  207. systemic_latency, systemic_latency/2);
  208. if (mtdm._err > 0.2) printf (" ??");
  209. if (mtdm._inv) printf (" Inv");
  210. printf ("\n");
  211. }
  212. }
  213. return 0;
  214. }
  215. // --------------------------------------------------------------------------------