1 /***
2 This file is part of PulseAudio.
3
4 Copyright 2004-2006 Lennart Poettering
5
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2.1 of the License,
9 or (at your option) any later version.
10
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <string.h>
25 #include <math.h>
26
27 #include <pulse/xmalloc.h>
28 #include <pulse/timeval.h>
29 #include <pulsecore/log.h>
30 #include <pulsecore/macro.h>
31 #include <pulsecore/strbuf.h>
32 #include <pulsecore/core-util.h>
33
34 #include "resampler.h"
35 #include "downmix.h"
36 #include "resampleLoader.h"
37
38 /* Number of samples of extra space we allow the resamplers to return */
39 #define EXTRA_FRAMES 128
40 #define RESAMPLER_CACHE_SIZE_RATIO 20
41
42 struct ffmpeg_data { /* data specific to ffmpeg */
43 struct AVResampleContext *state;
44 };
45
46 static int copy_init(pa_resampler *r);
47 static int (*ProResamlerInit) (pa_resampler *r) = NULL;
48
49 static void setup_remap(const pa_resampler *r, pa_remap_t *m, bool *lfe_remixed);
50 static void free_remap(pa_remap_t *m);
51
52 static int (* const init_table[])(pa_resampler *r) = {
53 #ifdef HAVE_LIBSAMPLERATE
54 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = pa_resampler_libsamplerate_init,
55 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = pa_resampler_libsamplerate_init,
56 [PA_RESAMPLER_SRC_SINC_FASTEST] = pa_resampler_libsamplerate_init,
57 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = pa_resampler_libsamplerate_init,
58 [PA_RESAMPLER_SRC_LINEAR] = pa_resampler_libsamplerate_init,
59 #else
60 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = NULL,
61 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = NULL,
62 [PA_RESAMPLER_SRC_SINC_FASTEST] = NULL,
63 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = NULL,
64 [PA_RESAMPLER_SRC_LINEAR] = NULL,
65 #endif
66 [PA_RESAMPLER_TRIVIAL] = pa_resampler_trivial_init,
67 #ifdef HAVE_SPEEX
68 [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = pa_resampler_speex_init,
69 [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = pa_resampler_speex_init,
70 [PA_RESAMPLER_SPEEX_FLOAT_BASE+2] = pa_resampler_speex_init,
71 [PA_RESAMPLER_SPEEX_FLOAT_BASE+3] = pa_resampler_speex_init,
72 [PA_RESAMPLER_SPEEX_FLOAT_BASE+4] = pa_resampler_speex_init,
73 [PA_RESAMPLER_SPEEX_FLOAT_BASE+5] = pa_resampler_speex_init,
74 [PA_RESAMPLER_SPEEX_FLOAT_BASE+6] = pa_resampler_speex_init,
75 [PA_RESAMPLER_SPEEX_FLOAT_BASE+7] = pa_resampler_speex_init,
76 [PA_RESAMPLER_SPEEX_FLOAT_BASE+8] = pa_resampler_speex_init,
77 [PA_RESAMPLER_SPEEX_FLOAT_BASE+9] = pa_resampler_speex_init,
78 [PA_RESAMPLER_SPEEX_FLOAT_BASE+10] = pa_resampler_speex_init,
79 [PA_RESAMPLER_SPEEX_FIXED_BASE+0] = pa_resampler_speex_init,
80 [PA_RESAMPLER_SPEEX_FIXED_BASE+1] = pa_resampler_speex_init,
81 [PA_RESAMPLER_SPEEX_FIXED_BASE+2] = pa_resampler_speex_init,
82 [PA_RESAMPLER_SPEEX_FIXED_BASE+3] = pa_resampler_speex_init,
83 [PA_RESAMPLER_SPEEX_FIXED_BASE+4] = pa_resampler_speex_init,
84 [PA_RESAMPLER_SPEEX_FIXED_BASE+5] = pa_resampler_speex_init,
85 [PA_RESAMPLER_SPEEX_FIXED_BASE+6] = pa_resampler_speex_init,
86 [PA_RESAMPLER_SPEEX_FIXED_BASE+7] = pa_resampler_speex_init,
87 [PA_RESAMPLER_SPEEX_FIXED_BASE+8] = pa_resampler_speex_init,
88 [PA_RESAMPLER_SPEEX_FIXED_BASE+9] = pa_resampler_speex_init,
89 [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = pa_resampler_speex_init,
90 #else
91 [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = NULL,
92 [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = NULL,
93 [PA_RESAMPLER_SPEEX_FLOAT_BASE+2] = NULL,
94 [PA_RESAMPLER_SPEEX_FLOAT_BASE+3] = NULL,
95 [PA_RESAMPLER_SPEEX_FLOAT_BASE+4] = NULL,
96 [PA_RESAMPLER_SPEEX_FLOAT_BASE+5] = NULL,
97 [PA_RESAMPLER_SPEEX_FLOAT_BASE+6] = NULL,
98 [PA_RESAMPLER_SPEEX_FLOAT_BASE+7] = NULL,
99 [PA_RESAMPLER_SPEEX_FLOAT_BASE+8] = NULL,
100 [PA_RESAMPLER_SPEEX_FLOAT_BASE+9] = NULL,
101 [PA_RESAMPLER_SPEEX_FLOAT_BASE+10] = NULL,
102 [PA_RESAMPLER_SPEEX_FIXED_BASE+0] = NULL,
103 [PA_RESAMPLER_SPEEX_FIXED_BASE+1] = NULL,
104 [PA_RESAMPLER_SPEEX_FIXED_BASE+2] = NULL,
105 [PA_RESAMPLER_SPEEX_FIXED_BASE+3] = NULL,
106 [PA_RESAMPLER_SPEEX_FIXED_BASE+4] = NULL,
107 [PA_RESAMPLER_SPEEX_FIXED_BASE+5] = NULL,
108 [PA_RESAMPLER_SPEEX_FIXED_BASE+6] = NULL,
109 [PA_RESAMPLER_SPEEX_FIXED_BASE+7] = NULL,
110 [PA_RESAMPLER_SPEEX_FIXED_BASE+8] = NULL,
111 [PA_RESAMPLER_SPEEX_FIXED_BASE+9] = NULL,
112 [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = NULL,
113 #endif
114 [PA_RESAMPLER_FFMPEG] = pa_resampler_ffmpeg_init,
115 [PA_RESAMPLER_AUTO] = NULL,
116 [PA_RESAMPLER_COPY] = copy_init,
117 [PA_RESAMPLER_PEAKS] = pa_resampler_peaks_init,
118 #ifdef HAVE_SOXR
119 [PA_RESAMPLER_SOXR_MQ] = pa_resampler_soxr_init,
120 [PA_RESAMPLER_SOXR_HQ] = pa_resampler_soxr_init,
121 [PA_RESAMPLER_SOXR_VHQ] = pa_resampler_soxr_init,
122 #else
123 [PA_RESAMPLER_SOXR_MQ] = NULL,
124 [PA_RESAMPLER_SOXR_HQ] = NULL,
125 [PA_RESAMPLER_SOXR_VHQ] = NULL,
126 #endif
127 };
128
calculate_gcd(pa_resampler * r)129 static void calculate_gcd(pa_resampler *r) {
130 unsigned gcd, n;
131
132 pa_assert(r);
133
134 gcd = r->i_ss.rate;
135 n = r->o_ss.rate;
136
137 while (n != 0) {
138 unsigned tmp = gcd;
139
140 gcd = n;
141 n = tmp % n;
142 }
143
144 r->gcd = gcd;
145 }
146
choose_auto_resampler(pa_resample_flags_t flags,const uint32_t rate_a,const uint32_t rate_b)147 static pa_resample_method_t choose_auto_resampler(pa_resample_flags_t flags,
148 const uint32_t rate_a, const uint32_t rate_b) {
149 pa_resample_method_t method;
150 if (pa_resample_method_supported(PA_PRORESAMPLER_BASE + 1) && (rate_a != rate_b) &&
151 LoadProResampler(&ProResamlerInit)) {
152 method = PA_PRORESAMPLER_BASE + 1;
153 } else if (pa_resample_method_supported(PA_RESAMPLER_SPEEX_FLOAT_BASE + 1) && (rate_a != rate_b)) {
154 method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 1;
155 } else {
156 method = PA_RESAMPLER_TRIVIAL;
157 }
158
159 return method;
160 }
161
fix_method(pa_resample_flags_t flags,pa_resample_method_t method,const uint32_t rate_a,const uint32_t rate_b)162 static pa_resample_method_t fix_method(
163 pa_resample_flags_t flags,
164 pa_resample_method_t method,
165 const uint32_t rate_a,
166 const uint32_t rate_b) {
167
168 pa_assert(pa_sample_rate_valid(rate_a));
169 pa_assert(pa_sample_rate_valid(rate_b));
170 pa_assert(method >= 0);
171 pa_assert(method < PA_RESAMPLER_MAX);
172
173 if (!(flags & PA_RESAMPLER_VARIABLE_RATE) && rate_a == rate_b) {
174 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
175 method = PA_RESAMPLER_COPY;
176 }
177
178 if (!pa_resample_method_supported(method)) {
179 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method));
180 method = PA_RESAMPLER_AUTO;
181 }
182
183 switch (method) {
184 case PA_RESAMPLER_COPY:
185 if (rate_a != rate_b) {
186 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
187 method = PA_RESAMPLER_AUTO;
188 break;
189 }
190 /* Else fall through */
191 case PA_RESAMPLER_FFMPEG:
192 if (flags & PA_RESAMPLER_VARIABLE_RATE) {
193 pa_log_info("Resampler '%s' cannot do variable rate, reverting to resampler 'auto'.", pa_resample_method_to_string(method));
194 method = PA_RESAMPLER_AUTO;
195 }
196 break;
197
198 /* The Peaks resampler only supports downsampling.
199 * Revert to auto if we are upsampling */
200 case PA_RESAMPLER_PEAKS:
201 if (rate_a < rate_b) {
202 pa_log_warn("The 'peaks' resampler only supports downsampling, reverting to resampler 'auto'.");
203 method = PA_RESAMPLER_AUTO;
204 }
205 break;
206
207 default:
208 break;
209 }
210
211 if (method == PA_RESAMPLER_AUTO)
212 method = choose_auto_resampler(flags, rate_a, rate_b);
213
214 #ifdef HAVE_SPEEX
215 /* At this point, method is supported in the sense that it
216 * has an init function and supports the required flags. However,
217 * speex-float implementation in PulseAudio relies on the
218 * assumption that is invalid if speex has been compiled with
219 * --enable-fixed-point. Besides, speex-fixed is more efficient
220 * in this configuration. So use it instead.
221 */
222 if (method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && method <= PA_RESAMPLER_SPEEX_FLOAT_MAX) {
223 if (pa_speex_is_fixed_point()) {
224 pa_log_info("Speex appears to be compiled with --enable-fixed-point. "
225 "Switching to a fixed-point resampler because it should be faster.");
226 method = method - PA_RESAMPLER_SPEEX_FLOAT_BASE + PA_RESAMPLER_SPEEX_FIXED_BASE;
227 }
228 }
229 #endif
230
231 return method;
232 }
233
234 /* Return true if a is a more precise sample format than b, else return false */
sample_format_more_precise(pa_sample_format_t a,pa_sample_format_t b)235 static bool sample_format_more_precise(pa_sample_format_t a, pa_sample_format_t b) {
236 pa_assert(pa_sample_format_valid(a));
237 pa_assert(pa_sample_format_valid(b));
238
239 switch (a) {
240 case PA_SAMPLE_U8:
241 case PA_SAMPLE_ALAW:
242 case PA_SAMPLE_ULAW:
243 return false;
244 break;
245
246 case PA_SAMPLE_S16LE:
247 case PA_SAMPLE_S16BE:
248 if (b == PA_SAMPLE_ULAW || b == PA_SAMPLE_ALAW || b == PA_SAMPLE_U8)
249 return true;
250 else
251 return false;
252 break;
253
254 case PA_SAMPLE_S24LE:
255 case PA_SAMPLE_S24BE:
256 case PA_SAMPLE_S24_32LE:
257 case PA_SAMPLE_S24_32BE:
258 if (b == PA_SAMPLE_ULAW || b == PA_SAMPLE_ALAW || b == PA_SAMPLE_U8 ||
259 b == PA_SAMPLE_S16LE || b == PA_SAMPLE_S16BE)
260 return true;
261 else
262 return false;
263 break;
264
265 case PA_SAMPLE_FLOAT32LE:
266 case PA_SAMPLE_FLOAT32BE:
267 case PA_SAMPLE_S32LE:
268 case PA_SAMPLE_S32BE:
269 if (b == PA_SAMPLE_FLOAT32LE || b == PA_SAMPLE_FLOAT32BE ||
270 b == PA_SAMPLE_S32LE || b == PA_SAMPLE_S32BE)
271 return false;
272 else
273 return true;
274 break;
275
276 default:
277 return false;
278 }
279 }
280
choose_work_format(pa_resample_method_t method,pa_sample_format_t a,pa_sample_format_t b,bool map_required)281 static pa_sample_format_t choose_work_format(
282 pa_resample_method_t method,
283 pa_sample_format_t a,
284 pa_sample_format_t b,
285 bool map_required) {
286 pa_sample_format_t work_format;
287
288 pa_assert(pa_sample_format_valid(a));
289 pa_assert(pa_sample_format_valid(b));
290 pa_assert(method >= 0);
291 pa_assert(method < PA_RESAMPLER_MAX);
292
293 if (method >= PA_RESAMPLER_SPEEX_FIXED_BASE && method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
294 method = PA_RESAMPLER_SPEEX_FIXED_BASE;
295
296 switch (method) {
297 /* This block is for resampling functions that only
298 * support the S16 sample format. */
299 case PA_RESAMPLER_SPEEX_FIXED_BASE:
300 case PA_RESAMPLER_FFMPEG:
301 work_format = PA_SAMPLE_S16NE;
302 break;
303
304 /* This block is for resampling functions that support
305 * any sample format. */
306 case PA_RESAMPLER_COPY:
307 case PA_RESAMPLER_TRIVIAL:
308 if (!map_required && a == b) {
309 work_format = a;
310 break;
311 }
312 /* If both input and output are using S32NE and we don't
313 * need any resampling we can use S32NE directly, avoiding
314 * converting back and forth between S32NE and
315 * FLOAT32NE. */
316 if ((a == PA_SAMPLE_S32NE) && (b == PA_SAMPLE_S32NE)) {
317 work_format = PA_SAMPLE_S32NE;
318 break;
319 }
320 /* Else fall through */
321 case PA_RESAMPLER_PEAKS:
322 /* PEAKS, COPY and TRIVIAL do not benefit from increased
323 * working precision, so for better performance use s16ne
324 * if either input or output fits in it. */
325 if (a == PA_SAMPLE_S16NE || b == PA_SAMPLE_S16NE) {
326 work_format = PA_SAMPLE_S16NE;
327 break;
328 }
329 /* Else fall through */
330 case PA_RESAMPLER_SOXR_MQ:
331 case PA_RESAMPLER_SOXR_HQ:
332 case PA_RESAMPLER_SOXR_VHQ:
333 /* Do processing with max precision of input and output. */
334 if (sample_format_more_precise(a, PA_SAMPLE_S16NE) ||
335 sample_format_more_precise(b, PA_SAMPLE_S16NE))
336 work_format = PA_SAMPLE_FLOAT32NE;
337 else
338 work_format = PA_SAMPLE_S16NE;
339 break;
340
341 default:
342 work_format = PA_SAMPLE_FLOAT32NE;
343 }
344
345 return work_format;
346 }
347
pa_resampler_new(pa_mempool * pool,const pa_sample_spec * a,const pa_channel_map * am,const pa_sample_spec * b,const pa_channel_map * bm,unsigned crossover_freq,pa_resample_method_t method,pa_resample_flags_t flags)348 pa_resampler* pa_resampler_new(
349 pa_mempool *pool,
350 const pa_sample_spec *a,
351 const pa_channel_map *am,
352 const pa_sample_spec *b,
353 const pa_channel_map *bm,
354 unsigned crossover_freq,
355 pa_resample_method_t method,
356 pa_resample_flags_t flags) {
357
358 pa_resampler *r = NULL;
359 bool lfe_remixed = false;
360
361 pa_assert(pool);
362 pa_assert(a);
363 pa_assert(b);
364 pa_assert(pa_sample_spec_valid(a));
365 pa_assert(pa_sample_spec_valid(b));
366 pa_assert(method >= 0);
367 pa_assert(method < PA_RESAMPLER_MAX);
368
369 method = fix_method(flags, method, a->rate, b->rate);
370
371 r = pa_xnew0(pa_resampler, 1);
372 r->mempool = pool;
373 r->method = method;
374 r->flags = flags;
375 r->in_frames = 0;
376 r->out_frames = 0;
377
378 /* Fill sample specs */
379 r->i_ss = *a;
380 r->o_ss = *b;
381 calculate_gcd(r);
382
383 if (am)
384 r->i_cm = *am;
385 else if (!pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels, PA_CHANNEL_MAP_DEFAULT))
386 goto fail;
387
388 if (bm)
389 r->o_cm = *bm;
390 else if (!pa_channel_map_init_auto(&r->o_cm, r->o_ss.channels, PA_CHANNEL_MAP_DEFAULT))
391 goto fail;
392
393 r->i_fz = pa_frame_size(a);
394 r->o_fz = pa_frame_size(b);
395
396 r->map_required = (r->i_ss.channels != r->o_ss.channels || (!(r->flags & PA_RESAMPLER_NO_REMAP) &&
397 !pa_channel_map_equal(&r->i_cm, &r->o_cm)));
398
399 r->work_format = choose_work_format(method, a->format, b->format, r->map_required);
400 r->w_sz = pa_sample_size_of_format(r->work_format);
401
402 if (r->i_ss.format != r->work_format) {
403 if (r->work_format == PA_SAMPLE_FLOAT32NE) {
404 if (!(r->to_work_format_func = pa_get_convert_to_float32ne_function(r->i_ss.format)))
405 goto fail;
406 } else {
407 pa_assert(r->work_format == PA_SAMPLE_S16NE);
408 if (!(r->to_work_format_func = pa_get_convert_to_s16ne_function(r->i_ss.format)))
409 goto fail;
410 }
411 }
412
413 if (r->o_ss.format != r->work_format) {
414 if (r->work_format == PA_SAMPLE_FLOAT32NE) {
415 if (!(r->from_work_format_func = pa_get_convert_from_float32ne_function(r->o_ss.format)))
416 goto fail;
417 } else {
418 pa_assert(r->work_format == PA_SAMPLE_S16NE);
419 if (!(r->from_work_format_func = pa_get_convert_from_s16ne_function(r->o_ss.format)))
420 goto fail;
421 }
422 }
423
424 if (r->o_ss.channels <= r->i_ss.channels) {
425 /* pipeline is: format conv. -> remap -> resample -> format conv. */
426 r->work_channels = r->o_ss.channels;
427
428 /* leftover buffer is remap output buffer (before resampling) */
429 r->leftover_buf = &r->remap_buf;
430 r->leftover_buf_size = &r->remap_buf_size;
431 r->have_leftover = &r->leftover_in_remap;
432 } else {
433 /* pipeline is: format conv. -> resample -> remap -> format conv. */
434 r->work_channels = r->i_ss.channels;
435
436 /* leftover buffer is to_work output buffer (before resampling) */
437 r->leftover_buf = &r->to_work_format_buf;
438 r->leftover_buf_size = &r->to_work_format_buf_size;
439 r->have_leftover = &r->leftover_in_to_work;
440 }
441 r->w_fz = pa_sample_size_of_format(r->work_format) * r->work_channels;
442
443 AUDIO_INFO_LOG("pa_resampler_new: rate %{public}u -> %{public}u (method %{public}s), "
444 "format %{public}s -> %{public}s (intermediate %{public}s), "
445 "channels %{public}u -> %{public}u (resampling %{public}u)",
446 a->rate, b->rate, pa_resample_method_to_string(r->method), pa_sample_format_to_string(a->format),
447 pa_sample_format_to_string(b->format), pa_sample_format_to_string(r->work_format), a->channels, b->channels,
448 r->work_channels);
449
450 /* set up the remap structure */
451 if (r->map_required)
452 setup_remap(r, &r->remap, &lfe_remixed);
453
454 if (lfe_remixed && crossover_freq > 0) {
455 pa_sample_spec wss = r->o_ss;
456 wss.format = r->work_format;
457 /* FIXME: For now just hardcode maxrewind to 3 seconds */
458 r->lfe_filter = pa_lfe_filter_new(&wss, &r->o_cm, (float)crossover_freq, b->rate * 3);
459 pa_log_debug(" lfe filter activated (LR4 type), the crossover_freq = %uHz", crossover_freq);
460 }
461
462 /* initialize implementation */
463 if (method >= PA_PRORESAMPLER_BASE && method <= PA_PRORESAMPLER_MAX) {
464 if (ProResamlerInit(r) < 0) {
465 goto fail;
466 }
467 } else {
468 if (init_table[method](r) < 0) {
469 goto fail;
470 }
471 }
472 return r;
473
474 fail:
475 if (r->lfe_filter)
476 pa_lfe_filter_free(r->lfe_filter);
477 pa_xfree(r);
478
479 return NULL;
480 }
481
pa_resampler_free(pa_resampler * r)482 void pa_resampler_free(pa_resampler *r) {
483 pa_assert(r);
484
485 if (r->impl.free)
486 r->impl.free(r);
487 else
488 pa_xfree(r->impl.data);
489
490 if (r->lfe_filter)
491 pa_lfe_filter_free(r->lfe_filter);
492
493 if (r->to_work_format_buf.memblock)
494 pa_memblock_unref(r->to_work_format_buf.memblock);
495 if (r->remap_buf.memblock)
496 pa_memblock_unref(r->remap_buf.memblock);
497 if (r->resample_buf.memblock)
498 pa_memblock_unref(r->resample_buf.memblock);
499 if (r->from_work_format_buf.memblock)
500 pa_memblock_unref(r->from_work_format_buf.memblock);
501
502 free_remap(&r->remap);
503
504 pa_xfree(r);
505 }
506
pa_resampler_set_input_rate(pa_resampler * r,uint32_t rate)507 void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) {
508 pa_assert(r);
509 pa_assert(rate > 0);
510 pa_assert(r->impl.update_rates);
511
512 if (r->i_ss.rate == rate)
513 return;
514
515 /* Recalculate delay counters */
516 r->in_frames = pa_resampler_get_delay(r, false);
517 r->out_frames = 0;
518
519 r->i_ss.rate = rate;
520 calculate_gcd(r);
521
522 r->impl.update_rates(r);
523 }
524
pa_resampler_set_output_rate(pa_resampler * r,uint32_t rate)525 void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) {
526 pa_assert(r);
527 pa_assert(rate > 0);
528 pa_assert(r->impl.update_rates);
529
530 if (r->o_ss.rate == rate)
531 return;
532
533 /* Recalculate delay counters */
534 r->in_frames = pa_resampler_get_delay(r, false);
535 r->out_frames = 0;
536
537 r->o_ss.rate = rate;
538 calculate_gcd(r);
539
540 r->impl.update_rates(r);
541
542 if (r->lfe_filter)
543 pa_lfe_filter_update_rate(r->lfe_filter, rate);
544 }
545
546 /* pa_resampler_request() and pa_resampler_result() should be as exact as
547 * possible to ensure that no samples are lost or duplicated during rewinds.
548 * Ignore the leftover buffer, the value appears to be wrong for ffmpeg
549 * and 0 in all other cases. If the resampler is NULL it means that no
550 * resampling is necessary and the input length equals the output length.
551 * FIXME: These functions are not exact for the soxr resamplers because
552 * soxr uses a different algorithm. */
pa_resampler_request(pa_resampler * r,size_t out_length)553 size_t pa_resampler_request(pa_resampler *r, size_t out_length) {
554 size_t in_length;
555
556 if (!r || out_length == 0)
557 return out_length;
558
559 /* Convert to output frames */
560 out_length = out_length / r->o_fz;
561
562 /* Convert to input frames. The equation matches exactly the
563 * behavior of the used resamplers and will calculate the
564 * minimum number of input frames that are needed to produce
565 * the given number of output frames. */
566 if (r->o_ss.rate % 50 != 0 || r->i_ss.rate % 50 != 0) { // 1s/20ms(oh frmLen) = 50
567 in_length = (out_length - 1) * r->i_ss.rate / r->o_ss.rate + 1;
568 } else {
569 in_length = out_length * r->i_ss.rate / r->o_ss.rate;
570 }
571
572 /* Convert to input length */
573 return in_length * r->i_fz;
574 }
575
pa_resampler_result(pa_resampler * r,size_t in_length)576 size_t pa_resampler_result(pa_resampler *r, size_t in_length) {
577 size_t out_length;
578
579 if (!r)
580 return in_length;
581
582 /* Convert to intput frames */
583 in_length = in_length / r->i_fz;
584
585 /* soxr processes samples in blocks, depending on the ratio.
586 * Therefore samples that do not fit into a block must be
587 * ignored. */
588 if (r->method == PA_RESAMPLER_SOXR_MQ || r->method == PA_RESAMPLER_SOXR_HQ || r->method == PA_RESAMPLER_SOXR_VHQ) {
589 double ratio;
590 size_t block_size;
591 int k;
592
593 ratio = (double)r->i_ss.rate / (double)r->o_ss.rate;
594
595 for (k = 0; k < 7; k++) {
596 if (ratio < pow(2, k + 1))
597 break;
598 }
599 block_size = pow(2, k);
600 in_length = in_length - in_length % block_size;
601 }
602
603 /* Convert to output frames. This matches exactly the algorithm
604 * used by the resamplers except for the soxr resamplers. */
605
606 out_length = in_length * r->o_ss.rate / r->i_ss.rate;
607 if ((double)in_length * (double)r->o_ss.rate / (double)r->i_ss.rate - out_length > 0)
608 out_length++;
609 /* The libsamplerate resamplers return one sample more if the result is integral and the ratio is not integral. */
610 else if (r->method >= PA_RESAMPLER_SRC_SINC_BEST_QUALITY && r->method <= PA_RESAMPLER_SRC_SINC_FASTEST && r->i_ss.rate > r->o_ss.rate && r->i_ss.rate % r->o_ss.rate > 0 && (double)in_length * (double)r->o_ss.rate / (double)r->i_ss.rate - out_length <= 0)
611 out_length++;
612 else if (r->method == PA_RESAMPLER_SRC_ZERO_ORDER_HOLD && r->i_ss.rate > r->o_ss.rate && (double)in_length * (double)r->o_ss.rate / (double)r->i_ss.rate - out_length <= 0)
613 out_length++;
614
615 /* Convert to output length */
616 return out_length * r->o_fz;
617 }
618
pa_resampler_max_block_size(pa_resampler * r)619 size_t pa_resampler_max_block_size(pa_resampler *r) {
620 size_t block_size_max;
621 pa_sample_spec max_ss;
622 size_t max_fs;
623 size_t frames;
624
625 pa_assert(r);
626
627 block_size_max = pa_mempool_block_size_max(r->mempool);
628
629 /* We deduce the "largest" sample spec we're using during the
630 * conversion */
631 max_ss.channels = (uint8_t) (PA_MAX(r->i_ss.channels, r->o_ss.channels));
632
633 max_ss.format = r->i_ss.format;
634
635 if (pa_sample_size_of_format(max_ss.format) < pa_sample_size_of_format(r->o_ss.format))
636 max_ss.format = r->o_ss.format;
637
638 if (pa_sample_size_of_format(max_ss.format) < pa_sample_size_of_format(r->work_format))
639 max_ss.format = r->work_format;
640
641 max_ss.rate = PA_MAX(r->i_ss.rate, r->o_ss.rate);
642
643 max_fs = pa_frame_size(&max_ss);
644 frames = block_size_max / max_fs - EXTRA_FRAMES;
645
646 pa_assert(frames >= (r->leftover_buf->length / r->w_fz));
647 if (*r->have_leftover)
648 frames -= r->leftover_buf->length / r->w_fz;
649
650 block_size_max = ((uint64_t) frames * r->i_ss.rate / max_ss.rate) * r->i_fz;
651
652 if (block_size_max > 0)
653 return block_size_max;
654 else
655 /* A single input frame may result in so much output that it doesn't
656 * fit in one standard memblock (e.g. converting 1 Hz to 44100 Hz). In
657 * this case the max block size will be set to one frame, and some
658 * memory will be probably be allocated with malloc() instead of using
659 * the memory pool.
660 *
661 * XXX: Should we support this case at all? We could also refuse to
662 * create resamplers whose max block size would exceed the memory pool
663 * block size. In this case also updating the resampler rate should
664 * fail if the new rate would cause an excessive max block size (in
665 * which case the stream would probably have to be killed). */
666 return r->i_fz;
667 }
668
pa_resampler_reset(pa_resampler * r)669 void pa_resampler_reset(pa_resampler *r) {
670 pa_assert(r);
671
672 if (r->impl.reset)
673 r->impl.reset(r);
674
675 if (r->lfe_filter)
676 pa_lfe_filter_reset(r->lfe_filter);
677
678 *r->have_leftover = false;
679
680 r->in_frames = 0;
681 r->out_frames = 0;
682 }
683
684 /* This function runs amount bytes of data from the history queue through the
685 * resampler and discards the result. The history queue is unchanged after the
686 * call. This is used to preload a resampler after a reset. Returns the number
687 * of frames produced by the resampler. */
pa_resampler_prepare(pa_resampler * r,pa_memblockq * history_queue,size_t amount)688 size_t pa_resampler_prepare(pa_resampler *r, pa_memblockq *history_queue, size_t amount) {
689 size_t history_bytes, max_block_size, out_size;
690 int64_t to_run;
691
692 pa_assert(r);
693
694 if (!history_queue || amount == 0)
695 return 0;
696
697 /* Rewind the LFE filter by the amount of history data. */
698 history_bytes = pa_resampler_result(r, amount);
699 if (r->lfe_filter)
700 pa_lfe_filter_rewind(r->lfe_filter, history_bytes);
701
702 pa_memblockq_rewind(history_queue, amount);
703 max_block_size = pa_resampler_max_block_size(r);
704 to_run = amount;
705 out_size = 0;
706
707 while (to_run > 0) {
708 pa_memchunk in_chunk, out_chunk;
709 size_t current;
710
711 current = PA_MIN(to_run, (int64_t) max_block_size);
712
713 /* Get data from memblockq */
714 if (pa_memblockq_peek_fixed_size(history_queue, current, &in_chunk) < 0) {
715 pa_log_warn("Could not read history data for resampler.");
716
717 /* Restore queue to original state and reset resampler */
718 pa_memblockq_drop(history_queue, to_run);
719 pa_resampler_reset(r);
720 return out_size;
721 }
722
723 /* Run the resampler */
724 pa_resampler_run(r, &in_chunk, &out_chunk);
725
726 /* Discard result */
727 if (out_chunk.length != 0) {
728 out_size += out_chunk.length;
729 pa_memblock_unref(out_chunk.memblock);
730 }
731
732 pa_memblock_unref(in_chunk.memblock);
733 pa_memblockq_drop(history_queue, current);
734 to_run -= current;
735 }
736
737 return out_size;
738 }
739
pa_resampler_rewind(pa_resampler * r,size_t out_bytes,pa_memblockq * history_queue,size_t amount)740 size_t pa_resampler_rewind(pa_resampler *r, size_t out_bytes, pa_memblockq *history_queue, size_t amount) {
741 pa_assert(r);
742
743 /* For now, we don't have any rewindable resamplers, so we just reset
744 * the resampler if we cannot rewind using pa_resampler_prepare(). */
745 if (r->impl.reset && !history_queue)
746 r->impl.reset(r);
747
748 if (r->lfe_filter)
749 pa_lfe_filter_rewind(r->lfe_filter, out_bytes);
750
751 if (!history_queue) {
752 *r->have_leftover = false;
753
754 r->in_frames = 0;
755 r->out_frames = 0;
756 }
757
758 if (history_queue && amount > 0)
759 return pa_resampler_prepare(r, history_queue, amount);
760
761 return 0;
762 }
763
pa_resampler_get_method(pa_resampler * r)764 pa_resample_method_t pa_resampler_get_method(pa_resampler *r) {
765 pa_assert(r);
766
767 return r->method;
768 }
769
pa_resampler_input_channel_map(pa_resampler * r)770 const pa_channel_map* pa_resampler_input_channel_map(pa_resampler *r) {
771 pa_assert(r);
772
773 return &r->i_cm;
774 }
775
pa_resampler_input_sample_spec(pa_resampler * r)776 const pa_sample_spec* pa_resampler_input_sample_spec(pa_resampler *r) {
777 pa_assert(r);
778
779 return &r->i_ss;
780 }
781
pa_resampler_output_channel_map(pa_resampler * r)782 const pa_channel_map* pa_resampler_output_channel_map(pa_resampler *r) {
783 pa_assert(r);
784
785 return &r->o_cm;
786 }
787
pa_resampler_output_sample_spec(pa_resampler * r)788 const pa_sample_spec* pa_resampler_output_sample_spec(pa_resampler *r) {
789 pa_assert(r);
790
791 return &r->o_ss;
792 }
793
794 static const char * const resample_methods[] = {
795 "src-sinc-best-quality",
796 "src-sinc-medium-quality",
797 "src-sinc-fastest",
798 "src-zero-order-hold",
799 "src-linear",
800 "trivial",
801 "speex-float-0",
802 "speex-float-1",
803 "speex-float-2",
804 "speex-float-3",
805 "speex-float-4",
806 "speex-float-5",
807 "speex-float-6",
808 "speex-float-7",
809 "speex-float-8",
810 "speex-float-9",
811 "speex-float-10",
812 "speex-fixed-0",
813 "speex-fixed-1",
814 "speex-fixed-2",
815 "speex-fixed-3",
816 "speex-fixed-4",
817 "speex-fixed-5",
818 "speex-fixed-6",
819 "speex-fixed-7",
820 "speex-fixed-8",
821 "speex-fixed-9",
822 "speex-fixed-10",
823 "ffmpeg",
824 "auto",
825 "copy",
826 "peaks",
827 "soxr-mq",
828 "soxr-hq",
829 "soxr-vhq",
830 "proresampler-0",
831 "proresampler-1",
832 "proresampler-2",
833 "proresampler-3",
834 "proresampler-4",
835 "proresampler-5",
836 "proresampler-6",
837 "proresampler-7",
838 "proresampler-8",
839 "proresampler-9",
840 "proresampler-10",
841 };
842
pa_resample_method_to_string(pa_resample_method_t m)843 const char *pa_resample_method_to_string(pa_resample_method_t m) {
844
845 if (m < 0 || m >= PA_RESAMPLER_MAX)
846 return NULL;
847
848 return resample_methods[m];
849 }
850
pa_resample_method_supported(pa_resample_method_t m)851 int pa_resample_method_supported(pa_resample_method_t m) {
852
853 if (m < 0 || m >= PA_RESAMPLER_MAX)
854 return 0;
855
856 #ifndef HAVE_LIBSAMPLERATE
857 if (m <= PA_RESAMPLER_SRC_LINEAR)
858 return 0;
859 #endif
860
861 #ifndef HAVE_SPEEX
862 if (m >= PA_RESAMPLER_SPEEX_FLOAT_BASE && m <= PA_RESAMPLER_SPEEX_FLOAT_MAX)
863 return 0;
864 if (m >= PA_RESAMPLER_SPEEX_FIXED_BASE && m <= PA_RESAMPLER_SPEEX_FIXED_MAX)
865 return 0;
866 #endif
867
868 #ifndef HAVE_SOXR
869 if (m >= PA_RESAMPLER_SOXR_MQ && m <= PA_RESAMPLER_SOXR_VHQ)
870 return 0;
871 #endif
872
873 return 1;
874 }
875
pa_parse_resample_method(const char * string)876 pa_resample_method_t pa_parse_resample_method(const char *string) {
877 pa_resample_method_t m;
878
879 pa_assert(string);
880
881 for (m = 0; m < PA_RESAMPLER_MAX; m++)
882 if (pa_streq(string, resample_methods[m]))
883 return m;
884
885 if (pa_streq(string, "speex-fixed"))
886 return PA_RESAMPLER_SPEEX_FIXED_BASE + 1;
887
888 if (pa_streq(string, "speex-float"))
889 return PA_RESAMPLER_SPEEX_FLOAT_BASE + 1;
890
891 return PA_RESAMPLER_INVALID;
892 }
893
on_left(pa_channel_position_t p)894 static bool on_left(pa_channel_position_t p) {
895
896 return
897 p == PA_CHANNEL_POSITION_FRONT_LEFT ||
898 p == PA_CHANNEL_POSITION_REAR_LEFT ||
899 p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ||
900 p == PA_CHANNEL_POSITION_SIDE_LEFT ||
901 p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT ||
902 p == PA_CHANNEL_POSITION_TOP_REAR_LEFT;
903 }
904
on_right(pa_channel_position_t p)905 static bool on_right(pa_channel_position_t p) {
906
907 return
908 p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
909 p == PA_CHANNEL_POSITION_REAR_RIGHT ||
910 p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER ||
911 p == PA_CHANNEL_POSITION_SIDE_RIGHT ||
912 p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ||
913 p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
914 }
915
on_center(pa_channel_position_t p)916 static bool on_center(pa_channel_position_t p) {
917
918 return
919 p == PA_CHANNEL_POSITION_FRONT_CENTER ||
920 p == PA_CHANNEL_POSITION_REAR_CENTER ||
921 p == PA_CHANNEL_POSITION_TOP_CENTER ||
922 p == PA_CHANNEL_POSITION_TOP_FRONT_CENTER ||
923 p == PA_CHANNEL_POSITION_TOP_REAR_CENTER;
924 }
925
on_lfe(pa_channel_position_t p)926 static bool on_lfe(pa_channel_position_t p) {
927 return
928 p == PA_CHANNEL_POSITION_LFE;
929 }
930
on_front(pa_channel_position_t p)931 static bool on_front(pa_channel_position_t p) {
932 return
933 p == PA_CHANNEL_POSITION_FRONT_LEFT ||
934 p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
935 p == PA_CHANNEL_POSITION_FRONT_CENTER ||
936 p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT ||
937 p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ||
938 p == PA_CHANNEL_POSITION_TOP_FRONT_CENTER ||
939 p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ||
940 p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
941 }
942
on_rear(pa_channel_position_t p)943 static bool on_rear(pa_channel_position_t p) {
944 return
945 p == PA_CHANNEL_POSITION_REAR_LEFT ||
946 p == PA_CHANNEL_POSITION_REAR_RIGHT ||
947 p == PA_CHANNEL_POSITION_REAR_CENTER ||
948 p == PA_CHANNEL_POSITION_TOP_REAR_LEFT ||
949 p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT ||
950 p == PA_CHANNEL_POSITION_TOP_REAR_CENTER;
951 }
952
on_side(pa_channel_position_t p)953 static bool on_side(pa_channel_position_t p) {
954 return
955 p == PA_CHANNEL_POSITION_SIDE_LEFT ||
956 p == PA_CHANNEL_POSITION_SIDE_RIGHT ||
957 p == PA_CHANNEL_POSITION_TOP_CENTER;
958 }
959
960 typedef enum pa_channel_direction {
961 ON_FRONT,
962 ON_REAR,
963 ON_SIDE,
964 ON_OTHER
965 } pa_channel_direction_t;
966
front_rear_side(pa_channel_position_t p)967 static int front_rear_side(pa_channel_position_t p) {
968 if (on_front(p))
969 return ON_FRONT;
970 if (on_rear(p))
971 return ON_REAR;
972 if (on_side(p))
973 return ON_SIDE;
974 return ON_OTHER;
975 }
976
977 /* For downmixing other output format, usage [direction_of_input_channel][direction_of_output_channel] */
978 /* layout */
979 /* front rear side */
980 /* front | | | | */
981 /* rear | | | | */
982 /* side | | | | */
983 static const float directionDownMixMatrix[ON_OTHER][ON_OTHER] = {
984 {1.0f, 0.5f, 0.7071f},
985 {0.5f, 1.0f, 0.7071f},
986 {0.7071f, 0.7071f, 1.0f},
987 };
988
989 /* Fill a map of which output channels should get mono from input, not including
990 * LFE output channels. (The LFE output channels are mapped separately.)
991 */
setup_oc_mono_map(const pa_resampler * r,float * oc_mono_map)992 static void setup_oc_mono_map(const pa_resampler *r, float *oc_mono_map) {
993 unsigned oc;
994 unsigned n_oc;
995 bool found_oc_for_mono = false;
996
997 pa_assert(r);
998 pa_assert(oc_mono_map);
999
1000 n_oc = r->o_ss.channels;
1001
1002 if (!(r->flags & PA_RESAMPLER_NO_FILL_SINK)) {
1003 /* Mono goes to all non-LFE output channels and we're done. */
1004 for (oc = 0; oc < n_oc; oc++)
1005 oc_mono_map[oc] = on_lfe(r->o_cm.map[oc]) ? 0.0f : 1.0f;
1006 return;
1007 } else {
1008 /* Initialize to all zero so we can select individual channels below. */
1009 for (oc = 0; oc < n_oc; oc++)
1010 oc_mono_map[oc] = 0.0f;
1011 }
1012
1013 for (oc = 0; oc < n_oc; oc++) {
1014 if (r->o_cm.map[oc] == PA_CHANNEL_POSITION_MONO) {
1015 oc_mono_map[oc] = 1.0f;
1016 found_oc_for_mono = true;
1017 }
1018 }
1019 if (found_oc_for_mono)
1020 return;
1021
1022 for (oc = 0; oc < n_oc; oc++) {
1023 if (r->o_cm.map[oc] == PA_CHANNEL_POSITION_FRONT_CENTER) {
1024 oc_mono_map[oc] = 1.0f;
1025 found_oc_for_mono = true;
1026 }
1027 }
1028 if (found_oc_for_mono)
1029 return;
1030
1031 for (oc = 0; oc < n_oc; oc++) {
1032 if (r->o_cm.map[oc] == PA_CHANNEL_POSITION_FRONT_LEFT || r->o_cm.map[oc] == PA_CHANNEL_POSITION_FRONT_RIGHT) {
1033 oc_mono_map[oc] = 1.0f;
1034 found_oc_for_mono = true;
1035 }
1036 }
1037 if (found_oc_for_mono)
1038 return;
1039
1040 /* Give up on finding a suitable map for mono, and just send it to all
1041 * non-LFE output channels.
1042 */
1043 for (oc = 0; oc < n_oc; oc++)
1044 oc_mono_map[oc] = on_lfe(r->o_cm.map[oc]) ? 0.0f : 1.0f;
1045 }
1046
setup_remap(const pa_resampler * r,pa_remap_t * m,bool * lfe_remixed)1047 static void setup_remap(const pa_resampler *r, pa_remap_t *m, bool *lfe_remixed) {
1048 unsigned oc, ic;
1049 unsigned n_oc, n_ic;
1050 bool ic_connected[PA_CHANNELS_MAX];
1051 pa_strbuf *s;
1052 char *t;
1053
1054 pa_assert(r);
1055 pa_assert(m);
1056 pa_assert(lfe_remixed);
1057
1058 n_oc = r->o_ss.channels;
1059 n_ic = r->i_ss.channels;
1060
1061 m->format = r->work_format;
1062 m->i_ss = r->i_ss;
1063 m->o_ss = r->o_ss;
1064
1065 memset(m->map_table_f, 0, sizeof(m->map_table_f));
1066 memset(m->map_table_i, 0, sizeof(m->map_table_i));
1067
1068 memset(ic_connected, 0, sizeof(ic_connected));
1069 *lfe_remixed = false;
1070
1071 if (r->flags & PA_RESAMPLER_NO_REMAP) {
1072 for (oc = 0; oc < PA_MIN(n_ic, n_oc); oc++)
1073 m->map_table_f[oc][oc] = 1.0f;
1074
1075 } else if (r->flags & PA_RESAMPLER_NO_REMIX) {
1076 for (oc = 0; oc < n_oc; oc++) {
1077 pa_channel_position_t b = r->o_cm.map[oc];
1078
1079 for (ic = 0; ic < n_ic; ic++) {
1080 pa_channel_position_t a = r->i_cm.map[ic];
1081
1082 /* We shall not do any remixing. Hence, just check by name */
1083 if (a == b)
1084 m->map_table_f[oc][ic] = 1.0f;
1085 }
1086 }
1087 } else {
1088
1089 /* OK, we shall do the full monty: upmixing and downmixing. Our
1090 * algorithm is relatively simple, does not do spacialization, or delay
1091 * elements. LFE filters are done after the remap step. Patches are always
1092 * welcome, though. Oh, and it doesn't do any matrix decoding. (Which
1093 * probably wouldn't make any sense anyway.)
1094 *
1095 * This code is not idempotent: downmixing an upmixed stereo stream is
1096 * not identical to the original. The volume will not match, and the
1097 * two channels will be a linear combination of both.
1098 *
1099 * This is loosely based on random suggestions found on the Internet,
1100 * such as this:
1101 * http://www.halfgaar.net/surround-sound-in-linux and the alsa upmix
1102 * plugin.
1103 *
1104 * The algorithm works basically like this:
1105 *
1106 * 1) Connect all channels with matching names.
1107 * This also includes fixing confusion between "5.1" and
1108 * "5.1 (Side)" layouts, done by mpv.
1109 *
1110 * 2) Mono Handling:
1111 * S:Mono: See setup_oc_mono_map().
1112 * D:Mono: Avg all S:channels
1113 *
1114 * 3) Mix D:Left, D:Right (if PA_RESAMPLER_NO_FILL_SINK is clear):
1115 * D:Left: If not connected, avg all S:Left
1116 * D:Right: If not connected, avg all S:Right
1117 *
1118 * 4) Mix D:Center (if PA_RESAMPLER_NO_FILL_SINK is clear):
1119 * If not connected, avg all S:Center
1120 * If still not connected, avg all S:Left, S:Right
1121 *
1122 * 5) Mix D:LFE
1123 * If not connected, avg all S:*
1124 *
1125 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If not
1126 * connected, mix into all D:left and all D:right channels. Gain is
1127 * 1/9.
1128 *
1129 * 7) Make sure S:Center, S:LFE is used:
1130 *
1131 * S:Center, S:LFE: If not connected, mix into all D:left, all
1132 * D:right, all D:center channels. Gain is 0.5 for center and 0.375
1133 * for LFE. C-front is only mixed into L-front/R-front if available,
1134 * otherwise into all L/R channels. Similarly for C-rear.
1135 *
1136 * 8) Normalize each row in the matrix such that the sum for each row is
1137 * not larger than 1.0 in order to avoid clipping.
1138 *
1139 * S: and D: shall relate to the source resp. destination channels.
1140 *
1141 * Rationale: 1, 2 are probably obvious. For 3: this copies front to
1142 * rear if needed. For 4: we try to find some suitable C source for C,
1143 * if we don't find any, we avg L and R. For 5: LFE is mixed from all
1144 * channels. For 6: the rear channels should not be dropped entirely,
1145 * however have only minimal impact. For 7: movies usually encode
1146 * speech on the center channel. Thus we have to make sure this channel
1147 * is distributed to L and R if not available in the output. Also, LFE
1148 * is used to achieve a greater dynamic range, and thus we should try
1149 * to do our best to pass it to L+R.
1150 */
1151
1152 unsigned
1153 ic_left = 0,
1154 ic_right = 0,
1155 ic_center = 0,
1156 ic_unconnected_center = 0,
1157 ic_unconnected_lfe = 0;
1158 bool ic_unconnected_center_mixed_in = 0;
1159 float oc_mono_map[PA_CHANNELS_MAX];
1160
1161 for (ic = 0; ic < n_ic; ic++) {
1162 if (on_left(r->i_cm.map[ic]))
1163 ic_left++;
1164 if (on_right(r->i_cm.map[ic]))
1165 ic_right++;
1166 if (on_center(r->i_cm.map[ic]))
1167 ic_center++;
1168 }
1169
1170 setup_oc_mono_map(r, oc_mono_map);
1171
1172 // mono ouput or input channel = output channel
1173 for (oc = 0; oc < n_oc; oc++) {
1174 bool oc_connected = false;
1175 pa_channel_position_t b = r->o_cm.map[oc];
1176
1177 for (ic = 0; ic < n_ic; ic++) {
1178 pa_channel_position_t a = r->i_cm.map[ic];
1179
1180 if (a == b) {
1181 m->map_table_f[oc][ic] = 1.0f;
1182
1183 oc_connected = true;
1184 ic_connected[ic] = true;
1185 }
1186 else if (a == PA_CHANNEL_POSITION_MONO && oc_mono_map[oc] > 0.0f) {
1187 m->map_table_f[oc][ic] = oc_mono_map[oc];
1188
1189 oc_connected = true;
1190 ic_connected[ic] = true;
1191 }
1192 else if (b == PA_CHANNEL_POSITION_MONO) {
1193 m->map_table_f[oc][ic] = 1.0f / (float) n_ic;
1194
1195 oc_connected = true;
1196 ic_connected[ic] = true;
1197 }
1198 }
1199 // output channel has no relating input channel, upmix here
1200 if (!oc_connected) {
1201 /* Try to find matching input ports for this output port */
1202
1203 if (on_left(b) && !(r->flags & PA_RESAMPLER_NO_FILL_SINK)) {
1204
1205 /* We are not connected and on the left side, let's
1206 * average all left side input channels. */
1207
1208 if (ic_left > 0)
1209 for (ic = 0; ic < n_ic; ic++)
1210 if (on_left(r->i_cm.map[ic])) {
1211 m->map_table_f[oc][ic] = 1.0f / (float) ic_left;
1212 ic_connected[ic] = true;
1213 }
1214
1215 /* We ignore the case where there is no left input channel.
1216 * Something is really wrong in this case anyway. */
1217
1218 } else if (on_right(b) && !(r->flags & PA_RESAMPLER_NO_FILL_SINK)) {
1219
1220 /* We are not connected and on the right side, let's
1221 * average all right side input channels. */
1222
1223 if (ic_right > 0)
1224 for (ic = 0; ic < n_ic; ic++)
1225 if (on_right(r->i_cm.map[ic])) {
1226 m->map_table_f[oc][ic] = 1.0f / (float) ic_right;
1227 ic_connected[ic] = true;
1228 }
1229
1230 /* We ignore the case where there is no right input
1231 * channel. Something is really wrong in this case anyway.
1232 * */
1233
1234 } else if (on_center(b) && !(r->flags & PA_RESAMPLER_NO_FILL_SINK)) {
1235
1236 if (ic_center > 0) {
1237
1238 /* We are not connected and at the center. Let's average
1239 * all center input channels. */
1240
1241 for (ic = 0; ic < n_ic; ic++)
1242 if (on_center(r->i_cm.map[ic])) {
1243 m->map_table_f[oc][ic] = 1.0f / (float) ic_center;
1244 ic_connected[ic] = true;
1245 }
1246
1247 } else if (ic_left + ic_right > 0) {
1248
1249 /* Hmm, no center channel around, let's synthesize it
1250 * by mixing L and R.*/
1251
1252 for (ic = 0; ic < n_ic; ic++)
1253 if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic])) {
1254 m->map_table_f[oc][ic] = 1.0f / (float) (ic_left + ic_right);
1255 ic_connected[ic] = true;
1256 }
1257 }
1258
1259 /* We ignore the case where there is not even a left or
1260 * right input channel. Something is really wrong in this
1261 * case anyway. */
1262
1263 } else if (on_lfe(b) && (r->flags & PA_RESAMPLER_PRODUCE_LFE)) {
1264
1265 /* We are not connected and an LFE. Let's average all
1266 * channels for LFE. */
1267
1268 for (ic = 0; ic < n_ic; ic++)
1269 m->map_table_f[oc][ic] = 1.0f / (float) n_ic;
1270
1271 /* Please note that a channel connected to LFE doesn't
1272 * really count as connected. */
1273
1274 *lfe_remixed = true;
1275 }
1276 }
1277 } /* upmix done, so far every output should be connected*/
1278 /* downmix here, connect unconnected input here */
1279 /* check if output format is supported with downmix table */
1280 pa_channel_layout_index_t output_layout_index = pa_channel_map_to_index(&r->o_cm);
1281
1282 for (ic = 0; ic < n_ic; ic++) {
1283 pa_channel_position_t a = r->i_cm.map[ic];
1284 if (ic_connected[ic]) {
1285 continue;
1286 } else if (on_center(a)) {
1287 ic_unconnected_center++;
1288 } else if (on_lfe(a)) {
1289 ic_unconnected_lfe++;
1290 }
1291 }
1292
1293 if (output_layout_index != PA_CHANNEL_LAYOUT_OTHER) {
1294 for (ic = 0; ic < n_ic; ic++) {
1295 if (ic_connected[ic]) { continue; }
1296 pa_channel_position_t a = r->i_cm.map[ic];
1297 int a_downmix = pa_to_downmix_position(a);
1298 for (oc = 0; oc < n_oc; oc++) {
1299 pa_channel_position_t b = r->o_cm.map[oc];
1300 int b_downmix = pa_to_downmix_position(b);
1301 m->map_table_f[oc][ic] =
1302 (float)channelDownmixMatrix[output_layout_index][a_downmix][b_downmix]/(float)RESCALE_COEF;
1303 /* force lfe downmix*/
1304 if (on_lfe(a))
1305 m->map_table_f[oc][ic] = .375f/(float)ic_unconnected_lfe;
1306 }
1307 }
1308 } else { /* channels that are not supported by downmix table */
1309 for (ic = 0; ic < n_ic; ic++) {
1310 pa_channel_position_t a = r->i_cm.map[ic];
1311 pa_channel_direction_t ic_direction = front_rear_side(r->i_cm.map[ic]);
1312 if (ic_connected[ic]) {
1313 continue;
1314 }
1315 for (oc = 0; oc < n_oc; oc++) {
1316 pa_channel_position_t b = r->o_cm.map[oc];
1317 pa_channel_direction_t oc_direction = front_rear_side(r->o_cm.map[oc]);
1318 if (on_left(a) && on_left(b)) {
1319 m->map_table_f[oc][ic] = directionDownMixMatrix[ic_direction][oc_direction];
1320 } else if (on_right(a) && on_right(b)) {
1321 m->map_table_f[oc][ic] = directionDownMixMatrix[ic_direction][oc_direction];
1322 } else if (on_center(a) && on_center(b)) {
1323 m->map_table_f[oc][ic] = directionDownMixMatrix[ic_direction][oc_direction];
1324 ic_unconnected_center_mixed_in = true;
1325 } else if (on_lfe(a)) {
1326 /* force lfe downmix */
1327 m->map_table_f[oc][ic] = .375f / (float) ic_unconnected_lfe;
1328 }
1329 }
1330 }
1331 if (ic_unconnected_center > 0 && !ic_unconnected_center_mixed_in) {
1332 unsigned ncenter[PA_CHANNELS_MAX];
1333 bool found_frs[PA_CHANNELS_MAX];
1334
1335 memset(ncenter, 0, sizeof(ncenter));
1336 memset(found_frs, 0, sizeof(found_frs));
1337
1338 /* Hmm, as it appears there was no center channel we
1339 could mix our center channel in. In this case, mix it into
1340 left and right. Using .5 as the factor. */
1341
1342 for (ic = 0; ic < n_ic; ic++) {
1343
1344 if (ic_connected[ic])
1345 continue;
1346
1347 if (!on_center(r->i_cm.map[ic]))
1348 continue;
1349
1350 for (oc = 0; oc < n_oc; oc++) {
1351
1352 if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
1353 continue;
1354
1355 if (front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc])) {
1356 found_frs[ic] = true;
1357 break;
1358 }
1359 }
1360
1361 for (oc = 0; oc < n_oc; oc++) {
1362
1363 if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
1364 continue;
1365
1366 if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
1367 ncenter[oc]++;
1368 }
1369 }
1370
1371 for (oc = 0; oc < n_oc; oc++) {
1372
1373 if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
1374 continue;
1375
1376 if (ncenter[oc] <= 0)
1377 continue;
1378
1379 for (ic = 0; ic < n_ic; ic++) {
1380
1381 if (!on_center(r->i_cm.map[ic]))
1382 continue;
1383
1384 if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
1385 m->map_table_f[oc][ic] = .5f / (float) ncenter[oc];
1386 }
1387 }
1388 }
1389 }
1390 }
1391
1392 // uniform with maximum sum
1393 float max_sum = 0.0f;
1394
1395 for (oc = 0; oc < n_oc; oc++) {
1396 float sum = 0.0f;
1397 for (ic = 0; ic < n_ic; ic++) {
1398 sum += m->map_table_f[oc][ic];
1399 }
1400 if (sum > max_sum) { max_sum = sum; }
1401 }
1402 for (oc = 0; oc < n_oc; oc++) {
1403 for (ic = 0; ic < n_ic; ic++) {
1404 m->map_table_f[oc][ic] /= max_sum;
1405 }
1406 }
1407 /* make an 16:16 int version of the matrix */
1408 for (oc = 0; oc < n_oc; oc++)
1409 for (ic = 0; ic < n_ic; ic++)
1410 m->map_table_i[oc][ic] = (int32_t) (m->map_table_f[oc][ic] * 0x10000);
1411
1412 s = pa_strbuf_new();
1413
1414 pa_strbuf_printf(s, " ");
1415 for (ic = 0; ic < n_ic; ic++)
1416 pa_strbuf_printf(s, " I%02u ", ic);
1417 pa_strbuf_puts(s, "\n +");
1418
1419 for (ic = 0; ic < n_ic; ic++)
1420 pa_strbuf_printf(s, "------");
1421 pa_strbuf_puts(s, "\n");
1422
1423 for (oc = 0; oc < n_oc; oc++) {
1424 pa_strbuf_printf(s, "O%02u |", oc);
1425
1426 for (ic = 0; ic < n_ic; ic++)
1427 pa_strbuf_printf(s, " %1.3f", m->map_table_f[oc][ic]);
1428
1429 pa_strbuf_puts(s, "\n");
1430 }
1431
1432 pa_log_debug("Channel matrix:\n%s", t = pa_strbuf_to_string_free(s));
1433 pa_xfree(t);
1434
1435 /* initialize the remapping function */
1436 pa_init_remap_func(m);
1437 }
1438
free_remap(pa_remap_t * m)1439 static void free_remap(pa_remap_t *m) {
1440 pa_assert(m);
1441
1442 pa_xfree(m->state);
1443 }
1444
1445 /* check if buf's memblock is large enough to hold 'len' bytes; create a
1446 * new memblock if necessary and optionally preserve 'copy' data bytes */
fit_buf(pa_resampler * r,pa_memchunk * buf,size_t len,size_t * size,size_t copy)1447 static void fit_buf(pa_resampler *r, pa_memchunk *buf, size_t len, size_t *size, size_t copy) {
1448 pa_assert(size);
1449
1450 if (!buf->memblock || len > *size) {
1451 pa_memblock *new_block = pa_memblock_new(r->mempool, len);
1452
1453 if (buf->memblock) {
1454 if (copy > 0) {
1455 void *src = pa_memblock_acquire(buf->memblock);
1456 void *dst = pa_memblock_acquire(new_block);
1457 pa_assert(copy <= len);
1458 memcpy(dst, src, copy);
1459 pa_memblock_release(new_block);
1460 pa_memblock_release(buf->memblock);
1461 }
1462
1463 pa_memblock_unref(buf->memblock);
1464 }
1465
1466 buf->memblock = new_block;
1467 *size = len;
1468 }
1469
1470 buf->length = len;
1471 }
1472
convert_to_work_format(pa_resampler * r,pa_memchunk * input)1473 static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) {
1474 unsigned in_n_samples, out_n_samples;
1475 void *src, *dst;
1476 bool have_leftover;
1477 size_t leftover_length = 0;
1478
1479 pa_assert(r);
1480 pa_assert(input);
1481 pa_assert(input->memblock);
1482
1483 /* Convert the incoming sample into the work sample format and place them
1484 * in to_work_format_buf. The leftover data is already converted, so it's
1485 * part of the output buffer. */
1486
1487 have_leftover = r->leftover_in_to_work;
1488 r->leftover_in_to_work = false;
1489
1490 if (!have_leftover && (!r->to_work_format_func || !input->length))
1491 return input;
1492 else if (input->length <= 0)
1493 return &r->to_work_format_buf;
1494
1495 in_n_samples = out_n_samples = (unsigned) ((input->length / r->i_fz) * r->i_ss.channels);
1496
1497 if (have_leftover) {
1498 leftover_length = r->to_work_format_buf.length;
1499 out_n_samples += (unsigned) (leftover_length / r->w_sz);
1500 }
1501
1502 fit_buf(r, &r->to_work_format_buf, r->w_sz * out_n_samples, &r->to_work_format_buf_size, leftover_length);
1503
1504 src = pa_memblock_acquire_chunk(input);
1505 dst = (uint8_t *) pa_memblock_acquire(r->to_work_format_buf.memblock) + leftover_length;
1506
1507 if (r->to_work_format_func)
1508 r->to_work_format_func(in_n_samples, src, dst);
1509 else
1510 memcpy(dst, src, input->length);
1511
1512 pa_memblock_release(input->memblock);
1513 pa_memblock_release(r->to_work_format_buf.memblock);
1514
1515 return &r->to_work_format_buf;
1516 }
1517
remap_channels(pa_resampler * r,pa_memchunk * input)1518 static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
1519 unsigned in_n_samples, out_n_samples, in_n_frames, out_n_frames;
1520 void *src, *dst;
1521 size_t leftover_length = 0;
1522 bool have_leftover;
1523
1524 pa_assert(r);
1525 pa_assert(input);
1526 pa_assert(input->memblock);
1527
1528 /* Remap channels and place the result in remap_buf. There may be leftover
1529 * data in the beginning of remap_buf. The leftover data is already
1530 * remapped, so it's not part of the input, it's part of the output. */
1531
1532 have_leftover = r->leftover_in_remap;
1533 r->leftover_in_remap = false;
1534
1535 if (!have_leftover && (!r->map_required || input->length <= 0))
1536 return input;
1537 else if (input->length <= 0)
1538 return &r->remap_buf;
1539
1540 in_n_samples = (unsigned) (input->length / r->w_sz);
1541 in_n_frames = out_n_frames = in_n_samples / r->i_ss.channels;
1542
1543 if (have_leftover) {
1544 leftover_length = r->remap_buf.length;
1545 out_n_frames += leftover_length / r->w_fz;
1546 }
1547
1548 out_n_samples = out_n_frames * r->o_ss.channels;
1549 fit_buf(r, &r->remap_buf, out_n_samples * r->w_sz, &r->remap_buf_size, leftover_length);
1550
1551 src = pa_memblock_acquire_chunk(input);
1552 dst = (uint8_t *) pa_memblock_acquire(r->remap_buf.memblock) + leftover_length;
1553
1554 if (r->map_required) {
1555 pa_remap_t *remap = &r->remap;
1556
1557 pa_assert(remap->do_remap);
1558 remap->do_remap(remap, dst, src, in_n_frames);
1559
1560 } else
1561 memcpy(dst, src, input->length);
1562
1563 pa_memblock_release(input->memblock);
1564 pa_memblock_release(r->remap_buf.memblock);
1565
1566 return &r->remap_buf;
1567 }
1568
save_leftover(pa_resampler * r,void * buf,size_t len)1569 static void save_leftover(pa_resampler *r, void *buf, size_t len) {
1570 void *dst;
1571
1572 pa_assert(r);
1573 pa_assert(buf);
1574 pa_assert(len > 0);
1575
1576 /* Store the leftover data. */
1577 fit_buf(r, r->leftover_buf, len, r->leftover_buf_size, 0);
1578 *r->have_leftover = true;
1579
1580 dst = pa_memblock_acquire(r->leftover_buf->memblock);
1581 memmove(dst, buf, len);
1582 pa_memblock_release(r->leftover_buf->memblock);
1583 }
1584
resample(pa_resampler * r,pa_memchunk * input)1585 static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {
1586 unsigned in_n_frames, out_n_frames, leftover_n_frames;
1587
1588 pa_assert(r);
1589 pa_assert(input);
1590
1591 /* Resample the data and place the result in resample_buf. */
1592
1593 if (!r->impl.resample || !input->length)
1594 return input;
1595
1596 in_n_frames = (unsigned) (input->length / r->w_fz);
1597
1598 out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_FRAMES;
1599 fit_buf(r, &r->resample_buf, r->w_fz * out_n_frames, &r->resample_buf_size, 0);
1600
1601 leftover_n_frames = r->impl.resample(r, input, in_n_frames, &r->resample_buf, &out_n_frames);
1602
1603 if (leftover_n_frames > 0) {
1604 void *leftover_data = (uint8_t *) pa_memblock_acquire_chunk(input) + (in_n_frames - leftover_n_frames) * r->w_fz;
1605 save_leftover(r, leftover_data, leftover_n_frames * r->w_fz);
1606 pa_memblock_release(input->memblock);
1607 }
1608
1609 r->resample_buf.length = out_n_frames * r->w_fz;
1610
1611 return &r->resample_buf;
1612 }
1613
convert_from_work_format(pa_resampler * r,pa_memchunk * input)1614 static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input) {
1615 unsigned n_samples, n_frames;
1616 void *src, *dst;
1617
1618 pa_assert(r);
1619 pa_assert(input);
1620
1621 /* Convert the data into the correct sample type and place the result in
1622 * from_work_format_buf. */
1623
1624 if (!r->from_work_format_func || !input->length)
1625 return input;
1626
1627 n_samples = (unsigned) (input->length / r->w_sz);
1628 n_frames = n_samples / r->o_ss.channels;
1629 fit_buf(r, &r->from_work_format_buf, r->o_fz * n_frames, &r->from_work_format_buf_size, 0);
1630
1631 src = pa_memblock_acquire_chunk(input);
1632 dst = pa_memblock_acquire(r->from_work_format_buf.memblock);
1633 r->from_work_format_func(n_samples, src, dst);
1634 pa_memblock_release(input->memblock);
1635 pa_memblock_release(r->from_work_format_buf.memblock);
1636
1637 return &r->from_work_format_buf;
1638 }
1639
pa_resampler_run(pa_resampler * r,const pa_memchunk * in,pa_memchunk * out)1640 void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) {
1641 pa_memchunk *buf;
1642
1643 pa_assert(r);
1644 pa_assert(in);
1645 pa_assert(out);
1646 pa_assert(in->length);
1647 pa_assert(in->memblock);
1648 pa_assert(in->length % r->i_fz == 0);
1649
1650 /* If first frame and resampler doesn't init, push one frame to init.
1651 * Otherwise, resamplers demand 2 or 3 times to output*/
1652 if ((r->in_frames == 0) && (r->i_ss.rate != r->o_ss.rate)) {
1653 pa_memchunk dumpBuf;
1654 buf = &dumpBuf;
1655 size_t tempLength = r->i_fz * RESAMPLER_CACHE_SIZE_RATIO * r->o_fz;
1656 buf->length = tempLength;
1657 buf->memblock = pa_memblock_new(r->mempool, tempLength);
1658 buf->index = 0;
1659
1660 // silence memblock
1661 void *data = pa_memblock_acquire(buf->memblock);
1662 memset(data, 0, buf->length);
1663
1664 resample(r, buf);
1665 pa_memblock_release(buf->memblock);
1666 pa_memblock_unref(buf->memblock);
1667 }
1668
1669 buf = (pa_memchunk*) in;
1670 r->in_frames += buf->length / r->i_fz;
1671 buf = convert_to_work_format(r, buf);
1672
1673 /* Try to save resampling effort: if we have more output channels than
1674 * input channels, do resampling first, then remapping. */
1675 if (r->o_ss.channels <= r->i_ss.channels) {
1676 buf = remap_channels(r, buf);
1677 buf = resample(r, buf);
1678 } else {
1679 buf = resample(r, buf);
1680 buf = remap_channels(r, buf);
1681 }
1682
1683 if (r->lfe_filter)
1684 buf = pa_lfe_filter_process(r->lfe_filter, buf);
1685
1686 if (buf->length) {
1687 buf = convert_from_work_format(r, buf);
1688 *out = *buf;
1689 r->out_frames += buf->length / r->o_fz;
1690
1691 if (buf == in)
1692 pa_memblock_ref(buf->memblock);
1693 else
1694 pa_memchunk_reset(buf);
1695 } else
1696 pa_memchunk_reset(out);
1697 }
1698
1699 /* Get delay in input frames. Some resamplers may have negative delay. */
pa_resampler_get_delay(pa_resampler * r,bool allow_negative)1700 double pa_resampler_get_delay(pa_resampler *r, bool allow_negative) {
1701 double frames;
1702
1703 frames = r->out_frames * r->i_ss.rate / r->o_ss.rate;
1704 if (frames >= r->in_frames && !allow_negative)
1705 return 0;
1706 return r->in_frames - frames;
1707 }
1708
1709 /* Get delay in usec */
pa_resampler_get_delay_usec(pa_resampler * r)1710 pa_usec_t pa_resampler_get_delay_usec(pa_resampler *r) {
1711
1712 if (!r)
1713 return 0;
1714
1715 return (pa_usec_t) (pa_resampler_get_delay(r, false) * PA_USEC_PER_SEC / r->i_ss.rate);
1716 }
1717
1718 /* Get GCD of input and output rate. */
pa_resampler_get_gcd(pa_resampler * r)1719 unsigned pa_resampler_get_gcd(pa_resampler *r) {
1720 pa_assert(r);
1721
1722 return r->gcd;
1723 }
1724
1725 /* Get maximum resampler history. The resamplers have finite impulse response, so really old
1726 * data (more than 2x the resampler latency) cannot affect the output. This means, that in an
1727 * ideal case, we should re-run 2 - 3 times the resampler delay through the resampler when it
1728 * is rewound. On the other hand this would mean for high sample rates that more than 25000
1729 * samples would need to be used (384k * 33ms). Therefore limit the history to 1.5 times the
1730 * maximum resampler delay, which should be fully sufficient in most cases and allows to run
1731 * at least more than one delay through the resampler in case of high rates. */
pa_resampler_get_max_history(pa_resampler * r)1732 size_t pa_resampler_get_max_history(pa_resampler *r) {
1733
1734 if (!r)
1735 return 0;
1736
1737 return (uint64_t) PA_RESAMPLER_MAX_DELAY_USEC * r->i_ss.rate * 3 / PA_USEC_PER_SEC / 2;
1738 }
1739
1740 /*** copy (noop) implementation ***/
1741
copy_init(pa_resampler * r)1742 static int copy_init(pa_resampler *r) {
1743 pa_assert(r);
1744
1745 pa_assert(r->o_ss.rate == r->i_ss.rate);
1746
1747 return 0;
1748 }
1749