Fix up according to Coding Style
[pulseaudio-mirror.git] / src / pulsecore / resampler.c
blobe5202212f4738538d248d8d80c9da39c146c68d0
1 /***
2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
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.
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.
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #include <string.h>
28 #ifdef HAVE_LIBSAMPLERATE
29 #include <samplerate.h>
30 #endif
32 #include <speex/speex_resampler.h>
34 #include <pulse/xmalloc.h>
35 #include <pulsecore/sconv.h>
36 #include <pulsecore/log.h>
37 #include <pulsecore/macro.h>
38 #include <pulsecore/strbuf.h>
40 #include "ffmpeg/avcodec.h"
42 #include "resampler.h"
43 #include "remap.h"
45 /* Number of samples of extra space we allow the resamplers to return */
46 #define EXTRA_FRAMES 128
48 struct pa_resampler {
49 pa_resample_method_t method;
50 pa_resample_flags_t flags;
52 pa_sample_spec i_ss, o_ss;
53 pa_channel_map i_cm, o_cm;
54 size_t i_fz, o_fz, w_sz;
55 pa_mempool *mempool;
57 pa_memchunk buf1, buf2, buf3, buf4;
58 unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples;
60 pa_sample_format_t work_format;
62 pa_convert_func_t to_work_format_func;
63 pa_convert_func_t from_work_format_func;
65 pa_remap_t remap;
66 pa_bool_t map_required;
68 void (*impl_free)(pa_resampler *r);
69 void (*impl_update_rates)(pa_resampler *r);
70 void (*impl_resample)(pa_resampler *r, const pa_memchunk *in, unsigned in_samples, pa_memchunk *out, unsigned *out_samples);
71 void (*impl_reset)(pa_resampler *r);
73 struct { /* data specific to the trivial resampler */
74 unsigned o_counter;
75 unsigned i_counter;
76 } trivial;
78 struct { /* data specific to the peak finder pseudo resampler */
79 unsigned o_counter;
80 unsigned i_counter;
82 float max_f[PA_CHANNELS_MAX];
83 int16_t max_i[PA_CHANNELS_MAX];
85 } peaks;
87 #ifdef HAVE_LIBSAMPLERATE
88 struct { /* data specific to libsamplerate */
89 SRC_STATE *state;
90 } src;
91 #endif
93 struct { /* data specific to speex */
94 SpeexResamplerState* state;
95 } speex;
97 struct { /* data specific to ffmpeg */
98 struct AVResampleContext *state;
99 pa_memchunk buf[PA_CHANNELS_MAX];
100 } ffmpeg;
103 static int copy_init(pa_resampler *r);
104 static int trivial_init(pa_resampler*r);
105 static int speex_init(pa_resampler*r);
106 static int ffmpeg_init(pa_resampler*r);
107 static int peaks_init(pa_resampler*r);
108 #ifdef HAVE_LIBSAMPLERATE
109 static int libsamplerate_init(pa_resampler*r);
110 #endif
112 static void calc_map_table(pa_resampler *r);
114 static int (* const init_table[])(pa_resampler*r) = {
115 #ifdef HAVE_LIBSAMPLERATE
116 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = libsamplerate_init,
117 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = libsamplerate_init,
118 [PA_RESAMPLER_SRC_SINC_FASTEST] = libsamplerate_init,
119 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = libsamplerate_init,
120 [PA_RESAMPLER_SRC_LINEAR] = libsamplerate_init,
121 #else
122 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = NULL,
123 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = NULL,
124 [PA_RESAMPLER_SRC_SINC_FASTEST] = NULL,
125 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = NULL,
126 [PA_RESAMPLER_SRC_LINEAR] = NULL,
127 #endif
128 [PA_RESAMPLER_TRIVIAL] = trivial_init,
129 [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = speex_init,
130 [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = speex_init,
131 [PA_RESAMPLER_SPEEX_FLOAT_BASE+2] = speex_init,
132 [PA_RESAMPLER_SPEEX_FLOAT_BASE+3] = speex_init,
133 [PA_RESAMPLER_SPEEX_FLOAT_BASE+4] = speex_init,
134 [PA_RESAMPLER_SPEEX_FLOAT_BASE+5] = speex_init,
135 [PA_RESAMPLER_SPEEX_FLOAT_BASE+6] = speex_init,
136 [PA_RESAMPLER_SPEEX_FLOAT_BASE+7] = speex_init,
137 [PA_RESAMPLER_SPEEX_FLOAT_BASE+8] = speex_init,
138 [PA_RESAMPLER_SPEEX_FLOAT_BASE+9] = speex_init,
139 [PA_RESAMPLER_SPEEX_FLOAT_BASE+10] = speex_init,
140 [PA_RESAMPLER_SPEEX_FIXED_BASE+0] = speex_init,
141 [PA_RESAMPLER_SPEEX_FIXED_BASE+1] = speex_init,
142 [PA_RESAMPLER_SPEEX_FIXED_BASE+2] = speex_init,
143 [PA_RESAMPLER_SPEEX_FIXED_BASE+3] = speex_init,
144 [PA_RESAMPLER_SPEEX_FIXED_BASE+4] = speex_init,
145 [PA_RESAMPLER_SPEEX_FIXED_BASE+5] = speex_init,
146 [PA_RESAMPLER_SPEEX_FIXED_BASE+6] = speex_init,
147 [PA_RESAMPLER_SPEEX_FIXED_BASE+7] = speex_init,
148 [PA_RESAMPLER_SPEEX_FIXED_BASE+8] = speex_init,
149 [PA_RESAMPLER_SPEEX_FIXED_BASE+9] = speex_init,
150 [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = speex_init,
151 [PA_RESAMPLER_FFMPEG] = ffmpeg_init,
152 [PA_RESAMPLER_AUTO] = NULL,
153 [PA_RESAMPLER_COPY] = copy_init,
154 [PA_RESAMPLER_PEAKS] = peaks_init,
157 pa_resampler* pa_resampler_new(
158 pa_mempool *pool,
159 const pa_sample_spec *a,
160 const pa_channel_map *am,
161 const pa_sample_spec *b,
162 const pa_channel_map *bm,
163 pa_resample_method_t method,
164 pa_resample_flags_t flags) {
166 pa_resampler *r = NULL;
168 pa_assert(pool);
169 pa_assert(a);
170 pa_assert(b);
171 pa_assert(pa_sample_spec_valid(a));
172 pa_assert(pa_sample_spec_valid(b));
173 pa_assert(method >= 0);
174 pa_assert(method < PA_RESAMPLER_MAX);
176 /* Fix method */
178 if (!(flags & PA_RESAMPLER_VARIABLE_RATE) && a->rate == b->rate) {
179 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
180 method = PA_RESAMPLER_COPY;
183 if (!pa_resample_method_supported(method)) {
184 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method));
185 method = PA_RESAMPLER_AUTO;
188 if (method == PA_RESAMPLER_FFMPEG && (flags & PA_RESAMPLER_VARIABLE_RATE)) {
189 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
190 method = PA_RESAMPLER_AUTO;
193 if (method == PA_RESAMPLER_COPY && ((flags & PA_RESAMPLER_VARIABLE_RATE) || a->rate != b->rate)) {
194 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
195 method = PA_RESAMPLER_AUTO;
198 if (method == PA_RESAMPLER_AUTO)
199 method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
201 r = pa_xnew(pa_resampler, 1);
202 r->mempool = pool;
203 r->method = method;
204 r->flags = flags;
206 r->impl_free = NULL;
207 r->impl_update_rates = NULL;
208 r->impl_resample = NULL;
209 r->impl_reset = NULL;
211 /* Fill sample specs */
212 r->i_ss = *a;
213 r->o_ss = *b;
215 /* set up the remap structure */
216 r->remap.i_ss = &r->i_ss;
217 r->remap.o_ss = &r->o_ss;
218 r->remap.format = &r->work_format;
220 if (am)
221 r->i_cm = *am;
222 else if (!pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels, PA_CHANNEL_MAP_DEFAULT))
223 goto fail;
225 if (bm)
226 r->o_cm = *bm;
227 else if (!pa_channel_map_init_auto(&r->o_cm, r->o_ss.channels, PA_CHANNEL_MAP_DEFAULT))
228 goto fail;
230 r->i_fz = pa_frame_size(a);
231 r->o_fz = pa_frame_size(b);
233 pa_memchunk_reset(&r->buf1);
234 pa_memchunk_reset(&r->buf2);
235 pa_memchunk_reset(&r->buf3);
236 pa_memchunk_reset(&r->buf4);
238 r->buf1_samples = r->buf2_samples = r->buf3_samples = r->buf4_samples = 0;
240 calc_map_table(r);
242 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method));
244 if ((method >= PA_RESAMPLER_SPEEX_FIXED_BASE && method <= PA_RESAMPLER_SPEEX_FIXED_MAX) ||
245 (method == PA_RESAMPLER_FFMPEG))
246 r->work_format = PA_SAMPLE_S16NE;
247 else if (method == PA_RESAMPLER_TRIVIAL || method == PA_RESAMPLER_COPY || method == PA_RESAMPLER_PEAKS) {
249 if (r->map_required || a->format != b->format || method == PA_RESAMPLER_PEAKS) {
251 if (a->format == PA_SAMPLE_S32NE || a->format == PA_SAMPLE_S32RE ||
252 a->format == PA_SAMPLE_FLOAT32NE || a->format == PA_SAMPLE_FLOAT32RE ||
253 a->format == PA_SAMPLE_S24NE || a->format == PA_SAMPLE_S24RE ||
254 a->format == PA_SAMPLE_S24_32NE || a->format == PA_SAMPLE_S24_32RE ||
255 b->format == PA_SAMPLE_S32NE || b->format == PA_SAMPLE_S32RE ||
256 b->format == PA_SAMPLE_FLOAT32NE || b->format == PA_SAMPLE_FLOAT32RE ||
257 b->format == PA_SAMPLE_S24NE || b->format == PA_SAMPLE_S24RE ||
258 b->format == PA_SAMPLE_S24_32NE || b->format == PA_SAMPLE_S24_32RE)
259 r->work_format = PA_SAMPLE_FLOAT32NE;
260 else
261 r->work_format = PA_SAMPLE_S16NE;
263 } else
264 r->work_format = a->format;
266 } else
267 r->work_format = PA_SAMPLE_FLOAT32NE;
269 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r->work_format));
271 r->w_sz = pa_sample_size_of_format(r->work_format);
273 if (r->i_ss.format == r->work_format)
274 r->to_work_format_func = NULL;
275 else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
276 if (!(r->to_work_format_func = pa_get_convert_to_float32ne_function(r->i_ss.format)))
277 goto fail;
278 } else {
279 pa_assert(r->work_format == PA_SAMPLE_S16NE);
280 if (!(r->to_work_format_func = pa_get_convert_to_s16ne_function(r->i_ss.format)))
281 goto fail;
284 if (r->o_ss.format == r->work_format)
285 r->from_work_format_func = NULL;
286 else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
287 if (!(r->from_work_format_func = pa_get_convert_from_float32ne_function(r->o_ss.format)))
288 goto fail;
289 } else {
290 pa_assert(r->work_format == PA_SAMPLE_S16NE);
291 if (!(r->from_work_format_func = pa_get_convert_from_s16ne_function(r->o_ss.format)))
292 goto fail;
295 /* initialize implementation */
296 if (init_table[method](r) < 0)
297 goto fail;
299 return r;
301 fail:
302 pa_xfree(r);
304 return NULL;
307 void pa_resampler_free(pa_resampler *r) {
308 pa_assert(r);
310 if (r->impl_free)
311 r->impl_free(r);
313 if (r->buf1.memblock)
314 pa_memblock_unref(r->buf1.memblock);
315 if (r->buf2.memblock)
316 pa_memblock_unref(r->buf2.memblock);
317 if (r->buf3.memblock)
318 pa_memblock_unref(r->buf3.memblock);
319 if (r->buf4.memblock)
320 pa_memblock_unref(r->buf4.memblock);
322 pa_xfree(r);
325 void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) {
326 pa_assert(r);
327 pa_assert(rate > 0);
329 if (r->i_ss.rate == rate)
330 return;
332 r->i_ss.rate = rate;
334 r->impl_update_rates(r);
337 void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) {
338 pa_assert(r);
339 pa_assert(rate > 0);
341 if (r->o_ss.rate == rate)
342 return;
344 r->o_ss.rate = rate;
346 r->impl_update_rates(r);
349 size_t pa_resampler_request(pa_resampler *r, size_t out_length) {
350 pa_assert(r);
352 /* Let's round up here */
354 return (((((out_length + r->o_fz-1) / r->o_fz) * r->i_ss.rate) + r->o_ss.rate-1) / r->o_ss.rate) * r->i_fz;
357 size_t pa_resampler_result(pa_resampler *r, size_t in_length) {
358 pa_assert(r);
360 /* Let's round up here */
362 return (((((in_length + r->i_fz-1) / r->i_fz) * r->o_ss.rate) + r->i_ss.rate-1) / r->i_ss.rate) * r->o_fz;
365 size_t pa_resampler_max_block_size(pa_resampler *r) {
366 size_t block_size_max;
367 pa_sample_spec ss;
368 size_t fs;
370 pa_assert(r);
372 block_size_max = pa_mempool_block_size_max(r->mempool);
374 /* We deduce the "largest" sample spec we're using during the
375 * conversion */
376 ss.channels = (uint8_t) (PA_MAX(r->i_ss.channels, r->o_ss.channels));
378 /* We silently assume that the format enum is ordered by size */
379 ss.format = PA_MAX(r->i_ss.format, r->o_ss.format);
380 ss.format = PA_MAX(ss.format, r->work_format);
382 ss.rate = PA_MAX(r->i_ss.rate, r->o_ss.rate);
384 fs = pa_frame_size(&ss);
386 return (((block_size_max/fs - EXTRA_FRAMES)*r->i_ss.rate)/ss.rate)*r->i_fz;
389 void pa_resampler_reset(pa_resampler *r) {
390 pa_assert(r);
392 if (r->impl_reset)
393 r->impl_reset(r);
396 pa_resample_method_t pa_resampler_get_method(pa_resampler *r) {
397 pa_assert(r);
399 return r->method;
402 const pa_channel_map* pa_resampler_input_channel_map(pa_resampler *r) {
403 pa_assert(r);
405 return &r->i_cm;
408 const pa_sample_spec* pa_resampler_input_sample_spec(pa_resampler *r) {
409 pa_assert(r);
411 return &r->i_ss;
414 const pa_channel_map* pa_resampler_output_channel_map(pa_resampler *r) {
415 pa_assert(r);
417 return &r->o_cm;
420 const pa_sample_spec* pa_resampler_output_sample_spec(pa_resampler *r) {
421 pa_assert(r);
423 return &r->o_ss;
426 static const char * const resample_methods[] = {
427 "src-sinc-best-quality",
428 "src-sinc-medium-quality",
429 "src-sinc-fastest",
430 "src-zero-order-hold",
431 "src-linear",
432 "trivial",
433 "speex-float-0",
434 "speex-float-1",
435 "speex-float-2",
436 "speex-float-3",
437 "speex-float-4",
438 "speex-float-5",
439 "speex-float-6",
440 "speex-float-7",
441 "speex-float-8",
442 "speex-float-9",
443 "speex-float-10",
444 "speex-fixed-0",
445 "speex-fixed-1",
446 "speex-fixed-2",
447 "speex-fixed-3",
448 "speex-fixed-4",
449 "speex-fixed-5",
450 "speex-fixed-6",
451 "speex-fixed-7",
452 "speex-fixed-8",
453 "speex-fixed-9",
454 "speex-fixed-10",
455 "ffmpeg",
456 "auto",
457 "copy",
458 "peaks"
461 const char *pa_resample_method_to_string(pa_resample_method_t m) {
463 if (m < 0 || m >= PA_RESAMPLER_MAX)
464 return NULL;
466 return resample_methods[m];
469 int pa_resample_method_supported(pa_resample_method_t m) {
471 if (m < 0 || m >= PA_RESAMPLER_MAX)
472 return 0;
474 #ifndef HAVE_LIBSAMPLERATE
475 if (m <= PA_RESAMPLER_SRC_LINEAR)
476 return 0;
477 #endif
479 return 1;
482 pa_resample_method_t pa_parse_resample_method(const char *string) {
483 pa_resample_method_t m;
485 pa_assert(string);
487 for (m = 0; m < PA_RESAMPLER_MAX; m++)
488 if (!strcmp(string, resample_methods[m]))
489 return m;
491 if (!strcmp(string, "speex-fixed"))
492 return PA_RESAMPLER_SPEEX_FIXED_BASE + 3;
494 if (!strcmp(string, "speex-float"))
495 return PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
497 return PA_RESAMPLER_INVALID;
500 static pa_bool_t on_left(pa_channel_position_t p) {
502 return
503 p == PA_CHANNEL_POSITION_FRONT_LEFT ||
504 p == PA_CHANNEL_POSITION_REAR_LEFT ||
505 p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ||
506 p == PA_CHANNEL_POSITION_SIDE_LEFT ||
507 p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT ||
508 p == PA_CHANNEL_POSITION_TOP_REAR_LEFT;
511 static pa_bool_t on_right(pa_channel_position_t p) {
513 return
514 p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
515 p == PA_CHANNEL_POSITION_REAR_RIGHT ||
516 p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER ||
517 p == PA_CHANNEL_POSITION_SIDE_RIGHT ||
518 p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ||
519 p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
522 static pa_bool_t on_center(pa_channel_position_t p) {
524 return
525 p == PA_CHANNEL_POSITION_FRONT_CENTER ||
526 p == PA_CHANNEL_POSITION_REAR_CENTER ||
527 p == PA_CHANNEL_POSITION_TOP_CENTER ||
528 p == PA_CHANNEL_POSITION_TOP_FRONT_CENTER ||
529 p == PA_CHANNEL_POSITION_TOP_REAR_CENTER;
532 static pa_bool_t on_lfe(pa_channel_position_t p) {
533 return
534 p == PA_CHANNEL_POSITION_LFE;
537 static pa_bool_t on_front(pa_channel_position_t p) {
538 return
539 p == PA_CHANNEL_POSITION_FRONT_LEFT ||
540 p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
541 p == PA_CHANNEL_POSITION_FRONT_CENTER ||
542 p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT ||
543 p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ||
544 p == PA_CHANNEL_POSITION_TOP_FRONT_CENTER ||
545 p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ||
546 p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
549 static pa_bool_t on_rear(pa_channel_position_t p) {
550 return
551 p == PA_CHANNEL_POSITION_REAR_LEFT ||
552 p == PA_CHANNEL_POSITION_REAR_RIGHT ||
553 p == PA_CHANNEL_POSITION_REAR_CENTER ||
554 p == PA_CHANNEL_POSITION_TOP_REAR_LEFT ||
555 p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT ||
556 p == PA_CHANNEL_POSITION_TOP_REAR_CENTER;
559 static pa_bool_t on_side(pa_channel_position_t p) {
560 return
561 p == PA_CHANNEL_POSITION_SIDE_LEFT ||
562 p == PA_CHANNEL_POSITION_SIDE_RIGHT ||
563 p == PA_CHANNEL_POSITION_TOP_CENTER;
566 enum {
567 ON_FRONT,
568 ON_REAR,
569 ON_SIDE,
570 ON_OTHER
573 static int front_rear_side(pa_channel_position_t p) {
574 if (on_front(p))
575 return ON_FRONT;
576 if (on_rear(p))
577 return ON_REAR;
578 if (on_side(p))
579 return ON_SIDE;
580 return ON_OTHER;
583 static void calc_map_table(pa_resampler *r) {
584 unsigned oc, ic;
585 unsigned n_oc, n_ic;
586 pa_bool_t ic_connected[PA_CHANNELS_MAX];
587 pa_bool_t remix;
588 pa_strbuf *s;
589 char *t;
590 pa_remap_t *m;
592 pa_assert(r);
594 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)))))
595 return;
597 m = &r->remap;
599 n_oc = r->o_ss.channels;
600 n_ic = r->i_ss.channels;
602 memset(m->map_table_f, 0, sizeof(m->map_table_f));
603 memset(m->map_table_i, 0, sizeof(m->map_table_i));
605 memset(ic_connected, 0, sizeof(ic_connected));
606 remix = (r->flags & (PA_RESAMPLER_NO_REMAP|PA_RESAMPLER_NO_REMIX)) == 0;
608 for (oc = 0; oc < n_oc; oc++) {
609 pa_bool_t oc_connected = FALSE;
610 pa_channel_position_t b = r->o_cm.map[oc];
612 for (ic = 0; ic < n_ic; ic++) {
613 pa_channel_position_t a = r->i_cm.map[ic];
615 if (r->flags & PA_RESAMPLER_NO_REMAP) {
616 /* We shall not do any remapping. Hence, just check by index */
618 if (ic == oc)
619 m->map_table_f[oc][ic] = 1.0;
621 continue;
624 if (r->flags & PA_RESAMPLER_NO_REMIX) {
625 /* We shall not do any remixing. Hence, just check by name */
627 if (a == b)
628 m->map_table_f[oc][ic] = 1.0;
630 continue;
633 pa_assert(remix);
635 /* OK, we shall do the full monty: upmixing and
636 * downmixing. Our algorithm is relatively simple, does
637 * not do spacialization, delay elements or apply lowpass
638 * filters for LFE. Patches are always welcome,
639 * though. Oh, and it doesn't do any matrix
640 * decoding. (Which probably wouldn't make any sense
641 * anyway.)
643 * This code is not idempotent: downmixing an upmixed
644 * stereo stream is not identical to the original. The
645 * volume will not match, and the two channels will be a
646 * linear combination of both.
648 * This is losely based on random suggestions found on the
649 * Internet, such as this:
650 * http://www.halfgaar.net/surround-sound-in-linux and the
651 * alsa upmix plugin.
653 * The algorithm works basically like this:
655 * 1) Connect all channels with matching names.
657 * 2) Mono Handling:
658 * S:Mono: Copy into all D:channels
659 * D:Mono: Copy in all S:channels
661 * 3) Mix D:Left, D:Right:
662 * D:Left: If not connected, avg all S:Left
663 * D:Right: If not connected, avg all S:Right
665 * 4) Mix D:Center
666 * If not connected, avg all S:Center
667 * If still not connected, avg all S:Left, S:Right
669 * 5) Mix D:LFE
670 * If not connected, avg all S:*
672 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
673 * not connected, mix into all D:left and all D:right
674 * channels. Gain is 0.1, the current left and right
675 * should be multiplied by 0.9.
677 * 7) Make sure S:Center, S:LFE is used:
679 * S:Center, S:LFE: If not connected, mix into all
680 * D:left, all D:right, all D:center channels, gain is
681 * 0.375. The current (as result of 1..6) factors
682 * should be multiplied by 0.75. (Alt. suggestion: 0.25
683 * vs. 0.5) If C-front is only mixed into
684 * L-front/R-front if available, otherwise into all L/R
685 * channels. Similarly for C-rear.
687 * S: and D: shall relate to the source resp. destination channels.
689 * Rationale: 1, 2 are probably obvious. For 3: this
690 * copies front to rear if needed. For 4: we try to find
691 * some suitable C source for C, if we don't find any, we
692 * avg L and R. For 5: LFE is mixed from all channels. For
693 * 6: the rear channels should not be dropped entirely,
694 * however have only minimal impact. For 7: movies usually
695 * encode speech on the center channel. Thus we have to
696 * make sure this channel is distributed to L and R if not
697 * available in the output. Also, LFE is used to achieve a
698 * greater dynamic range, and thus we should try to do our
699 * best to pass it to L+R.
702 if (a == b || a == PA_CHANNEL_POSITION_MONO || b == PA_CHANNEL_POSITION_MONO) {
703 m->map_table_f[oc][ic] = 1.0;
705 oc_connected = TRUE;
706 ic_connected[ic] = TRUE;
710 if (!oc_connected && remix) {
711 /* OK, we shall remix */
713 /* Try to find matching input ports for this output port */
715 if (on_left(b)) {
716 unsigned n = 0;
718 /* We are not connected and on the left side, let's
719 * average all left side input channels. */
721 for (ic = 0; ic < n_ic; ic++)
722 if (on_left(r->i_cm.map[ic]))
723 n++;
725 if (n > 0)
726 for (ic = 0; ic < n_ic; ic++)
727 if (on_left(r->i_cm.map[ic])) {
728 m->map_table_f[oc][ic] = 1.0f / (float) n;
729 ic_connected[ic] = TRUE;
732 /* We ignore the case where there is no left input
733 * channel. Something is really wrong in this case
734 * anyway. */
736 } else if (on_right(b)) {
737 unsigned n = 0;
739 /* We are not connected and on the right side, let's
740 * average all right side input channels. */
742 for (ic = 0; ic < n_ic; ic++)
743 if (on_right(r->i_cm.map[ic]))
744 n++;
746 if (n > 0)
747 for (ic = 0; ic < n_ic; ic++)
748 if (on_right(r->i_cm.map[ic])) {
749 m->map_table_f[oc][ic] = 1.0f / (float) n;
750 ic_connected[ic] = TRUE;
753 /* We ignore the case where there is no right input
754 * channel. Something is really wrong in this case
755 * anyway. */
757 } else if (on_center(b)) {
758 unsigned n = 0;
760 /* We are not connected and at the center. Let's
761 * average all center input channels. */
763 for (ic = 0; ic < n_ic; ic++)
764 if (on_center(r->i_cm.map[ic]))
765 n++;
767 if (n > 0) {
768 for (ic = 0; ic < n_ic; ic++)
769 if (on_center(r->i_cm.map[ic])) {
770 m->map_table_f[oc][ic] = 1.0f / (float) n;
771 ic_connected[ic] = TRUE;
773 } else {
775 /* Hmm, no center channel around, let's synthesize
776 * it by mixing L and R.*/
778 n = 0;
780 for (ic = 0; ic < n_ic; ic++)
781 if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic]))
782 n++;
784 if (n > 0)
785 for (ic = 0; ic < n_ic; ic++)
786 if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic])) {
787 m->map_table_f[oc][ic] = 1.0f / (float) n;
788 ic_connected[ic] = TRUE;
791 /* We ignore the case where there is not even a
792 * left or right input channel. Something is
793 * really wrong in this case anyway. */
796 } else if (on_lfe(b)) {
798 /* We are not connected and an LFE. Let's average all
799 * channels for LFE. */
801 for (ic = 0; ic < n_ic; ic++) {
803 if (!(r->flags & PA_RESAMPLER_NO_LFE))
804 m->map_table_f[oc][ic] = 1.0f / (float) n_ic;
805 else
806 m->map_table_f[oc][ic] = 0;
808 /* Please note that a channel connected to LFE
809 * doesn't really count as connected. */
815 if (remix) {
816 unsigned
817 ic_unconnected_left = 0,
818 ic_unconnected_right = 0,
819 ic_unconnected_center = 0,
820 ic_unconnected_lfe = 0;
822 for (ic = 0; ic < n_ic; ic++) {
823 pa_channel_position_t a = r->i_cm.map[ic];
825 if (ic_connected[ic])
826 continue;
828 if (on_left(a))
829 ic_unconnected_left++;
830 else if (on_right(a))
831 ic_unconnected_right++;
832 else if (on_center(a))
833 ic_unconnected_center++;
834 else if (on_lfe(a))
835 ic_unconnected_lfe++;
838 if (ic_unconnected_left > 0) {
840 /* OK, so there are unconnected input channels on the
841 * left. Let's multiply all already connected channels on
842 * the left side by .9 and add in our averaged unconnected
843 * channels multplied by .1 */
845 for (oc = 0; oc < n_oc; oc++) {
847 if (!on_left(r->o_cm.map[oc]))
848 continue;
850 for (ic = 0; ic < n_ic; ic++) {
852 if (ic_connected[ic]) {
853 m->map_table_f[oc][ic] *= .9f;
854 continue;
857 if (on_left(r->i_cm.map[ic]))
858 m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_left;
863 if (ic_unconnected_right > 0) {
865 /* OK, so there are unconnected input channels on the
866 * right. Let's multiply all already connected channels on
867 * the right side by .9 and add in our averaged unconnected
868 * channels multplied by .1 */
870 for (oc = 0; oc < n_oc; oc++) {
872 if (!on_right(r->o_cm.map[oc]))
873 continue;
875 for (ic = 0; ic < n_ic; ic++) {
877 if (ic_connected[ic]) {
878 m->map_table_f[oc][ic] *= .9f;
879 continue;
882 if (on_right(r->i_cm.map[ic]))
883 m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_right;
888 if (ic_unconnected_center > 0) {
889 pa_bool_t mixed_in = FALSE;
891 /* OK, so there are unconnected input channels on the
892 * center. Let's multiply all already connected channels on
893 * the center side by .9 and add in our averaged unconnected
894 * channels multplied by .1 */
896 for (oc = 0; oc < n_oc; oc++) {
898 if (!on_center(r->o_cm.map[oc]))
899 continue;
901 for (ic = 0; ic < n_ic; ic++) {
903 if (ic_connected[ic]) {
904 m->map_table_f[oc][ic] *= .9f;
905 continue;
908 if (on_center(r->i_cm.map[ic])) {
909 m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_center;
910 mixed_in = TRUE;
915 if (!mixed_in) {
916 unsigned ncenter[PA_CHANNELS_MAX];
917 pa_bool_t found_frs[PA_CHANNELS_MAX];
919 memset(ncenter, 0, sizeof(ncenter));
920 memset(found_frs, 0, sizeof(found_frs));
922 /* Hmm, as it appears there was no center channel we
923 could mix our center channel in. In this case, mix
924 it into left and right. Using .375 and 0.75 as
925 factors. */
927 for (ic = 0; ic < n_ic; ic++) {
929 if (ic_connected[ic])
930 continue;
932 if (!on_center(r->i_cm.map[ic]))
933 continue;
935 for (oc = 0; oc < n_oc; oc++) {
937 if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
938 continue;
940 if (front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc])) {
941 found_frs[ic] = TRUE;
942 break;
946 for (oc = 0; oc < n_oc; oc++) {
948 if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
949 continue;
951 if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
952 ncenter[oc]++;
956 for (oc = 0; oc < n_oc; oc++) {
958 if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
959 continue;
961 if (ncenter[oc] <= 0)
962 continue;
964 for (ic = 0; ic < n_ic; ic++) {
966 if (ic_connected[ic]) {
967 m->map_table_f[oc][ic] *= .75f;
968 continue;
971 if (!on_center(r->i_cm.map[ic]))
972 continue;
974 if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
975 m->map_table_f[oc][ic] = .375f / (float) ncenter[oc];
981 if (ic_unconnected_lfe > 0 && !(r->flags & PA_RESAMPLER_NO_LFE)) {
983 /* OK, so there is an unconnected LFE channel. Let's mix
984 * it into all channels, with factor 0.375 */
986 for (ic = 0; ic < n_ic; ic++) {
988 if (!on_lfe(r->i_cm.map[ic]))
989 continue;
991 for (oc = 0; oc < n_oc; oc++)
992 m->map_table_f[oc][ic] = 0.375f / (float) ic_unconnected_lfe;
996 /* make an 16:16 int version of the matrix */
997 for (oc = 0; oc < n_oc; oc++)
998 for (ic = 0; ic < n_ic; ic++)
999 m->map_table_i[oc][ic] = (int32_t) (m->map_table_f[oc][ic] * 0x10000);
1001 s = pa_strbuf_new();
1003 pa_strbuf_printf(s, " ");
1004 for (ic = 0; ic < n_ic; ic++)
1005 pa_strbuf_printf(s, " I%02u ", ic);
1006 pa_strbuf_puts(s, "\n +");
1008 for (ic = 0; ic < n_ic; ic++)
1009 pa_strbuf_printf(s, "------");
1010 pa_strbuf_puts(s, "\n");
1012 for (oc = 0; oc < n_oc; oc++) {
1013 pa_strbuf_printf(s, "O%02u |", oc);
1015 for (ic = 0; ic < n_ic; ic++)
1016 pa_strbuf_printf(s, " %1.3f", m->map_table_f[oc][ic]);
1018 pa_strbuf_puts(s, "\n");
1021 pa_log_debug("Channel matrix:\n%s", t = pa_strbuf_tostring_free(s));
1022 pa_xfree(t);
1024 /* initialize the remapping function */
1025 pa_init_remap(m);
1028 static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) {
1029 unsigned n_samples;
1030 void *src, *dst;
1032 pa_assert(r);
1033 pa_assert(input);
1034 pa_assert(input->memblock);
1036 /* Convert the incoming sample into the work sample format and place them in buf1 */
1038 if (!r->to_work_format_func || !input->length)
1039 return input;
1041 n_samples = (unsigned) ((input->length / r->i_fz) * r->i_ss.channels);
1043 r->buf1.index = 0;
1044 r->buf1.length = r->w_sz * n_samples;
1046 if (!r->buf1.memblock || r->buf1_samples < n_samples) {
1047 if (r->buf1.memblock)
1048 pa_memblock_unref(r->buf1.memblock);
1050 r->buf1_samples = n_samples;
1051 r->buf1.memblock = pa_memblock_new(r->mempool, r->buf1.length);
1054 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
1055 dst = (uint8_t*) pa_memblock_acquire(r->buf1.memblock);
1057 r->to_work_format_func(n_samples, src, dst);
1059 pa_memblock_release(input->memblock);
1060 pa_memblock_release(r->buf1.memblock);
1062 return &r->buf1;
1065 static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
1066 unsigned in_n_samples, out_n_samples, n_frames;
1067 void *src, *dst;
1068 pa_remap_t *remap;
1070 pa_assert(r);
1071 pa_assert(input);
1072 pa_assert(input->memblock);
1074 /* Remap channels and place the result int buf2 */
1076 if (!r->map_required || !input->length)
1077 return input;
1079 in_n_samples = (unsigned) (input->length / r->w_sz);
1080 n_frames = in_n_samples / r->i_ss.channels;
1081 out_n_samples = n_frames * r->o_ss.channels;
1083 r->buf2.index = 0;
1084 r->buf2.length = r->w_sz * out_n_samples;
1086 if (!r->buf2.memblock || r->buf2_samples < out_n_samples) {
1087 if (r->buf2.memblock)
1088 pa_memblock_unref(r->buf2.memblock);
1090 r->buf2_samples = out_n_samples;
1091 r->buf2.memblock = pa_memblock_new(r->mempool, r->buf2.length);
1094 src = ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
1095 dst = pa_memblock_acquire(r->buf2.memblock);
1097 remap = &r->remap;
1099 pa_assert(remap->do_remap);
1100 remap->do_remap(remap, dst, src, n_frames);
1102 pa_memblock_release(input->memblock);
1103 pa_memblock_release(r->buf2.memblock);
1105 return &r->buf2;
1108 static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {
1109 unsigned in_n_frames, in_n_samples;
1110 unsigned out_n_frames, out_n_samples;
1112 pa_assert(r);
1113 pa_assert(input);
1115 /* Resample the data and place the result in buf3 */
1117 if (!r->impl_resample || !input->length)
1118 return input;
1120 in_n_samples = (unsigned) (input->length / r->w_sz);
1121 in_n_frames = (unsigned) (in_n_samples / r->o_ss.channels);
1123 out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_FRAMES;
1124 out_n_samples = out_n_frames * r->o_ss.channels;
1126 r->buf3.index = 0;
1127 r->buf3.length = r->w_sz * out_n_samples;
1129 if (!r->buf3.memblock || r->buf3_samples < out_n_samples) {
1130 if (r->buf3.memblock)
1131 pa_memblock_unref(r->buf3.memblock);
1133 r->buf3_samples = out_n_samples;
1134 r->buf3.memblock = pa_memblock_new(r->mempool, r->buf3.length);
1137 r->impl_resample(r, input, in_n_frames, &r->buf3, &out_n_frames);
1138 r->buf3.length = out_n_frames * r->w_sz * r->o_ss.channels;
1140 return &r->buf3;
1143 static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input) {
1144 unsigned n_samples, n_frames;
1145 void *src, *dst;
1147 pa_assert(r);
1148 pa_assert(input);
1150 /* Convert the data into the correct sample type and place the result in buf4 */
1152 if (!r->from_work_format_func || !input->length)
1153 return input;
1155 n_samples = (unsigned) (input->length / r->w_sz);
1156 n_frames = n_samples / r->o_ss.channels;
1158 r->buf4.index = 0;
1159 r->buf4.length = r->o_fz * n_frames;
1161 if (!r->buf4.memblock || r->buf4_samples < n_samples) {
1162 if (r->buf4.memblock)
1163 pa_memblock_unref(r->buf4.memblock);
1165 r->buf4_samples = n_samples;
1166 r->buf4.memblock = pa_memblock_new(r->mempool, r->buf4.length);
1169 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
1170 dst = pa_memblock_acquire(r->buf4.memblock);
1171 r->from_work_format_func(n_samples, src, dst);
1172 pa_memblock_release(input->memblock);
1173 pa_memblock_release(r->buf4.memblock);
1175 r->buf4.length = r->o_fz * n_frames;
1177 return &r->buf4;
1180 void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) {
1181 pa_memchunk *buf;
1183 pa_assert(r);
1184 pa_assert(in);
1185 pa_assert(out);
1186 pa_assert(in->length);
1187 pa_assert(in->memblock);
1188 pa_assert(in->length % r->i_fz == 0);
1190 buf = (pa_memchunk*) in;
1191 buf = convert_to_work_format(r, buf);
1192 buf = remap_channels(r, buf);
1193 buf = resample(r, buf);
1195 if (buf->length) {
1196 buf = convert_from_work_format(r, buf);
1197 *out = *buf;
1199 if (buf == in)
1200 pa_memblock_ref(buf->memblock);
1201 else
1202 pa_memchunk_reset(buf);
1203 } else
1204 pa_memchunk_reset(out);
1207 /*** libsamplerate based implementation ***/
1209 #ifdef HAVE_LIBSAMPLERATE
1210 static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1211 SRC_DATA data;
1213 pa_assert(r);
1214 pa_assert(input);
1215 pa_assert(output);
1216 pa_assert(out_n_frames);
1218 memset(&data, 0, sizeof(data));
1220 data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
1221 data.input_frames = (long int) in_n_frames;
1223 data.data_out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
1224 data.output_frames = (long int) *out_n_frames;
1226 data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate;
1227 data.end_of_input = 0;
1229 pa_assert_se(src_process(r->src.state, &data) == 0);
1230 pa_assert((unsigned) data.input_frames_used == in_n_frames);
1232 pa_memblock_release(input->memblock);
1233 pa_memblock_release(output->memblock);
1235 *out_n_frames = (unsigned) data.output_frames_gen;
1238 static void libsamplerate_update_rates(pa_resampler *r) {
1239 pa_assert(r);
1241 pa_assert_se(src_set_ratio(r->src.state, (double) r->o_ss.rate / r->i_ss.rate) == 0);
1244 static void libsamplerate_reset(pa_resampler *r) {
1245 pa_assert(r);
1247 pa_assert_se(src_reset(r->src.state) == 0);
1250 static void libsamplerate_free(pa_resampler *r) {
1251 pa_assert(r);
1253 if (r->src.state)
1254 src_delete(r->src.state);
1257 static int libsamplerate_init(pa_resampler *r) {
1258 int err;
1260 pa_assert(r);
1262 if (!(r->src.state = src_new(r->method, r->o_ss.channels, &err)))
1263 return -1;
1265 r->impl_free = libsamplerate_free;
1266 r->impl_update_rates = libsamplerate_update_rates;
1267 r->impl_resample = libsamplerate_resample;
1268 r->impl_reset = libsamplerate_reset;
1270 return 0;
1272 #endif
1274 /*** speex based implementation ***/
1276 static void speex_resample_float(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1277 float *in, *out;
1278 uint32_t inf = in_n_frames, outf = *out_n_frames;
1280 pa_assert(r);
1281 pa_assert(input);
1282 pa_assert(output);
1283 pa_assert(out_n_frames);
1285 in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
1286 out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
1288 pa_assert_se(speex_resampler_process_interleaved_float(r->speex.state, in, &inf, out, &outf) == 0);
1290 pa_memblock_release(input->memblock);
1291 pa_memblock_release(output->memblock);
1293 pa_assert(inf == in_n_frames);
1294 *out_n_frames = outf;
1297 static void speex_resample_int(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1298 int16_t *in, *out;
1299 uint32_t inf = in_n_frames, outf = *out_n_frames;
1301 pa_assert(r);
1302 pa_assert(input);
1303 pa_assert(output);
1304 pa_assert(out_n_frames);
1306 in = (int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
1307 out = (int16_t*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
1309 pa_assert_se(speex_resampler_process_interleaved_int(r->speex.state, in, &inf, out, &outf) == 0);
1311 pa_memblock_release(input->memblock);
1312 pa_memblock_release(output->memblock);
1314 pa_assert(inf == in_n_frames);
1315 *out_n_frames = outf;
1318 static void speex_update_rates(pa_resampler *r) {
1319 pa_assert(r);
1321 pa_assert_se(speex_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0);
1324 static void speex_reset(pa_resampler *r) {
1325 pa_assert(r);
1327 pa_assert_se(speex_resampler_reset_mem(r->speex.state) == 0);
1330 static void speex_free(pa_resampler *r) {
1331 pa_assert(r);
1333 if (!r->speex.state)
1334 return;
1336 speex_resampler_destroy(r->speex.state);
1339 static int speex_init(pa_resampler *r) {
1340 int q, err;
1342 pa_assert(r);
1344 r->impl_free = speex_free;
1345 r->impl_update_rates = speex_update_rates;
1346 r->impl_reset = speex_reset;
1348 if (r->method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->method <= PA_RESAMPLER_SPEEX_FIXED_MAX) {
1350 q = r->method - PA_RESAMPLER_SPEEX_FIXED_BASE;
1351 r->impl_resample = speex_resample_int;
1353 } else {
1354 pa_assert(r->method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
1356 q = r->method - PA_RESAMPLER_SPEEX_FLOAT_BASE;
1357 r->impl_resample = speex_resample_float;
1360 pa_log_info("Choosing speex quality setting %i.", q);
1362 if (!(r->speex.state = speex_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
1363 return -1;
1365 return 0;
1368 /* Trivial implementation */
1370 static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1371 size_t fz;
1372 unsigned o_index;
1373 void *src, *dst;
1375 pa_assert(r);
1376 pa_assert(input);
1377 pa_assert(output);
1378 pa_assert(out_n_frames);
1380 fz = r->w_sz * r->o_ss.channels;
1382 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
1383 dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
1385 for (o_index = 0;; o_index++, r->trivial.o_counter++) {
1386 unsigned j;
1388 j = ((r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate);
1389 j = j > r->trivial.i_counter ? j - r->trivial.i_counter : 0;
1391 if (j >= in_n_frames)
1392 break;
1394 pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
1396 memcpy((uint8_t*) dst + fz * o_index,
1397 (uint8_t*) src + fz * j, (int) fz);
1400 pa_memblock_release(input->memblock);
1401 pa_memblock_release(output->memblock);
1403 *out_n_frames = o_index;
1405 r->trivial.i_counter += in_n_frames;
1407 /* Normalize counters */
1408 while (r->trivial.i_counter >= r->i_ss.rate) {
1409 pa_assert(r->trivial.o_counter >= r->o_ss.rate);
1411 r->trivial.i_counter -= r->i_ss.rate;
1412 r->trivial.o_counter -= r->o_ss.rate;
1416 static void trivial_update_rates_or_reset(pa_resampler *r) {
1417 pa_assert(r);
1419 r->trivial.i_counter = 0;
1420 r->trivial.o_counter = 0;
1423 static int trivial_init(pa_resampler*r) {
1424 pa_assert(r);
1426 r->trivial.o_counter = r->trivial.i_counter = 0;
1428 r->impl_resample = trivial_resample;
1429 r->impl_update_rates = trivial_update_rates_or_reset;
1430 r->impl_reset = trivial_update_rates_or_reset;
1432 return 0;
1435 /* Peak finder implementation */
1437 static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1438 size_t fz;
1439 unsigned o_index;
1440 void *src, *dst;
1441 unsigned start = 0;
1443 pa_assert(r);
1444 pa_assert(input);
1445 pa_assert(output);
1446 pa_assert(out_n_frames);
1448 fz = r->w_sz * r->o_ss.channels;
1450 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
1451 dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
1453 for (o_index = 0;; o_index++, r->peaks.o_counter++) {
1454 unsigned j;
1456 j = ((r->peaks.o_counter * r->i_ss.rate) / r->o_ss.rate);
1458 if (j > r->peaks.i_counter)
1459 j -= r->peaks.i_counter;
1460 else
1461 j = 0;
1463 pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
1465 if (r->work_format == PA_SAMPLE_S16NE) {
1466 unsigned i, c;
1467 int16_t *s = (int16_t*) ((uint8_t*) src + fz * start);
1468 int16_t *d = (int16_t*) ((uint8_t*) dst + fz * o_index);
1470 for (i = start; i <= j && i < in_n_frames; i++)
1472 for (c = 0; c < r->o_ss.channels; c++, s++) {
1473 int16_t n;
1475 n = (int16_t) (*s < 0 ? -*s : *s);
1477 if (PA_UNLIKELY(n > r->peaks.max_i[c]))
1478 r->peaks.max_i[c] = n;
1481 if (i >= in_n_frames)
1482 break;
1484 for (c = 0; c < r->o_ss.channels; c++, d++) {
1485 *d = r->peaks.max_i[c];
1486 r->peaks.max_i[c] = 0;
1489 } else {
1490 unsigned i, c;
1491 float *s = (float*) ((uint8_t*) src + fz * start);
1492 float *d = (float*) ((uint8_t*) dst + fz * o_index);
1494 pa_assert(r->work_format == PA_SAMPLE_FLOAT32NE);
1496 for (i = start; i <= j && i < in_n_frames; i++)
1497 for (c = 0; c < r->o_ss.channels; c++, s++) {
1498 float n = fabsf(*s);
1500 if (n > r->peaks.max_f[c])
1501 r->peaks.max_f[c] = n;
1504 if (i >= in_n_frames)
1505 break;
1507 for (c = 0; c < r->o_ss.channels; c++, d++) {
1508 *d = r->peaks.max_f[c];
1509 r->peaks.max_f[c] = 0;
1513 start = j;
1516 pa_memblock_release(input->memblock);
1517 pa_memblock_release(output->memblock);
1519 *out_n_frames = o_index;
1521 r->peaks.i_counter += in_n_frames;
1523 /* Normalize counters */
1524 while (r->peaks.i_counter >= r->i_ss.rate) {
1525 pa_assert(r->peaks.o_counter >= r->o_ss.rate);
1527 r->peaks.i_counter -= r->i_ss.rate;
1528 r->peaks.o_counter -= r->o_ss.rate;
1532 static void peaks_update_rates_or_reset(pa_resampler *r) {
1533 pa_assert(r);
1535 r->peaks.i_counter = 0;
1536 r->peaks.o_counter = 0;
1539 static int peaks_init(pa_resampler*r) {
1540 pa_assert(r);
1542 r->peaks.o_counter = r->peaks.i_counter = 0;
1543 memset(r->peaks.max_i, 0, sizeof(r->peaks.max_i));
1544 memset(r->peaks.max_f, 0, sizeof(r->peaks.max_f));
1546 r->impl_resample = peaks_resample;
1547 r->impl_update_rates = peaks_update_rates_or_reset;
1548 r->impl_reset = peaks_update_rates_or_reset;
1550 return 0;
1553 /*** ffmpeg based implementation ***/
1555 static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1556 unsigned used_frames = 0, c;
1558 pa_assert(r);
1559 pa_assert(input);
1560 pa_assert(output);
1561 pa_assert(out_n_frames);
1563 for (c = 0; c < r->o_ss.channels; c++) {
1564 unsigned u;
1565 pa_memblock *b, *w;
1566 int16_t *p, *t, *k, *q, *s;
1567 int consumed_frames;
1568 unsigned in, l;
1570 /* Allocate a new block */
1571 b = pa_memblock_new(r->mempool, r->ffmpeg.buf[c].length + in_n_frames * sizeof(int16_t));
1572 p = pa_memblock_acquire(b);
1574 /* Copy the remaining data into it */
1575 l = (unsigned) r->ffmpeg.buf[c].length;
1576 if (r->ffmpeg.buf[c].memblock) {
1577 t = (int16_t*) ((uint8_t*) pa_memblock_acquire(r->ffmpeg.buf[c].memblock) + r->ffmpeg.buf[c].index);
1578 memcpy(p, t, l);
1579 pa_memblock_release(r->ffmpeg.buf[c].memblock);
1580 pa_memblock_unref(r->ffmpeg.buf[c].memblock);
1581 pa_memchunk_reset(&r->ffmpeg.buf[c]);
1584 /* Now append the new data, splitting up channels */
1585 t = ((int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index)) + c;
1586 k = (int16_t*) ((uint8_t*) p + l);
1587 for (u = 0; u < in_n_frames; u++) {
1588 *k = *t;
1589 t += r->o_ss.channels;
1590 k ++;
1592 pa_memblock_release(input->memblock);
1594 /* Calculate the resulting number of frames */
1595 in = (unsigned) in_n_frames + l / (unsigned) sizeof(int16_t);
1597 /* Allocate buffer for the result */
1598 w = pa_memblock_new(r->mempool, *out_n_frames * sizeof(int16_t));
1599 q = pa_memblock_acquire(w);
1601 /* Now, resample */
1602 used_frames = (unsigned) av_resample(r->ffmpeg.state,
1603 q, p,
1604 &consumed_frames,
1605 (int) in, (int) *out_n_frames,
1606 c >= (unsigned) (r->o_ss.channels-1));
1608 pa_memblock_release(b);
1610 /* Now store the remaining samples away */
1611 pa_assert(consumed_frames <= (int) in);
1612 if (consumed_frames < (int) in) {
1613 r->ffmpeg.buf[c].memblock = b;
1614 r->ffmpeg.buf[c].index = (size_t) consumed_frames * sizeof(int16_t);
1615 r->ffmpeg.buf[c].length = (size_t) (in - (unsigned) consumed_frames) * sizeof(int16_t);
1616 } else
1617 pa_memblock_unref(b);
1619 /* And place the results in the output buffer */
1620 s = (short*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index) + c;
1621 for (u = 0; u < used_frames; u++) {
1622 *s = *q;
1623 q++;
1624 s += r->o_ss.channels;
1626 pa_memblock_release(output->memblock);
1627 pa_memblock_release(w);
1628 pa_memblock_unref(w);
1631 *out_n_frames = used_frames;
1634 static void ffmpeg_free(pa_resampler *r) {
1635 unsigned c;
1637 pa_assert(r);
1639 if (r->ffmpeg.state)
1640 av_resample_close(r->ffmpeg.state);
1642 for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
1643 if (r->ffmpeg.buf[c].memblock)
1644 pa_memblock_unref(r->ffmpeg.buf[c].memblock);
1647 static int ffmpeg_init(pa_resampler *r) {
1648 unsigned c;
1650 pa_assert(r);
1652 /* We could probably implement different quality levels by
1653 * adjusting the filter parameters here. However, ffmpeg
1654 * internally only uses these hardcoded values, so let's use them
1655 * here for now as well until ffmpeg makes this configurable. */
1657 if (!(r->ffmpeg.state = av_resample_init((int) r->o_ss.rate, (int) r->i_ss.rate, 16, 10, 0, 0.8)))
1658 return -1;
1660 r->impl_free = ffmpeg_free;
1661 r->impl_resample = ffmpeg_resample;
1663 for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
1664 pa_memchunk_reset(&r->ffmpeg.buf[c]);
1666 return 0;
1669 /*** copy (noop) implementation ***/
1671 static int copy_init(pa_resampler *r) {
1672 pa_assert(r);
1674 pa_assert(r->o_ss.rate == r->i_ss.rate);
1676 return 0;