]> code.delx.au - pulseaudio/blob - src/pulsecore/resampler.c
merge 'lennart' branch back into trunk.
[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 + 0;
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_FLOAT32NE || a->format == PA_SAMPLE_FLOAT32RE ||
244 b->format == PA_SAMPLE_FLOAT32NE || b->format == PA_SAMPLE_FLOAT32RE)
245 r->work_format = PA_SAMPLE_FLOAT32NE;
246 else
247 r->work_format = PA_SAMPLE_S16NE;
248
249 } else
250 r->work_format = a->format;
251
252 } else
253 r->work_format = PA_SAMPLE_FLOAT32NE;
254
255 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r->work_format));
256
257 r->w_sz = sample_size(r->work_format);
258
259 if (r->i_ss.format == r->work_format)
260 r->to_work_format_func = NULL;
261 else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
262 if (!(r->to_work_format_func = pa_get_convert_to_float32ne_function(r->i_ss.format)))
263 goto fail;
264 } else {
265 pa_assert(r->work_format == PA_SAMPLE_S16NE);
266 if (!(r->to_work_format_func = pa_get_convert_to_s16ne_function(r->i_ss.format)))
267 goto fail;
268 }
269
270 if (r->o_ss.format == r->work_format)
271 r->from_work_format_func = NULL;
272 else if (r->work_format == PA_SAMPLE_FLOAT32NE) {
273 if (!(r->from_work_format_func = pa_get_convert_from_float32ne_function(r->o_ss.format)))
274 goto fail;
275 } else {
276 pa_assert(r->work_format == PA_SAMPLE_S16NE);
277 if (!(r->from_work_format_func = pa_get_convert_from_s16ne_function(r->o_ss.format)))
278 goto fail;
279 }
280
281 /* initialize implementation */
282 if (init_table[resample_method](r) < 0)
283 goto fail;
284
285 return r;
286
287 fail:
288 if (r)
289 pa_xfree(r);
290
291 return NULL;
292 }
293
294 void pa_resampler_free(pa_resampler *r) {
295 pa_assert(r);
296
297 if (r->impl_free)
298 r->impl_free(r);
299
300 if (r->buf1.memblock)
301 pa_memblock_unref(r->buf1.memblock);
302 if (r->buf2.memblock)
303 pa_memblock_unref(r->buf2.memblock);
304 if (r->buf3.memblock)
305 pa_memblock_unref(r->buf3.memblock);
306 if (r->buf4.memblock)
307 pa_memblock_unref(r->buf4.memblock);
308
309 pa_xfree(r);
310 }
311
312 void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) {
313 pa_assert(r);
314 pa_assert(rate > 0);
315
316 if (r->i_ss.rate == rate)
317 return;
318
319 r->i_ss.rate = rate;
320
321 r->impl_update_rates(r);
322 }
323
324 void pa_resampler_set_output_rate(pa_resampler *r, uint32_t rate) {
325 pa_assert(r);
326 pa_assert(rate > 0);
327
328 if (r->o_ss.rate == rate)
329 return;
330
331 r->o_ss.rate = rate;
332
333 r->impl_update_rates(r);
334 }
335
336 size_t pa_resampler_request(pa_resampler *r, size_t out_length) {
337 pa_assert(r);
338
339 return (((out_length / r->o_fz)*r->i_ss.rate)/r->o_ss.rate) * r->i_fz;
340 }
341
342 size_t pa_resampler_max_block_size(pa_resampler *r) {
343 size_t block_size_max;
344 pa_sample_spec ss;
345 size_t fs;
346
347 pa_assert(r);
348
349 block_size_max = pa_mempool_block_size_max(r->mempool);
350
351 /* We deduce the "largest" sample spec we're using during the
352 * conversion */
353 ss = r->i_ss;
354 if (r->o_ss.channels > ss.channels)
355 ss.channels = r->o_ss.channels;
356
357 /* We silently assume that the format enum is ordered by size */
358 if (r->o_ss.format > ss.format)
359 ss.format = r->o_ss.format;
360 if (r->work_format > ss.format)
361 ss.format = r->work_format;
362
363 if (r->o_ss.rate > ss.rate)
364 ss.rate = r->o_ss.rate;
365
366 fs = pa_frame_size(&ss);
367
368 return (((block_size_max/fs + EXTRA_SAMPLES)*r->i_ss.rate)/ss.rate)*r->i_fz;
369 }
370
371 pa_resample_method_t pa_resampler_get_method(pa_resampler *r) {
372 pa_assert(r);
373
374 return r->resample_method;
375 }
376
377 static const char * const resample_methods[] = {
378 "src-sinc-best-quality",
379 "src-sinc-medium-quality",
380 "src-sinc-fastest",
381 "src-zero-order-hold",
382 "src-linear",
383 "trivial",
384 "speex-float-0",
385 "speex-float-1",
386 "speex-float-2",
387 "speex-float-3",
388 "speex-float-4",
389 "speex-float-5",
390 "speex-float-6",
391 "speex-float-7",
392 "speex-float-8",
393 "speex-float-9",
394 "speex-float-10",
395 "speex-fixed-0",
396 "speex-fixed-1",
397 "speex-fixed-2",
398 "speex-fixed-3",
399 "speex-fixed-4",
400 "speex-fixed-5",
401 "speex-fixed-6",
402 "speex-fixed-7",
403 "speex-fixed-8",
404 "speex-fixed-9",
405 "speex-fixed-10",
406 "ffmpeg",
407 "auto",
408 "copy"
409 };
410
411 const char *pa_resample_method_to_string(pa_resample_method_t m) {
412
413 if (m < 0 || m >= PA_RESAMPLER_MAX)
414 return NULL;
415
416 return resample_methods[m];
417 }
418
419 int pa_resample_method_supported(pa_resample_method_t m) {
420
421 if (m < 0 || m >= PA_RESAMPLER_MAX)
422 return 0;
423
424 #ifndef HAVE_LIBSAMPLERATE
425 if (m <= PA_RESAMPLER_SRC_LINEAR)
426 return 0;
427 #endif
428
429 return 1;
430 }
431
432 pa_resample_method_t pa_parse_resample_method(const char *string) {
433 pa_resample_method_t m;
434
435 pa_assert(string);
436
437 for (m = 0; m < PA_RESAMPLER_MAX; m++)
438 if (!strcmp(string, resample_methods[m]))
439 return m;
440
441 if (!strcmp(string, "speex-fixed"))
442 return PA_RESAMPLER_SPEEX_FIXED_BASE + 0;
443
444 if (!strcmp(string, "speex-float"))
445 return PA_RESAMPLER_SPEEX_FLOAT_BASE + 0;
446
447 return PA_RESAMPLER_INVALID;
448 }
449
450 static void calc_map_table(pa_resampler *r) {
451 unsigned oc;
452
453 pa_assert(r);
454
455 if (!(r->map_required = (r->i_ss.channels != r->o_ss.channels || !pa_channel_map_equal(&r->i_cm, &r->o_cm))))
456 return;
457
458 for (oc = 0; oc < r->o_ss.channels; oc++) {
459 unsigned ic, i = 0;
460
461 for (ic = 0; ic < r->i_ss.channels; ic++) {
462 pa_channel_position_t a, b;
463
464 a = r->i_cm.map[ic];
465 b = r->o_cm.map[oc];
466
467 if (a == b ||
468 (a == PA_CHANNEL_POSITION_MONO && b == PA_CHANNEL_POSITION_LEFT) ||
469 (a == PA_CHANNEL_POSITION_MONO && b == PA_CHANNEL_POSITION_RIGHT) ||
470 (a == PA_CHANNEL_POSITION_LEFT && b == PA_CHANNEL_POSITION_MONO) ||
471 (a == PA_CHANNEL_POSITION_RIGHT && b == PA_CHANNEL_POSITION_MONO))
472
473 r->map_table[oc][i++] = ic;
474 }
475
476 /* Add an end marker */
477 if (i < PA_CHANNELS_MAX)
478 r->map_table[oc][i] = -1;
479 }
480 }
481
482 static pa_memchunk* convert_to_work_format(pa_resampler *r, pa_memchunk *input) {
483 unsigned n_samples;
484 void *src, *dst;
485
486 pa_assert(r);
487 pa_assert(input);
488 pa_assert(input->memblock);
489
490 /* Convert the incoming sample into the work sample format and place them in buf1 */
491
492 if (!r->to_work_format_func || !input->length)
493 return input;
494
495 n_samples = (input->length / r->i_fz) * r->i_ss.channels;
496
497 r->buf1.index = 0;
498 r->buf1.length = r->w_sz * n_samples;
499
500 if (!r->buf1.memblock || r->buf1_samples < n_samples) {
501 if (r->buf1.memblock)
502 pa_memblock_unref(r->buf1.memblock);
503
504 r->buf1_samples = n_samples;
505 r->buf1.memblock = pa_memblock_new(r->mempool, r->buf1.length);
506 }
507
508 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
509 dst = (uint8_t*) pa_memblock_acquire(r->buf1.memblock);
510
511 r->to_work_format_func(n_samples, src, dst);
512
513 pa_memblock_release(input->memblock);
514 pa_memblock_release(r->buf1.memblock);
515
516 return &r->buf1;
517 }
518
519 static pa_memchunk *remap_channels(pa_resampler *r, pa_memchunk *input) {
520 unsigned in_n_samples, out_n_samples, n_frames;
521 int i_skip, o_skip;
522 unsigned oc;
523 void *src, *dst;
524
525 pa_assert(r);
526 pa_assert(input);
527 pa_assert(input->memblock);
528
529 /* Remap channels and place the result int buf2 */
530
531 if (!r->map_required || !input->length)
532 return input;
533
534 in_n_samples = input->length / r->w_sz;
535 n_frames = in_n_samples / r->i_ss.channels;
536 out_n_samples = n_frames * r->o_ss.channels;
537
538 r->buf2.index = 0;
539 r->buf2.length = r->w_sz * out_n_samples;
540
541 if (!r->buf2.memblock || r->buf2_samples < out_n_samples) {
542 if (r->buf2.memblock)
543 pa_memblock_unref(r->buf2.memblock);
544
545 r->buf2_samples = out_n_samples;
546 r->buf2.memblock = pa_memblock_new(r->mempool, r->buf2.length);
547 }
548
549 src = ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
550 dst = pa_memblock_acquire(r->buf2.memblock);
551
552 memset(dst, 0, r->buf2.length);
553
554 o_skip = r->w_sz * r->o_ss.channels;
555 i_skip = r->w_sz * r->i_ss.channels;
556
557 switch (r->work_format) {
558 case PA_SAMPLE_FLOAT32NE:
559
560 for (oc = 0; oc < r->o_ss.channels; oc++) {
561 unsigned i;
562 static const float one = 1.0;
563
564 for (i = 0; i < PA_CHANNELS_MAX && r->map_table[oc][i] >= 0; i++)
565 oil_vectoradd_f32(
566 (float*) dst + oc, o_skip,
567 (float*) dst + oc, o_skip,
568 (float*) src + r->map_table[oc][i], i_skip,
569 n_frames,
570 &one, &one);
571 }
572
573 break;
574
575 case PA_SAMPLE_S16NE:
576
577 for (oc = 0; oc < r->o_ss.channels; oc++) {
578 unsigned i;
579 static const int16_t one = 1;
580
581 for (i = 0; i < PA_CHANNELS_MAX && r->map_table[oc][i] >= 0; i++)
582 oil_vectoradd_s16(
583 (int16_t*) dst + oc, o_skip,
584 (int16_t*) dst + oc, o_skip,
585 (int16_t*) src + r->map_table[oc][i], i_skip,
586 n_frames,
587 &one, &one);
588 }
589
590 break;
591
592 default:
593 pa_assert_not_reached();
594 }
595
596 pa_memblock_release(input->memblock);
597 pa_memblock_release(r->buf2.memblock);
598
599 r->buf2.length = out_n_samples * r->w_sz;
600
601 return &r->buf2;
602 }
603
604 static pa_memchunk *resample(pa_resampler *r, pa_memchunk *input) {
605 unsigned in_n_frames, in_n_samples;
606 unsigned out_n_frames, out_n_samples;
607
608 pa_assert(r);
609 pa_assert(input);
610
611 /* Resample the data and place the result in buf3 */
612
613 if (!r->impl_resample || !input->length)
614 return input;
615
616 in_n_samples = input->length / r->w_sz;
617 in_n_frames = in_n_samples / r->o_ss.channels;
618
619 out_n_frames = ((in_n_frames*r->o_ss.rate)/r->i_ss.rate)+EXTRA_SAMPLES;
620 out_n_samples = out_n_frames * r->o_ss.channels;
621
622 r->buf3.index = 0;
623 r->buf3.length = r->w_sz * out_n_samples;
624
625 if (!r->buf3.memblock || r->buf3_samples < out_n_samples) {
626 if (r->buf3.memblock)
627 pa_memblock_unref(r->buf3.memblock);
628
629 r->buf3_samples = out_n_samples;
630 r->buf3.memblock = pa_memblock_new(r->mempool, r->buf3.length);
631 }
632
633 r->impl_resample(r, input, in_n_frames, &r->buf3, &out_n_frames);
634 r->buf3.length = out_n_frames * r->w_sz * r->o_ss.channels;
635
636 return &r->buf3;
637 }
638
639 static pa_memchunk *convert_from_work_format(pa_resampler *r, pa_memchunk *input) {
640 unsigned n_samples, n_frames;
641 void *src, *dst;
642
643 pa_assert(r);
644 pa_assert(input);
645
646 /* Convert the data into the correct sample type and place the result in buf4 */
647
648 if (!r->from_work_format_func || !input->length)
649 return input;
650
651 n_samples = input->length / r->w_sz;
652 n_frames = n_samples / r->o_ss.channels;
653
654 r->buf4.index = 0;
655 r->buf4.length = r->o_fz * n_frames;
656
657 if (!r->buf4.memblock || r->buf4_samples < n_samples) {
658 if (r->buf4.memblock)
659 pa_memblock_unref(r->buf4.memblock);
660
661 r->buf4_samples = n_samples;
662 r->buf4.memblock = pa_memblock_new(r->mempool, r->buf4.length);
663 }
664
665 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
666 dst = pa_memblock_acquire(r->buf4.memblock);
667 r->from_work_format_func(n_samples, src, dst);
668 pa_memblock_release(input->memblock);
669 pa_memblock_release(r->buf4.memblock);
670
671 r->buf4.length = r->o_fz * n_frames;
672
673 return &r->buf4;
674 }
675
676 void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) {
677 pa_memchunk *buf;
678
679 pa_assert(r);
680 pa_assert(in);
681 pa_assert(out);
682 pa_assert(in->length);
683 pa_assert(in->memblock);
684 pa_assert(in->length % r->i_fz == 0);
685
686 buf = (pa_memchunk*) in;
687 buf = convert_to_work_format(r, buf);
688 buf = remap_channels(r, buf);
689 buf = resample(r, buf);
690
691 if (buf->length) {
692 buf = convert_from_work_format(r, buf);
693 *out = *buf;
694
695 if (buf == in)
696 pa_memblock_ref(buf->memblock);
697 else
698 pa_memchunk_reset(buf);
699 } else
700 pa_memchunk_reset(out);
701 }
702
703 /*** libsamplerate based implementation ***/
704
705 #ifdef HAVE_LIBSAMPLERATE
706 static void libsamplerate_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
707 SRC_DATA data;
708
709 pa_assert(r);
710 pa_assert(input);
711 pa_assert(output);
712 pa_assert(out_n_frames);
713
714 memset(&data, 0, sizeof(data));
715
716 data.data_in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
717 data.input_frames = in_n_frames;
718
719 data.data_out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
720 data.output_frames = *out_n_frames;
721
722 data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate;
723 data.end_of_input = 0;
724
725 pa_assert_se(src_process(r->src.state, &data) == 0);
726 pa_assert((unsigned) data.input_frames_used == in_n_frames);
727
728 pa_memblock_release(input->memblock);
729 pa_memblock_release(output->memblock);
730
731 *out_n_frames = data.output_frames_gen;
732 }
733
734 static void libsamplerate_update_rates(pa_resampler *r) {
735 pa_assert(r);
736
737 pa_assert_se(src_set_ratio(r->src.state, (double) r->o_ss.rate / r->i_ss.rate) == 0);
738 }
739
740 static void libsamplerate_free(pa_resampler *r) {
741 pa_assert(r);
742
743 if (r->src.state)
744 src_delete(r->src.state);
745 }
746
747 static int libsamplerate_init(pa_resampler *r) {
748 int err;
749
750 pa_assert(r);
751
752 if (!(r->src.state = src_new(r->resample_method, r->o_ss.channels, &err)))
753 return -1;
754
755 r->impl_free = libsamplerate_free;
756 r->impl_update_rates = libsamplerate_update_rates;
757 r->impl_resample = libsamplerate_resample;
758
759 return 0;
760 }
761 #endif
762
763 /*** speex based implementation ***/
764
765 static void speex_resample_float(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
766 float *in, *out;
767 uint32_t inf = in_n_frames, outf = *out_n_frames;
768
769 pa_assert(r);
770 pa_assert(input);
771 pa_assert(output);
772 pa_assert(out_n_frames);
773
774 in = (float*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
775 out = (float*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
776
777 pa_assert_se(paspfl_resampler_process_interleaved_float(r->speex.state, in, &inf, out, &outf) == 0);
778
779 pa_memblock_release(input->memblock);
780 pa_memblock_release(output->memblock);
781
782 pa_assert(inf == in_n_frames);
783 *out_n_frames = outf;
784 }
785
786 static void speex_resample_int(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
787 int16_t *in, *out;
788 uint32_t inf = in_n_frames, outf = *out_n_frames;
789
790 pa_assert(r);
791 pa_assert(input);
792 pa_assert(output);
793 pa_assert(out_n_frames);
794
795 in = (int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index);
796 out = (int16_t*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index);
797
798 pa_assert_se(paspfx_resampler_process_interleaved_int(r->speex.state, in, &inf, out, &outf) == 0);
799
800 pa_memblock_release(input->memblock);
801 pa_memblock_release(output->memblock);
802
803 pa_assert(inf == in_n_frames);
804 *out_n_frames = outf;
805 }
806
807 static void speex_update_rates(pa_resampler *r) {
808 pa_assert(r);
809
810 if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
811 pa_assert_se(paspfx_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0);
812 else {
813 pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
814 pa_assert_se(paspfl_resampler_set_rate(r->speex.state, r->i_ss.rate, r->o_ss.rate) == 0);
815 }
816 }
817
818 static void speex_free(pa_resampler *r) {
819 pa_assert(r);
820
821 if (!r->speex.state)
822 return;
823
824 if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX)
825 paspfx_resampler_destroy(r->speex.state);
826 else {
827 pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
828 paspfl_resampler_destroy(r->speex.state);
829 }
830 }
831
832 static int speex_init(pa_resampler *r) {
833 int q, err;
834
835 pa_assert(r);
836
837 r->impl_free = speex_free;
838 r->impl_update_rates = speex_update_rates;
839
840 if (r->resample_method >= PA_RESAMPLER_SPEEX_FIXED_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FIXED_MAX) {
841 q = r->resample_method - PA_RESAMPLER_SPEEX_FIXED_BASE;
842
843 pa_log_info("Choosing speex quality setting %i.", q);
844
845 if (!(r->speex.state = paspfx_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
846 return -1;
847
848 r->impl_resample = speex_resample_int;
849 } else {
850 pa_assert(r->resample_method >= PA_RESAMPLER_SPEEX_FLOAT_BASE && r->resample_method <= PA_RESAMPLER_SPEEX_FLOAT_MAX);
851 q = r->resample_method - PA_RESAMPLER_SPEEX_FLOAT_BASE;
852
853 pa_log_info("Choosing speex quality setting %i.", q);
854
855 if (!(r->speex.state = paspfl_resampler_init(r->o_ss.channels, r->i_ss.rate, r->o_ss.rate, q, &err)))
856 return -1;
857
858 r->impl_resample = speex_resample_float;
859 }
860
861 return 0;
862 }
863
864 /* Trivial implementation */
865
866 static void trivial_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
867 size_t fz;
868 unsigned o_index;
869 void *src, *dst;
870
871 pa_assert(r);
872 pa_assert(input);
873 pa_assert(output);
874 pa_assert(out_n_frames);
875
876 fz = r->w_sz * r->o_ss.channels;
877
878 src = (uint8_t*) pa_memblock_acquire(input->memblock) + input->index;
879 dst = (uint8_t*) pa_memblock_acquire(output->memblock) + output->index;
880
881 for (o_index = 0;; o_index++, r->trivial.o_counter++) {
882 unsigned j;
883
884 j = ((r->trivial.o_counter * r->i_ss.rate) / r->o_ss.rate);
885 j = j > r->trivial.i_counter ? j - r->trivial.i_counter : 0;
886
887 if (j >= in_n_frames)
888 break;
889
890 pa_assert(o_index * fz < pa_memblock_get_length(output->memblock));
891
892 oil_memcpy((uint8_t*) dst + fz * o_index,
893 (uint8_t*) src + fz * j, fz);
894 }
895
896 pa_memblock_release(input->memblock);
897 pa_memblock_release(output->memblock);
898
899 *out_n_frames = o_index;
900
901 r->trivial.i_counter += in_n_frames;
902
903 /* Normalize counters */
904 while (r->trivial.i_counter >= r->i_ss.rate) {
905 pa_assert(r->trivial.o_counter >= r->o_ss.rate);
906
907 r->trivial.i_counter -= r->i_ss.rate;
908 r->trivial.o_counter -= r->o_ss.rate;
909 }
910 }
911
912 static void trivial_update_rates(pa_resampler *r) {
913 pa_assert(r);
914
915 r->trivial.i_counter = 0;
916 r->trivial.o_counter = 0;
917 }
918
919 static int trivial_init(pa_resampler*r) {
920 pa_assert(r);
921
922 r->trivial.o_counter = r->trivial.i_counter = 0;
923
924 r->impl_resample = trivial_resample;
925 r->impl_update_rates = trivial_update_rates;
926 r->impl_free = NULL;
927
928 return 0;
929 }
930
931 /*** ffmpeg based implementation ***/
932
933 static void ffmpeg_resample(pa_resampler *r, const pa_memchunk *input, unsigned in_n_frames, pa_memchunk *output, unsigned *out_n_frames) {
934 unsigned used_frames = 0, c;
935
936 pa_assert(r);
937 pa_assert(input);
938 pa_assert(output);
939 pa_assert(out_n_frames);
940
941 for (c = 0; c < r->o_ss.channels; c++) {
942 unsigned u;
943 pa_memblock *b, *w;
944 int16_t *p, *t, *k, *q, *s;
945 int consumed_frames;
946 unsigned in, l;
947
948 /* Allocate a new block */
949 b = pa_memblock_new(r->mempool, r->ffmpeg.buf[c].length + in_n_frames * sizeof(int16_t));
950 p = pa_memblock_acquire(b);
951
952 /* Copy the remaining data into it */
953 l = r->ffmpeg.buf[c].length;
954 if (r->ffmpeg.buf[c].memblock) {
955 t = (int16_t*) ((uint8_t*) pa_memblock_acquire(r->ffmpeg.buf[c].memblock) + r->ffmpeg.buf[c].index);
956 memcpy(p, t, l);
957 pa_memblock_release(r->ffmpeg.buf[c].memblock);
958 pa_memblock_unref(r->ffmpeg.buf[c].memblock);
959 pa_memchunk_reset(&r->ffmpeg.buf[c]);
960 }
961
962 /* Now append the new data, splitting up channels */
963 t = ((int16_t*) ((uint8_t*) pa_memblock_acquire(input->memblock) + input->index)) + c;
964 k = (int16_t*) ((uint8_t*) p + l);
965 for (u = 0; u < in_n_frames; u++) {
966 *k = *t;
967 t += r->o_ss.channels;
968 k ++;
969 }
970 pa_memblock_release(input->memblock);
971
972 /* Calculate the resulting number of frames */
973 in = in_n_frames + l / sizeof(int16_t);
974
975 /* Allocate buffer for the result */
976 w = pa_memblock_new(r->mempool, *out_n_frames * sizeof(int16_t));
977 q = pa_memblock_acquire(w);
978
979 /* Now, resample */
980 used_frames = av_resample(r->ffmpeg.state,
981 q, p,
982 &consumed_frames,
983 in, *out_n_frames,
984 c >= (unsigned) r->o_ss.channels-1);
985
986 pa_memblock_release(b);
987
988 /* Now store the remaining samples away */
989 pa_assert(consumed_frames <= (int) in);
990 if (consumed_frames < (int) in) {
991 r->ffmpeg.buf[c].memblock = b;
992 r->ffmpeg.buf[c].index = consumed_frames * sizeof(int16_t);
993 r->ffmpeg.buf[c].length = (in - consumed_frames) * sizeof(int16_t);
994 } else
995 pa_memblock_unref(b);
996
997 /* And place the results in the output buffer */
998 s = (short*) ((uint8_t*) pa_memblock_acquire(output->memblock) + output->index) + c;
999 for (u = 0; u < used_frames; u++) {
1000 *s = *q;
1001 q++;
1002 s += r->o_ss.channels;
1003 }
1004 pa_memblock_release(output->memblock);
1005 pa_memblock_release(w);
1006 pa_memblock_unref(w);
1007 }
1008
1009 *out_n_frames = used_frames;
1010 }
1011
1012 static void ffmpeg_free(pa_resampler *r) {
1013 unsigned c;
1014
1015 pa_assert(r);
1016
1017 if (r->ffmpeg.state)
1018 av_resample_close(r->ffmpeg.state);
1019
1020 for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
1021 if (r->ffmpeg.buf[c].memblock)
1022 pa_memblock_unref(r->ffmpeg.buf[c].memblock);
1023 }
1024
1025 static int ffmpeg_init(pa_resampler *r) {
1026 unsigned c;
1027
1028 pa_assert(r);
1029
1030 /* We could probably implement different quality levels by
1031 * adjusting the filter parameters here. However, ffmpeg
1032 * internally only uses these hardcoded values, so let's use them
1033 * here for now as well until ffmpeg makes this configurable. */
1034
1035 if (!(r->ffmpeg.state = av_resample_init(r->o_ss.rate, r->i_ss.rate, 16, 10, 0, 0.8)))
1036 return -1;
1037
1038 r->impl_free = ffmpeg_free;
1039 r->impl_resample = ffmpeg_resample;
1040
1041 for (c = 0; c < PA_ELEMENTSOF(r->ffmpeg.buf); c++)
1042 pa_memchunk_reset(&r->ffmpeg.buf[c]);
1043
1044 return 0;
1045 }
1046
1047 /*** copy (noop) implementation ***/
1048
1049 static int copy_init(pa_resampler *r) {
1050 pa_assert(r);
1051
1052 pa_assert(r->o_ss.rate == r->i_ss.rate);
1053
1054 r->impl_free = NULL;
1055 r->impl_resample = NULL;
1056 r->impl_update_rates = NULL;
1057
1058 return 0;
1059 }