Typo
[jack2.git] / tests / jdelay.cpp
blob3d23404f0343ac3583b5a85a73d5830fd93a8516
1 /*
2 Copyright (C) 2003 Fons Adriaensen <fons.adriaensen@skynet.be>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 // --------------------------------------------------------------------------------
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <math.h>
26 #ifdef WIN32
27 #include "jack.h"
28 #define M_PI 3.141562653
29 #else
30 #include <unistd.h>
31 #include <jack/jack.h>
32 #endif
34 class Freq
36 public:
38 int p;
39 int f;
40 float a;
41 float xa;
42 float ya;
43 float xf;
44 float yf;
48 class MTDM
50 public:
52 MTDM (void);
53 int process (size_t len, float *inp, float *out);
54 int resolve (void);
55 void invert (void) { _inv ^= 1; }
56 int inv (void) { return _inv; }
57 double del (void) { return _del; }
58 double err (void) { return _err; }
60 private:
62 double _del;
63 double _err;
64 int _cnt;
65 int _inv;
66 Freq _freq [5];
70 MTDM::MTDM (void) : _cnt (0), _inv (0)
72 int i;
73 Freq *F;
75 _freq [0].f = 4096;
76 _freq [1].f = 512;
77 _freq [2].f = 1088;
78 _freq [3].f = 1544;
79 _freq [4].f = 2049;
81 _freq [0].a = 0.2f;
82 _freq [1].a = 0.1f;
83 _freq [2].a = 0.1f;
84 _freq [3].a = 0.1f;
85 _freq [4].a = 0.1f;
87 for (i = 0, F = _freq; i < 5; i++, F++)
89 F->p = 128;
90 F->xa = F->ya = 0.0f;
91 F->xf = F->yf = 0.0f;
95 int MTDM::process (size_t len, float *ip, float *op)
97 int i;
98 float vip, vop, a, c, s;
99 Freq *F;
101 while (len--)
103 vop = 0.0f;
104 vip = *ip++;
105 for (i = 0, F = _freq; i < 5; i++, F++)
107 a = 2 * M_PI * (F->p & 0xFFFF) / 65536.0;
108 F->p += F->f;
109 c = cosf (a);
110 s = -sinf (a);
111 vop += F->a * s;
112 F->xa += s * vip;
113 F->ya += c * vip;
115 *op++ = vop;
116 if (++_cnt == 16)
118 for (i = 0, F = _freq; i < 5; i++, F++)
120 F->xf += 1e-3f * (F->xa - F->xf + 1e-20);
121 F->yf += 1e-3f * (F->ya - F->yf + 1e-20);
122 F->xa = F->ya = 0.0f;
124 _cnt = 0;
128 return 0;
131 int MTDM::resolve (void)
133 int i, k, m;
134 double d, e, f0, p;
135 Freq *F = _freq;
137 if (hypot (F->xf, F->yf) < 0.01) return -1;
138 d = atan2 (F->yf, F->xf) / (2 * M_PI);
139 if (_inv) d += 0.5f;
140 if (d > 0.5f) d -= 1.0f;
141 f0 = _freq [0].f;
142 m = 1;
143 _err = 0.0;
144 for (i = 0; i < 4; i++)
146 F++;
147 p = atan2 (F->yf, F->xf) / (2 * M_PI) - d * F->f / f0;
148 if (_inv) p += 0.5f;
149 p -= floor (p);
150 p *= 8;
151 k = (int)(floor (p + 0.5));
152 e = fabs (p - k);
153 if (e > _err) _err = e;
154 if (e > 0.4) return 1;
155 d += m * (k & 7);
156 m *= 8;
158 _del = 16 * d;
160 return 0;
163 // --------------------------------------------------------------------------------
164 static MTDM mtdm;
165 static jack_client_t *jack_handle;
166 static jack_port_t *jack_capt;
167 static jack_port_t *jack_play;
169 static void jack_shutdown (void *arg)
171 exit (1);
174 static int jack_callback (jack_nframes_t nframes, void *arg)
176 float *ip, *op;
178 ip = (float *)(jack_port_get_buffer (jack_capt, nframes));
179 op = (float *)(jack_port_get_buffer (jack_play, nframes));
180 return mtdm.process (nframes, ip, op);;
183 int main (int ac, char *av [])
185 int i, k;
186 const char** ports;
188 if ((jack_handle = jack_client_new ("jdelay")) == 0)
190 fprintf (stderr, "Can't connect to JACK\n");
191 return 1;
194 jack_set_process_callback (jack_handle, jack_callback, 0);
195 jack_on_shutdown (jack_handle, jack_shutdown, 0);
196 jack_capt = jack_port_register (jack_handle, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
197 jack_play = jack_port_register (jack_handle, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
199 if (jack_activate (jack_handle))
201 fprintf(stderr, "Can't activate JACK");
202 return 1;
205 if ((ports = jack_get_ports(jack_handle, NULL, NULL, JackPortIsPhysical | JackPortIsOutput)) == NULL) {
206 printf("Cannot find any physical capture ports\n");
207 } else {
208 for (int i = 0; i < 8 && ports[i] ; i++) {
209 jack_connect(jack_handle, ports[i], jack_port_name(jack_capt));
211 free(ports);
214 if ((ports = jack_get_ports(jack_handle, NULL, NULL, JackPortIsPhysical | JackPortIsInput)) == NULL) {
215 printf("Cannot find any physical playback ports");
216 } else {
217 for (int i = 0; i < 8 && ports[i]; i++) {
218 jack_connect(jack_handle, jack_port_name(jack_play), ports[i]);
220 free(ports);
223 while (1)
225 #ifdef WIN32
226 Sleep (250);
227 #else
228 usleep (250000);
229 #endif
231 if (mtdm.resolve () < 0) printf ("Signal below threshold...\n");
232 else
234 if (mtdm.err () > 0.3)
236 mtdm.invert ();
237 mtdm.resolve ();
239 printf ("%10.3lf frames", mtdm.del ());
240 if (mtdm.err () > 0.2) printf (" ??");
241 if (mtdm.inv ()) printf (" Inv");
242 printf ("\n");
246 return 0;