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