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.

247 lines
5.3KB

  1. /*
  2. Copyright (C) 2003 Fons Adriaensen <fons.adriaensen@skynet.be>
  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 <jack/jack.h>
  20. #ifdef WIN32
  21. #define M_PI 3.141562653
  22. #else
  23. #include <unistd.h>
  24. #endif
  25. class Freq
  26. {
  27. public:
  28. int p;
  29. int f;
  30. float a;
  31. float xa;
  32. float ya;
  33. float xf;
  34. float yf;
  35. };
  36. class MTDM
  37. {
  38. public:
  39. MTDM (void);
  40. int process (size_t len, float *inp, float *out);
  41. int resolve (void);
  42. void invert (void) { _inv ^= 1; }
  43. int inv (void) { return _inv; }
  44. double del (void) { return _del; }
  45. double err (void) { return _err; }
  46. private:
  47. double _del;
  48. double _err;
  49. int _cnt;
  50. int _inv;
  51. Freq _freq [5];
  52. };
  53. MTDM::MTDM (void) : _cnt (0), _inv (0)
  54. {
  55. int i;
  56. Freq *F;
  57. _freq [0].f = 4096;
  58. _freq [1].f = 512;
  59. _freq [2].f = 1088;
  60. _freq [3].f = 1544;
  61. _freq [4].f = 2049;
  62. _freq [0].a = 0.2f;
  63. _freq [1].a = 0.1f;
  64. _freq [2].a = 0.1f;
  65. _freq [3].a = 0.1f;
  66. _freq [4].a = 0.1f;
  67. for (i = 0, F = _freq; i < 5; i++, F++)
  68. {
  69. F->p = 128;
  70. F->xa = F->ya = 0.0f;
  71. F->xf = F->yf = 0.0f;
  72. }
  73. }
  74. int MTDM::process (size_t len, float *ip, float *op)
  75. {
  76. int i;
  77. float vip, vop, a, c, s;
  78. Freq *F;
  79. while (len--)
  80. {
  81. vop = 0.0f;
  82. vip = *ip++;
  83. for (i = 0, F = _freq; i < 5; i++, F++)
  84. {
  85. a = 2 * M_PI * (F->p & 0xFFFF) / 65536.0;
  86. F->p += F->f;
  87. c = cosf (a);
  88. s = -sinf (a);
  89. vop += F->a * s;
  90. F->xa += s * vip;
  91. F->ya += c * vip;
  92. }
  93. *op++ = vop;
  94. if (++_cnt == 16)
  95. {
  96. for (i = 0, F = _freq; i < 5; i++, F++)
  97. {
  98. F->xf += 1e-3f * (F->xa - F->xf + 1e-20);
  99. F->yf += 1e-3f * (F->ya - F->yf + 1e-20);
  100. F->xa = F->ya = 0.0f;
  101. }
  102. _cnt = 0;
  103. }
  104. }
  105. return 0;
  106. }
  107. int MTDM::resolve (void)
  108. {
  109. int i, k, m;
  110. double d, e, f0, p;
  111. Freq *F = _freq;
  112. if (hypot (F->xf, F->yf) < 0.01) return -1;
  113. d = atan2 (F->yf, F->xf) / (2 * M_PI);
  114. if (_inv) d += 0.5f;
  115. if (d > 0.5f) d -= 1.0f;
  116. f0 = _freq [0].f;
  117. m = 1;
  118. _err = 0.0;
  119. for (i = 0; i < 4; i++)
  120. {
  121. F++;
  122. p = atan2 (F->yf, F->xf) / (2 * M_PI) - d * F->f / f0;
  123. if (_inv) p += 0.5f;
  124. p -= floor (p);
  125. p *= 8;
  126. k = (int)(floor (p + 0.5));
  127. e = fabs (p - k);
  128. if (e > _err) _err = e;
  129. if (e > 0.4) return 1;
  130. d += m * (k & 7);
  131. m *= 8;
  132. }
  133. _del = 16 * d;
  134. return 0;
  135. }
  136. // --------------------------------------------------------------------------------
  137. static MTDM mtdm;
  138. static jack_client_t *jack_handle;
  139. static jack_port_t *jack_capt;
  140. static jack_port_t *jack_play;
  141. static void jack_shutdown (void *arg)
  142. {
  143. exit (1);
  144. }
  145. static int jack_callback (jack_nframes_t nframes, void *arg)
  146. {
  147. float *ip, *op;
  148. ip = (float *)(jack_port_get_buffer (jack_capt, nframes));
  149. op = (float *)(jack_port_get_buffer (jack_play, nframes));
  150. return mtdm.process (nframes, ip, op);;
  151. }
  152. int main (int ac, char *av [])
  153. {
  154. const char** ports;
  155. if ((jack_handle = jack_client_new ("jdelay")) == 0)
  156. {
  157. fprintf (stderr, "Can't connect to JACK\n");
  158. return 1;
  159. }
  160. jack_set_process_callback (jack_handle, jack_callback, 0);
  161. jack_on_shutdown (jack_handle, jack_shutdown, 0);
  162. jack_capt = jack_port_register (jack_handle, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
  163. jack_play = jack_port_register (jack_handle, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
  164. if (jack_activate (jack_handle))
  165. {
  166. fprintf(stderr, "Can't activate JACK");
  167. return 1;
  168. }
  169. if ((ports = jack_get_ports(jack_handle, NULL, NULL, JackPortIsPhysical | JackPortIsOutput)) == NULL) {
  170. printf("Cannot find any physical capture ports\n");
  171. } else {
  172. for (int i = 0; i < 8 && ports[i] ; i++) {
  173. jack_connect(jack_handle, ports[i], jack_port_name(jack_capt));
  174. }
  175. free(ports);
  176. }
  177. if ((ports = jack_get_ports(jack_handle, NULL, NULL, JackPortIsPhysical | JackPortIsInput)) == NULL) {
  178. printf("Cannot find any physical playback ports");
  179. } else {
  180. for (int i = 0; i < 8 && ports[i]; i++) {
  181. jack_connect(jack_handle, jack_port_name(jack_play), ports[i]);
  182. }
  183. free(ports);
  184. }
  185. while (1)
  186. {
  187. #ifdef WIN32
  188. Sleep (250);
  189. #else
  190. usleep (250000);
  191. #endif
  192. if (mtdm.resolve () < 0) printf ("Signal below threshold...\n");
  193. else
  194. {
  195. if (mtdm.err () > 0.3)
  196. {
  197. mtdm.invert ();
  198. mtdm.resolve ();
  199. }
  200. printf ("%10.3lf frames", mtdm.del ());
  201. if (mtdm.err () > 0.2) printf (" ??");
  202. if (mtdm.inv ()) printf (" Inv");
  203. printf ("\n");
  204. }
  205. }
  206. return 0;
  207. }