]> code.delx.au - pulseaudio/blob - src/pulsecore/resampler.c
add support for 32bit integer samples
[pulseaudio] / src / pulsecore / resampler.c
1 /* $Id$ */
2
3 /***
4 This file is part of PulseAudio.
5
6 Copyright 2004-2006 Lennart Poettering
7
8 PulseAudio is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published
10 by the Free Software Foundation; either version 2 of the License,
11 or (at your option) any later version.
12
13 PulseAudio is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with PulseAudio; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 USA.
22 ***/
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <string.h>
29
30 #if HAVE_LIBSAMPLERATE
31 #include <samplerate.h>
32 #endif
33
34 #include <liboil/liboilfuncs.h>
35 #include <liboil/liboil.h>
36
37 #include <pulse/xmalloc.h>
38 #include <pulsecore/sconv.h>
39 #include <pulsecore/log.h>
40 #include <pulsecore/macro.h>
41
42 #include "speexwrap.h"
43
44 #include "ffmpeg/avcodec.h"
45
46 #include "resampler.h"
47
48 /* Number of samples of extra space we allow the resamplers to return */
49 #define EXTRA_SAMPLES 128
50
51 struct pa_resampler {
52 pa_resample_method_t resample_method;
53 pa_sample_spec i_ss, o_ss;
54 pa_channel_map i_cm, o_cm;
55 size_t i_fz, o_fz, w_sz;
56 pa_mempool *mempool;
57
58 pa_memchunk buf1, buf2, buf3, buf4;
59 unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples;
60
61 pa_sample_format_t work_format;
62
63 pa_convert_func_t to_work_format_func;
64 pa_convert_func_t from_work_format_func;
65
66 int map_table[PA_CHANNELS_MAX][PA_CHANNELS_MAX];
67 int map_required;
68
69 void (*impl_free)(pa_resampler *r);
70 void (*impl_update_rates)(pa_resampler *r);
71 void (*impl_resample)(pa_resampler *r, const pa_memchunk *in, unsigned in_samples, pa_memchunk *out, unsigned *out_samples);
72
73 struct { /* data specific to the trivial resampler */
74 unsigned o_counter;
75 unsigned i_counter;
76 } trivial;
77
78 #ifdef HAVE_LIBSAMPLERATE
79 struct { /* data specific to libsamplerate */
80 SRC_STATE *state;
81 } src;
82 #endif
83
84 struct { /* data specific to speex */
85 SpeexResamplerState* state;
86 } speex;
87
88 struct { /* data specific to ffmpeg */
89 struct AVResampleContext *state;
90 pa_memchunk buf[PA_CHANNELS_MAX];
91 } ffmpeg;
92 };
93
94 static int copy_init(pa_resampler *r);
95 static int trivial_init(pa_resampler*r);
96 static int speex_init(pa_resampler*r);
97 static int ffmpeg_init(pa_resampler*r);
98 #ifdef HAVE_LIBSAMPLERATE
99 static int libsamplerate_init(pa_resampler*r);
100 #endif
101
102 static void calc_map_table(pa_resampler *r);
103
104 static int (* const init_table[])(pa_resampler*r) = {
105 #ifdef HAVE_LIBSAMPLERATE
106 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = libsamplerate_init,
107 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = libsamplerate_init,
108 [PA_RESAMPLER_SRC_SINC_FASTEST] = libsamplerate_init,
109 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = libsamplerate_init,
110 [PA_RESAMPLER_SRC_LINEAR] = libsamplerate_init,
111 #else
112 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY] = NULL,
113 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY] = NULL,
114 [PA_RESAMPLER_SRC_SINC_FASTEST] = NULL,
115 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD] = NULL,
116 [PA_RESAMPLER_SRC_LINEAR] = NULL,
117 #endif
118 [PA_RESAMPLER_TRIVIAL] = trivial_init,
119 [PA_RESAMPLER_SPEEX_FLOAT_BASE+0] = speex_init,
120 [PA_RESAMPLER_SPEEX_FLOAT_BASE+1] = speex_init,
121 [PA_RESAMPLER_SPEEX_FLOAT_BASE+2] = speex_init,
122 [PA_RESAMPLER_SPEEX_FLOAT_BASE+3] = speex_init,
123 [PA_RESAMPLER_SPEEX_FLOAT_BASE+4] = speex_init,
124 [PA_RESAMPLER_SPEEX_FLOAT_BASE+5] = speex_init,
125 [PA_RESAMPLER_SPEEX_FLOAT_BASE+6] = speex_init,
126 [PA_RESAMPLER_SPEEX_FLOAT_BASE+7] = speex_init,
127 [PA_RESAMPLER_SPEEX_FLOAT_BASE+8] = speex_init,
128 [PA_RESAMPLER_SPEEX_FLOAT_BASE+9] = speex_init,
129 [PA_RESAMPLER_SPEEX_FLOAT_BASE+10] = speex_init,
130 [PA_RESAMPLER_SPEEX_FIXED_BASE+0] = speex_init,
131 [PA_RESAMPLER_SPEEX_FIXED_BASE+1] = speex_init,
132 [PA_RESAMPLER_SPEEX_FIXED_BASE+2] = speex_init,
133 [PA_RESAMPLER_SPEEX_FIXED_BASE+3] = speex_init,
134 [PA_RESAMPLER_SPEEX_FIXED_BASE+4] = speex_init,
135 [PA_RESAMPLER_SPEEX_FIXED_BASE+5] = speex_init,
136 [PA_RESAMPLER_SPEEX_FIXED_BASE+6] = speex_init,
137 [PA_RESAMPLER_SPEEX_FIXED_BASE+7] = speex_init,
138 [PA_RESAMPLER_SPEEX_FIXED_BASE+8] = speex_init,
139 [PA_RESAMPLER_SPEEX_FIXED_BASE+9] = speex_init,
140 [PA_RESAMPLER_SPEEX_FIXED_BASE+10] = speex_init,
141 [PA_RESAMPLER_FFMPEG] = ffmpeg_init,
142 [PA_RESAMPLER_AUTO] = NULL,
143 [PA_RESAMPLER_COPY] = copy_init
144 };
145
146 static inline size_t sample_size(pa_sample_format_t f) {
147 pa_sample_spec ss = {
148 .format = f,
149 .rate = 0,
150 .channels = 1
151 };
152
153 return pa_sample_size(&ss);
154 }
155
156 pa_resampler* pa_resampler_new(
157 pa_mempool *pool,
158 const pa_sample_spec *a,
159 const pa_channel_map *am,
160 const pa_sample_spec *b,
161 const pa_channel_map *bm,
162 pa_resample_method_t resample_method,
163 int variable_rate) {
164
165 pa_resampler *r = NULL;
166
167 pa_assert(pool);
168 pa_assert(a);
169 pa_assert(b);
170 pa_assert(pa_sample_spec_valid(a));
171 pa_assert(pa_sample_spec_valid(b));
172 pa_assert(resample_method >= 0);
173 pa_assert(resample_method < PA_RESAMPLER_MAX);
174
175 /* Fix method */
176
177 if (!variable_rate && a->rate == b->rate) {
178 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
179 resample_method = PA_RESAMPLER_COPY;
180 }
181
182 if (!pa_resample_method_supported(resample_method)) {
183 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(resample_method));
184 resample_method = PA_RESAMPLER_AUTO;
185 }
186
187 if (resample_method == PA_RESAMPLER_FFMPEG && variable_rate) {
188 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
189 resample_method = PA_RESAMPLER_AUTO;
190 }
191
192 if (resample_method == PA_RESAMPLER_COPY && (variable_rate || a->rate != b->rate)) {
193 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
194 resample_method = PA_RESAMPLER_AUTO;
195 }
196
197 if (resample_method == PA_RESAMPLER_AUTO)
198 resample_method = PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
199
200 r = pa_xnew(pa_resampler, 1);
201 r->mempool = pool;
202 r->resample_method = resample_method;
203
204 r->impl_free = NULL;
205 r->impl_update_rates = NULL;
206 r->impl_resample = NULL;
207
208 /* Fill sample specs */
209 r->i_ss = *a;
210 r->o_ss = *b;
211
212 if (am)
213 r->i_cm = *am;
214 else
215 pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels, PA_CHANNEL_MAP_DEFAULT);
216
217 if (bm)
218 r->o_cm = *bm;
219 else
220 pa_channel_map_init_auto(&r->o_cm, r->o_ss.channels, PA_CHANNEL_MAP_DEFAULT);
221
222 r->i_fz = pa_frame_size(a);
223 r->o_fz = pa_frame_size(b);
224
225 pa_memchunk_reset(&r->buf1);
226 pa_memchunk_reset(&r->buf2);
227 pa_memchunk_reset(&r->buf3);
228 pa_memchunk_reset(&r->buf4);
229
230 r->buf1_samples = r->buf2_samples = r->buf3_samples = r->buf4_samples = 0;
231
232 calc_map_table(r);
233
234 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(resample_method));
235
236 if ((resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) ||
237 (resample_method == PA_RESAMPLER_FFMPEG))
238 r->work_format = PA_SAMPLE_S16NE;
239 else if (resample_method == PA_RESAMPLER_TRIVIAL || resample_method == PA_RESAMPLER_COPY) {
240
241 if (r->map_required || a->format != b->format) {
242
243 if (a->format == PA_SAMPLE_S32NE || a->format == PA_SAMPLE_S32RE ||
244 a->format == PA_SAMPLE_FLOAT32NE || a->format == PA_SAMPLE_FLOAT32RE ||
245 b->format == PA_SAMPLE_S32NE || b->format == PA_SAMPLE_S32RE ||
246 b->format == PA_SAMPLE_FLOAT32NE || b->format == PA_SAMPLE_FLOAT32RE)
247 r->work_format = PA_SAMPLE_FLOAT32NE;
248 else
249 r->work_format = PA_SAMPLE_S16NE;
250
251 } else
252 r->work_format = a->format;
253
254 } else
255 r->work_format = PA_SAMPLE_FLOAT32NE;
256
257 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r->work_format));
258
259 r->w_sz = sample_size(r->work_format);
260
261 if (r->i_ss.format == r->work_format)
262 r->to_work_format_func = NULL;
263 else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
264 if (!(r->to_work_format_func = pa_get_convert_to_float32ne_function(r->i_ss.format)))
265 goto fail;
266 } else {
267 pa_assert(r->work_format == PA_SAMPLE_S16NE);
268 if (!(r->to_work_format_func = pa_get_convert_to_s16ne_function(r->i_ss.format)))
269 goto fail;
270 }
271
272 if (r->o_ss.format == r->work_format)
273 r->from_work_format_func = NULL;
274 else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
275 if (!(r->from_work_format_func = pa_get_convert_from_float32ne_function(r->o_ss.format)))
276 goto fail;
277 } else {
278 pa_assert(r->work_format == PA_SAMPLE_S16NE);
279 if (!(r->from_work_format_func = pa_get_convert_from_s16ne_function(r->o_ss.format)))
280 goto fail;
281 }
282
283 /* initialize implementation */
284 if (init_table[resample_method](r) < 0)
285 goto fail;
286
287 return r;
288
289 fail:
290 if (r)
291 pa_xfree(r);
292
293 return NULL;
294 }
295
296 void pa_resampler_free(pa_resampler *r) {
297 pa_assert(r);
298
299 if (r->impl_free)
300 r->impl_free(r);
301
302 if (r->buf1.memblock)
303 pa_memblock_unref(r->buf1.memblock);
304 if (r->buf2.memblock)
305 pa_memblock_unref(r->buf2.memblock);
306 if (r->buf3.memblock)
307 pa_memblock_unref(r->buf3.memblock);
308 if (r->buf4.memblock)
309 pa_memblock_unref(r->buf4.memblock);
310
311 pa_xfree(r);
312 }
313
314 void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) {
315 pa_assert(r);
316 pa_assert(rate > 0);
317
318 if (r->i_ss.rate == rate)
319 return;
320
321 r->i_ss.rate = rate;
322
323 r->impl_update_rates(r);
324 }
325
326 void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) {
327 pa_assert(r);
328 pa_assert(rate > 0);
329
330 if (r->o_ss.rate == rate)
331 return;
332
333 r->o_ss.rate = rate;
334
335 r->impl_update_rates(r);
336 }
337
338 size_t pa_resampler_request(pa_resampler *r, size_t out_length) {
339 pa_assert(r);
340
341 return (((out_length / r->o_fz)*r->i_ss.rate)/r->o_ss.rate) * r->i_fz;
342 }
343
344 size_t pa_resampler_max_block_size(pa_resampler *r) {
345 size_t block_size_max;
346 pa_sample_spec ss;
347 size_t fs;
348
349 pa_assert(r);
350
351 block_size_max = pa_mempool_block_size_max(r->mempool);
352
353 /* We deduce the "largest" sample spec we're using during the
354 * conversion */
355 ss = r->i_ss;
356 if (r->o_ss.channels > ss.channels)
357 ss.channels = r->o_ss.channels;
358
359 /* We silently assume that the format enum is ordered by size */
360 if (r->o_ss.format > ss.format)
361 ss.format = r->o_ss.format;
362 if (r->work_format > ss.format)
363 ss.format = r->work_format;
364
365 if (r->o_ss.rate > ss.rate)
366 ss.rate = r->o_ss.rate;
367
368 fs = pa_frame_size(&ss);
369
370 return (((block_size_max/fs + EXTRA_SAMPLES)*r->i_ss.rate)/ss.rate)*r->i_fz;
371 }
372
373 pa_resample_method_t pa_resampler_get_method(pa_resampler *r) {
374 pa_assert(r);
375
376 return r->resample_method;
377 }
378
379 static const char * const resample_methods[] = {
380 "src-sinc-best-quality",
381 "src-sinc-medium-quality",
382 "src-sinc-fastest",
383 "src-zero-order-hold",
384 "src-linear",
385 "trivial",
386 "speex-float-0",
387 "speex-float-1",
388 "speex-float-2",
389 "speex-float-3",
390 "speex-float-4",
391 "speex-float-5",
392 "speex-float-6",
393 "speex-float-7",
394 "speex-float-8",
395 "speex-float-9",
396 "speex-float-10",
397 "speex-fixed-0",
398 "speex-fixed-1",
399 "speex-fixed-2",
400 "speex-fixed-3",
401 "speex-fixed-4",
402 "speex-fixed-5",
403 "speex-fixed-6",
404 "speex-fixed-7",
405 "speex-fixed-8",
406 "speex-fixed-9",
407 "speex-fixed-10",
408 "ffmpeg",
409 "auto",
410 "copy"
411 };
412
413 const char *pa_resample_method_to_string(pa_resample_method_t m) {
414
415 if (m < 0 || m >= PA_RESAMPLER_MAX)
416 return NULL;
417
418 return resample_methods[m];
419 }
420
421 int pa_resample_method_supported(pa_resample_method_t m) {
422
423 if (m < 0 || m >= PA_RESAMPLER_MAX)
424 return 0;
425
426 #ifndef HAVE_LIBSAMPLERATE
427 if (m <= PA_RESAMPLER_SRC_LINEAR)
428 return 0;
429 #endif
430
431 return 1;
432 }
433
434 pa_resample_method_t pa_parse_resample_method(const char *string) {
435 pa_resample_method_t m;
436
437 pa_assert(string);
438
439 for (m = 0; m < PA_RESAMPLER_MAX; m++)
440 if (!strcmp(string, resample_methods[m]))
441 return m;
442
443 if (!strcmp(string, "speex-fixed"))
444 return PA_RESAMPLER_SPEEX_FIXED_BASE + 3;
445
446 if (!strcmp(string, "speex-float"))
447 return PA_RESAMPLER_SPEEX_FLOAT_BASE + 3;
448
449 return PA_RESAMPLER_INVALID;
450 }
451
452 static void calc_map_table(pa_resampler *r) {
453 unsigned oc;
454
455 pa_assert(r);
456
457 if (!(r->map_required = (r->i_ss.channels != r->o_ss.channels || !pa_channel_map_equal(&r->i_cm, &r->o_cm))))
458 return;
459
460 for (oc = 0; oc < r->o_ss.channels; oc++) {
461 unsigned ic, i = 0;
462
463 for (ic = 0; ic < r->i_ss.channels; ic++) {
464 pa_channel_position_t a, b;
465
466 a = r->i_cm.map[ic];
467 b = r->o_cm.map[oc];
468
469 if (a == b ||
470 (a == PA_CHANNEL_POSITION_MONO && b == PA_CHANNEL_POSITION_LEFT) ||
471 (a == PA_CHANNEL_POSITION_MONO && b == PA_CHANNEL_POSITION_RIGHT) ||
472 (a == PA_CHANNEL_POSITION_LEFT && b == PA_CHANNEL_POSITION_MONO) ||
473 (a == PA_CHANNEL_POSITION_RIGHT && b == PA_CHANNEL_POSITION_MONO))
474
475 r->map_table[oc][i++] = ic;
476 }
477
478 /* Add an end marker */
479 if (i < PA_CHANNELS_MAX)
480 r->map_table[oc][i] = -1;
481 }
482 }
483
484 static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) {
485 unsigned n_samples;
486 void *src, *dst;
487
488 pa_assert(r);
489 pa_assert(input);
490 pa_assert(input->memblock);
491
492 /* Convert the incoming sample into the work sample format and place them in buf1 */
493
494 if (!r->to_work_format_func || !input->length)
495 return input;
496
497 n_samples = (input->length / r->i_fz) * r->i_ss.channels;
498
499 r->buf1.index = 0;
500 r->buf1.length = r->w_sz * n_samples;
501
502 if (!r->buf1.memblock || r->buf1_samples < n_samples) {
503 if (r->buf1.memblock)
504 pa_memblock_unref(r->buf1.memblock);
505
506 r->buf1_samples = n_samples;
507 r->buf1.memblock = pa_memblock_new(r->mempool, r->buf1.length);
508 }
509
510 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
511 dst = (uint8_t*) pa_memblock_acquire(r->buf1.memblock);
512
513 r->to_work_format_func(n_samples, src, dst);
514
515 pa_memblock_release(input->memblock);
516 pa_memblock_release(r->buf1.memblock);
517
518 return &r->buf1;
519 }
520
521 static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
522 unsigned in_n_samples, out_n_samples, n_frames;
523 int i_skip, o_skip;
524 unsigned oc;
525 void *src, *dst;
526
527 pa_assert(r);
528 pa_assert(input);
529 pa_assert(input->memblock);
530
531 /* Remap channels and place the result int buf2 */
532
533 if (!r->map_required || !input->length)
534 return input;
535
536 in_n_samples = input->length / r->w_sz;
537 n_frames = in_n_samples / r->i_ss.channels;
538 out_n_samples = n_frames * r->o_ss.channels;
539
540 r->buf2.index = 0;
541 r->buf2.length = r->w_sz * out_n_samples;
542
543 if (!r->buf2.memblock || r->buf2_samples < out_n_samples) {
544 if (r->buf2.memblock)
545 pa_memblock_unref(r->buf2.memblock);
546
547 r->buf2_samples = out_n_samples;
548 r->buf2.memblock = pa_memblock_new(r->mempool, r->buf2.length);
549 }
550
551 src = ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
552 dst = pa_memblock_acquire(r->buf2.memblock);
553
554 memset(dst, 0, r->buf2.length);
555
556 o_skip = r->w_sz * r->o_ss.channels;
557 i_skip = r->w_sz * r->i_ss.channels;
558
559 switch (r->work_format) {
560 case PA_SAMPLE_FLOAT32NE:
561
562 for (oc = 0; oc < r->o_ss.channels; oc++) {
563 unsigned i;
564 static const float one = 1.0;
565
566 for (i = 0; i < PA_CHANNELS_MAX && r->map_table[oc][i] >= 0; i++)
567 oil_vectoradd_f32(
568 (float*) dst + oc, o_skip,
569 (float*) dst + oc, o_skip,
570 (float*) src + r->map_table[oc][i], i_skip,
571 n_frames,
572 &one, &one);
573 }
574
575 break;
576
577 case PA_SAMPLE_S16NE:
578
579 for (oc = 0; oc < r->o_ss.channels; oc++) {
580 unsigned i;
581 static const int16_t one = 1;
582
583 for (i = 0; i < PA_CHANNELS_MAX && r->map_table[oc][i] >= 0; i++)
584 oil_vectoradd_s16(
585 (int16_t*) dst + oc, o_skip,
586 (int16_t*) dst + oc, o_skip,
587 (int16_t*) src + r->map_table[oc][i], i_skip,
588 n_frames,
589 &one, &one);
590 }
591
592 break;
593
594 default:
595 pa_assert_not_reached();
596 }
597
598 pa_memblock_release(input->memblock);
599 pa_memblock_release(r->buf2.memblock);
600
601 r->buf2.length = out_n_samples * r->w_sz;
602
603 return &r->buf2;
604 }
605
606 static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {
607 unsigned in_n_frames, in_n_samples;
608 unsigned out_n_frames, out_n_samples;
609
610 pa_assert(r);
611 pa_assert(input);
612
613 /* Resample the data and place the result in buf3 */
614
615 if (!r->impl_resample || !input->length)
616 return input;
617
618 in_n_samples = input->length / r->w_sz;
619 in_n_frames = in_n_samples / r->o_ss.channels;
620
621 out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_SAMPLES;
622 out_n_samples = out_n_frames * r->o_ss.channels;
623
624 r->buf3.index = 0;
625 r->buf3.length = r->w_sz * out_n_samples;
626
627 if (!r->buf3.memblock || r->buf3_samples < out_n_samples) {
628 if (r->buf3.memblock)
629 pa_memblock_unref(r->buf3.memblock);
630
631 r->buf3_samples = out_n_samples;
632 r->buf3.memblock = pa_memblock_new(r->mempool, r->buf3.length);
633 }
634
635 r->impl_resample(r, input, in_n_frames, &r->buf3, &out_n_frames);
636 r->buf3.length = out_n_frames * r->w_sz * r->o_ss.channels;
637
638 return &r->buf3;
639 }
640
641 static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input) {
642 unsigned n_samples, n_frames;
643 void *src, *dst;
644
645 pa_assert(r);
646 pa_assert(input);
647
648 /* Convert the data into the correct sample type and place the result in buf4 */
649
650 if (!r->from_work_format_func || !input->length)
651 return input;
652
653 n_samples = input->length / r->w_sz;
654 n_frames = n_samples / r->o_ss.channels;
655
656 r->buf4.index = 0;
657 r->buf4.length = r->o_fz * n_frames;
658
659 if (!r->buf4.memblock || r->buf4_samples < n_samples) {
660 if (r->buf4.memblock)
661 pa_memblock_unref(r->buf4.memblock);
662
663 r->buf4_samples = n_samples;
664 r->buf4.memblock = pa_memblock_new(r->mempool, r->buf4.length);
665 }
666
667 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
668 dst = pa_memblock_acquire(r->buf4.memblock);
669 r->from_work_format_func(n_samples, src, dst);
670 pa_memblock_release(input->memblock);
671 pa_memblock_release(r->buf4.memblock);
672
673 r->buf4.length = r->o_fz * n_frames;
674
675 return &r->buf4;
676 }
677
678 void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) {
679 pa_memchunk *buf;
680
681 pa_assert(r);
682 pa_assert(in);
683 pa_assert(out);
684 pa_assert(in->length);
685 pa_assert(in->memblock);
686 pa_assert(in->length % r->i_fz == 0);
687
688 buf = (pa_memchunk*) in;
689 buf = convert_to_work_format(r, buf);
690 buf = remap_channels(r, buf);
691 buf = resample(r, buf);
692
693 if (buf->length) {
694 buf = convert_from_work_format(r, buf);
695 *out = *buf;
696
697 if (buf == in)
698 pa_memblock_ref(buf->memblock);
699 else
700 pa_memchunk_reset(buf);
701 } else
702 pa_memchunk_reset(out);
703 }
704
705 /*** libsamplerate based implementation ***/
706
707 #ifdef HAVE_LIBSAMPLERATE
708 static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
709 SRC_DATA data;
710
711 pa_assert(r);
712 pa_assert(input);
713 pa_assert(output);
714 pa_assert(out_n_frames);
715
716 memset(&data, 0, sizeof(data));
717
718 data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
719 data.input_frames = in_n_frames;
720
721 data.data_out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
722 data.output_frames = *out_n_frames;
723
724 data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate;
725 data.end_of_input = 0;
726
727 pa_assert_se(src_process(r->src.state, &data) == 0);
728 pa_assert((unsigned) data.input_frames_used == in_n_frames);
729
730 pa_memblock_release(input->memblock);
731 pa_memblock_release(output->memblock);
732
733 *out_n_frames = data.output_frames_gen;
734 }
735
736 static void libsamplerate_update_rates(pa_resampler *r) {
737 pa_assert(r);
738
739 pa_assert_se(src_set_ratio(r->src.state, (double) r->o_ss.rate / r->i_ss.rate) == 0);
740 }
741
742 static void libsamplerate_free(pa_resampler *r) {
743 pa_assert(r);
744
745 if (r->src.state)
746 src_delete(r->src.state);
747 }
748
749 static int libsamplerate_init(pa_resampler *r) {
750 int err;
751
752 pa_assert(r);
753
754 if (!(r->src.state = src_new(r->resample_method, r->o_ss.channels, &err)))
755 return -1;
756
757 r->impl_free = libsamplerate_free;
758 r->impl_update_rates = libsamplerate_update_rates;
759 r->impl_resample = libsamplerate_resample;
760
761 return 0;
762 }
763 #endif
764
765 /*** speex based implementation ***/
766
767 static void speex_resample_float(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
768 float *in, *out;
769 uint32_t inf = in_n_frames, outf = *out_n_frames;
770
771 pa_assert(r);
772 pa_assert(input);
773 pa_assert(output);
774 pa_assert(out_n_frames);
775
776 in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
777 out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
778
779 pa_assert_se(paspfl_resampler_process_interleaved_float(r->speex.state, in, &inf, out, &outf) == 0);
780
781 pa_memblock_release(input->memblock);
782 pa_memblock_release(output->memblock);
783
784 pa_assert(inf == in_n_frames);
785 *out_n_frames = outf;
786 }
787
788 static void speex_resample_int(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
789 int16_t *in, *out;
790 uint32_t inf = in_n_frames, outf = *out_n_frames;
791
792 pa_assert(r);
793 pa_assert(input);
794 pa_assert(output);
795 pa_assert(out_n_frames);
796
797 in = (int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
798 out = (int16_t*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
799
800 pa_assert_se(paspfx_resampler_process_interleaved_int(r->speex.state, in, &inf, out, &outf) == 0);
801
802 pa_memblock_release(input->memblock);
803 pa_memblock_release(output->memblock);
804
805 pa_assert(inf == in_n_frames);
806 *out_n_frames = outf;
807 }
808
809 static void speex_update_rates(pa_resampler *r) {
810 pa_assert(r);
811
812 if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
813 pa_assert_se(paspfx_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0);
814 else {
815 pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
816 pa_assert_se(paspfl_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0);
817 }
818 }
819
820 static void speex_free(pa_resampler *r) {
821 pa_assert(r);
822
823 if (!r->speex.state)
824 return;
825
826 if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
827 paspfx_resampler_destroy(r->speex.state);
828 else {
829 pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
830 paspfl_resampler_destroy(r->speex.state);
831 }
832 }
833
834 static int speex_init(pa_resampler *r) {
835 int q, err;
836
837 pa_assert(r);
838
839 r->impl_free = speex_free;
840 r->impl_update_rates = speex_update_rates;
841
842 if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) {
843 q = r->resample_method - PA_RESAMPLER_SPEEX_FIXED_BASE;
844
845 pa_log_info("Choosing speex quality setting %i.", q);
846
847 if (!(r->speex.state = paspfx_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
848 return -1;
849
850 r->impl_resample = speex_resample_int;
851 } else {
852 pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
853 q = r->resample_method - PA_RESAMPLER_SPEEX_FLOAT_BASE;
854
855 pa_log_info("Choosing speex quality setting %i.", q);
856
857 if (!(r->speex.state = paspfl_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
858 return -1;
859
860 r->impl_resample = speex_resample_float;
861 }
862
863 return 0;
864 }
865
866 /* Trivial implementation */
867
868 static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
869 size_t fz;
870 unsigned o_index;
871 void *src, *dst;
872
873 pa_assert(r);
874 pa_assert(input);
875 pa_assert(output);
876 pa_assert(out_n_frames);
877
878 fz = r->w_sz * r->o_ss.channels;
879
880 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
881 dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
882
883 for (o_index = 0;; o_index++, r->trivial.o_counter++) {
884 unsigned j;
885
886 j = ((r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate);
887 j = j > r->trivial.i_counter ? j - r->trivial.i_counter : 0;
888
889 if (j >= in_n_frames)
890 break;
891
892 pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
893
894 oil_memcpy((uint8_t*) dst + fz * o_index,
895 (uint8_t*) src + fz * j, fz);
896 }
897
898 pa_memblock_release(input->memblock);
899 pa_memblock_release(output->memblock);
900
901 *out_n_frames = o_index;
902
903 r->trivial.i_counter += in_n_frames;
904
905 /* Normalize counters */
906 while (r->trivial.i_counter >= r->i_ss.rate) {
907 pa_assert(r->trivial.o_counter >= r->o_ss.rate);
908
909 r->trivial.i_counter -= r->i_ss.rate;
910 r->trivial.o_counter -= r->o_ss.rate;
911 }
912 }
913
914 static void trivial_update_rates(pa_resampler *r) {
915 pa_assert(r);
916
917 r->trivial.i_counter = 0;
918 r->trivial.o_counter = 0;
919 }
920
921 static int trivial_init(pa_resampler*r) {
922 pa_assert(r);
923
924 r->trivial.o_counter = r->trivial.i_counter = 0;
925
926 r->impl_resample = trivial_resample;
927 r->impl_update_rates = trivial_update_rates;
928 r->impl_free = NULL;
929
930 return 0;
931 }
932
933 /*** ffmpeg based implementation ***/
934
935 static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
936 unsigned used_frames = 0, c;
937
938 pa_assert(r);
939 pa_assert(input);
940 pa_assert(output);
941 pa_assert(out_n_frames);
942
943 for (c = 0; c < r->o_ss.channels; c++) {
944 unsigned u;
945 pa_memblock *b, *w;
946 int16_t *p, *t, *k, *q, *s;
947 int consumed_frames;
948 unsigned in, l;
949
950 /* Allocate a new block */
951 b = pa_memblock_new(r->mempool, r->ffmpeg.buf[c].length + in_n_frames * sizeof(int16_t));
952 p = pa_memblock_acquire(b);
953
954 /* Copy the remaining data into it */
955 l = r->ffmpeg.buf[c].length;
956 if (r->ffmpeg.buf[c].memblock) {
957 t = (int16_t*) ((uint8_t*) pa_memblock_acquire(r->ffmpeg.buf[c].memblock) + r->ffmpeg.buf[c].index);
958 memcpy(p, t, l);
959 pa_memblock_release(r->ffmpeg.buf[c].memblock);
960 pa_memblock_unref(r->ffmpeg.buf[c].memblock);
961 pa_memchunk_reset(&r->ffmpeg.buf[c]);
962 }
963
964 /* Now append the new data, splitting up channels */
965 t = ((int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index)) + c;
966 k = (int16_t*) ((uint8_t*) p + l);
967 for (u = 0; u < in_n_frames; u++) {
968 *k = *t;
969 t += r->o_ss.channels;
970 k ++;
971 }
972 pa_memblock_release(input->memblock);
973
974 /* Calculate the resulting number of frames */
975 in = in_n_frames + l / sizeof(int16_t);
976
977 /* Allocate buffer for the result */
978 w = pa_memblock_new(r->mempool, *out_n_frames * sizeof(int16_t));
979 q = pa_memblock_acquire(w);
980
981 /* Now, resample */
982 used_frames = av_resample(r->ffmpeg.state,
983 q, p,
984 &consumed_frames,
985 in, *out_n_frames,
986 c >= (unsigned) r->o_ss.channels-1);
987
988 pa_memblock_release(b);
989
990 /* Now store the remaining samples away */
991 pa_assert(consumed_frames <= (int) in);
992 if (consumed_frames < (int) in) {
993 r->ffmpeg.buf[c].memblock = b;
994 r->ffmpeg.buf[c].index = consumed_frames * sizeof(int16_t);
995 r->ffmpeg.buf[c].length = (in - consumed_frames) * sizeof(int16_t);
996 } else
997 pa_memblock_unref(b);
998
999 /* And place the results in the output buffer */
1000 s = (short*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index) + c;
1001 for (u = 0; u < used_frames; u++) {
1002 *s = *q;
1003 q++;
1004 s += r->o_ss.channels;
1005 }
1006 pa_memblock_release(output->memblock);
1007 pa_memblock_release(w);
1008 pa_memblock_unref(w);
1009 }
1010
1011 *out_n_frames = used_frames;
1012 }
1013
1014 static void ffmpeg_free(pa_resampler *r) {
1015 unsigned c;
1016
1017 pa_assert(r);
1018
1019 if (r->ffmpeg.state)
1020 av_resample_close(r->ffmpeg.state);
1021
1022 for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
1023 if (r->ffmpeg.buf[c].memblock)
1024 pa_memblock_unref(r->ffmpeg.buf[c].memblock);
1025 }
1026
1027 static int ffmpeg_init(pa_resampler *r) {
1028 unsigned c;
1029
1030 pa_assert(r);
1031
1032 /* We could probably implement different quality levels by
1033 * adjusting the filter parameters here. However, ffmpeg
1034 * internally only uses these hardcoded values, so let's use them
1035 * here for now as well until ffmpeg makes this configurable. */
1036
1037 if (!(r->ffmpeg.state = av_resample_init(r->o_ss.rate, r->i_ss.rate, 16, 10, 0, 0.8)))
1038 return -1;
1039
1040 r->impl_free = ffmpeg_free;
1041 r->impl_resample = ffmpeg_resample;
1042
1043 for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
1044 pa_memchunk_reset(&r->ffmpeg.buf[c]);
1045
1046 return 0;
1047 }
1048
1049 /*** copy (noop) implementation ***/
1050
1051 static int copy_init(pa_resampler *r) {
1052 pa_assert(r);
1053
1054 pa_assert(r->o_ss.rate == r->i_ss.rate);
1055
1056 r->impl_free = NULL;
1057 r->impl_resample = NULL;
1058 r->impl_update_rates = NULL;
1059
1060 return 0;
1061 }