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.

249 lines
5.4KB

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