2 Copyright (C) 2003-2008 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.
19 // --------------------------------------------------------------------------------
23 #define __STDC_LIMIT_MACROS
27 #include <jack/jack.h>
50 struct Freq _freq
[13];
54 struct MTDM
* mtdm_new (double fsamp
)
59 struct MTDM
*retval
= (MTDM
*)malloc( sizeof(struct MTDM
) );
67 retval
->_freq
[0].f
= 4096;
68 retval
->_freq
[1].f
= 2048;
69 retval
->_freq
[2].f
= 3072;
70 retval
->_freq
[3].f
= 2560;
71 retval
->_freq
[4].f
= 2304;
72 retval
->_freq
[5].f
= 2176;
73 retval
->_freq
[6].f
= 1088;
74 retval
->_freq
[7].f
= 1312;
75 retval
->_freq
[8].f
= 1552;
76 retval
->_freq
[9].f
= 1800;
77 retval
->_freq
[10].f
= 3332;
78 retval
->_freq
[11].f
= 3586;
79 retval
->_freq
[12].f
= 3841;
80 retval
->_wlp
= 200.0f
/ fsamp
;
81 for (i
= 0, F
= retval
->_freq
; i
< 13; i
++, F
++) {
91 int mtdm_process (struct MTDM
*self
, size_t len
, float *ip
, float *op
)
94 float vip
, vop
, a
, c
, s
;
101 for (i
= 0, F
= self
->_freq
; i
< 13; i
++, F
++)
103 a
= 2 * (float) M_PI
* (F
->p
& 65535) / 65536.0;
107 vop
+= (i
? 0.01f
: 0.20f
) * s
;
112 if (++self
->_cnt
== 16)
114 for (i
= 0, F
= self
->_freq
; i
< 13; i
++, F
++)
116 F
->x1
+= self
->_wlp
* (F
->xa
- F
->x1
+ 1e-20);
117 F
->y1
+= self
->_wlp
* (F
->ya
- F
->y1
+ 1e-20);
118 F
->x2
+= self
->_wlp
* (F
->x1
- F
->x2
+ 1e-20);
119 F
->y2
+= self
->_wlp
* (F
->y1
- F
->y2
+ 1e-20);
120 F
->xa
= F
->ya
= 0.0f
;
129 int mtdm_resolve (struct MTDM
*self
)
133 struct Freq
*F
= self
->_freq
;
135 if (hypot (F
->x2
, F
->y2
) < 0.001) return -1;
136 d
= atan2 (F
->y2
, F
->x2
) / (2 * M_PI
);
137 if (self
->_inv
) d
+= 0.5;
138 if (d
> 0.5) d
-= 1.0;
139 f0
= self
->_freq
[0].f
;
142 for (i
= 0; i
< 12; i
++)
145 p
= atan2 (F
->y2
, F
->x2
) / (2 * M_PI
) - d
* F
->f
/ f0
;
146 if (self
->_inv
) p
+= 0.5;
149 k
= (int)(floor (p
+ 0.5));
151 if (e
> self
->_err
) self
->_err
= e
;
152 if (e
> 0.4) return 1;
161 void mtdm_invert (struct MTDM
*self
)
165 // --------------------------------------------------------------------------------
167 static struct MTDM
*mtdm
;
168 static jack_client_t
*jack_handle
;
169 static jack_port_t
*jack_capt
;
170 static jack_port_t
*jack_play
;
172 jack_latency_range_t capture_latency
= {UINT32_MAX
, UINT32_MAX
};
173 jack_latency_range_t playback_latency
= {UINT32_MAX
, UINT32_MAX
};
176 latency_cb (jack_latency_callback_mode_t mode
, void *arg
)
178 jack_latency_range_t range
;
180 range
.min
= range
.max
= 0;
182 if (mode
== JackCaptureLatency
) {
183 jack_port_set_latency_range (jack_play
, mode
, &range
);
184 jack_port_get_latency_range (jack_capt
, mode
, &range
);
185 if ((range
.min
!= capture_latency
.min
) || (range
.max
!= capture_latency
.max
)) {
186 capture_latency
= range
;
187 printf ("new capture latency: [%d, %d]\n", range
.min
, range
.max
);
190 jack_port_set_latency_range (jack_capt
, mode
, &range
);
191 jack_port_get_latency_range (jack_play
, mode
, &range
);
192 if ((range
.min
!= playback_latency
.min
) || (range
.max
!= playback_latency
.max
)) {
193 playback_latency
= range
;
194 printf ("new playback latency: [%d, %d]\n", range
.min
, range
.max
);
200 int jack_callback (jack_nframes_t nframes
, void *arg
)
204 ip
= (float *)(jack_port_get_buffer (jack_capt
, nframes
));
205 op
= (float *)(jack_port_get_buffer (jack_play
, nframes
));
206 mtdm_process (mtdm
, nframes
, ip
, op
);
210 int main (int ac
, char *av
[])
215 jack_handle
= jack_client_open ("jack_delay", JackNoStartServer
, &s
);
216 if (jack_handle
== 0)
218 fprintf (stderr
, "Can't connect to Jack, is the server running ?\n");
222 mtdm
= mtdm_new(jack_get_sample_rate(jack_handle
));
224 jack_set_process_callback (jack_handle
, jack_callback
, 0);
226 if (jack_set_latency_callback
)
227 jack_set_latency_callback (jack_handle
, latency_cb
, 0);
229 jack_capt
= jack_port_register (jack_handle
, "in", JACK_DEFAULT_AUDIO_TYPE
, JackPortIsInput
, 0);
230 jack_play
= jack_port_register (jack_handle
, "out", JACK_DEFAULT_AUDIO_TYPE
, JackPortIsOutput
, 0);
232 t
= 1000.0f
/ jack_get_sample_rate (jack_handle
);
234 if (jack_activate (jack_handle
))
236 fprintf(stderr
, "Can't activate Jack");
248 if (mtdm_resolve (mtdm
) < 0) printf ("Signal below threshold...\n");
251 jack_nframes_t systemic_latency
;
253 if (mtdm
->_err
> 0.3)
255 mtdm_invert ( mtdm
);
256 mtdm_resolve ( mtdm
);
258 systemic_latency
= (jack_nframes_t
) floor (mtdm
->_del
- (capture_latency
.max
+ playback_latency
.max
));
260 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", mtdm
->_del
, mtdm
->_del
* t
,
261 systemic_latency
, systemic_latency
/2);
262 if (mtdm
->_err
> 0.2) printf (" ??");
263 if (mtdm
->_inv
) printf (" Inv");
271 // --------------------------------------------------------------------------------