]> code.delx.au - pulseaudio/blob - src/pulsecore/resampler.c
resampler: Remove invalid channel asserts in peak and trivial
[pulseaudio] / src / pulsecore / resampler.c
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, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27
28 #ifdef HAVE_LIBSAMPLERATE
29 #include <samplerate.h>
30 #endif
31
32 #ifdef HAVE_SPEEX
33 #include <speex/speex_resampler.h>
34 #endif
35
36 #include <pulse/xmalloc.h>
37 #include <pulsecore/sconv.h>
38 #include <pulsecore/log.h>
39 #include <pulsecore/macro.h>
40 #include <pulsecore/strbuf.h>
41 #include <pulsecore/remap.h>
42
43 #include "ffmpeg/avcodec.h"
44
45 #include "resampler.h"
46
47 /* Number of samples of extra space we allow the resamplers to return */
48 #define EXTRA_FRAMES 128
49
50 struct pa_resampler {
51 pa_resample_method_t method;
52 pa_resample_flags_t flags;
53
54 pa_sample_spec i_ss, o_ss;
55 pa_channel_map i_cm, o_cm;
56 size_t i_fz, o_fz, w_sz;
57 pa_mempool *mempool;
58
59 pa_memchunk buf1, buf2, buf3, buf4;
60 unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples;
61
62 pa_sample_format_t work_format;
63
64 pa_convert_func_t to_work_format_func;
65 pa_convert_func_t from_work_format_func;
66
67 pa_remap_t remap;
68 pa_bool_t map_required;
69
70 void (*impl_free)(pa_resampler *r);
71 void (*impl_update_rates)(pa_resampler *r);
72 void (*impl_resample)(pa_resampler *r, const pa_memchunk *in, unsigned in_samples, pa_memchunk *out, unsigned *out_samples);
73 void (*impl_reset)(pa_resampler *r);
74
75 struct { /* data specific to the trivial resampler */
76 unsigned o_counter;
77 unsigned i_counter;
78 } trivial;
79
80 struct { /* data specific to the peak finder pseudo resampler */
81 unsigned o_counter;
82 unsigned i_counter;
83
84 float max_f[PA_CHANNELS_MAX];
85 int16_t max_i[PA_CHANNELS_MAX];
86
87 } peaks;
88
89 #ifdef HAVE_LIBSAMPLERATE
90 struct { /* data specific to libsamplerate */
91 SRC_STATE *state;
92 } src;
93 #endif
94
95 #ifdef HAVE_SPEEX
96 struct { /* data specific to speex */
97 SpeexResamplerState* state;
98 } speex;
99 #endif
100
101 struct { /* data specific to ffmpeg */
102 struct AVResampleContext *state;
103 pa_memchunk buf[PA_CHANNELS_MAX];
104 } ffmpeg;
105 };
106
107 static int copy_init(pa_resampler *r);
108 static int trivial_init(pa_resampler*r);
109 #ifdef HAVE_SPEEX
110 static int speex_init(pa_resampler*r);
111 #endif
112 static int ffmpeg_init(pa_resampler*r);
113 static int peaks_init(pa_resampler*r);
114 #ifdef HAVE_LIBSAMPLERATE
115 static int libsamplerate_init(pa_resampler*r);
116 #endif
117
118 static void calc_map_table(pa_resampler *r);
119
120 static int (* const init_table[])(pa_resampler*r) = {
121 #ifdef HAVE_LIBSAMPLERATE
122 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = libsamplerate_init,
123 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = libsamplerate_init,
124 [PA_RESAMPLER_SRC_SINC_FASTEST] = libsamplerate_init,
125 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = libsamplerate_init,
126 [PA_RESAMPLER_SRC_LINEAR] = libsamplerate_init,
127 #else
128 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = NULL,
129 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = NULL,
130 [PA_RESAMPLER_SRC_SINC_FASTEST] = NULL,
131 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = NULL,
132 [PA_RESAMPLER_SRC_LINEAR] = NULL,
133 #endif
134 [PA_RESAMPLER_TRIVIAL] = trivial_init,
135 #ifdef HAVE_SPEEX
136 [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = speex_init,
137 [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = speex_init,
138 [PA_RESAMPLER_SPEEX_FLOAT_BASE+2] = speex_init,
139 [PA_RESAMPLER_SPEEX_FLOAT_BASE+3] = speex_init,
140 [PA_RESAMPLER_SPEEX_FLOAT_BASE+4] = speex_init,
141 [PA_RESAMPLER_SPEEX_FLOAT_BASE+5] = speex_init,
142 [PA_RESAMPLER_SPEEX_FLOAT_BASE+6] = speex_init,
143 [PA_RESAMPLER_SPEEX_FLOAT_BASE+7] = speex_init,
144 [PA_RESAMPLER_SPEEX_FLOAT_BASE+8] = speex_init,
145 [PA_RESAMPLER_SPEEX_FLOAT_BASE+9] = speex_init,
146 [PA_RESAMPLER_SPEEX_FLOAT_BASE+10] = speex_init,
147 [PA_RESAMPLER_SPEEX_FIXED_BASE+0] = speex_init,
148 [PA_RESAMPLER_SPEEX_FIXED_BASE+1] = speex_init,
149 [PA_RESAMPLER_SPEEX_FIXED_BASE+2] = speex_init,
150 [PA_RESAMPLER_SPEEX_FIXED_BASE+3] = speex_init,
151 [PA_RESAMPLER_SPEEX_FIXED_BASE+4] = speex_init,
152 [PA_RESAMPLER_SPEEX_FIXED_BASE+5] = speex_init,
153 [PA_RESAMPLER_SPEEX_FIXED_BASE+6] = speex_init,
154 [PA_RESAMPLER_SPEEX_FIXED_BASE+7] = speex_init,
155 [PA_RESAMPLER_SPEEX_FIXED_BASE+8] = speex_init,
156 [PA_RESAMPLER_SPEEX_FIXED_BASE+9] = speex_init,
157 [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = speex_init,
158 #else
159 [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = NULL,
160 [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = NULL,
161 [PA_RESAMPLER_SPEEX_FLOAT_BASE+2] = NULL,
162 [PA_RESAMPLER_SPEEX_FLOAT_BASE+3] = NULL,
163 [PA_RESAMPLER_SPEEX_FLOAT_BASE+4] = NULL,
164 [PA_RESAMPLER_SPEEX_FLOAT_BASE+5] = NULL,
165 [PA_RESAMPLER_SPEEX_FLOAT_BASE+6] = NULL,
166 [PA_RESAMPLER_SPEEX_FLOAT_BASE+7] = NULL,
167 [PA_RESAMPLER_SPEEX_FLOAT_BASE+8] = NULL,
168 [PA_RESAMPLER_SPEEX_FLOAT_BASE+9] = NULL,
169 [PA_RESAMPLER_SPEEX_FLOAT_BASE+10] = NULL,
170 [PA_RESAMPLER_SPEEX_FIXED_BASE+0] = NULL,
171 [PA_RESAMPLER_SPEEX_FIXED_BASE+1] = NULL,
172 [PA_RESAMPLER_SPEEX_FIXED_BASE+2] = NULL,
173 [PA_RESAMPLER_SPEEX_FIXED_BASE+3] = NULL,
174 [PA_RESAMPLER_SPEEX_FIXED_BASE+4] = NULL,
175 [PA_RESAMPLER_SPEEX_FIXED_BASE+5] = NULL,
176 [PA_RESAMPLER_SPEEX_FIXED_BASE+6] = NULL,
177 [PA_RESAMPLER_SPEEX_FIXED_BASE+7] = NULL,
178 [PA_RESAMPLER_SPEEX_FIXED_BASE+8] = NULL,
179 [PA_RESAMPLER_SPEEX_FIXED_BASE+9] = NULL,
180 [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = NULL,
181 #endif
182 [PA_RESAMPLER_FFMPEG] = ffmpeg_init,
183 [PA_RESAMPLER_AUTO] = NULL,
184 [PA_RESAMPLER_COPY] = copy_init,
185 [PA_RESAMPLER_PEAKS] = peaks_init,
186 };
187
188 pa_resampler* pa_resampler_new(
189 pa_mempool *pool,
190 const pa_sample_spec *a,
191 const pa_channel_map *am,
192 const pa_sample_spec *b,
193 const pa_channel_map *bm,
194 pa_resample_method_t method,
195 pa_resample_flags_t flags) {
196
197 pa_resampler *r = NULL;
198
199 pa_assert(pool);
200 pa_assert(a);
201 pa_assert(b);
202 pa_assert(pa_sample_spec_valid(a));
203 pa_assert(pa_sample_spec_valid(b));
204 pa_assert(method >= 0);
205 pa_assert(method < PA_RESAMPLER_MAX);
206
207 /* Fix method */
208
209 if (!(flags & PA_RESAMPLER_VARIABLE_RATE) && a->rate == b->rate) {
210 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
211 method = PA_RESAMPLER_COPY;
212 }
213
214 if (!pa_resample_method_supported(method)) {
215 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method));
216 method = PA_RESAMPLER_AUTO;
217 }
218
219 if (method == PA_RESAMPLER_FFMPEG && (flags & PA_RESAMPLER_VARIABLE_RATE)) {
220 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
221 method = PA_RESAMPLER_AUTO;
222 }
223
224 if (method == PA_RESAMPLER_COPY && ((flags & PA_RESAMPLER_VARIABLE_RATE) || a->rate != b->rate)) {
225 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
226 method = PA_RESAMPLER_AUTO;
227 }
228
229 if (method == PA_RESAMPLER_AUTO) {
230 #ifdef HAVE_SPEEX
231 method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
232 #else
233 method = PA_RESAMPLER_FFMPEG;
234 #endif
235 }
236
237 r = pa_xnew(pa_resampler, 1);
238 r->mempool = pool;
239 r->method = method;
240 r->flags = flags;
241
242 r->impl_free = NULL;
243 r->impl_update_rates = NULL;
244 r->impl_resample = NULL;
245 r->impl_reset = NULL;
246
247 /* Fill sample specs */
248 r->i_ss = *a;
249 r->o_ss = *b;
250
251 /* set up the remap structure */
252 r->remap.i_ss = &r->i_ss;
253 r->remap.o_ss = &r->o_ss;
254 r->remap.format = &r->work_format;
255
256 if (am)
257 r->i_cm = *am;
258 else if (!pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels, PA_CHANNEL_MAP_DEFAULT))
259 goto fail;
260
261 if (bm)
262 r->o_cm = *bm;
263 else if (!pa_channel_map_init_auto(&r->o_cm, r->o_ss.channels, PA_CHANNEL_MAP_DEFAULT))
264 goto fail;
265
266 r->i_fz = pa_frame_size(a);
267 r->o_fz = pa_frame_size(b);
268
269 pa_memchunk_reset(&r->buf1);
270 pa_memchunk_reset(&r->buf2);
271 pa_memchunk_reset(&r->buf3);
272 pa_memchunk_reset(&r->buf4);
273
274 r->buf1_samples = r->buf2_samples = r->buf3_samples = r->buf4_samples = 0;
275
276 calc_map_table(r);
277
278 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method));
279
280 if ((method >= PA_RESAMPLER_SPEEX_FIXED_BASE && method <= PA_RESAMPLER_SPEEX_FIXED_MAX) ||
281 (method == PA_RESAMPLER_FFMPEG))
282 r->work_format = PA_SAMPLE_S16NE;
283 else if (method == PA_RESAMPLER_TRIVIAL || method == PA_RESAMPLER_COPY || method == PA_RESAMPLER_PEAKS) {
284
285 if (r->map_required || a->format != b->format || method == PA_RESAMPLER_PEAKS) {
286
287 if (a->format == PA_SAMPLE_S32NE || a->format == PA_SAMPLE_S32RE ||
288 a->format == PA_SAMPLE_FLOAT32NE || a->format == PA_SAMPLE_FLOAT32RE ||
289 a->format == PA_SAMPLE_S24NE || a->format == PA_SAMPLE_S24RE ||
290 a->format == PA_SAMPLE_S24_32NE || a->format == PA_SAMPLE_S24_32RE ||
291 b->format == PA_SAMPLE_S32NE || b->format == PA_SAMPLE_S32RE ||
292 b->format == PA_SAMPLE_FLOAT32NE || b->format == PA_SAMPLE_FLOAT32RE ||
293 b->format == PA_SAMPLE_S24NE || b->format == PA_SAMPLE_S24RE ||
294 b->format == PA_SAMPLE_S24_32NE || b->format == PA_SAMPLE_S24_32RE)
295 r->work_format = PA_SAMPLE_FLOAT32NE;
296 else
297 r->work_format = PA_SAMPLE_S16NE;
298
299 } else
300 r->work_format = a->format;
301
302 } else
303 r->work_format = PA_SAMPLE_FLOAT32NE;
304
305 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r->work_format));
306
307 r->w_sz = pa_sample_size_of_format(r->work_format);
308
309 if (r->i_ss.format == r->work_format)
310 r->to_work_format_func = NULL;
311 else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
312 if (!(r->to_work_format_func = pa_get_convert_to_float32ne_function(r->i_ss.format)))
313 goto fail;
314 } else {
315 pa_assert(r->work_format == PA_SAMPLE_S16NE);
316 if (!(r->to_work_format_func = pa_get_convert_to_s16ne_function(r->i_ss.format)))
317 goto fail;
318 }
319
320 if (r->o_ss.format == r->work_format)
321 r->from_work_format_func = NULL;
322 else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
323 if (!(r->from_work_format_func = pa_get_convert_from_float32ne_function(r->o_ss.format)))
324 goto fail;
325 } else {
326 pa_assert(r->work_format == PA_SAMPLE_S16NE);
327 if (!(r->from_work_format_func = pa_get_convert_from_s16ne_function(r->o_ss.format)))
328 goto fail;
329 }
330
331 /* initialize implementation */
332 if (init_table[method](r) < 0)
333 goto fail;
334
335 return r;
336
337 fail:
338 pa_xfree(r);
339
340 return NULL;
341 }
342
343 void pa_resampler_free(pa_resampler *r) {
344 pa_assert(r);
345
346 if (r->impl_free)
347 r->impl_free(r);
348
349 if (r->buf1.memblock)
350 pa_memblock_unref(r->buf1.memblock);
351 if (r->buf2.memblock)
352 pa_memblock_unref(r->buf2.memblock);
353 if (r->buf3.memblock)
354 pa_memblock_unref(r->buf3.memblock);
355 if (r->buf4.memblock)
356 pa_memblock_unref(r->buf4.memblock);
357
358 pa_xfree(r);
359 }
360
361 void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) {
362 pa_assert(r);
363 pa_assert(rate > 0);
364
365 if (r->i_ss.rate == rate)
366 return;
367
368 r->i_ss.rate = rate;
369
370 r->impl_update_rates(r);
371 }
372
373 void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) {
374 pa_assert(r);
375 pa_assert(rate > 0);
376
377 if (r->o_ss.rate == rate)
378 return;
379
380 r->o_ss.rate = rate;
381
382 r->impl_update_rates(r);
383 }
384
385 size_t pa_resampler_request(pa_resampler *r, size_t out_length) {
386 pa_assert(r);
387
388 /* Let's round up here */
389
390 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;
391 }
392
393 size_t pa_resampler_result(pa_resampler *r, size_t in_length) {
394 pa_assert(r);
395
396 /* Let's round up here */
397
398 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;
399 }
400
401 size_t pa_resampler_max_block_size(pa_resampler *r) {
402 size_t block_size_max;
403 pa_sample_spec ss;
404 size_t fs;
405
406 pa_assert(r);
407
408 block_size_max = pa_mempool_block_size_max(r->mempool);
409
410 /* We deduce the "largest" sample spec we're using during the
411 * conversion */
412 ss.channels = (uint8_t) (PA_MAX(r->i_ss.channels, r->o_ss.channels));
413
414 /* We silently assume that the format enum is ordered by size */
415 ss.format = PA_MAX(r->i_ss.format, r->o_ss.format);
416 ss.format = PA_MAX(ss.format, r->work_format);
417
418 ss.rate = PA_MAX(r->i_ss.rate, r->o_ss.rate);
419
420 fs = pa_frame_size(&ss);
421
422 return (((block_size_max/fs - EXTRA_FRAMES)*r->i_ss.rate)/ss.rate)*r->i_fz;
423 }
424
425 void pa_resampler_reset(pa_resampler *r) {
426 pa_assert(r);
427
428 if (r->impl_reset)
429 r->impl_reset(r);
430 }
431
432 pa_resample_method_t pa_resampler_get_method(pa_resampler *r) {
433 pa_assert(r);
434
435 return r->method;
436 }
437
438 const pa_channel_map* pa_resampler_input_channel_map(pa_resampler *r) {
439 pa_assert(r);
440
441 return &r->i_cm;
442 }
443
444 const pa_sample_spec* pa_resampler_input_sample_spec(pa_resampler *r) {
445 pa_assert(r);
446
447 return &r->i_ss;
448 }
449
450 const pa_channel_map* pa_resampler_output_channel_map(pa_resampler *r) {
451 pa_assert(r);
452
453 return &r->o_cm;
454 }
455
456 const pa_sample_spec* pa_resampler_output_sample_spec(pa_resampler *r) {
457 pa_assert(r);
458
459 return &r->o_ss;
460 }
461
462 static const char * const resample_methods[] = {
463 "src-sinc-best-quality",
464 "src-sinc-medium-quality",
465 "src-sinc-fastest",
466 "src-zero-order-hold",
467 "src-linear",
468 "trivial",
469 "speex-float-0",
470 "speex-float-1",
471 "speex-float-2",
472 "speex-float-3",
473 "speex-float-4",
474 "speex-float-5",
475 "speex-float-6",
476 "speex-float-7",
477 "speex-float-8",
478 "speex-float-9",
479 "speex-float-10",
480 "speex-fixed-0",
481 "speex-fixed-1",
482 "speex-fixed-2",
483 "speex-fixed-3",
484 "speex-fixed-4",
485 "speex-fixed-5",
486 "speex-fixed-6",
487 "speex-fixed-7",
488 "speex-fixed-8",
489 "speex-fixed-9",
490 "speex-fixed-10",
491 "ffmpeg",
492 "auto",
493 "copy",
494 "peaks"
495 };
496
497 const char *pa_resample_method_to_string(pa_resample_method_t m) {
498
499 if (m < 0 || m >= PA_RESAMPLER_MAX)
500 return NULL;
501
502 return resample_methods[m];
503 }
504
505 int pa_resample_method_supported(pa_resample_method_t m) {
506
507 if (m < 0 || m >= PA_RESAMPLER_MAX)
508 return 0;
509
510 #ifndef HAVE_LIBSAMPLERATE
511 if (m <= PA_RESAMPLER_SRC_LINEAR)
512 return 0;
513 #endif
514
515 #ifndef HAVE_SPEEX
516 if (m >= PA_RESAMPLER_SPEEX_FLOAT_BASE && m <= PA_RESAMPLER_SPEEX_FLOAT_MAX)
517 return 0;
518 if (m >= PA_RESAMPLER_SPEEX_FIXED_BASE && m <= PA_RESAMPLER_SPEEX_FIXED_MAX)
519 return 0;
520 #endif
521
522 return 1;
523 }
524
525 pa_resample_method_t pa_parse_resample_method(const char *string) {
526 pa_resample_method_t m;
527
528 pa_assert(string);
529
530 for (m = 0; m < PA_RESAMPLER_MAX; m++)
531 if (!strcmp(string, resample_methods[m]))
532 return m;
533
534 if (!strcmp(string, "speex-fixed"))
535 return PA_RESAMPLER_SPEEX_FIXED_BASE + 3;
536
537 if (!strcmp(string, "speex-float"))
538 return PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
539
540 return PA_RESAMPLER_INVALID;
541 }
542
543 static pa_bool_t on_left(pa_channel_position_t p) {
544
545 return
546 p == PA_CHANNEL_POSITION_FRONT_LEFT ||
547 p == PA_CHANNEL_POSITION_REAR_LEFT ||
548 p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ||
549 p == PA_CHANNEL_POSITION_SIDE_LEFT ||
550 p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT ||
551 p == PA_CHANNEL_POSITION_TOP_REAR_LEFT;
552 }
553
554 static pa_bool_t on_right(pa_channel_position_t p) {
555
556 return
557 p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
558 p == PA_CHANNEL_POSITION_REAR_RIGHT ||
559 p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER ||
560 p == PA_CHANNEL_POSITION_SIDE_RIGHT ||
561 p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ||
562 p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
563 }
564
565 static pa_bool_t on_center(pa_channel_position_t p) {
566
567 return
568 p == PA_CHANNEL_POSITION_FRONT_CENTER ||
569 p == PA_CHANNEL_POSITION_REAR_CENTER ||
570 p == PA_CHANNEL_POSITION_TOP_CENTER ||
571 p == PA_CHANNEL_POSITION_TOP_FRONT_CENTER ||
572 p == PA_CHANNEL_POSITION_TOP_REAR_CENTER;
573 }
574
575 static pa_bool_t on_lfe(pa_channel_position_t p) {
576 return
577 p == PA_CHANNEL_POSITION_LFE;
578 }
579
580 static pa_bool_t on_front(pa_channel_position_t p) {
581 return
582 p == PA_CHANNEL_POSITION_FRONT_LEFT ||
583 p == PA_CHANNEL_POSITION_FRONT_RIGHT ||
584 p == PA_CHANNEL_POSITION_FRONT_CENTER ||
585 p == PA_CHANNEL_POSITION_TOP_FRONT_LEFT ||
586 p == PA_CHANNEL_POSITION_TOP_FRONT_RIGHT ||
587 p == PA_CHANNEL_POSITION_TOP_FRONT_CENTER ||
588 p == PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER ||
589 p == PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
590 }
591
592 static pa_bool_t on_rear(pa_channel_position_t p) {
593 return
594 p == PA_CHANNEL_POSITION_REAR_LEFT ||
595 p == PA_CHANNEL_POSITION_REAR_RIGHT ||
596 p == PA_CHANNEL_POSITION_REAR_CENTER ||
597 p == PA_CHANNEL_POSITION_TOP_REAR_LEFT ||
598 p == PA_CHANNEL_POSITION_TOP_REAR_RIGHT ||
599 p == PA_CHANNEL_POSITION_TOP_REAR_CENTER;
600 }
601
602 static pa_bool_t on_side(pa_channel_position_t p) {
603 return
604 p == PA_CHANNEL_POSITION_SIDE_LEFT ||
605 p == PA_CHANNEL_POSITION_SIDE_RIGHT ||
606 p == PA_CHANNEL_POSITION_TOP_CENTER;
607 }
608
609 enum {
610 ON_FRONT,
611 ON_REAR,
612 ON_SIDE,
613 ON_OTHER
614 };
615
616 static int front_rear_side(pa_channel_position_t p) {
617 if (on_front(p))
618 return ON_FRONT;
619 if (on_rear(p))
620 return ON_REAR;
621 if (on_side(p))
622 return ON_SIDE;
623 return ON_OTHER;
624 }
625
626 static void calc_map_table(pa_resampler *r) {
627 unsigned oc, ic;
628 unsigned n_oc, n_ic;
629 pa_bool_t ic_connected[PA_CHANNELS_MAX];
630 pa_bool_t remix;
631 pa_strbuf *s;
632 char *t;
633 pa_remap_t *m;
634
635 pa_assert(r);
636
637 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)))))
638 return;
639
640 m = &r->remap;
641
642 n_oc = r->o_ss.channels;
643 n_ic = r->i_ss.channels;
644
645 memset(m->map_table_f, 0, sizeof(m->map_table_f));
646 memset(m->map_table_i, 0, sizeof(m->map_table_i));
647
648 memset(ic_connected, 0, sizeof(ic_connected));
649 remix = (r->flags & (PA_RESAMPLER_NO_REMAP|PA_RESAMPLER_NO_REMIX)) == 0;
650
651 for (oc = 0; oc < n_oc; oc++) {
652 pa_bool_t oc_connected = FALSE;
653 pa_channel_position_t b = r->o_cm.map[oc];
654
655 for (ic = 0; ic < n_ic; ic++) {
656 pa_channel_position_t a = r->i_cm.map[ic];
657
658 if (r->flags & PA_RESAMPLER_NO_REMAP) {
659 /* We shall not do any remapping. Hence, just check by index */
660
661 if (ic == oc)
662 m->map_table_f[oc][ic] = 1.0;
663
664 continue;
665 }
666
667 if (r->flags & PA_RESAMPLER_NO_REMIX) {
668 /* We shall not do any remixing. Hence, just check by name */
669
670 if (a == b)
671 m->map_table_f[oc][ic] = 1.0;
672
673 continue;
674 }
675
676 pa_assert(remix);
677
678 /* OK, we shall do the full monty: upmixing and
679 * downmixing. Our algorithm is relatively simple, does
680 * not do spacialization, delay elements or apply lowpass
681 * filters for LFE. Patches are always welcome,
682 * though. Oh, and it doesn't do any matrix
683 * decoding. (Which probably wouldn't make any sense
684 * anyway.)
685 *
686 * This code is not idempotent: downmixing an upmixed
687 * stereo stream is not identical to the original. The
688 * volume will not match, and the two channels will be a
689 * linear combination of both.
690 *
691 * This is loosely based on random suggestions found on the
692 * Internet, such as this:
693 * http://www.halfgaar.net/surround-sound-in-linux and the
694 * alsa upmix plugin.
695 *
696 * The algorithm works basically like this:
697 *
698 * 1) Connect all channels with matching names.
699 *
700 * 2) Mono Handling:
701 * S:Mono: Copy into all D:channels
702 * D:Mono: Copy in all S:channels
703 *
704 * 3) Mix D:Left, D:Right:
705 * D:Left: If not connected, avg all S:Left
706 * D:Right: If not connected, avg all S:Right
707 *
708 * 4) Mix D:Center
709 * If not connected, avg all S:Center
710 * If still not connected, avg all S:Left, S:Right
711 *
712 * 5) Mix D:LFE
713 * If not connected, avg all S:*
714 *
715 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
716 * not connected, mix into all D:left and all D:right
717 * channels. Gain is 0.1, the current left and right
718 * should be multiplied by 0.9.
719 *
720 * 7) Make sure S:Center, S:LFE is used:
721 *
722 * S:Center, S:LFE: If not connected, mix into all
723 * D:left, all D:right, all D:center channels, gain is
724 * 0.375. The current (as result of 1..6) factors
725 * should be multiplied by 0.75. (Alt. suggestion: 0.25
726 * vs. 0.5) If C-front is only mixed into
727 * L-front/R-front if available, otherwise into all L/R
728 * channels. Similarly for C-rear.
729 *
730 * S: and D: shall relate to the source resp. destination channels.
731 *
732 * Rationale: 1, 2 are probably obvious. For 3: this
733 * copies front to rear if needed. For 4: we try to find
734 * some suitable C source for C, if we don't find any, we
735 * avg L and R. For 5: LFE is mixed from all channels. For
736 * 6: the rear channels should not be dropped entirely,
737 * however have only minimal impact. For 7: movies usually
738 * encode speech on the center channel. Thus we have to
739 * make sure this channel is distributed to L and R if not
740 * available in the output. Also, LFE is used to achieve a
741 * greater dynamic range, and thus we should try to do our
742 * best to pass it to L+R.
743 */
744
745 if (a == b || a == PA_CHANNEL_POSITION_MONO || b == PA_CHANNEL_POSITION_MONO) {
746 m->map_table_f[oc][ic] = 1.0;
747
748 oc_connected = TRUE;
749 ic_connected[ic] = TRUE;
750 }
751 }
752
753 if (!oc_connected && remix) {
754 /* OK, we shall remix */
755
756 /* Try to find matching input ports for this output port */
757
758 if (on_left(b)) {
759 unsigned n = 0;
760
761 /* We are not connected and on the left side, let's
762 * average all left side input channels. */
763
764 for (ic = 0; ic < n_ic; ic++)
765 if (on_left(r->i_cm.map[ic]))
766 n++;
767
768 if (n > 0)
769 for (ic = 0; ic < n_ic; ic++)
770 if (on_left(r->i_cm.map[ic])) {
771 m->map_table_f[oc][ic] = 1.0f / (float) n;
772 ic_connected[ic] = TRUE;
773 }
774
775 /* We ignore the case where there is no left input
776 * channel. Something is really wrong in this case
777 * anyway. */
778
779 } else if (on_right(b)) {
780 unsigned n = 0;
781
782 /* We are not connected and on the right side, let's
783 * average all right side input channels. */
784
785 for (ic = 0; ic < n_ic; ic++)
786 if (on_right(r->i_cm.map[ic]))
787 n++;
788
789 if (n > 0)
790 for (ic = 0; ic < n_ic; ic++)
791 if (on_right(r->i_cm.map[ic])) {
792 m->map_table_f[oc][ic] = 1.0f / (float) n;
793 ic_connected[ic] = TRUE;
794 }
795
796 /* We ignore the case where there is no right input
797 * channel. Something is really wrong in this case
798 * anyway. */
799
800 } else if (on_center(b)) {
801 unsigned n = 0;
802
803 /* We are not connected and at the center. Let's
804 * average all center input channels. */
805
806 for (ic = 0; ic < n_ic; ic++)
807 if (on_center(r->i_cm.map[ic]))
808 n++;
809
810 if (n > 0) {
811 for (ic = 0; ic < n_ic; ic++)
812 if (on_center(r->i_cm.map[ic])) {
813 m->map_table_f[oc][ic] = 1.0f / (float) n;
814 ic_connected[ic] = TRUE;
815 }
816 } else {
817
818 /* Hmm, no center channel around, let's synthesize
819 * it by mixing L and R.*/
820
821 n = 0;
822
823 for (ic = 0; ic < n_ic; ic++)
824 if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic]))
825 n++;
826
827 if (n > 0)
828 for (ic = 0; ic < n_ic; ic++)
829 if (on_left(r->i_cm.map[ic]) || on_right(r->i_cm.map[ic])) {
830 m->map_table_f[oc][ic] = 1.0f / (float) n;
831 ic_connected[ic] = TRUE;
832 }
833
834 /* We ignore the case where there is not even a
835 * left or right input channel. Something is
836 * really wrong in this case anyway. */
837 }
838
839 } else if (on_lfe(b)) {
840
841 /* We are not connected and an LFE. Let's average all
842 * channels for LFE. */
843
844 for (ic = 0; ic < n_ic; ic++) {
845
846 if (!(r->flags & PA_RESAMPLER_NO_LFE))
847 m->map_table_f[oc][ic] = 1.0f / (float) n_ic;
848 else
849 m->map_table_f[oc][ic] = 0;
850
851 /* Please note that a channel connected to LFE
852 * doesn't really count as connected. */
853 }
854 }
855 }
856 }
857
858 if (remix) {
859 unsigned
860 ic_unconnected_left = 0,
861 ic_unconnected_right = 0,
862 ic_unconnected_center = 0,
863 ic_unconnected_lfe = 0;
864
865 for (ic = 0; ic < n_ic; ic++) {
866 pa_channel_position_t a = r->i_cm.map[ic];
867
868 if (ic_connected[ic])
869 continue;
870
871 if (on_left(a))
872 ic_unconnected_left++;
873 else if (on_right(a))
874 ic_unconnected_right++;
875 else if (on_center(a))
876 ic_unconnected_center++;
877 else if (on_lfe(a))
878 ic_unconnected_lfe++;
879 }
880
881 if (ic_unconnected_left > 0) {
882
883 /* OK, so there are unconnected input channels on the
884 * left. Let's multiply all already connected channels on
885 * the left side by .9 and add in our averaged unconnected
886 * channels multiplied by .1 */
887
888 for (oc = 0; oc < n_oc; oc++) {
889
890 if (!on_left(r->o_cm.map[oc]))
891 continue;
892
893 for (ic = 0; ic < n_ic; ic++) {
894
895 if (ic_connected[ic]) {
896 m->map_table_f[oc][ic] *= .9f;
897 continue;
898 }
899
900 if (on_left(r->i_cm.map[ic]))
901 m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_left;
902 }
903 }
904 }
905
906 if (ic_unconnected_right > 0) {
907
908 /* OK, so there are unconnected input channels on the
909 * right. Let's multiply all already connected channels on
910 * the right side by .9 and add in our averaged unconnected
911 * channels multiplied by .1 */
912
913 for (oc = 0; oc < n_oc; oc++) {
914
915 if (!on_right(r->o_cm.map[oc]))
916 continue;
917
918 for (ic = 0; ic < n_ic; ic++) {
919
920 if (ic_connected[ic]) {
921 m->map_table_f[oc][ic] *= .9f;
922 continue;
923 }
924
925 if (on_right(r->i_cm.map[ic]))
926 m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_right;
927 }
928 }
929 }
930
931 if (ic_unconnected_center > 0) {
932 pa_bool_t mixed_in = FALSE;
933
934 /* OK, so there are unconnected input channels on the
935 * center. Let's multiply all already connected channels on
936 * the center side by .9 and add in our averaged unconnected
937 * channels multiplied by .1 */
938
939 for (oc = 0; oc < n_oc; oc++) {
940
941 if (!on_center(r->o_cm.map[oc]))
942 continue;
943
944 for (ic = 0; ic < n_ic; ic++) {
945
946 if (ic_connected[ic]) {
947 m->map_table_f[oc][ic] *= .9f;
948 continue;
949 }
950
951 if (on_center(r->i_cm.map[ic])) {
952 m->map_table_f[oc][ic] = .1f / (float) ic_unconnected_center;
953 mixed_in = TRUE;
954 }
955 }
956 }
957
958 if (!mixed_in) {
959 unsigned ncenter[PA_CHANNELS_MAX];
960 pa_bool_t found_frs[PA_CHANNELS_MAX];
961
962 memset(ncenter, 0, sizeof(ncenter));
963 memset(found_frs, 0, sizeof(found_frs));
964
965 /* Hmm, as it appears there was no center channel we
966 could mix our center channel in. In this case, mix
967 it into left and right. Using .375 and 0.75 as
968 factors. */
969
970 for (ic = 0; ic < n_ic; ic++) {
971
972 if (ic_connected[ic])
973 continue;
974
975 if (!on_center(r->i_cm.map[ic]))
976 continue;
977
978 for (oc = 0; oc < n_oc; oc++) {
979
980 if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
981 continue;
982
983 if (front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc])) {
984 found_frs[ic] = TRUE;
985 break;
986 }
987 }
988
989 for (oc = 0; oc < n_oc; oc++) {
990
991 if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
992 continue;
993
994 if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
995 ncenter[oc]++;
996 }
997 }
998
999 for (oc = 0; oc < n_oc; oc++) {
1000
1001 if (!on_left(r->o_cm.map[oc]) && !on_right(r->o_cm.map[oc]))
1002 continue;
1003
1004 if (ncenter[oc] <= 0)
1005 continue;
1006
1007 for (ic = 0; ic < n_ic; ic++) {
1008
1009 if (ic_connected[ic]) {
1010 m->map_table_f[oc][ic] *= .75f;
1011 continue;
1012 }
1013
1014 if (!on_center(r->i_cm.map[ic]))
1015 continue;
1016
1017 if (!found_frs[ic] || front_rear_side(r->i_cm.map[ic]) == front_rear_side(r->o_cm.map[oc]))
1018 m->map_table_f[oc][ic] = .375f / (float) ncenter[oc];
1019 }
1020 }
1021 }
1022 }
1023
1024 if (ic_unconnected_lfe > 0 && !(r->flags & PA_RESAMPLER_NO_LFE)) {
1025
1026 /* OK, so there is an unconnected LFE channel. Let's mix
1027 * it into all channels, with factor 0.375 */
1028
1029 for (ic = 0; ic < n_ic; ic++) {
1030
1031 if (!on_lfe(r->i_cm.map[ic]))
1032 continue;
1033
1034 for (oc = 0; oc < n_oc; oc++)
1035 m->map_table_f[oc][ic] = 0.375f / (float) ic_unconnected_lfe;
1036 }
1037 }
1038 }
1039 /* make an 16:16 int version of the matrix */
1040 for (oc = 0; oc < n_oc; oc++)
1041 for (ic = 0; ic < n_ic; ic++)
1042 m->map_table_i[oc][ic] = (int32_t) (m->map_table_f[oc][ic] * 0x10000);
1043
1044 s = pa_strbuf_new();
1045
1046 pa_strbuf_printf(s, " ");
1047 for (ic = 0; ic < n_ic; ic++)
1048 pa_strbuf_printf(s, " I%02u ", ic);
1049 pa_strbuf_puts(s, "\n +");
1050
1051 for (ic = 0; ic < n_ic; ic++)
1052 pa_strbuf_printf(s, "------");
1053 pa_strbuf_puts(s, "\n");
1054
1055 for (oc = 0; oc < n_oc; oc++) {
1056 pa_strbuf_printf(s, "O%02u |", oc);
1057
1058 for (ic = 0; ic < n_ic; ic++)
1059 pa_strbuf_printf(s, " %1.3f", m->map_table_f[oc][ic]);
1060
1061 pa_strbuf_puts(s, "\n");
1062 }
1063
1064 pa_log_debug("Channel matrix:\n%s", t = pa_strbuf_tostring_free(s));
1065 pa_xfree(t);
1066
1067 /* initialize the remapping function */
1068 pa_init_remap(m);
1069 }
1070
1071 static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) {
1072 unsigned n_samples;
1073 void *src, *dst;
1074
1075 pa_assert(r);
1076 pa_assert(input);
1077 pa_assert(input->memblock);
1078
1079 /* Convert the incoming sample into the work sample format and place them in buf1 */
1080
1081 if (!r->to_work_format_func || !input->length)
1082 return input;
1083
1084 n_samples = (unsigned) ((input->length / r->i_fz) * r->i_ss.channels);
1085
1086 r->buf1.index = 0;
1087 r->buf1.length = r->w_sz * n_samples;
1088
1089 if (!r->buf1.memblock || r->buf1_samples < n_samples) {
1090 if (r->buf1.memblock)
1091 pa_memblock_unref(r->buf1.memblock);
1092
1093 r->buf1_samples = n_samples;
1094 r->buf1.memblock = pa_memblock_new(r->mempool, r->buf1.length);
1095 }
1096
1097 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
1098 dst = (uint8_t*) pa_memblock_acquire(r->buf1.memblock);
1099
1100 r->to_work_format_func(n_samples, src, dst);
1101
1102 pa_memblock_release(input->memblock);
1103 pa_memblock_release(r->buf1.memblock);
1104
1105 return &r->buf1;
1106 }
1107
1108 static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
1109 unsigned in_n_samples, out_n_samples, n_frames;
1110 void *src, *dst;
1111 pa_remap_t *remap;
1112
1113 pa_assert(r);
1114 pa_assert(input);
1115 pa_assert(input->memblock);
1116
1117 /* Remap channels and place the result int buf2 */
1118
1119 if (!r->map_required || !input->length)
1120 return input;
1121
1122 in_n_samples = (unsigned) (input->length / r->w_sz);
1123 n_frames = in_n_samples / r->i_ss.channels;
1124 out_n_samples = n_frames * r->o_ss.channels;
1125
1126 r->buf2.index = 0;
1127 r->buf2.length = r->w_sz * out_n_samples;
1128
1129 if (!r->buf2.memblock || r->buf2_samples < out_n_samples) {
1130 if (r->buf2.memblock)
1131 pa_memblock_unref(r->buf2.memblock);
1132
1133 r->buf2_samples = out_n_samples;
1134 r->buf2.memblock = pa_memblock_new(r->mempool, r->buf2.length);
1135 }
1136
1137 src = ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
1138 dst = pa_memblock_acquire(r->buf2.memblock);
1139
1140 remap = &r->remap;
1141
1142 pa_assert(remap->do_remap);
1143 remap->do_remap(remap, dst, src, n_frames);
1144
1145 pa_memblock_release(input->memblock);
1146 pa_memblock_release(r->buf2.memblock);
1147
1148 return &r->buf2;
1149 }
1150
1151 static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {
1152 unsigned in_n_frames, in_n_samples;
1153 unsigned out_n_frames, out_n_samples;
1154
1155 pa_assert(r);
1156 pa_assert(input);
1157
1158 /* Resample the data and place the result in buf3 */
1159
1160 if (!r->impl_resample || !input->length)
1161 return input;
1162
1163 in_n_samples = (unsigned) (input->length / r->w_sz);
1164 in_n_frames = (unsigned) (in_n_samples / r->o_ss.channels);
1165
1166 out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_FRAMES;
1167 out_n_samples = out_n_frames * r->o_ss.channels;
1168
1169 r->buf3.index = 0;
1170 r->buf3.length = r->w_sz * out_n_samples;
1171
1172 if (!r->buf3.memblock || r->buf3_samples < out_n_samples) {
1173 if (r->buf3.memblock)
1174 pa_memblock_unref(r->buf3.memblock);
1175
1176 r->buf3_samples = out_n_samples;
1177 r->buf3.memblock = pa_memblock_new(r->mempool, r->buf3.length);
1178 }
1179
1180 r->impl_resample(r, input, in_n_frames, &r->buf3, &out_n_frames);
1181 r->buf3.length = out_n_frames * r->w_sz * r->o_ss.channels;
1182
1183 return &r->buf3;
1184 }
1185
1186 static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input) {
1187 unsigned n_samples, n_frames;
1188 void *src, *dst;
1189
1190 pa_assert(r);
1191 pa_assert(input);
1192
1193 /* Convert the data into the correct sample type and place the result in buf4 */
1194
1195 if (!r->from_work_format_func || !input->length)
1196 return input;
1197
1198 n_samples = (unsigned) (input->length / r->w_sz);
1199 n_frames = n_samples / r->o_ss.channels;
1200
1201 r->buf4.index = 0;
1202 r->buf4.length = r->o_fz * n_frames;
1203
1204 if (!r->buf4.memblock || r->buf4_samples < n_samples) {
1205 if (r->buf4.memblock)
1206 pa_memblock_unref(r->buf4.memblock);
1207
1208 r->buf4_samples = n_samples;
1209 r->buf4.memblock = pa_memblock_new(r->mempool, r->buf4.length);
1210 }
1211
1212 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
1213 dst = pa_memblock_acquire(r->buf4.memblock);
1214 r->from_work_format_func(n_samples, src, dst);
1215 pa_memblock_release(input->memblock);
1216 pa_memblock_release(r->buf4.memblock);
1217
1218 r->buf4.length = r->o_fz * n_frames;
1219
1220 return &r->buf4;
1221 }
1222
1223 void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) {
1224 pa_memchunk *buf;
1225
1226 pa_assert(r);
1227 pa_assert(in);
1228 pa_assert(out);
1229 pa_assert(in->length);
1230 pa_assert(in->memblock);
1231 pa_assert(in->length % r->i_fz == 0);
1232
1233 buf = (pa_memchunk*) in;
1234 buf = convert_to_work_format(r, buf);
1235 buf = remap_channels(r, buf);
1236 buf = resample(r, buf);
1237
1238 if (buf->length) {
1239 buf = convert_from_work_format(r, buf);
1240 *out = *buf;
1241
1242 if (buf == in)
1243 pa_memblock_ref(buf->memblock);
1244 else
1245 pa_memchunk_reset(buf);
1246 } else
1247 pa_memchunk_reset(out);
1248 }
1249
1250 /*** libsamplerate based implementation ***/
1251
1252 #ifdef HAVE_LIBSAMPLERATE
1253 static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1254 SRC_DATA data;
1255
1256 pa_assert(r);
1257 pa_assert(input);
1258 pa_assert(output);
1259 pa_assert(out_n_frames);
1260
1261 memset(&data, 0, sizeof(data));
1262
1263 data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
1264 data.input_frames = (long int) in_n_frames;
1265
1266 data.data_out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
1267 data.output_frames = (long int) *out_n_frames;
1268
1269 data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate;
1270 data.end_of_input = 0;
1271
1272 pa_assert_se(src_process(r->src.state, &data) == 0);
1273 pa_assert((unsigned) data.input_frames_used == in_n_frames);
1274
1275 pa_memblock_release(input->memblock);
1276 pa_memblock_release(output->memblock);
1277
1278 *out_n_frames = (unsigned) data.output_frames_gen;
1279 }
1280
1281 static void libsamplerate_update_rates(pa_resampler *r) {
1282 pa_assert(r);
1283
1284 pa_assert_se(src_set_ratio(r->src.state, (double) r->o_ss.rate / r->i_ss.rate) == 0);
1285 }
1286
1287 static void libsamplerate_reset(pa_resampler *r) {
1288 pa_assert(r);
1289
1290 pa_assert_se(src_reset(r->src.state) == 0);
1291 }
1292
1293 static void libsamplerate_free(pa_resampler *r) {
1294 pa_assert(r);
1295
1296 if (r->src.state)
1297 src_delete(r->src.state);
1298 }
1299
1300 static int libsamplerate_init(pa_resampler *r) {
1301 int err;
1302
1303 pa_assert(r);
1304
1305 if (!(r->src.state = src_new(r->method, r->o_ss.channels, &err)))
1306 return -1;
1307
1308 r->impl_free = libsamplerate_free;
1309 r->impl_update_rates = libsamplerate_update_rates;
1310 r->impl_resample = libsamplerate_resample;
1311 r->impl_reset = libsamplerate_reset;
1312
1313 return 0;
1314 }
1315 #endif
1316
1317 #ifdef HAVE_SPEEX
1318 /*** speex based implementation ***/
1319
1320 static void speex_resample_float(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1321 float *in, *out;
1322 uint32_t inf = in_n_frames, outf = *out_n_frames;
1323
1324 pa_assert(r);
1325 pa_assert(input);
1326 pa_assert(output);
1327 pa_assert(out_n_frames);
1328
1329 in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
1330 out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
1331
1332 pa_assert_se(speex_resampler_process_interleaved_float(r->speex.state, in, &inf, out, &outf) == 0);
1333
1334 pa_memblock_release(input->memblock);
1335 pa_memblock_release(output->memblock);
1336
1337 pa_assert(inf == in_n_frames);
1338 *out_n_frames = outf;
1339 }
1340
1341 static void speex_resample_int(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1342 int16_t *in, *out;
1343 uint32_t inf = in_n_frames, outf = *out_n_frames;
1344
1345 pa_assert(r);
1346 pa_assert(input);
1347 pa_assert(output);
1348 pa_assert(out_n_frames);
1349
1350 in = (int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
1351 out = (int16_t*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
1352
1353 pa_assert_se(speex_resampler_process_interleaved_int(r->speex.state, in, &inf, out, &outf) == 0);
1354
1355 pa_memblock_release(input->memblock);
1356 pa_memblock_release(output->memblock);
1357
1358 pa_assert(inf == in_n_frames);
1359 *out_n_frames = outf;
1360 }
1361
1362 static void speex_update_rates(pa_resampler *r) {
1363 pa_assert(r);
1364
1365 pa_assert_se(speex_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0);
1366 }
1367
1368 static void speex_reset(pa_resampler *r) {
1369 pa_assert(r);
1370
1371 pa_assert_se(speex_resampler_reset_mem(r->speex.state) == 0);
1372 }
1373
1374 static void speex_free(pa_resampler *r) {
1375 pa_assert(r);
1376
1377 if (!r->speex.state)
1378 return;
1379
1380 speex_resampler_destroy(r->speex.state);
1381 }
1382
1383 static int speex_init(pa_resampler *r) {
1384 int q, err;
1385
1386 pa_assert(r);
1387
1388 r->impl_free = speex_free;
1389 r->impl_update_rates = speex_update_rates;
1390 r->impl_reset = speex_reset;
1391
1392 if (r->method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->method <= PA_RESAMPLER_SPEEX_FIXED_MAX) {
1393
1394 q = r->method - PA_RESAMPLER_SPEEX_FIXED_BASE;
1395 r->impl_resample = speex_resample_int;
1396
1397 } else {
1398 pa_assert(r->method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
1399
1400 q = r->method - PA_RESAMPLER_SPEEX_FLOAT_BASE;
1401 r->impl_resample = speex_resample_float;
1402 }
1403
1404 pa_log_info("Choosing speex quality setting %i.", q);
1405
1406 if (!(r->speex.state = speex_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
1407 return -1;
1408
1409 return 0;
1410 }
1411 #endif
1412
1413 /* Trivial implementation */
1414
1415 static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1416 size_t fz;
1417 unsigned i_index, o_index;
1418 void *src, *dst;
1419
1420 pa_assert(r);
1421 pa_assert(input);
1422 pa_assert(output);
1423 pa_assert(out_n_frames);
1424
1425 fz = r->w_sz * r->o_ss.channels;
1426
1427 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
1428 dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
1429
1430 for (o_index = 0;; o_index++, r->trivial.o_counter++) {
1431 i_index = (r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate;
1432 i_index = i_index > r->trivial.i_counter ? i_index - r->trivial.i_counter : 0;
1433
1434 if (i_index >= in_n_frames)
1435 break;
1436
1437 pa_assert_fp(o_index * fz < pa_memblock_get_length(output->memblock));
1438
1439 /* Directly assign some common sample sizes, use memcpy as fallback */
1440 if (r->w_sz == 2) {
1441 for (unsigned c = 0; c < r->o_ss.channels; c++)
1442 ((uint16_t *) dst)[o_index+c] = ((uint16_t *) src)[i_index+c];
1443 } else if (r->w_sz == 4) {
1444 for (unsigned c = 0; c < r->o_ss.channels; c++)
1445 ((uint32_t *) dst)[o_index+c] = ((uint32_t *) src)[i_index+c];
1446 } else {
1447 memcpy((uint8_t *) dst + fz * o_index, (uint8_t *) src + fz * i_index, (int) fz);
1448 }
1449 }
1450
1451 pa_memblock_release(input->memblock);
1452 pa_memblock_release(output->memblock);
1453
1454 *out_n_frames = o_index;
1455
1456 r->trivial.i_counter += in_n_frames;
1457
1458 /* Normalize counters */
1459 while (r->trivial.i_counter >= r->i_ss.rate) {
1460 pa_assert(r->trivial.o_counter >= r->o_ss.rate);
1461
1462 r->trivial.i_counter -= r->i_ss.rate;
1463 r->trivial.o_counter -= r->o_ss.rate;
1464 }
1465 }
1466
1467 static void trivial_update_rates_or_reset(pa_resampler *r) {
1468 pa_assert(r);
1469
1470 r->trivial.i_counter = 0;
1471 r->trivial.o_counter = 0;
1472 }
1473
1474 static int trivial_init(pa_resampler*r) {
1475 pa_assert(r);
1476
1477 r->trivial.o_counter = r->trivial.i_counter = 0;
1478
1479 r->impl_resample = trivial_resample;
1480 r->impl_update_rates = trivial_update_rates_or_reset;
1481 r->impl_reset = trivial_update_rates_or_reset;
1482
1483 return 0;
1484 }
1485
1486 /* Peak finder implementation */
1487
1488 static void peaks_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1489 unsigned c, o_index = 0;
1490 unsigned i, i_end = 0;
1491 void *src, *dst;
1492
1493 pa_assert(r);
1494 pa_assert(input);
1495 pa_assert(output);
1496 pa_assert(out_n_frames);
1497 pa_assert(r->i_ss.rate >= r->o_ss.rate);
1498 pa_assert(r->work_format == PA_SAMPLE_S16NE || r->work_format == PA_SAMPLE_FLOAT32NE);
1499
1500 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
1501 dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
1502
1503 i = (r->peaks.o_counter * r->i_ss.rate) / r->o_ss.rate;
1504 i = i > r->peaks.i_counter ? i - r->peaks.i_counter : 0;
1505
1506 while (i_end < in_n_frames) {
1507 i_end = ((r->peaks.o_counter+1) * r->i_ss.rate) / r->o_ss.rate;
1508 i_end = i_end > r->peaks.i_counter ? i_end - r->peaks.i_counter : 0;
1509
1510 pa_assert_fp(o_index * r->w_sz * r->o_ss.channels < pa_memblock_get_length(output->memblock));
1511
1512 /* 1ch float is treated separately, because that is the common case */
1513 if (r->o_ss.channels == 1 && r->work_format == PA_SAMPLE_FLOAT32NE) {
1514 float *s = (float*) src + i;
1515 float *d = (float*) dst + o_index;
1516
1517 for (; i < i_end && i < in_n_frames; i++) {
1518 float n = fabsf(*s++);
1519
1520 if (n > r->peaks.max_f[0])
1521 r->peaks.max_f[0] = n;
1522 }
1523
1524 if (i == i_end) {
1525 *d = r->peaks.max_f[0];
1526 r->peaks.max_f[0] = 0;
1527 o_index++, r->peaks.o_counter++;
1528 }
1529 } else if (r->work_format == PA_SAMPLE_S16NE) {
1530 int16_t *s = (int16_t*) src + r->i_ss.channels * i;
1531 int16_t *d = (int16_t*) dst + r->o_ss.channels * o_index;
1532
1533 for (; i < i_end && i < in_n_frames; i++)
1534 for (c = 0; c < r->o_ss.channels; c++) {
1535 int16_t n = abs(*s++);
1536
1537 if (n > r->peaks.max_i[c])
1538 r->peaks.max_i[c] = n;
1539 }
1540
1541 if (i == i_end) {
1542 for (c = 0; c < r->o_ss.channels; c++, d++) {
1543 *d = r->peaks.max_i[c];
1544 r->peaks.max_i[c] = 0;
1545 }
1546 o_index++, r->peaks.o_counter++;
1547 }
1548 } else {
1549 float *s = (float*) src + r->i_ss.channels * i;
1550 float *d = (float*) dst + r->o_ss.channels * o_index;
1551
1552 for (; i < i_end && i < in_n_frames; i++)
1553 for (c = 0; c < r->o_ss.channels; c++) {
1554 float n = fabsf(*s++);
1555
1556 if (n > r->peaks.max_f[c])
1557 r->peaks.max_f[c] = n;
1558 }
1559
1560 if (i == i_end) {
1561 for (c = 0; c < r->o_ss.channels; c++, d++) {
1562 *d = r->peaks.max_f[c];
1563 r->peaks.max_f[c] = 0;
1564 }
1565 o_index++, r->peaks.o_counter++;
1566 }
1567 }
1568 }
1569
1570 pa_memblock_release(input->memblock);
1571 pa_memblock_release(output->memblock);
1572
1573 *out_n_frames = o_index;
1574
1575 r->peaks.i_counter += in_n_frames;
1576
1577 /* Normalize counters */
1578 while (r->peaks.i_counter >= r->i_ss.rate) {
1579 pa_assert(r->peaks.o_counter >= r->o_ss.rate);
1580
1581 r->peaks.i_counter -= r->i_ss.rate;
1582 r->peaks.o_counter -= r->o_ss.rate;
1583 }
1584 }
1585
1586 static void peaks_update_rates_or_reset(pa_resampler *r) {
1587 pa_assert(r);
1588
1589 r->peaks.i_counter = 0;
1590 r->peaks.o_counter = 0;
1591 }
1592
1593 static int peaks_init(pa_resampler*r) {
1594 pa_assert(r);
1595
1596 r->peaks.o_counter = r->peaks.i_counter = 0;
1597 memset(r->peaks.max_i, 0, sizeof(r->peaks.max_i));
1598 memset(r->peaks.max_f, 0, sizeof(r->peaks.max_f));
1599
1600 r->impl_resample = peaks_resample;
1601 r->impl_update_rates = peaks_update_rates_or_reset;
1602 r->impl_reset = peaks_update_rates_or_reset;
1603
1604 return 0;
1605 }
1606
1607 /*** ffmpeg based implementation ***/
1608
1609 static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
1610 unsigned used_frames = 0, c;
1611
1612 pa_assert(r);
1613 pa_assert(input);
1614 pa_assert(output);
1615 pa_assert(out_n_frames);
1616
1617 for (c = 0; c < r->o_ss.channels; c++) {
1618 unsigned u;
1619 pa_memblock *b, *w;
1620 int16_t *p, *t, *k, *q, *s;
1621 int consumed_frames;
1622 unsigned in, l;
1623
1624 /* Allocate a new block */
1625 b = pa_memblock_new(r->mempool, r->ffmpeg.buf[c].length + in_n_frames * sizeof(int16_t));
1626 p = pa_memblock_acquire(b);
1627
1628 /* Copy the remaining data into it */
1629 l = (unsigned) r->ffmpeg.buf[c].length;
1630 if (r->ffmpeg.buf[c].memblock) {
1631 t = (int16_t*) ((uint8_t*) pa_memblock_acquire(r->ffmpeg.buf[c].memblock) + r->ffmpeg.buf[c].index);
1632 memcpy(p, t, l);
1633 pa_memblock_release(r->ffmpeg.buf[c].memblock);
1634 pa_memblock_unref(r->ffmpeg.buf[c].memblock);
1635 pa_memchunk_reset(&r->ffmpeg.buf[c]);
1636 }
1637
1638 /* Now append the new data, splitting up channels */
1639 t = ((int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index)) + c;
1640 k = (int16_t*) ((uint8_t*) p + l);
1641 for (u = 0; u < in_n_frames; u++) {
1642 *k = *t;
1643 t += r->o_ss.channels;
1644 k ++;
1645 }
1646 pa_memblock_release(input->memblock);
1647
1648 /* Calculate the resulting number of frames */
1649 in = (unsigned) in_n_frames + l / (unsigned) sizeof(int16_t);
1650
1651 /* Allocate buffer for the result */
1652 w = pa_memblock_new(r->mempool, *out_n_frames * sizeof(int16_t));
1653 q = pa_memblock_acquire(w);
1654
1655 /* Now, resample */
1656 used_frames = (unsigned) av_resample(r->ffmpeg.state,
1657 q, p,
1658 &consumed_frames,
1659 (int) in, (int) *out_n_frames,
1660 c >= (unsigned) (r->o_ss.channels-1));
1661
1662 pa_memblock_release(b);
1663
1664 /* Now store the remaining samples away */
1665 pa_assert(consumed_frames <= (int) in);
1666 if (consumed_frames < (int) in) {
1667 r->ffmpeg.buf[c].memblock = b;
1668 r->ffmpeg.buf[c].index = (size_t) consumed_frames * sizeof(int16_t);
1669 r->ffmpeg.buf[c].length = (size_t) (in - (unsigned) consumed_frames) * sizeof(int16_t);
1670 } else
1671 pa_memblock_unref(b);
1672
1673 /* And place the results in the output buffer */
1674 s = (short*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index) + c;
1675 for (u = 0; u < used_frames; u++) {
1676 *s = *q;
1677 q++;
1678 s += r->o_ss.channels;
1679 }
1680 pa_memblock_release(output->memblock);
1681 pa_memblock_release(w);
1682 pa_memblock_unref(w);
1683 }
1684
1685 *out_n_frames = used_frames;
1686 }
1687
1688 static void ffmpeg_free(pa_resampler *r) {
1689 unsigned c;
1690
1691 pa_assert(r);
1692
1693 if (r->ffmpeg.state)
1694 av_resample_close(r->ffmpeg.state);
1695
1696 for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
1697 if (r->ffmpeg.buf[c].memblock)
1698 pa_memblock_unref(r->ffmpeg.buf[c].memblock);
1699 }
1700
1701 static int ffmpeg_init(pa_resampler *r) {
1702 unsigned c;
1703
1704 pa_assert(r);
1705
1706 /* We could probably implement different quality levels by
1707 * adjusting the filter parameters here. However, ffmpeg
1708 * internally only uses these hardcoded values, so let's use them
1709 * here for now as well until ffmpeg makes this configurable. */
1710
1711 if (!(r->ffmpeg.state = av_resample_init((int) r->o_ss.rate, (int) r->i_ss.rate, 16, 10, 0, 0.8)))
1712 return -1;
1713
1714 r->impl_free = ffmpeg_free;
1715 r->impl_resample = ffmpeg_resample;
1716
1717 for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
1718 pa_memchunk_reset(&r->ffmpeg.buf[c]);
1719
1720 return 0;
1721 }
1722
1723 /*** copy (noop) implementation ***/
1724
1725 static int copy_init(pa_resampler *r) {
1726 pa_assert(r);
1727
1728 pa_assert(r->o_ss.rate == r->i_ss.rate);
1729
1730 return 0;
1731 }