add API for resetting allocated resamplers
[pulseaudio.git] / src / pulsecore / resampler.c
blob40fc28004419d6377c2a82f2f0a5f0301e360a81
1 /* $Id$ */
3 /***
4 This file is part of PulseAudio.
6 Copyright 2004-2006 Lennart Poettering
8 PulseAudio is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published
10 by the Free Software Foundation; either version 2 of the License,
11 or (at your option) any later version.
13 PulseAudio is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with PulseAudio; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 USA.
22 ***/
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
28 #include <string.h>
30 #if HAVE_LIBSAMPLERATE
31 #include <samplerate.h>
32 #endif
34 #include <liboil/liboilfuncs.h>
35 #include <liboil/liboil.h>
37 #include <pulse/xmalloc.h>
38 #include <pulsecore/sconv.h>
39 #include <pulsecore/log.h>
40 #include <pulsecore/macro.h>
41 #include <pulsecore/strbuf.h>
43 #include "speexwrap.h"
45 #include "ffmpeg/avcodec.h"
47 #include "resampler.h"
49 /* Number of samples of extra space we allow the resamplers to return */
50 #define EXTRA_SAMPLES 128
52 struct pa_resampler {
53 pa_resample_method_t method;
54 pa_resample_flags_t flags;
56 pa_sample_spec i_ss, o_ss;
57 pa_channel_map i_cm, o_cm;
58 size_t i_fz, o_fz, w_sz;
59 pa_mempool *mempool;
61 pa_memchunk buf1, buf2, buf3, buf4;
62 unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples;
64 pa_sample_format_t work_format;
66 pa_convert_func_t to_work_format_func;
67 pa_convert_func_t from_work_format_func;
69 float map_table[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
70 pa_bool_t map_required;
72 void (*impl_free)(pa_resampler *r);
73 void (*impl_update_rates)(pa_resampler *r);
74 void (*impl_resample)(pa_resampler *r, const pa_memchunk *in, unsigned in_samples, pa_memchunk *out, unsigned *out_samples);
75 void (*impl_reset)(pa_resampler *r);
77 struct { /* data specific to the trivial resampler */
78 unsigned o_counter;
79 unsigned i_counter;
80 } trivial;
82 #ifdef HAVE_LIBSAMPLERATE
83 struct { /* data specific to libsamplerate */
84 SRC_STATE *state;
85 } src;
86 #endif
88 struct { /* data specific to speex */
89 SpeexResamplerState* state;
90 } speex;
92 struct { /* data specific to ffmpeg */
93 struct AVResampleContext *state;
94 pa_memchunk buf[PA_CHANNELS_MAX];
95 } ffmpeg;
98 static int copy_init(pa_resampler *r);
99 static int trivial_init(pa_resampler*r);
100 static int speex_init(pa_resampler*r);
101 static int ffmpeg_init(pa_resampler*r);
102 #ifdef HAVE_LIBSAMPLERATE
103 static int libsamplerate_init(pa_resampler*r);
104 #endif
106 static void calc_map_table(pa_resampler *r);
108 static int (* const init_table[])(pa_resampler*r) = {
109 #ifdef HAVE_LIBSAMPLERATE
110 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = libsamplerate_init,
111 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = libsamplerate_init,
112 [PA_RESAMPLER_SRC_SINC_FASTEST] = libsamplerate_init,
113 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = libsamplerate_init,
114 [PA_RESAMPLER_SRC_LINEAR] = libsamplerate_init,
115 #else
116 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = NULL,
117 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = NULL,
118 [PA_RESAMPLER_SRC_SINC_FASTEST] = NULL,
119 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = NULL,
120 [PA_RESAMPLER_SRC_LINEAR] = NULL,
121 #endif
122 [PA_RESAMPLER_TRIVIAL] = trivial_init,
123 [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = speex_init,
124 [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = speex_init,
125 [PA_RESAMPLER_SPEEX_FLOAT_BASE+2] = speex_init,
126 [PA_RESAMPLER_SPEEX_FLOAT_BASE+3] = speex_init,
127 [PA_RESAMPLER_SPEEX_FLOAT_BASE+4] = speex_init,
128 [PA_RESAMPLER_SPEEX_FLOAT_BASE+5] = speex_init,
129 [PA_RESAMPLER_SPEEX_FLOAT_BASE+6] = speex_init,
130 [PA_RESAMPLER_SPEEX_FLOAT_BASE+7] = speex_init,
131 [PA_RESAMPLER_SPEEX_FLOAT_BASE+8] = speex_init,
132 [PA_RESAMPLER_SPEEX_FLOAT_BASE+9] = speex_init,
133 [PA_RESAMPLER_SPEEX_FLOAT_BASE+10] = speex_init,
134 [PA_RESAMPLER_SPEEX_FIXED_BASE+0] = speex_init,
135 [PA_RESAMPLER_SPEEX_FIXED_BASE+1] = speex_init,
136 [PA_RESAMPLER_SPEEX_FIXED_BASE+2] = speex_init,
137 [PA_RESAMPLER_SPEEX_FIXED_BASE+3] = speex_init,
138 [PA_RESAMPLER_SPEEX_FIXED_BASE+4] = speex_init,
139 [PA_RESAMPLER_SPEEX_FIXED_BASE+5] = speex_init,
140 [PA_RESAMPLER_SPEEX_FIXED_BASE+6] = speex_init,
141 [PA_RESAMPLER_SPEEX_FIXED_BASE+7] = speex_init,
142 [PA_RESAMPLER_SPEEX_FIXED_BASE+8] = speex_init,
143 [PA_RESAMPLER_SPEEX_FIXED_BASE+9] = speex_init,
144 [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = speex_init,
145 [PA_RESAMPLER_FFMPEG] = ffmpeg_init,
146 [PA_RESAMPLER_AUTO] = NULL,
147 [PA_RESAMPLER_COPY] = copy_init
150 static inline size_t sample_size(pa_sample_format_t f) {
151 pa_sample_spec ss = {
152 .format = f,
153 .rate = 0,
154 .channels = 1
157 return pa_sample_size(&ss);
160 pa_resampler* pa_resampler_new(
161 pa_mempool *pool,
162 const pa_sample_spec *a,
163 const pa_channel_map *am,
164 const pa_sample_spec *b,
165 const pa_channel_map *bm,
166 pa_resample_method_t method,
167 pa_resample_flags_t flags) {
169 pa_resampler *r = NULL;
171 pa_assert(pool);
172 pa_assert(a);
173 pa_assert(b);
174 pa_assert(pa_sample_spec_valid(a));
175 pa_assert(pa_sample_spec_valid(b));
176 pa_assert(method >= 0);
177 pa_assert(method < PA_RESAMPLER_MAX);
179 /* Fix method */
181 if (!(flags & PA_RESAMPLER_VARIABLE_RATE) && a->rate == b->rate) {
182 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
183 method = PA_RESAMPLER_COPY;
186 if (!pa_resample_method_supported(method)) {
187 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method));
188 method = PA_RESAMPLER_AUTO;
191 if (method == PA_RESAMPLER_FFMPEG && (flags & PA_RESAMPLER_VARIABLE_RATE)) {
192 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
193 method = PA_RESAMPLER_AUTO;
196 if (method == PA_RESAMPLER_COPY && ((flags & PA_RESAMPLER_VARIABLE_RATE) || a->rate != b->rate)) {
197 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
198 method = PA_RESAMPLER_AUTO;
201 if (method == PA_RESAMPLER_AUTO)
202 method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
204 r = pa_xnew(pa_resampler, 1);
205 r->mempool = pool;
206 r->method = method;
207 r->flags = flags;
209 r->impl_free = NULL;
210 r->impl_update_rates = NULL;
211 r->impl_resample = NULL;
212 r->impl_reset = NULL;
214 /* Fill sample specs */
215 r->i_ss = *a;
216 r->o_ss = *b;
218 if (am)
219 r->i_cm = *am;
220 else
221 pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels, PA_CHANNEL_MAP_DEFAULT);
223 if (bm)
224 r->o_cm = *bm;
225 else
226 pa_channel_map_init_auto(&r->o_cm, r->o_ss.channels, PA_CHANNEL_MAP_DEFAULT);
228 r->i_fz = pa_frame_size(a);
229 r->o_fz = pa_frame_size(b);
231 pa_memchunk_reset(&r->buf1);
232 pa_memchunk_reset(&r->buf2);
233 pa_memchunk_reset(&r->buf3);
234 pa_memchunk_reset(&r->buf4);
236 r->buf1_samples = r->buf2_samples = r->buf3_samples = r->buf4_samples = 0;
238 calc_map_table(r);
240 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method));
242 if ((method >= PA_RESAMPLER_SPEEX_FIXED_BASE && method <= PA_RESAMPLER_SPEEX_FIXED_MAX) ||
243 (method == PA_RESAMPLER_FFMPEG))
244 r->work_format = PA_SAMPLE_S16NE;
245 else if (method == PA_RESAMPLER_TRIVIAL || method == PA_RESAMPLER_COPY) {
247 if (r->map_required || a->format != b->format) {
249 if (a->format == PA_SAMPLE_S32NE || a->format == PA_SAMPLE_S32RE ||
250 a->format == PA_SAMPLE_FLOAT32NE || a->format == PA_SAMPLE_FLOAT32RE ||
251 b->format == PA_SAMPLE_S32NE || b->format == PA_SAMPLE_S32RE ||
252 b->format == PA_SAMPLE_FLOAT32NE || b->format == PA_SAMPLE_FLOAT32RE)
253 r->work_format = PA_SAMPLE_FLOAT32NE;
254 else
255 r->work_format = PA_SAMPLE_S16NE;
257 } else
258 r->work_format = a->format;
260 } else
261 r->work_format = PA_SAMPLE_FLOAT32NE;
263 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r->work_format));
265 r->w_sz = sample_size(r->work_format);
267 if (r->i_ss.format == r->work_format)
268 r->to_work_format_func = NULL;
269 else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
270 if (!(r->to_work_format_func = pa_get_convert_to_float32ne_function(r->i_ss.format)))
271 goto fail;
272 } else {
273 pa_assert(r->work_format == PA_SAMPLE_S16NE);
274 if (!(r->to_work_format_func = pa_get_convert_to_s16ne_function(r->i_ss.format)))
275 goto fail;
278 if (r->o_ss.format == r->work_format)
279 r->from_work_format_func = NULL;
280 else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
281 if (!(r->from_work_format_func = pa_get_convert_from_float32ne_function(r->o_ss.format)))
282 goto fail;
283 } else {
284 pa_assert(r->work_format == PA_SAMPLE_S16NE);
285 if (!(r->from_work_format_func = pa_get_convert_from_s16ne_function(r->o_ss.format)))
286 goto fail;
289 /* initialize implementation */
290 if (init_table[method](r) < 0)
291 goto fail;
293 return r;
295 fail:
296 if (r)
297 pa_xfree(r);
299 return NULL;
302 void pa_resampler_free(pa_resampler *r) {
303 pa_assert(r);
305 if (r->impl_free)
306 r->impl_free(r);
308 if (r->buf1.memblock)
309 pa_memblock_unref(r->buf1.memblock);
310 if (r->buf2.memblock)
311 pa_memblock_unref(r->buf2.memblock);
312 if (r->buf3.memblock)
313 pa_memblock_unref(r->buf3.memblock);
314 if (r->buf4.memblock)
315 pa_memblock_unref(r->buf4.memblock);
317 pa_xfree(r);
320 void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) {
321 pa_assert(r);
322 pa_assert(rate > 0);
324 if (r->i_ss.rate == rate)
325 return;
327 r->i_ss.rate = rate;
329 r->impl_update_rates(r);
332 void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) {
333 pa_assert(r);
334 pa_assert(rate > 0);
336 if (r->o_ss.rate == rate)
337 return;
339 r->o_ss.rate = rate;
341 r->impl_update_rates(r);
344 size_t pa_resampler_request(pa_resampler *r, size_t out_length) {
345 pa_assert(r);
347 return (((out_length / r->o_fz)*r->i_ss.rate)/r->o_ss.rate) * r->i_fz;
350 size_t pa_resampler_max_block_size(pa_resampler *r) {
351 size_t block_size_max;
352 pa_sample_spec ss;
353 size_t fs;
355 pa_assert(r);
357 block_size_max = pa_mempool_block_size_max(r->mempool);
359 /* We deduce the "largest" sample spec we're using during the
360 * conversion */
361 ss = r->i_ss;
362 if (r->o_ss.channels > ss.channels)
363 ss.channels = r->o_ss.channels;
365 /* We silently assume that the format enum is ordered by size */
366 if (r->o_ss.format > ss.format)
367 ss.format = r->o_ss.format;
368 if (r->work_format > ss.format)
369 ss.format = r->work_format;
371 if (r->o_ss.rate > ss.rate)
372 ss.rate = r->o_ss.rate;
374 fs = pa_frame_size(&ss);
376 return (((block_size_max/fs + EXTRA_SAMPLES)*r->i_ss.rate)/ss.rate)*r->i_fz;
379 void pa_resampler_reset(pa_resampler *r) {
380 pa_assert(r);
382 if (r->impl_reset)
383 r->impl_reset(r);
386 pa_resample_method_t pa_resampler_get_method(pa_resampler *r) {
387 pa_assert(r);
389 return r->method;
392 static const char * const resample_methods[] = {
393 "src-sinc-best-quality",
394 "src-sinc-medium-quality",
395 "src-sinc-fastest",
396 "src-zero-order-hold",
397 "src-linear",
398 "trivial",
399 "speex-float-0",
400 "speex-float-1",
401 "speex-float-2",
402 "speex-float-3",
403 "speex-float-4",
404 "speex-float-5",
405 "speex-float-6",
406 "speex-float-7",
407 "speex-float-8",
408 "speex-float-9",
409 "speex-float-10",
410 "speex-fixed-0",
411 "speex-fixed-1",
412 "speex-fixed-2",
413 "speex-fixed-3",
414 "speex-fixed-4",
415 "speex-fixed-5",
416 "speex-fixed-6",
417 "speex-fixed-7",
418 "speex-fixed-8",
419 "speex-fixed-9",
420 "speex-fixed-10",
421 "ffmpeg",
422 "auto",
423 "copy"
426 const char *pa_resample_method_to_string(pa_resample_method_t m) {
428 if (m < 0 || m >= PA_RESAMPLER_MAX)
429 return NULL;
431 return resample_methods[m];
434 int pa_resample_method_supported(pa_resample_method_t m) {
436 if (m < 0 || m >= PA_RESAMPLER_MAX)
437 return 0;
439 #ifndef HAVE_LIBSAMPLERATE
440 if (m <= PA_RESAMPLER_SRC_LINEAR)
441 return 0;
442 #endif
444 return 1;
447 pa_resample_method_t pa_parse_resample_method(const char *string) {
448 pa_resample_method_t m;
450 pa_assert(string);
452 for (m = 0; m < PA_RESAMPLER_MAX; m++)
453 if (!strcmp(string, resample_methods[m]))
454 return m;
456 if (!strcmp(string, "speex-fixed"))
457 return PA_RESAMPLER_SPEEX_FIXED_BASE + 3;
459 if (!strcmp(string, "speex-float"))
460 return PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
462 return PA_RESAMPLER_INVALID;
465 static pa_bool_t on_left(pa_channel_position_t p) {
467 return
468 p == PA_CHANNEL_POSITION_FRONT_LEFT ||
469 p == PA_CHANNEL_POSITION_REAR_LEFT ||
470 p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ||
471 p == PA_CHANNEL_POSITION_SIDE_LEFT ||
472 p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT ||
473 p == PA_CHANNEL_POSITION_TOP_REAR_LEFT;
476 static pa_bool_t on_right(pa_channel_position_t p) {
478 return
479 p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
480 p == PA_CHANNEL_POSITION_REAR_RIGHT ||
481 p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER ||
482 p == PA_CHANNEL_POSITION_SIDE_RIGHT ||
483 p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ||
484 p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
487 static pa_bool_t on_center(pa_channel_position_t p) {
489 return
490 p == PA_CHANNEL_POSITION_FRONT_CENTER ||
491 p == PA_CHANNEL_POSITION_REAR_CENTER ||
492 p == PA_CHANNEL_POSITION_TOP_CENTER ||
493 p == PA_CHANNEL_POSITION_TOP_FRONT_CENTER ||
494 p == PA_CHANNEL_POSITION_TOP_REAR_CENTER;
497 static pa_bool_t on_lfe(pa_channel_position_t p) {
498 return
499 p == PA_CHANNEL_POSITION_LFE;
502 static void calc_map_table(pa_resampler *r) {
503 unsigned oc, ic;
504 pa_bool_t ic_connected[PA_CHANNELS_MAX];
505 pa_bool_t remix;
506 pa_strbuf *s;
507 char *t;
509 pa_assert(r);
511 if (!(r->map_required = (r->i_ss.channels != r->o_ss.channels || (!(r->flags & PA_RESAMPLER_NO_REMAP) && !pa_channel_map_equal(&r->i_cm, &r->o_cm)))))
512 return;
514 memset(r->map_table, 0, sizeof(r->map_table));
515 memset(ic_connected, 0, sizeof(ic_connected));
516 remix = (r->flags & (PA_RESAMPLER_NO_REMAP|PA_RESAMPLER_NO_REMIX)) == 0;
518 for (oc = 0; oc < r->o_ss.channels; oc++) {
519 pa_bool_t oc_connected = FALSE;
520 pa_channel_position_t b = r->o_cm.map[oc];
522 for (ic = 0; ic < r->i_ss.channels; ic++) {
523 pa_channel_position_t a = r->i_cm.map[ic];
525 if (r->flags & PA_RESAMPLER_NO_REMAP) {
526 /* We shall not do any remapping. Hence, just check by index */
528 if (ic == oc)
529 r->map_table[oc][ic] = 1.0;
531 continue;
534 if (r->flags & PA_RESAMPLER_NO_REMIX) {
535 /* We shall not do any remixing. Hence, just check by name */
537 if (a == b)
538 r->map_table[oc][ic] = 1.0;
540 continue;
543 pa_assert(remix);
545 /* OK, we shall do the full monty: upmixing and
546 * downmixing. Our algorithm is relatively simple, does
547 * not do spacialization, delay elements or apply lowpass
548 * filters for LFE. Patches are always welcome,
549 * though. Oh, and it doesn't do any matrix
550 * decoding. (Which probably wouldn't make any sense
551 * anyway.)
553 * This code is not idempotent: downmixing an upmixed
554 * stereo stream is not identical to the original. The
555 * volume will not match, and the two channels will be a
556 * linear combination of both.
558 * This is losely based on random suggestions found on the
559 * Internet, such as this:
560 * http://www.halfgaar.net/surround-sound-in-linux and the
561 * alsa upmix plugin.
563 * The algorithm works basically like this:
565 * 1) Connect all channels with matching names.
567 * 2) Mono Handling:
568 * S:Mono: Copy into all D:channels
569 * D:Mono: Copy in all S:channels
571 * 3) Mix D:Left, D:Right:
572 * D:Left: If not connected, avg all S:Left
573 * D:Right: If not connected, avg all S:Right
575 * 4) Mix D:Center
576 * If not connected, avg all S:Center
577 * If still not connected, avg all S:Left, S:Right
579 * 5) Mix D:LFE
580 * If not connected, avg all S:*
582 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
583 * not connected, mix into all D:left and all D:right
584 * channels. Gain is 0.1, the current left and right
585 * should be multiplied by 0.9.
587 * 7) Make sure S:Center, S:LFE is used:
589 * S:Center, S:LFE: If not connected, mix into all
590 * D:left, all D:right, all D:center channels, gain is
591 * 0.375. The current (as result of 1..6) factors
592 * should be multiplied by 0.75. (Alt. suggestion: 0.25
593 * vs. 0.5)
595 * S: and D: shall relate to the source resp. destination channels.
597 * Rationale: 1, 2 are probably obvious. For 3: this
598 * copies front to rear if needed. For 4: we try to find
599 * some suitable C source for C, if we don't find any, we
600 * avg L and R. For 5: LFE is mixed from all channels. For
601 * 6: the rear channels should not be dropped entirely,
602 * however have only minimal impact. For 7: movies usually
603 * encode speech on the center channel. Thus we have to
604 * make sure this channel is distributed to L and R if not
605 * available in the output. Also, LFE is used to achieve a
606 * greater dynamic range, and thus we should try to do our
607 * best to pass it to L+R.
610 if (a == b || a == PA_CHANNEL_POSITION_MONO || b == PA_CHANNEL_POSITION_MONO) {
611 r->map_table[oc][ic] = 1.0;
613 oc_connected = TRUE;
614 ic_connected[ic] = TRUE;
618 if (!oc_connected && remix) {
619 /* OK, we shall remix */
621 if (on_left(b)) {
622 unsigned n = 0;
624 /* We are not connected and on the left side, let's
625 * average all left side input channels. */
627 for (ic = 0; ic < r->i_ss.channels; ic++)
628 if (on_left(r->i_cm.map[ic]))
629 n++;
631 if (n > 0)
632 for (ic = 0; ic < r->i_ss.channels; ic++)
633 if (on_left(r->i_cm.map[ic])) {
634 r->map_table[oc][ic] = 1.0 / n;
635 ic_connected[ic] = TRUE;
638 /* We ignore the case where there is no left input
639 * channel. Something is really wrong in this case
640 * anyway. */
642 } else if (on_right(b)) {
643 unsigned n = 0;
645 /* We are not connected and on the right side, let's
646 * average all right side input channels. */
648 for (ic = 0; ic < r->i_ss.channels; ic++)
649 if (on_right(r->i_cm.map[ic]))
650 n++;
652 if (n > 0)
653 for (ic = 0; ic < r->i_ss.channels; ic++)
654 if (on_right(r->i_cm.map[ic])) {
655 r->map_table[oc][ic] = 1.0 / n;
656 ic_connected[ic] = TRUE;
659 /* We ignore the case where there is no right input
660 * channel. Something is really wrong in this case
661 * anyway. */
663 } else if (on_center(b)) {
664 unsigned n = 0;
666 /* We are not connected and at the center. Let's
667 * average all center input channels. */
669 for (ic = 0; ic < r->i_ss.channels; ic++)
670 if (on_center(r->i_cm.map[ic]))
671 n++;
673 if (n > 0) {
674 for (ic = 0; ic < r->i_ss.channels; ic++)
675 if (on_center(r->i_cm.map[ic])) {
676 r->map_table[oc][ic] = 1.0 / n;
677 ic_connected[ic] = TRUE;
679 } else {
681 /* Hmm, no center channel around, let's synthesize
682 * it by mixing L and R.*/
684 n = 0;
686 for (ic = 0; ic < r->i_ss.channels; ic++)
687 if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic]))
688 n++;
690 if (n > 0)
691 for (ic = 0; ic < r->i_ss.channels; ic++)
692 if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic])) {
693 r->map_table[oc][ic] = 1.0 / n;
694 ic_connected[ic] = TRUE;
697 /* We ignore the case where there is not even a
698 * left or right input channel. Something is
699 * really wrong in this case anyway. */
702 } else if (on_lfe(b)) {
704 /* We are not connected and an LFE. Let's average all
705 * channels for LFE. */
707 for (ic = 0; ic < r->i_ss.channels; ic++) {
708 r->map_table[oc][ic] = 1.0 / r->i_ss.channels;
710 /* Please note that a channel connected to LFE
711 * doesn't really count as connected. */
717 if (remix) {
718 unsigned
719 ic_unconnected_left = 0,
720 ic_unconnected_right = 0,
721 ic_unconnected_center = 0,
722 ic_unconnected_lfe = 0;
724 for (ic = 0; ic < r->i_ss.channels; ic++) {
725 pa_channel_position_t a = r->i_cm.map[ic];
727 if (ic_connected[ic])
728 continue;
730 if (on_left(a))
731 ic_unconnected_left++;
732 else if (on_right(a))
733 ic_unconnected_right++;
734 else if (on_center(a))
735 ic_unconnected_center++;
736 else if (on_lfe(a))
737 ic_unconnected_lfe++;
740 if (ic_unconnected_left > 0) {
742 /* OK, so there are unconnected input channels on the
743 * left. Let's multiply all already connected channels on
744 * the left side by .9 and add in our averaged unconnected
745 * channels multplied by .1 */
747 for (oc = 0; oc < r->o_ss.channels; oc++) {
749 if (!on_left(r->o_cm.map[oc]))
750 continue;
752 for (ic = 0; ic < r->i_ss.channels; ic++) {
754 if (ic_connected[ic]) {
755 r->map_table[oc][ic] *= .9;
756 continue;
759 if (on_left(r->i_cm.map[ic]))
760 r->map_table[oc][ic] = .1 / ic_unconnected_left;
765 if (ic_unconnected_right > 0) {
767 /* OK, so there are unconnected input channels on the
768 * right. Let's multiply all already connected channels on
769 * the right side by .9 and add in our averaged unconnected
770 * channels multplied by .1 */
772 for (oc = 0; oc < r->o_ss.channels; oc++) {
774 if (!on_right(r->o_cm.map[oc]))
775 continue;
777 for (ic = 0; ic < r->i_ss.channels; ic++) {
779 if (ic_connected[ic]) {
780 r->map_table[oc][ic] *= .9;
781 continue;
784 if (on_right(r->i_cm.map[ic]))
785 r->map_table[oc][ic] = .1 / ic_unconnected_right;
790 if (ic_unconnected_center > 0) {
791 pa_bool_t mixed_in = FALSE;
793 /* OK, so there are unconnected input channels on the
794 * center. Let's multiply all already connected channels on
795 * the center side by .9 and add in our averaged unconnected
796 * channels multplied by .1 */
798 for (oc = 0; oc < r->o_ss.channels; oc++) {
800 if (!on_center(r->o_cm.map[oc]))
801 continue;
803 for (ic = 0; ic < r->i_ss.channels; ic++) {
805 if (ic_connected[ic]) {
806 r->map_table[oc][ic] *= .9;
807 continue;
810 if (on_center(r->i_cm.map[ic])) {
811 r->map_table[oc][ic] = .1 / ic_unconnected_center;
812 mixed_in = TRUE;
817 if (!mixed_in) {
819 /* Hmm, as it appears there was no center channel we
820 could mix our center channel in. In this case, mix
821 it into left and right. Using .375 and 0.75 as
822 factors. */
824 for (oc = 0; oc < r->o_ss.channels; oc++) {
826 if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
827 continue;
829 for (ic = 0; ic < r->i_ss.channels; ic++) {
831 if (ic_connected[ic]) {
832 r->map_table[oc][ic] *= .75;
833 continue;
836 if (on_center(r->i_cm.map[ic]))
837 r->map_table[oc][ic] = .375 / ic_unconnected_center;
843 if (ic_unconnected_lfe > 0) {
845 /* OK, so there is an unconnected LFE channel. Let's mix
846 * it into all channels, with factor 0.375 */
848 for (ic = 0; ic < r->i_ss.channels; ic++) {
850 if (!on_lfe(r->i_cm.map[ic]))
851 continue;
853 for (oc = 0; oc < r->o_ss.channels; oc++)
854 r->map_table[oc][ic] = 0.375 / ic_unconnected_lfe;
860 s = pa_strbuf_new();
862 pa_strbuf_printf(s, " ");
863 for (ic = 0; ic < r->i_ss.channels; ic++)
864 pa_strbuf_printf(s, " I%02u ", ic);
865 pa_strbuf_puts(s, "\n +");
867 for (ic = 0; ic < r->i_ss.channels; ic++)
868 pa_strbuf_printf(s, "------");
869 pa_strbuf_puts(s, "\n");
871 for (oc = 0; oc < r->o_ss.channels; oc++) {
872 pa_strbuf_printf(s, "O%02u |", oc);
874 for (ic = 0; ic < r->i_ss.channels; ic++)
875 pa_strbuf_printf(s, " %1.3f", r->map_table[oc][ic]);
877 pa_strbuf_puts(s, "\n");
880 pa_log_debug("Channel matrix:\n%s", t = pa_strbuf_tostring_free(s));
881 pa_xfree(t);
884 static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) {
885 unsigned n_samples;
886 void *src, *dst;
888 pa_assert(r);
889 pa_assert(input);
890 pa_assert(input->memblock);
892 /* Convert the incoming sample into the work sample format and place them in buf1 */
894 if (!r->to_work_format_func || !input->length)
895 return input;
897 n_samples = (input->length / r->i_fz) * r->i_ss.channels;
899 r->buf1.index = 0;
900 r->buf1.length = r->w_sz * n_samples;
902 if (!r->buf1.memblock || r->buf1_samples < n_samples) {
903 if (r->buf1.memblock)
904 pa_memblock_unref(r->buf1.memblock);
906 r->buf1_samples = n_samples;
907 r->buf1.memblock = pa_memblock_new(r->mempool, r->buf1.length);
910 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
911 dst = (uint8_t*) pa_memblock_acquire(r->buf1.memblock);
913 r->to_work_format_func(n_samples, src, dst);
915 pa_memblock_release(input->memblock);
916 pa_memblock_release(r->buf1.memblock);
918 return &r->buf1;
921 static void vectoradd_s16_with_fraction(
922 int16_t *d, int dstr,
923 const int16_t *s1, int sstr1,
924 const int16_t *s2, int sstr2,
925 int n,
926 float s3, float s4) {
928 int32_t i3, i4;
930 i3 = (int32_t) (s3 * 0x10000);
931 i4 = (int32_t) (s4 * 0x10000);
933 for (; n > 0; n--) {
934 int32_t a, b;
936 a = *s1;
937 b = *s2;
939 a = (a * i3) / 0x10000;
940 b = (b * i4) / 0x10000;
942 *d = (int16_t) (a + b);
944 s1 = (const int16_t*) ((const uint8_t*) s1 + sstr1);
945 s2 = (const int16_t*) ((const uint8_t*) s2 + sstr2);
946 d = (int16_t*) ((uint8_t*) d + dstr);
951 static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
952 unsigned in_n_samples, out_n_samples, n_frames;
953 int i_skip, o_skip;
954 unsigned oc;
955 void *src, *dst;
957 pa_assert(r);
958 pa_assert(input);
959 pa_assert(input->memblock);
961 /* Remap channels and place the result int buf2 */
963 if (!r->map_required || !input->length)
964 return input;
966 in_n_samples = input->length / r->w_sz;
967 n_frames = in_n_samples / r->i_ss.channels;
968 out_n_samples = n_frames * r->o_ss.channels;
970 r->buf2.index = 0;
971 r->buf2.length = r->w_sz * out_n_samples;
973 if (!r->buf2.memblock || r->buf2_samples < out_n_samples) {
974 if (r->buf2.memblock)
975 pa_memblock_unref(r->buf2.memblock);
977 r->buf2_samples = out_n_samples;
978 r->buf2.memblock = pa_memblock_new(r->mempool, r->buf2.length);
981 src = ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
982 dst = pa_memblock_acquire(r->buf2.memblock);
984 memset(dst, 0, r->buf2.length);
986 o_skip = r->w_sz * r->o_ss.channels;
987 i_skip = r->w_sz * r->i_ss.channels;
989 switch (r->work_format) {
990 case PA_SAMPLE_FLOAT32NE:
992 for (oc = 0; oc < r->o_ss.channels; oc++) {
993 unsigned ic;
994 static const float one = 1.0;
996 for (ic = 0; ic < r->i_ss.channels; ic++) {
998 if (r->map_table[oc][ic] <= 0.0)
999 continue;
1001 oil_vectoradd_f32(
1002 (float*) dst + oc, o_skip,
1003 (float*) dst + oc, o_skip,
1004 (float*) src + ic, i_skip,
1005 n_frames,
1006 &one, &r->map_table[oc][ic]);
1010 break;
1012 case PA_SAMPLE_S16NE:
1014 for (oc = 0; oc < r->o_ss.channels; oc++) {
1015 unsigned ic;
1017 for (ic = 0; ic < r->i_ss.channels; ic++) {
1019 if (r->map_table[oc][ic] <= 0.0)
1020 continue;
1022 if (r->map_table[oc][ic] >= 1.0) {
1023 static const int16_t one = 1;
1025 oil_vectoradd_s16(
1026 (int16_t*) dst + oc, o_skip,
1027 (int16_t*) dst + oc, o_skip,
1028 (int16_t*) src + ic, i_skip,
1029 n_frames,
1030 &one, &one);
1032 } else
1034 vectoradd_s16_with_fraction(
1035 (int16_t*) dst + oc, o_skip,
1036 (int16_t*) dst + oc, o_skip,
1037 (int16_t*) src + ic, i_skip,
1038 n_frames,
1039 1.0, r->map_table[oc][ic]);
1043 break;
1045 default:
1046 pa_assert_not_reached();
1049 pa_memblock_release(input->memblock);
1050 pa_memblock_release(r->buf2.memblock);
1052 r->buf2.length = out_n_samples * r->w_sz;
1054 return &r->buf2;
1057 static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {
1058 unsigned in_n_frames, in_n_samples;
1059 unsigned out_n_frames, out_n_samples;
1061 pa_assert(r);
1062 pa_assert(input);
1064 /* Resample the data and place the result in buf3 */
1066 if (!r->impl_resample || !input->length)
1067 return input;
1069 in_n_samples = input->length / r->w_sz;
1070 in_n_frames = in_n_samples / r->o_ss.channels;
1072 out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_SAMPLES;
1073 out_n_samples = out_n_frames * r->o_ss.channels;
1075 r->buf3.index = 0;
1076 r->buf3.length = r->w_sz * out_n_samples;
1078 if (!r->buf3.memblock || r->buf3_samples < out_n_samples) {
1079 if (r->buf3.memblock)
1080 pa_memblock_unref(r->buf3.memblock);
1082 r->buf3_samples = out_n_samples;
1083 r->buf3.memblock = pa_memblock_new(r->mempool, r->buf3.length);
1086 r->impl_resample(r, input, in_n_frames, &r->buf3, &out_n_frames);
1087 r->buf3.length = out_n_frames * r->w_sz * r->o_ss.channels;
1089 return &r->buf3;
1092 static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input) {
1093 unsigned n_samples, n_frames;
1094 void *src, *dst;
1096 pa_assert(r);
1097 pa_assert(input);
1099 /* Convert the data into the correct sample type and place the result in buf4 */
1101 if (!r->from_work_format_func || !input->length)
1102 return input;
1104 n_samples = input->length / r->w_sz;
1105 n_frames = n_samples / r->o_ss.channels;
1107 r->buf4.index = 0;
1108 r->buf4.length = r->o_fz * n_frames;
1110 if (!r->buf4.memblock || r->buf4_samples < n_samples) {
1111 if (r->buf4.memblock)
1112 pa_memblock_unref(r->buf4.memblock);
1114 r->buf4_samples = n_samples;
1115 r->buf4.memblock = pa_memblock_new(r->mempool, r->buf4.length);
1118 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
1119 dst = pa_memblock_acquire(r->buf4.memblock);
1120 r->from_work_format_func(n_samples, src, dst);
1121 pa_memblock_release(input->memblock);
1122 pa_memblock_release(r->buf4.memblock);
1124 r->buf4.length = r->o_fz * n_frames;
1126 return &r->buf4;
1129 void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) {
1130 pa_memchunk *buf;
1132 pa_assert(r);
1133 pa_assert(in);
1134 pa_assert(out);
1135 pa_assert(in->length);
1136 pa_assert(in->memblock);
1137 pa_assert(in->length % r->i_fz == 0);
1139 buf = (pa_memchunk*) in;
1140 buf = convert_to_work_format(r, buf);
1141 buf = remap_channels(r, buf);
1142 buf = resample(r, buf);
1144 if (buf->length) {
1145 buf = convert_from_work_format(r, buf);
1146 *out = *buf;
1148 if (buf == in)
1149 pa_memblock_ref(buf->memblock);
1150 else
1151 pa_memchunk_reset(buf);
1152 } else
1153 pa_memchunk_reset(out);
1156 /*** libsamplerate based implementation ***/
1158 #ifdef HAVE_LIBSAMPLERATE
1159 static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1160 SRC_DATA data;
1162 pa_assert(r);
1163 pa_assert(input);
1164 pa_assert(output);
1165 pa_assert(out_n_frames);
1167 memset(&data, 0, sizeof(data));
1169 data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
1170 data.input_frames = in_n_frames;
1172 data.data_out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
1173 data.output_frames = *out_n_frames;
1175 data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate;
1176 data.end_of_input = 0;
1178 pa_assert_se(src_process(r->src.state, &data) == 0);
1179 pa_assert((unsigned) data.input_frames_used == in_n_frames);
1181 pa_memblock_release(input->memblock);
1182 pa_memblock_release(output->memblock);
1184 *out_n_frames = data.output_frames_gen;
1187 static void libsamplerate_update_rates(pa_resampler *r) {
1188 pa_assert(r);
1190 pa_assert_se(src_set_ratio(r->src.state, (double) r->o_ss.rate / r->i_ss.rate) == 0);
1193 static void libsamplerate_reset(pa_resampler *r) {
1194 pa_assert(r);
1196 pa_assert_se(src_reset(r->src.state) == 0);
1199 static void libsamplerate_free(pa_resampler *r) {
1200 pa_assert(r);
1202 if (r->src.state)
1203 src_delete(r->src.state);
1206 static int libsamplerate_init(pa_resampler *r) {
1207 int err;
1209 pa_assert(r);
1211 if (!(r->src.state = src_new(r->method, r->o_ss.channels, &err)))
1212 return -1;
1214 r->impl_free = libsamplerate_free;
1215 r->impl_update_rates = libsamplerate_update_rates;
1216 r->impl_resample = libsamplerate_resample;
1217 r->impl_reset = libsamplerate_reset;
1219 return 0;
1221 #endif
1223 /*** speex based implementation ***/
1225 static void speex_resample_float(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1226 float *in, *out;
1227 uint32_t inf = in_n_frames, outf = *out_n_frames;
1229 pa_assert(r);
1230 pa_assert(input);
1231 pa_assert(output);
1232 pa_assert(out_n_frames);
1234 in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
1235 out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
1237 pa_assert_se(paspfl_resampler_process_interleaved_float(r->speex.state, in, &inf, out, &outf) == 0);
1239 pa_memblock_release(input->memblock);
1240 pa_memblock_release(output->memblock);
1242 pa_assert(inf == in_n_frames);
1243 *out_n_frames = outf;
1246 static void speex_resample_int(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1247 int16_t *in, *out;
1248 uint32_t inf = in_n_frames, outf = *out_n_frames;
1250 pa_assert(r);
1251 pa_assert(input);
1252 pa_assert(output);
1253 pa_assert(out_n_frames);
1255 in = (int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
1256 out = (int16_t*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
1258 pa_assert_se(paspfx_resampler_process_interleaved_int(r->speex.state, in, &inf, out, &outf) == 0);
1260 pa_memblock_release(input->memblock);
1261 pa_memblock_release(output->memblock);
1263 pa_assert(inf == in_n_frames);
1264 *out_n_frames = outf;
1267 static void speex_update_rates(pa_resampler *r) {
1268 pa_assert(r);
1270 if (r->method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
1271 pa_assert_se(paspfx_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0);
1272 else {
1273 pa_assert(r->method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
1274 pa_assert_se(paspfl_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0);
1278 static void speex_reset(pa_resampler *r) {
1279 pa_assert(r);
1281 if (r->method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
1282 pa_assert_se(paspfx_resampler_reset_mem(r->speex.state) == 0);
1283 else {
1284 pa_assert(r->method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
1285 pa_assert_se(paspfl_resampler_reset_mem(r->speex.state) == 0);
1289 static void speex_free(pa_resampler *r) {
1290 pa_assert(r);
1292 if (!r->speex.state)
1293 return;
1295 if (r->method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
1296 paspfx_resampler_destroy(r->speex.state);
1297 else {
1298 pa_assert(r->method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
1299 paspfl_resampler_destroy(r->speex.state);
1303 static int speex_init(pa_resampler *r) {
1304 int q, err;
1306 pa_assert(r);
1308 r->impl_free = speex_free;
1309 r->impl_update_rates = speex_update_rates;
1310 r->impl_reset = speex_reset;
1312 if (r->method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->method <= PA_RESAMPLER_SPEEX_FIXED_MAX) {
1313 q = r->method - PA_RESAMPLER_SPEEX_FIXED_BASE;
1315 pa_log_info("Choosing speex quality setting %i.", q);
1317 if (!(r->speex.state = paspfx_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
1318 return -1;
1320 r->impl_resample = speex_resample_int;
1321 } else {
1322 pa_assert(r->method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
1323 q = r->method - PA_RESAMPLER_SPEEX_FLOAT_BASE;
1325 pa_log_info("Choosing speex quality setting %i.", q);
1327 if (!(r->speex.state = paspfl_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
1328 return -1;
1330 r->impl_resample = speex_resample_float;
1333 return 0;
1336 /* Trivial implementation */
1338 static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1339 size_t fz;
1340 unsigned o_index;
1341 void *src, *dst;
1343 pa_assert(r);
1344 pa_assert(input);
1345 pa_assert(output);
1346 pa_assert(out_n_frames);
1348 fz = r->w_sz * r->o_ss.channels;
1350 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
1351 dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
1353 for (o_index = 0;; o_index++, r->trivial.o_counter++) {
1354 unsigned j;
1356 j = ((r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate);
1357 j = j > r->trivial.i_counter ? j - r->trivial.i_counter : 0;
1359 if (j >= in_n_frames)
1360 break;
1362 pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
1364 oil_memcpy((uint8_t*) dst + fz * o_index,
1365 (uint8_t*) src + fz * j, fz);
1368 pa_memblock_release(input->memblock);
1369 pa_memblock_release(output->memblock);
1371 *out_n_frames = o_index;
1373 r->trivial.i_counter += in_n_frames;
1375 /* Normalize counters */
1376 while (r->trivial.i_counter >= r->i_ss.rate) {
1377 pa_assert(r->trivial.o_counter >= r->o_ss.rate);
1379 r->trivial.i_counter -= r->i_ss.rate;
1380 r->trivial.o_counter -= r->o_ss.rate;
1384 static void trivial_update_rates_or_reset(pa_resampler *r) {
1385 pa_assert(r);
1387 r->trivial.i_counter = 0;
1388 r->trivial.o_counter = 0;
1391 static int trivial_init(pa_resampler*r) {
1392 pa_assert(r);
1394 r->trivial.o_counter = r->trivial.i_counter = 0;
1396 r->impl_resample = trivial_resample;
1397 r->impl_update_rates = trivial_update_rates_or_reset;
1398 r->impl_reset = trivial_update_rates_or_reset;
1400 return 0;
1403 /*** ffmpeg based implementation ***/
1405 static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1406 unsigned used_frames = 0, c;
1408 pa_assert(r);
1409 pa_assert(input);
1410 pa_assert(output);
1411 pa_assert(out_n_frames);
1413 for (c = 0; c < r->o_ss.channels; c++) {
1414 unsigned u;
1415 pa_memblock *b, *w;
1416 int16_t *p, *t, *k, *q, *s;
1417 int consumed_frames;
1418 unsigned in, l;
1420 /* Allocate a new block */
1421 b = pa_memblock_new(r->mempool, r->ffmpeg.buf[c].length + in_n_frames * sizeof(int16_t));
1422 p = pa_memblock_acquire(b);
1424 /* Copy the remaining data into it */
1425 l = r->ffmpeg.buf[c].length;
1426 if (r->ffmpeg.buf[c].memblock) {
1427 t = (int16_t*) ((uint8_t*) pa_memblock_acquire(r->ffmpeg.buf[c].memblock) + r->ffmpeg.buf[c].index);
1428 memcpy(p, t, l);
1429 pa_memblock_release(r->ffmpeg.buf[c].memblock);
1430 pa_memblock_unref(r->ffmpeg.buf[c].memblock);
1431 pa_memchunk_reset(&r->ffmpeg.buf[c]);
1434 /* Now append the new data, splitting up channels */
1435 t = ((int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index)) + c;
1436 k = (int16_t*) ((uint8_t*) p + l);
1437 for (u = 0; u < in_n_frames; u++) {
1438 *k = *t;
1439 t += r->o_ss.channels;
1440 k ++;
1442 pa_memblock_release(input->memblock);
1444 /* Calculate the resulting number of frames */
1445 in = in_n_frames + l / sizeof(int16_t);
1447 /* Allocate buffer for the result */
1448 w = pa_memblock_new(r->mempool, *out_n_frames * sizeof(int16_t));
1449 q = pa_memblock_acquire(w);
1451 /* Now, resample */
1452 used_frames = av_resample(r->ffmpeg.state,
1453 q, p,
1454 &consumed_frames,
1455 in, *out_n_frames,
1456 c >= (unsigned) r->o_ss.channels-1);
1458 pa_memblock_release(b);
1460 /* Now store the remaining samples away */
1461 pa_assert(consumed_frames <= (int) in);
1462 if (consumed_frames < (int) in) {
1463 r->ffmpeg.buf[c].memblock = b;
1464 r->ffmpeg.buf[c].index = consumed_frames * sizeof(int16_t);
1465 r->ffmpeg.buf[c].length = (in - consumed_frames) * sizeof(int16_t);
1466 } else
1467 pa_memblock_unref(b);
1469 /* And place the results in the output buffer */
1470 s = (short*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index) + c;
1471 for (u = 0; u < used_frames; u++) {
1472 *s = *q;
1473 q++;
1474 s += r->o_ss.channels;
1476 pa_memblock_release(output->memblock);
1477 pa_memblock_release(w);
1478 pa_memblock_unref(w);
1481 *out_n_frames = used_frames;
1484 static void ffmpeg_free(pa_resampler *r) {
1485 unsigned c;
1487 pa_assert(r);
1489 if (r->ffmpeg.state)
1490 av_resample_close(r->ffmpeg.state);
1492 for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
1493 if (r->ffmpeg.buf[c].memblock)
1494 pa_memblock_unref(r->ffmpeg.buf[c].memblock);
1497 static int ffmpeg_init(pa_resampler *r) {
1498 unsigned c;
1500 pa_assert(r);
1502 /* We could probably implement different quality levels by
1503 * adjusting the filter parameters here. However, ffmpeg
1504 * internally only uses these hardcoded values, so let's use them
1505 * here for now as well until ffmpeg makes this configurable. */
1507 if (!(r->ffmpeg.state = av_resample_init(r->o_ss.rate, r->i_ss.rate, 16, 10, 0, 0.8)))
1508 return -1;
1510 r->impl_free = ffmpeg_free;
1511 r->impl_resample = ffmpeg_resample;
1513 for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
1514 pa_memchunk_reset(&r->ffmpeg.buf[c]);
1516 return 0;
1519 /*** copy (noop) implementation ***/
1521 static int copy_init(pa_resampler *r) {
1522 pa_assert(r);
1524 pa_assert(r->o_ss.rate == r->i_ss.rate);
1526 return 0;