It's only used in the JACK device.
Fixes linking shared lavd with JACK enabled.
... | ... |
@@ -13,7 +13,7 @@ OBJS-$(CONFIG_ALSA_OUTDEV) += alsa-audio-common.o \ |
13 | 13 |
OBJS-$(CONFIG_BKTR_INDEV) += bktr.o |
14 | 14 |
OBJS-$(CONFIG_DV1394_INDEV) += dv1394.o |
15 | 15 |
OBJS-$(CONFIG_FBDEV_INDEV) += fbdev.o |
16 |
-OBJS-$(CONFIG_JACK_INDEV) += jack_audio.o |
|
16 |
+OBJS-$(CONFIG_JACK_INDEV) += jack_audio.o timefilter.o |
|
17 | 17 |
OBJS-$(CONFIG_OSS_INDEV) += oss_audio.o |
18 | 18 |
OBJS-$(CONFIG_OSS_OUTDEV) += oss_audio.o |
19 | 19 |
OBJS-$(CONFIG_SNDIO_INDEV) += sndio_common.o sndio_dec.o |
... | ... |
@@ -30,4 +30,6 @@ OBJS-$(CONFIG_LIBDC1394_INDEV) += libdc1394.o |
30 | 30 |
SKIPHEADERS-$(HAVE_ALSA_ASOUNDLIB_H) += alsa-audio.h |
31 | 31 |
SKIPHEADERS-$(HAVE_SNDIO_H) += sndio_common.h |
32 | 32 |
|
33 |
+TESTPROGS = timefilter |
|
34 |
+ |
|
33 | 35 |
include $(SRC_PATH)/subdir.mak |
36 | 36 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,151 @@ |
0 |
+/* |
|
1 |
+ * Delay Locked Loop based time filter |
|
2 |
+ * Copyright (c) 2009 Samalyse |
|
3 |
+ * Copyright (c) 2009 Michael Niedermayer |
|
4 |
+ * Author: Olivier Guilyardi <olivier samalyse com> |
|
5 |
+ * Michael Niedermayer <michaelni gmx at> |
|
6 |
+ * |
|
7 |
+ * This file is part of Libav. |
|
8 |
+ * |
|
9 |
+ * Libav is free software; you can redistribute it and/or |
|
10 |
+ * modify it under the terms of the GNU Lesser General Public |
|
11 |
+ * License as published by the Free Software Foundation; either |
|
12 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
13 |
+ * |
|
14 |
+ * Libav is distributed in the hope that it will be useful, |
|
15 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
17 |
+ * Lesser General Public License for more details. |
|
18 |
+ * |
|
19 |
+ * You should have received a copy of the GNU Lesser General Public |
|
20 |
+ * License along with Libav; if not, write to the Free Software |
|
21 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
22 |
+ */ |
|
23 |
+ |
|
24 |
+ |
|
25 |
+#include "config.h" |
|
26 |
+#include "timefilter.h" |
|
27 |
+#include "libavutil/mem.h" |
|
28 |
+ |
|
29 |
+struct TimeFilter { |
|
30 |
+ /// Delay Locked Loop data. These variables refer to mathematical |
|
31 |
+ /// concepts described in: http://www.kokkinizita.net/papers/usingdll.pdf |
|
32 |
+ double cycle_time; |
|
33 |
+ double feedback2_factor; |
|
34 |
+ double feedback3_factor; |
|
35 |
+ double clock_period; |
|
36 |
+ int count; |
|
37 |
+}; |
|
38 |
+ |
|
39 |
+TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor) |
|
40 |
+{ |
|
41 |
+ TimeFilter *self = av_mallocz(sizeof(TimeFilter)); |
|
42 |
+ self->clock_period = clock_period; |
|
43 |
+ self->feedback2_factor = feedback2_factor; |
|
44 |
+ self->feedback3_factor = feedback3_factor; |
|
45 |
+ return self; |
|
46 |
+} |
|
47 |
+ |
|
48 |
+void ff_timefilter_destroy(TimeFilter *self) |
|
49 |
+{ |
|
50 |
+ av_freep(&self); |
|
51 |
+} |
|
52 |
+ |
|
53 |
+void ff_timefilter_reset(TimeFilter *self) |
|
54 |
+{ |
|
55 |
+ self->count = 0; |
|
56 |
+} |
|
57 |
+ |
|
58 |
+double ff_timefilter_update(TimeFilter *self, double system_time, double period) |
|
59 |
+{ |
|
60 |
+ self->count++; |
|
61 |
+ if (self->count==1) { |
|
62 |
+ /// init loop |
|
63 |
+ self->cycle_time = system_time; |
|
64 |
+ } else { |
|
65 |
+ double loop_error; |
|
66 |
+ self->cycle_time += self->clock_period * period; |
|
67 |
+ /// calculate loop error |
|
68 |
+ loop_error = system_time - self->cycle_time; |
|
69 |
+ |
|
70 |
+ /// update loop |
|
71 |
+ self->cycle_time += FFMAX(self->feedback2_factor, 1.0/(self->count)) * loop_error; |
|
72 |
+ self->clock_period += self->feedback3_factor * loop_error / period; |
|
73 |
+ } |
|
74 |
+ return self->cycle_time; |
|
75 |
+} |
|
76 |
+ |
|
77 |
+#ifdef TEST |
|
78 |
+#include "libavutil/lfg.h" |
|
79 |
+#define LFG_MAX ((1LL << 32) - 1) |
|
80 |
+ |
|
81 |
+#undef printf |
|
82 |
+ |
|
83 |
+int main(void) |
|
84 |
+{ |
|
85 |
+ AVLFG prng; |
|
86 |
+ double n0,n1; |
|
87 |
+#define SAMPLES 1000 |
|
88 |
+ double ideal[SAMPLES]; |
|
89 |
+ double samples[SAMPLES]; |
|
90 |
+#if 1 |
|
91 |
+ for(n0= 0; n0<40; n0=2*n0+1){ |
|
92 |
+ for(n1= 0; n1<10; n1=2*n1+1){ |
|
93 |
+#else |
|
94 |
+ {{ |
|
95 |
+ n0=7; |
|
96 |
+ n1=1; |
|
97 |
+#endif |
|
98 |
+ double best_error= 1000000000; |
|
99 |
+ double bestpar0=1; |
|
100 |
+ double bestpar1=0.001; |
|
101 |
+ int better, i; |
|
102 |
+ |
|
103 |
+ av_lfg_init(&prng, 123); |
|
104 |
+ for(i=0; i<SAMPLES; i++){ |
|
105 |
+ ideal[i] = 10 + i + n1*i/(1000); |
|
106 |
+ samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2) |
|
107 |
+ / (LFG_MAX * 10LL); |
|
108 |
+ } |
|
109 |
+ |
|
110 |
+ do{ |
|
111 |
+ double par0, par1; |
|
112 |
+ better=0; |
|
113 |
+ for(par0= bestpar0*0.8; par0<=bestpar0*1.21; par0+=bestpar0*0.05){ |
|
114 |
+ for(par1= bestpar1*0.8; par1<=bestpar1*1.21; par1+=bestpar1*0.05){ |
|
115 |
+ double error=0; |
|
116 |
+ TimeFilter *tf= ff_timefilter_new(1, par0, par1); |
|
117 |
+ for(i=0; i<SAMPLES; i++){ |
|
118 |
+ double filtered; |
|
119 |
+ filtered= ff_timefilter_update(tf, samples[i], 1); |
|
120 |
+ error += (filtered - ideal[i]) * (filtered - ideal[i]); |
|
121 |
+ } |
|
122 |
+ ff_timefilter_destroy(tf); |
|
123 |
+ if(error < best_error){ |
|
124 |
+ best_error= error; |
|
125 |
+ bestpar0= par0; |
|
126 |
+ bestpar1= par1; |
|
127 |
+ better=1; |
|
128 |
+ } |
|
129 |
+ } |
|
130 |
+ } |
|
131 |
+ }while(better); |
|
132 |
+#if 0 |
|
133 |
+ double lastfil=9; |
|
134 |
+ TimeFilter *tf= ff_timefilter_new(1, bestpar0, bestpar1); |
|
135 |
+ for(i=0; i<SAMPLES; i++){ |
|
136 |
+ double filtered; |
|
137 |
+ filtered= ff_timefilter_update(tf, samples[i], 1); |
|
138 |
+ printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], samples[FFMAX(i, 1)] - samples[FFMAX(i-1, 0)], filtered - lastfil); |
|
139 |
+ lastfil= filtered; |
|
140 |
+ } |
|
141 |
+ ff_timefilter_destroy(tf); |
|
142 |
+#else |
|
143 |
+ printf(" [%f %f %9f]", bestpar0, bestpar1, best_error); |
|
144 |
+#endif |
|
145 |
+ } |
|
146 |
+ printf("\n"); |
|
147 |
+ } |
|
148 |
+ return 0; |
|
149 |
+} |
|
150 |
+#endif |
0 | 151 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,97 @@ |
0 |
+/* |
|
1 |
+ * Delay Locked Loop based time filter prototypes and declarations |
|
2 |
+ * Copyright (c) 2009 Samalyse |
|
3 |
+ * Copyright (c) 2009 Michael Niedermayer |
|
4 |
+ * Author: Olivier Guilyardi <olivier samalyse com> |
|
5 |
+ * Michael Niedermayer <michaelni gmx at> |
|
6 |
+ * |
|
7 |
+ * This file is part of Libav. |
|
8 |
+ * |
|
9 |
+ * Libav is free software; you can redistribute it and/or |
|
10 |
+ * modify it under the terms of the GNU Lesser General Public |
|
11 |
+ * License as published by the Free Software Foundation; either |
|
12 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
13 |
+ * |
|
14 |
+ * Libav is distributed in the hope that it will be useful, |
|
15 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
16 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
17 |
+ * Lesser General Public License for more details. |
|
18 |
+ * |
|
19 |
+ * You should have received a copy of the GNU Lesser General Public |
|
20 |
+ * License along with Libav; if not, write to the Free Software |
|
21 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
22 |
+ */ |
|
23 |
+ |
|
24 |
+#ifndef AVDEVICE_TIMEFILTER_H |
|
25 |
+#define AVDEVICE_TIMEFILTER_H |
|
26 |
+ |
|
27 |
+/** |
|
28 |
+ * Opaque type representing a time filter state |
|
29 |
+ * |
|
30 |
+ * The purpose of this filter is to provide a way to compute accurate time |
|
31 |
+ * stamps that can be compared to wall clock time, especially when dealing |
|
32 |
+ * with two clocks: the system clock and a hardware device clock, such as |
|
33 |
+ * a soundcard. |
|
34 |
+ */ |
|
35 |
+typedef struct TimeFilter TimeFilter; |
|
36 |
+ |
|
37 |
+ |
|
38 |
+/** |
|
39 |
+ * Create a new Delay Locked Loop time filter |
|
40 |
+ * |
|
41 |
+ * feedback2_factor and feedback3_factor are the factors used for the |
|
42 |
+ * multiplications that are respectively performed in the second and third |
|
43 |
+ * feedback paths of the loop. |
|
44 |
+ * |
|
45 |
+ * Unless you know what you are doing, you should set these as follow: |
|
46 |
+ * |
|
47 |
+ * o = 2 * M_PI * bandwidth * period |
|
48 |
+ * feedback2_factor = sqrt(2 * o) |
|
49 |
+ * feedback3_factor = o * o |
|
50 |
+ * |
|
51 |
+ * Where bandwidth is up to you to choose. Smaller values will filter out more |
|
52 |
+ * of the jitter, but also take a longer time for the loop to settle. A good |
|
53 |
+ * starting point is something between 0.3 and 3 Hz. |
|
54 |
+ * |
|
55 |
+ * @param clock_period period of the hardware clock in seconds |
|
56 |
+ * (for example 1.0/44100) |
|
57 |
+ * |
|
58 |
+ * For more details about these parameters and background concepts please see: |
|
59 |
+ * http://www.kokkinizita.net/papers/usingdll.pdf |
|
60 |
+ */ |
|
61 |
+TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor); |
|
62 |
+ |
|
63 |
+/** |
|
64 |
+ * Update the filter |
|
65 |
+ * |
|
66 |
+ * This function must be called in real time, at each process cycle. |
|
67 |
+ * |
|
68 |
+ * @param period the device cycle duration in clock_periods. For example, at |
|
69 |
+ * 44.1kHz and a buffer size of 512 frames, period = 512 when clock_period |
|
70 |
+ * was 1.0/44100, or 512/44100 if clock_period was 1. |
|
71 |
+ * |
|
72 |
+ * system_time, in seconds, should be the value of the system clock time, |
|
73 |
+ * at (or as close as possible to) the moment the device hardware interrupt |
|
74 |
+ * occured (or any other event the device clock raises at the beginning of a |
|
75 |
+ * cycle). |
|
76 |
+ * |
|
77 |
+ * @return the filtered time, in seconds |
|
78 |
+ */ |
|
79 |
+double ff_timefilter_update(TimeFilter *self, double system_time, double period); |
|
80 |
+ |
|
81 |
+/** |
|
82 |
+ * Reset the filter |
|
83 |
+ * |
|
84 |
+ * This function should mainly be called in case of XRUN. |
|
85 |
+ * |
|
86 |
+ * Warning: after calling this, the filter is in an undetermined state until |
|
87 |
+ * the next call to ff_timefilter_update() |
|
88 |
+ */ |
|
89 |
+void ff_timefilter_reset(TimeFilter *); |
|
90 |
+ |
|
91 |
+/** |
|
92 |
+ * Free all resources associated with the filter |
|
93 |
+ */ |
|
94 |
+void ff_timefilter_destroy(TimeFilter *); |
|
95 |
+ |
|
96 |
+#endif /* AVDEVICE_TIMEFILTER_H */ |
... | ... |
@@ -334,11 +334,8 @@ OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o |
334 | 334 |
OBJS-$(CONFIG_TCP_PROTOCOL) += tcp.o |
335 | 335 |
OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o |
336 | 336 |
|
337 |
-# libavdevice dependencies |
|
338 |
-OBJS-$(CONFIG_JACK_INDEV) += timefilter.o |
|
339 |
- |
|
340 | 337 |
EXAMPLES = metadata output |
341 |
-TESTPROGS = seek timefilter |
|
338 |
+TESTPROGS = seek |
|
342 | 339 |
TOOLS = pktdumper probetest |
343 | 340 |
|
344 | 341 |
include $(SRC_PATH)/subdir.mak |
345 | 342 |
deleted file mode 100644 |
... | ... |
@@ -1,151 +0,0 @@ |
1 |
-/* |
|
2 |
- * Delay Locked Loop based time filter |
|
3 |
- * Copyright (c) 2009 Samalyse |
|
4 |
- * Copyright (c) 2009 Michael Niedermayer |
|
5 |
- * Author: Olivier Guilyardi <olivier samalyse com> |
|
6 |
- * Michael Niedermayer <michaelni gmx at> |
|
7 |
- * |
|
8 |
- * This file is part of Libav. |
|
9 |
- * |
|
10 |
- * Libav is free software; you can redistribute it and/or |
|
11 |
- * modify it under the terms of the GNU Lesser General Public |
|
12 |
- * License as published by the Free Software Foundation; either |
|
13 |
- * version 2.1 of the License, or (at your option) any later version. |
|
14 |
- * |
|
15 |
- * Libav is distributed in the hope that it will be useful, |
|
16 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
18 |
- * Lesser General Public License for more details. |
|
19 |
- * |
|
20 |
- * You should have received a copy of the GNU Lesser General Public |
|
21 |
- * License along with Libav; if not, write to the Free Software |
|
22 |
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
23 |
- */ |
|
24 |
- |
|
25 |
- |
|
26 |
-#include "config.h" |
|
27 |
-#include "avformat.h" |
|
28 |
-#include "timefilter.h" |
|
29 |
- |
|
30 |
-struct TimeFilter { |
|
31 |
- /// Delay Locked Loop data. These variables refer to mathematical |
|
32 |
- /// concepts described in: http://www.kokkinizita.net/papers/usingdll.pdf |
|
33 |
- double cycle_time; |
|
34 |
- double feedback2_factor; |
|
35 |
- double feedback3_factor; |
|
36 |
- double clock_period; |
|
37 |
- int count; |
|
38 |
-}; |
|
39 |
- |
|
40 |
-TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor) |
|
41 |
-{ |
|
42 |
- TimeFilter *self = av_mallocz(sizeof(TimeFilter)); |
|
43 |
- self->clock_period = clock_period; |
|
44 |
- self->feedback2_factor = feedback2_factor; |
|
45 |
- self->feedback3_factor = feedback3_factor; |
|
46 |
- return self; |
|
47 |
-} |
|
48 |
- |
|
49 |
-void ff_timefilter_destroy(TimeFilter *self) |
|
50 |
-{ |
|
51 |
- av_freep(&self); |
|
52 |
-} |
|
53 |
- |
|
54 |
-void ff_timefilter_reset(TimeFilter *self) |
|
55 |
-{ |
|
56 |
- self->count = 0; |
|
57 |
-} |
|
58 |
- |
|
59 |
-double ff_timefilter_update(TimeFilter *self, double system_time, double period) |
|
60 |
-{ |
|
61 |
- self->count++; |
|
62 |
- if (self->count==1) { |
|
63 |
- /// init loop |
|
64 |
- self->cycle_time = system_time; |
|
65 |
- } else { |
|
66 |
- double loop_error; |
|
67 |
- self->cycle_time += self->clock_period * period; |
|
68 |
- /// calculate loop error |
|
69 |
- loop_error = system_time - self->cycle_time; |
|
70 |
- |
|
71 |
- /// update loop |
|
72 |
- self->cycle_time += FFMAX(self->feedback2_factor, 1.0/(self->count)) * loop_error; |
|
73 |
- self->clock_period += self->feedback3_factor * loop_error / period; |
|
74 |
- } |
|
75 |
- return self->cycle_time; |
|
76 |
-} |
|
77 |
- |
|
78 |
-#ifdef TEST |
|
79 |
-#include "libavutil/lfg.h" |
|
80 |
-#define LFG_MAX ((1LL << 32) - 1) |
|
81 |
- |
|
82 |
-#undef printf |
|
83 |
- |
|
84 |
-int main(void) |
|
85 |
-{ |
|
86 |
- AVLFG prng; |
|
87 |
- double n0,n1; |
|
88 |
-#define SAMPLES 1000 |
|
89 |
- double ideal[SAMPLES]; |
|
90 |
- double samples[SAMPLES]; |
|
91 |
-#if 1 |
|
92 |
- for(n0= 0; n0<40; n0=2*n0+1){ |
|
93 |
- for(n1= 0; n1<10; n1=2*n1+1){ |
|
94 |
-#else |
|
95 |
- {{ |
|
96 |
- n0=7; |
|
97 |
- n1=1; |
|
98 |
-#endif |
|
99 |
- double best_error= 1000000000; |
|
100 |
- double bestpar0=1; |
|
101 |
- double bestpar1=0.001; |
|
102 |
- int better, i; |
|
103 |
- |
|
104 |
- av_lfg_init(&prng, 123); |
|
105 |
- for(i=0; i<SAMPLES; i++){ |
|
106 |
- ideal[i] = 10 + i + n1*i/(1000); |
|
107 |
- samples[i] = ideal[i] + n0 * (av_lfg_get(&prng) - LFG_MAX / 2) |
|
108 |
- / (LFG_MAX * 10LL); |
|
109 |
- } |
|
110 |
- |
|
111 |
- do{ |
|
112 |
- double par0, par1; |
|
113 |
- better=0; |
|
114 |
- for(par0= bestpar0*0.8; par0<=bestpar0*1.21; par0+=bestpar0*0.05){ |
|
115 |
- for(par1= bestpar1*0.8; par1<=bestpar1*1.21; par1+=bestpar1*0.05){ |
|
116 |
- double error=0; |
|
117 |
- TimeFilter *tf= ff_timefilter_new(1, par0, par1); |
|
118 |
- for(i=0; i<SAMPLES; i++){ |
|
119 |
- double filtered; |
|
120 |
- filtered= ff_timefilter_update(tf, samples[i], 1); |
|
121 |
- error += (filtered - ideal[i]) * (filtered - ideal[i]); |
|
122 |
- } |
|
123 |
- ff_timefilter_destroy(tf); |
|
124 |
- if(error < best_error){ |
|
125 |
- best_error= error; |
|
126 |
- bestpar0= par0; |
|
127 |
- bestpar1= par1; |
|
128 |
- better=1; |
|
129 |
- } |
|
130 |
- } |
|
131 |
- } |
|
132 |
- }while(better); |
|
133 |
-#if 0 |
|
134 |
- double lastfil=9; |
|
135 |
- TimeFilter *tf= ff_timefilter_new(1, bestpar0, bestpar1); |
|
136 |
- for(i=0; i<SAMPLES; i++){ |
|
137 |
- double filtered; |
|
138 |
- filtered= ff_timefilter_update(tf, samples[i], 1); |
|
139 |
- printf("%f %f %f %f\n", i - samples[i] + 10, filtered - samples[i], samples[FFMAX(i, 1)] - samples[FFMAX(i-1, 0)], filtered - lastfil); |
|
140 |
- lastfil= filtered; |
|
141 |
- } |
|
142 |
- ff_timefilter_destroy(tf); |
|
143 |
-#else |
|
144 |
- printf(" [%f %f %9f]", bestpar0, bestpar1, best_error); |
|
145 |
-#endif |
|
146 |
- } |
|
147 |
- printf("\n"); |
|
148 |
- } |
|
149 |
- return 0; |
|
150 |
-} |
|
151 |
-#endif |
152 | 1 |
deleted file mode 100644 |
... | ... |
@@ -1,97 +0,0 @@ |
1 |
-/* |
|
2 |
- * Delay Locked Loop based time filter prototypes and declarations |
|
3 |
- * Copyright (c) 2009 Samalyse |
|
4 |
- * Copyright (c) 2009 Michael Niedermayer |
|
5 |
- * Author: Olivier Guilyardi <olivier samalyse com> |
|
6 |
- * Michael Niedermayer <michaelni gmx at> |
|
7 |
- * |
|
8 |
- * This file is part of Libav. |
|
9 |
- * |
|
10 |
- * Libav is free software; you can redistribute it and/or |
|
11 |
- * modify it under the terms of the GNU Lesser General Public |
|
12 |
- * License as published by the Free Software Foundation; either |
|
13 |
- * version 2.1 of the License, or (at your option) any later version. |
|
14 |
- * |
|
15 |
- * Libav is distributed in the hope that it will be useful, |
|
16 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
17 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
18 |
- * Lesser General Public License for more details. |
|
19 |
- * |
|
20 |
- * You should have received a copy of the GNU Lesser General Public |
|
21 |
- * License along with Libav; if not, write to the Free Software |
|
22 |
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
23 |
- */ |
|
24 |
- |
|
25 |
-#ifndef AVFORMAT_TIMEFILTER_H |
|
26 |
-#define AVFORMAT_TIMEFILTER_H |
|
27 |
- |
|
28 |
-/** |
|
29 |
- * Opaque type representing a time filter state |
|
30 |
- * |
|
31 |
- * The purpose of this filter is to provide a way to compute accurate time |
|
32 |
- * stamps that can be compared to wall clock time, especially when dealing |
|
33 |
- * with two clocks: the system clock and a hardware device clock, such as |
|
34 |
- * a soundcard. |
|
35 |
- */ |
|
36 |
-typedef struct TimeFilter TimeFilter; |
|
37 |
- |
|
38 |
- |
|
39 |
-/** |
|
40 |
- * Create a new Delay Locked Loop time filter |
|
41 |
- * |
|
42 |
- * feedback2_factor and feedback3_factor are the factors used for the |
|
43 |
- * multiplications that are respectively performed in the second and third |
|
44 |
- * feedback paths of the loop. |
|
45 |
- * |
|
46 |
- * Unless you know what you are doing, you should set these as follow: |
|
47 |
- * |
|
48 |
- * o = 2 * M_PI * bandwidth * period |
|
49 |
- * feedback2_factor = sqrt(2 * o) |
|
50 |
- * feedback3_factor = o * o |
|
51 |
- * |
|
52 |
- * Where bandwidth is up to you to choose. Smaller values will filter out more |
|
53 |
- * of the jitter, but also take a longer time for the loop to settle. A good |
|
54 |
- * starting point is something between 0.3 and 3 Hz. |
|
55 |
- * |
|
56 |
- * @param clock_period period of the hardware clock in seconds |
|
57 |
- * (for example 1.0/44100) |
|
58 |
- * |
|
59 |
- * For more details about these parameters and background concepts please see: |
|
60 |
- * http://www.kokkinizita.net/papers/usingdll.pdf |
|
61 |
- */ |
|
62 |
-TimeFilter * ff_timefilter_new(double clock_period, double feedback2_factor, double feedback3_factor); |
|
63 |
- |
|
64 |
-/** |
|
65 |
- * Update the filter |
|
66 |
- * |
|
67 |
- * This function must be called in real time, at each process cycle. |
|
68 |
- * |
|
69 |
- * @param period the device cycle duration in clock_periods. For example, at |
|
70 |
- * 44.1kHz and a buffer size of 512 frames, period = 512 when clock_period |
|
71 |
- * was 1.0/44100, or 512/44100 if clock_period was 1. |
|
72 |
- * |
|
73 |
- * system_time, in seconds, should be the value of the system clock time, |
|
74 |
- * at (or as close as possible to) the moment the device hardware interrupt |
|
75 |
- * occured (or any other event the device clock raises at the beginning of a |
|
76 |
- * cycle). |
|
77 |
- * |
|
78 |
- * @return the filtered time, in seconds |
|
79 |
- */ |
|
80 |
-double ff_timefilter_update(TimeFilter *self, double system_time, double period); |
|
81 |
- |
|
82 |
-/** |
|
83 |
- * Reset the filter |
|
84 |
- * |
|
85 |
- * This function should mainly be called in case of XRUN. |
|
86 |
- * |
|
87 |
- * Warning: after calling this, the filter is in an undetermined state until |
|
88 |
- * the next call to ff_timefilter_update() |
|
89 |
- */ |
|
90 |
-void ff_timefilter_reset(TimeFilter *); |
|
91 |
- |
|
92 |
-/** |
|
93 |
- * Free all resources associated with the filter |
|
94 |
- */ |
|
95 |
-void ff_timefilter_destroy(TimeFilter *); |
|
96 |
- |
|
97 |
-#endif /* AVFORMAT_TIMEFILTER_H */ |