2
Copyright (C) 2010 Fons Adriaensen <fons@kokkinizita.net>
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.
25
#include <clthreads.h>
26
#include <clalsadrv.h>
29
// --------------------------------------------------------------------------------
51
int process (size_t len, float *inp, float *out);
53
void invert (void) { _inv ^= 1; }
54
int inv (void) { return _inv; }
55
double del (void) { return _del; }
56
double err (void) { return _err; }
68
MTDM::MTDM (void) : _cnt (0), _inv (0)
85
for (i = 0, F = _freq; i < 5; i++, F++)
94
int MTDM::process (size_t len, float *ip, float *op)
97
float vip, vop, a, c, s;
104
for (i = 0, F = _freq; i < 5; i++, F++)
106
a = 2 * (float) M_PI * (F->p & 65535) / 65536.0;
117
for (i = 0, F = _freq; i < 5; i++, F++)
119
F->xf += 1e-3f * (F->xa - F->xf + 1e-20);
120
F->yf += 1e-3f * (F->ya - F->yf + 1e-20);
121
F->xa = F->ya = 0.0f;
131
int MTDM::resolve (void)
137
if (hypot (F->xf, F->yf) < 0.01) return -1;
138
d = atan2 (F->yf, F->xf) / (2 * M_PI);
140
if (d > 0.5f) d -= 1.0f;
144
for (i = 0; i < 4; i++)
147
p = atan2 (F->yf, F->xf) / (2 * M_PI) - d * F->f / f0;
151
k = (int)(floor (p + 0.5));
153
if (e > _err) _err = e;
154
if (e > 0.4) return 1;
164
// --------------------------------------------------------------------------------
167
static char playdev [256];
168
static char captdev [256];
169
static unsigned long fsamp;
170
static unsigned long frsize;
171
static unsigned long nfrags;
175
class Audiothr : public P_thread
179
virtual void thr_main (void);
188
void Audiothr::thr_main (void)
193
ipbuf = new float [frsize];
194
opbuf = new float [frsize];
196
D = new Alsa_driver (playdev, captdev, 0, fsamp, frsize, nfrags);
199
fprintf (stderr, "Can't open ALSA device\n");
211
D->capt_init (frsize);
212
D->capt_chan (0, ipbuf, frsize);
213
D->capt_done (frsize);
215
mtdm.process (frsize, ipbuf, opbuf);
217
D->play_init (frsize);
218
D->play_chan (0, opbuf, frsize);
219
D->play_done (frsize);
230
// --------------------------------------------------------------------------------
233
int main (int ac, char *av [])
240
fprintf (stderr, "alsa-latency <playdev><captdev><fsamp><frsize><nfrags>\n");
244
strcpy (playdev, av [1]);
245
strcpy (captdev, av [2]);
246
fsamp = atoi (av [3]);
247
frsize = atoi (av [4]);
248
nfrags = atoi (av [5]);
250
if (A.thr_start (SCHED_FIFO, -50, 0x20000))
252
fprintf (stderr, "Can't run in RT mode, trying normal scheduling.\n");
253
if (A.thr_start (SCHED_OTHER, 0, 0x20000))
255
fprintf (stderr, "Can't start audio thread.\n");
265
if (mtdm.resolve () < 0) printf ("Signal below threshold...\n");
268
if (mtdm.err () > 0.3)
273
printf ("%10.3lf frames %10.3lf ms", mtdm.del (), mtdm.del () * t);
274
if (mtdm.err () > 0.2) printf (" ??");
275
if (mtdm.inv ()) printf (" Inv");
284
// --------------------------------------------------------------------------------