2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2.1 of the License,
9 or (at your option) any later version.
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 #ifdef HAVE_LIBSAMPLERATE
29 #include <samplerate.h>
32 #include <speex/speex_resampler.h>
34 #include <pulse/xmalloc.h>
35 #include <pulsecore/sconv.h>
36 #include <pulsecore/log.h>
37 #include <pulsecore/macro.h>
38 #include <pulsecore/strbuf.h>
40 #include "ffmpeg/avcodec.h"
42 #include "resampler.h"
44 /* Number of samples of extra space we allow the resamplers to return */
45 #define EXTRA_FRAMES 128
47 typedef void (*pa_do_remap_func_t
) (pa_resampler
*r
, void *d
, const void *s
, unsigned n
);
49 static void remap_channels_matrix (pa_resampler
*r
, void *dst
, const void *src
, unsigned n
);
50 static void remap_mono_to_stereo(pa_resampler
*r
, void *dst
, const void *src
, unsigned n
);
53 pa_resample_method_t method
;
54 pa_resample_flags_t flags
;
56 pa_sample_spec i_ss
, o_ss
;
57 pa_channel_map i_cm
, o_cm
;
58 size_t i_fz
, o_fz
, w_sz
;
61 pa_memchunk buf1
, buf2
, buf3
, buf4
;
62 unsigned buf1_samples
, buf2_samples
, buf3_samples
, buf4_samples
;
64 pa_sample_format_t work_format
;
66 pa_convert_func_t to_work_format_func
;
67 pa_convert_func_t from_work_format_func
;
69 float map_table_f
[PA_CHANNELS_MAX
][PA_CHANNELS_MAX
];
70 int32_t map_table_i
[PA_CHANNELS_MAX
][PA_CHANNELS_MAX
];
71 pa_bool_t map_required
;
72 pa_do_remap_func_t do_remap
;
74 void (*impl_free
)(pa_resampler
*r
);
75 void (*impl_update_rates
)(pa_resampler
*r
);
76 void (*impl_resample
)(pa_resampler
*r
, const pa_memchunk
*in
, unsigned in_samples
, pa_memchunk
*out
, unsigned *out_samples
);
77 void (*impl_reset
)(pa_resampler
*r
);
79 struct { /* data specific to the trivial resampler */
84 struct { /* data specific to the peak finder pseudo resampler */
88 float max_f
[PA_CHANNELS_MAX
];
89 int16_t max_i
[PA_CHANNELS_MAX
];
93 #ifdef HAVE_LIBSAMPLERATE
94 struct { /* data specific to libsamplerate */
99 struct { /* data specific to speex */
100 SpeexResamplerState
* state
;
103 struct { /* data specific to ffmpeg */
104 struct AVResampleContext
*state
;
105 pa_memchunk buf
[PA_CHANNELS_MAX
];
109 static int copy_init(pa_resampler
*r
);
110 static int trivial_init(pa_resampler
*r
);
111 static int speex_init(pa_resampler
*r
);
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
);
118 static void calc_map_table(pa_resampler
*r
);
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
,
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
,
134 [PA_RESAMPLER_TRIVIAL
] = trivial_init
,
135 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+0] = speex_init
,
136 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+1] = speex_init
,
137 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+2] = speex_init
,
138 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+3] = speex_init
,
139 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+4] = speex_init
,
140 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+5] = speex_init
,
141 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+6] = speex_init
,
142 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+7] = speex_init
,
143 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+8] = speex_init
,
144 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+9] = speex_init
,
145 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+10] = speex_init
,
146 [PA_RESAMPLER_SPEEX_FIXED_BASE
+0] = speex_init
,
147 [PA_RESAMPLER_SPEEX_FIXED_BASE
+1] = speex_init
,
148 [PA_RESAMPLER_SPEEX_FIXED_BASE
+2] = speex_init
,
149 [PA_RESAMPLER_SPEEX_FIXED_BASE
+3] = speex_init
,
150 [PA_RESAMPLER_SPEEX_FIXED_BASE
+4] = speex_init
,
151 [PA_RESAMPLER_SPEEX_FIXED_BASE
+5] = speex_init
,
152 [PA_RESAMPLER_SPEEX_FIXED_BASE
+6] = speex_init
,
153 [PA_RESAMPLER_SPEEX_FIXED_BASE
+7] = speex_init
,
154 [PA_RESAMPLER_SPEEX_FIXED_BASE
+8] = speex_init
,
155 [PA_RESAMPLER_SPEEX_FIXED_BASE
+9] = speex_init
,
156 [PA_RESAMPLER_SPEEX_FIXED_BASE
+10] = speex_init
,
157 [PA_RESAMPLER_FFMPEG
] = ffmpeg_init
,
158 [PA_RESAMPLER_AUTO
] = NULL
,
159 [PA_RESAMPLER_COPY
] = copy_init
,
160 [PA_RESAMPLER_PEAKS
] = peaks_init
,
163 pa_resampler
* pa_resampler_new(
165 const pa_sample_spec
*a
,
166 const pa_channel_map
*am
,
167 const pa_sample_spec
*b
,
168 const pa_channel_map
*bm
,
169 pa_resample_method_t method
,
170 pa_resample_flags_t flags
) {
172 pa_resampler
*r
= NULL
;
177 pa_assert(pa_sample_spec_valid(a
));
178 pa_assert(pa_sample_spec_valid(b
));
179 pa_assert(method
>= 0);
180 pa_assert(method
< PA_RESAMPLER_MAX
);
184 if (!(flags
& PA_RESAMPLER_VARIABLE_RATE
) && a
->rate
== b
->rate
) {
185 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
186 method
= PA_RESAMPLER_COPY
;
189 if (!pa_resample_method_supported(method
)) {
190 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method
));
191 method
= PA_RESAMPLER_AUTO
;
194 if (method
== PA_RESAMPLER_FFMPEG
&& (flags
& PA_RESAMPLER_VARIABLE_RATE
)) {
195 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
196 method
= PA_RESAMPLER_AUTO
;
199 if (method
== PA_RESAMPLER_COPY
&& ((flags
& PA_RESAMPLER_VARIABLE_RATE
) || a
->rate
!= b
->rate
)) {
200 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
201 method
= PA_RESAMPLER_AUTO
;
204 if (method
== PA_RESAMPLER_AUTO
)
205 method
= PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
207 r
= pa_xnew(pa_resampler
, 1);
213 r
->impl_update_rates
= NULL
;
214 r
->impl_resample
= NULL
;
215 r
->impl_reset
= NULL
;
217 /* Fill sample specs */
223 else if (!pa_channel_map_init_auto(&r
->i_cm
, r
->i_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
228 else if (!pa_channel_map_init_auto(&r
->o_cm
, r
->o_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
231 r
->i_fz
= pa_frame_size(a
);
232 r
->o_fz
= pa_frame_size(b
);
234 pa_memchunk_reset(&r
->buf1
);
235 pa_memchunk_reset(&r
->buf2
);
236 pa_memchunk_reset(&r
->buf3
);
237 pa_memchunk_reset(&r
->buf4
);
239 r
->buf1_samples
= r
->buf2_samples
= r
->buf3_samples
= r
->buf4_samples
= 0;
243 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method
));
245 if ((method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) ||
246 (method
== PA_RESAMPLER_FFMPEG
))
247 r
->work_format
= PA_SAMPLE_S16NE
;
248 else if (method
== PA_RESAMPLER_TRIVIAL
|| method
== PA_RESAMPLER_COPY
|| method
== PA_RESAMPLER_PEAKS
) {
250 if (r
->map_required
|| a
->format
!= b
->format
|| method
== PA_RESAMPLER_PEAKS
) {
252 if (a
->format
== PA_SAMPLE_S32NE
|| a
->format
== PA_SAMPLE_S32RE
||
253 a
->format
== PA_SAMPLE_FLOAT32NE
|| a
->format
== PA_SAMPLE_FLOAT32RE
||
254 a
->format
== PA_SAMPLE_S24NE
|| a
->format
== PA_SAMPLE_S24RE
||
255 a
->format
== PA_SAMPLE_S24_32NE
|| a
->format
== PA_SAMPLE_S24_32RE
||
256 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
257 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
||
258 b
->format
== PA_SAMPLE_S24NE
|| b
->format
== PA_SAMPLE_S24RE
||
259 b
->format
== PA_SAMPLE_S24_32NE
|| b
->format
== PA_SAMPLE_S24_32RE
)
260 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
262 r
->work_format
= PA_SAMPLE_S16NE
;
265 r
->work_format
= a
->format
;
268 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
270 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
272 r
->w_sz
= pa_sample_size_of_format(r
->work_format
);
274 if (r
->i_ss
.format
== r
->work_format
)
275 r
->to_work_format_func
= NULL
;
276 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
277 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
280 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
281 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
285 if (r
->o_ss
.format
== r
->work_format
)
286 r
->from_work_format_func
= NULL
;
287 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
288 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
291 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
292 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
296 /* initialize implementation */
297 if (init_table
[method
](r
) < 0)
309 void pa_resampler_free(pa_resampler
*r
) {
315 if (r
->buf1
.memblock
)
316 pa_memblock_unref(r
->buf1
.memblock
);
317 if (r
->buf2
.memblock
)
318 pa_memblock_unref(r
->buf2
.memblock
);
319 if (r
->buf3
.memblock
)
320 pa_memblock_unref(r
->buf3
.memblock
);
321 if (r
->buf4
.memblock
)
322 pa_memblock_unref(r
->buf4
.memblock
);
327 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
331 if (r
->i_ss
.rate
== rate
)
336 r
->impl_update_rates(r
);
339 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
343 if (r
->o_ss
.rate
== rate
)
348 r
->impl_update_rates(r
);
351 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
354 /* Let's round up here */
356 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
;
359 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
362 /* Let's round up here */
364 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
;
367 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
368 size_t block_size_max
;
374 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
376 /* We deduce the "largest" sample spec we're using during the
378 ss
.channels
= (uint8_t) (PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
));
380 /* We silently assume that the format enum is ordered by size */
381 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
382 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
384 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
386 fs
= pa_frame_size(&ss
);
388 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
391 void pa_resampler_reset(pa_resampler
*r
) {
398 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
404 const pa_channel_map
* pa_resampler_input_channel_map(pa_resampler
*r
) {
410 const pa_sample_spec
* pa_resampler_input_sample_spec(pa_resampler
*r
) {
416 const pa_channel_map
* pa_resampler_output_channel_map(pa_resampler
*r
) {
422 const pa_sample_spec
* pa_resampler_output_sample_spec(pa_resampler
*r
) {
428 static const char * const resample_methods
[] = {
429 "src-sinc-best-quality",
430 "src-sinc-medium-quality",
432 "src-zero-order-hold",
463 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
465 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
468 return resample_methods
[m
];
471 int pa_resample_method_supported(pa_resample_method_t m
) {
473 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
476 #ifndef HAVE_LIBSAMPLERATE
477 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
484 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
485 pa_resample_method_t m
;
489 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
490 if (!strcmp(string
, resample_methods
[m
]))
493 if (!strcmp(string
, "speex-fixed"))
494 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
496 if (!strcmp(string
, "speex-float"))
497 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
499 return PA_RESAMPLER_INVALID
;
502 static pa_bool_t
on_left(pa_channel_position_t p
) {
505 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
506 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
507 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
508 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
509 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
510 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
513 static pa_bool_t
on_right(pa_channel_position_t p
) {
516 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
517 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
518 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
519 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
520 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
521 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
524 static pa_bool_t
on_center(pa_channel_position_t p
) {
527 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
528 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
529 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
530 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
531 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
534 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
536 p
== PA_CHANNEL_POSITION_LFE
;
539 static pa_bool_t
on_front(pa_channel_position_t p
) {
541 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
542 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
543 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
544 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
545 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
546 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
547 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
548 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
551 static pa_bool_t
on_rear(pa_channel_position_t p
) {
553 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
554 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
555 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
556 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
557 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
558 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
561 static pa_bool_t
on_side(pa_channel_position_t p
) {
563 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
564 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
565 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
575 static int front_rear_side(pa_channel_position_t p
) {
585 static void calc_map_table(pa_resampler
*r
) {
587 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
594 if (!(r
->map_required
= (r
->i_ss
.channels
!= r
->o_ss
.channels
|| (!(r
->flags
& PA_RESAMPLER_NO_REMAP
) && !pa_channel_map_equal(&r
->i_cm
, &r
->o_cm
)))))
597 memset(r
->map_table_f
, 0, sizeof(r
->map_table_f
));
598 memset(r
->map_table_i
, 0, sizeof(r
->map_table_i
));
599 memset(ic_connected
, 0, sizeof(ic_connected
));
600 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
602 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
603 pa_bool_t oc_connected
= FALSE
;
604 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
606 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
607 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
609 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
610 /* We shall not do any remapping. Hence, just check by index */
613 r
->map_table_f
[oc
][ic
] = 1.0;
618 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
619 /* We shall not do any remixing. Hence, just check by name */
622 r
->map_table_f
[oc
][ic
] = 1.0;
629 /* OK, we shall do the full monty: upmixing and
630 * downmixing. Our algorithm is relatively simple, does
631 * not do spacialization, delay elements or apply lowpass
632 * filters for LFE. Patches are always welcome,
633 * though. Oh, and it doesn't do any matrix
634 * decoding. (Which probably wouldn't make any sense
637 * This code is not idempotent: downmixing an upmixed
638 * stereo stream is not identical to the original. The
639 * volume will not match, and the two channels will be a
640 * linear combination of both.
642 * This is losely based on random suggestions found on the
643 * Internet, such as this:
644 * http://www.halfgaar.net/surround-sound-in-linux and the
647 * The algorithm works basically like this:
649 * 1) Connect all channels with matching names.
652 * S:Mono: Copy into all D:channels
653 * D:Mono: Copy in all S:channels
655 * 3) Mix D:Left, D:Right:
656 * D:Left: If not connected, avg all S:Left
657 * D:Right: If not connected, avg all S:Right
660 * If not connected, avg all S:Center
661 * If still not connected, avg all S:Left, S:Right
664 * If not connected, avg all S:*
666 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
667 * not connected, mix into all D:left and all D:right
668 * channels. Gain is 0.1, the current left and right
669 * should be multiplied by 0.9.
671 * 7) Make sure S:Center, S:LFE is used:
673 * S:Center, S:LFE: If not connected, mix into all
674 * D:left, all D:right, all D:center channels, gain is
675 * 0.375. The current (as result of 1..6) factors
676 * should be multiplied by 0.75. (Alt. suggestion: 0.25
677 * vs. 0.5) If C-front is only mixed into
678 * L-front/R-front if available, otherwise into all L/R
679 * channels. Similarly for C-rear.
681 * S: and D: shall relate to the source resp. destination channels.
683 * Rationale: 1, 2 are probably obvious. For 3: this
684 * copies front to rear if needed. For 4: we try to find
685 * some suitable C source for C, if we don't find any, we
686 * avg L and R. For 5: LFE is mixed from all channels. For
687 * 6: the rear channels should not be dropped entirely,
688 * however have only minimal impact. For 7: movies usually
689 * encode speech on the center channel. Thus we have to
690 * make sure this channel is distributed to L and R if not
691 * available in the output. Also, LFE is used to achieve a
692 * greater dynamic range, and thus we should try to do our
693 * best to pass it to L+R.
696 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
697 r
->map_table_f
[oc
][ic
] = 1.0;
700 ic_connected
[ic
] = TRUE
;
704 if (!oc_connected
&& remix
) {
705 /* OK, we shall remix */
707 /* Try to find matching input ports for this output port */
712 /* We are not connected and on the left side, let's
713 * average all left side input channels. */
715 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
716 if (on_left(r
->i_cm
.map
[ic
]))
720 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
721 if (on_left(r
->i_cm
.map
[ic
])) {
722 r
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
723 ic_connected
[ic
] = TRUE
;
726 /* We ignore the case where there is no left input
727 * channel. Something is really wrong in this case
730 } else if (on_right(b
)) {
733 /* We are not connected and on the right side, let's
734 * average all right side input channels. */
736 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
737 if (on_right(r
->i_cm
.map
[ic
]))
741 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
742 if (on_right(r
->i_cm
.map
[ic
])) {
743 r
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
744 ic_connected
[ic
] = TRUE
;
747 /* We ignore the case where there is no right input
748 * channel. Something is really wrong in this case
751 } else if (on_center(b
)) {
754 /* We are not connected and at the center. Let's
755 * average all center input channels. */
757 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
758 if (on_center(r
->i_cm
.map
[ic
]))
762 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
763 if (on_center(r
->i_cm
.map
[ic
])) {
764 r
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
765 ic_connected
[ic
] = TRUE
;
769 /* Hmm, no center channel around, let's synthesize
770 * it by mixing L and R.*/
774 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
775 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
779 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
780 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
781 r
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
782 ic_connected
[ic
] = TRUE
;
785 /* We ignore the case where there is not even a
786 * left or right input channel. Something is
787 * really wrong in this case anyway. */
790 } else if (on_lfe(b
)) {
792 /* We are not connected and an LFE. Let's average all
793 * channels for LFE. */
795 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
797 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
798 r
->map_table_f
[oc
][ic
] = 1.0f
/ (float) r
->i_ss
.channels
;
800 r
->map_table_f
[oc
][ic
] = 0;
802 /* Please note that a channel connected to LFE
803 * doesn't really count as connected. */
811 ic_unconnected_left
= 0,
812 ic_unconnected_right
= 0,
813 ic_unconnected_center
= 0,
814 ic_unconnected_lfe
= 0;
816 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
817 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
819 if (ic_connected
[ic
])
823 ic_unconnected_left
++;
824 else if (on_right(a
))
825 ic_unconnected_right
++;
826 else if (on_center(a
))
827 ic_unconnected_center
++;
829 ic_unconnected_lfe
++;
832 if (ic_unconnected_left
> 0) {
834 /* OK, so there are unconnected input channels on the
835 * left. Let's multiply all already connected channels on
836 * the left side by .9 and add in our averaged unconnected
837 * channels multplied by .1 */
839 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
841 if (!on_left(r
->o_cm
.map
[oc
]))
844 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
846 if (ic_connected
[ic
]) {
847 r
->map_table_f
[oc
][ic
] *= .9f
;
851 if (on_left(r
->i_cm
.map
[ic
]))
852 r
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
857 if (ic_unconnected_right
> 0) {
859 /* OK, so there are unconnected input channels on the
860 * right. Let's multiply all already connected channels on
861 * the right side by .9 and add in our averaged unconnected
862 * channels multplied by .1 */
864 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
866 if (!on_right(r
->o_cm
.map
[oc
]))
869 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
871 if (ic_connected
[ic
]) {
872 r
->map_table_f
[oc
][ic
] *= .9f
;
876 if (on_right(r
->i_cm
.map
[ic
]))
877 r
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
882 if (ic_unconnected_center
> 0) {
883 pa_bool_t mixed_in
= FALSE
;
885 /* OK, so there are unconnected input channels on the
886 * center. Let's multiply all already connected channels on
887 * the center side by .9 and add in our averaged unconnected
888 * channels multplied by .1 */
890 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
892 if (!on_center(r
->o_cm
.map
[oc
]))
895 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
897 if (ic_connected
[ic
]) {
898 r
->map_table_f
[oc
][ic
] *= .9f
;
902 if (on_center(r
->i_cm
.map
[ic
])) {
903 r
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
910 unsigned ncenter
[PA_CHANNELS_MAX
];
911 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
913 memset(ncenter
, 0, sizeof(ncenter
));
914 memset(found_frs
, 0, sizeof(found_frs
));
916 /* Hmm, as it appears there was no center channel we
917 could mix our center channel in. In this case, mix
918 it into left and right. Using .375 and 0.75 as
921 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
923 if (ic_connected
[ic
])
926 if (!on_center(r
->i_cm
.map
[ic
]))
929 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
931 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
934 if (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
935 found_frs
[ic
] = TRUE
;
940 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
942 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
945 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
950 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
952 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
955 if (ncenter
[oc
] <= 0)
958 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
960 if (ic_connected
[ic
]) {
961 r
->map_table_f
[oc
][ic
] *= .75f
;
965 if (!on_center(r
->i_cm
.map
[ic
]))
968 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
969 r
->map_table_f
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
975 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
977 /* OK, so there is an unconnected LFE channel. Let's mix
978 * it into all channels, with factor 0.375 */
980 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
982 if (!on_lfe(r
->i_cm
.map
[ic
]))
985 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
986 r
->map_table_f
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
990 /* make an 16:16 int version of the matrix */
991 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
992 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
993 r
->map_table_i
[oc
][ic
] = (int32_t) (r
->map_table_f
[oc
][ic
] * 0x10000);
997 pa_strbuf_printf(s
, " ");
998 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
999 pa_strbuf_printf(s
, " I%02u ", ic
);
1000 pa_strbuf_puts(s
, "\n +");
1002 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
1003 pa_strbuf_printf(s
, "------");
1004 pa_strbuf_puts(s
, "\n");
1006 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1007 pa_strbuf_printf(s
, "O%02u |", oc
);
1009 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
1010 pa_strbuf_printf(s
, " %1.3f", r
->map_table_f
[oc
][ic
]);
1012 pa_strbuf_puts(s
, "\n");
1015 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
1018 /* find some common channel remappings, fall back to full matrix operation. */
1019 if (r
->i_ss
.channels
== 1 && r
->o_ss
.channels
== 2 &&
1020 r
->map_table_f
[0][0] >= 1.0 && r
->map_table_f
[1][0] >= 1.0) {
1021 r
->do_remap
= (pa_do_remap_func_t
) remap_mono_to_stereo
;;
1022 pa_log_debug("Using mono to stereo remapping");
1024 r
->do_remap
= (pa_do_remap_func_t
) remap_channels_matrix
;
1025 pa_log_debug("Using generic matrix remapping");
1030 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1036 pa_assert(input
->memblock
);
1038 /* Convert the incoming sample into the work sample format and place them in buf1 */
1040 if (!r
->to_work_format_func
|| !input
->length
)
1043 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1046 r
->buf1
.length
= r
->w_sz
* n_samples
;
1048 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
1049 if (r
->buf1
.memblock
)
1050 pa_memblock_unref(r
->buf1
.memblock
);
1052 r
->buf1_samples
= n_samples
;
1053 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
1056 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1057 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
1059 r
->to_work_format_func(n_samples
, src
, dst
);
1061 pa_memblock_release(input
->memblock
);
1062 pa_memblock_release(r
->buf1
.memblock
);
1067 static void remap_mono_to_stereo(pa_resampler
*r
, void *dst
, const void *src
, unsigned n
) {
1070 switch (r
->work_format
) {
1071 case PA_SAMPLE_FLOAT32NE
:
1078 for (i
= n
>> 2; i
; i
--) {
1086 for (i
= n
& 3; i
; i
--) {
1093 case PA_SAMPLE_S16NE
:
1097 d
= (int16_t *) dst
;
1098 s
= (int16_t *) src
;
1100 for (i
= n
>> 2; i
; i
--) {
1108 for (i
= n
& 3; i
; i
--) {
1116 pa_assert_not_reached();
1120 static void remap_channels_matrix (pa_resampler
*r
, void *dst
, const void *src
, unsigned n
) {
1122 unsigned n_ic
, n_oc
;
1124 n_ic
= r
->i_ss
.channels
;
1125 n_oc
= r
->o_ss
.channels
;
1127 memset(dst
, 0, r
->buf2
.length
);
1129 switch (r
->work_format
) {
1130 case PA_SAMPLE_FLOAT32NE
:
1134 for (oc
= 0; oc
< n_oc
; oc
++) {
1137 for (ic
= 0; ic
< n_ic
; ic
++) {
1140 vol
= r
->map_table_f
[oc
][ic
];
1145 d
= (float *)dst
+ oc
;
1146 s
= (float *)src
+ ic
;
1149 for (i
= n
; i
> 0; i
--, s
+= n_ic
, d
+= n_oc
)
1152 for (i
= n
; i
> 0; i
--, s
+= n_ic
, d
+= n_oc
)
1160 case PA_SAMPLE_S16NE
:
1164 for (oc
= 0; oc
< n_oc
; oc
++) {
1167 for (ic
= 0; ic
< n_ic
; ic
++) {
1170 vol
= r
->map_table_i
[oc
][ic
];
1175 d
= (int16_t *)dst
+ oc
;
1176 s
= (int16_t *)src
+ ic
;
1178 if (vol
>= 0x10000) {
1179 for (i
= n
; i
> 0; i
--, s
+= n_ic
, d
+= n_oc
)
1182 for (i
= n
; i
> 0; i
--, s
+= n_ic
, d
+= n_oc
)
1183 *d
+= (int16_t) (((int32_t)*s
* vol
) >> 16);
1190 pa_assert_not_reached();
1194 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1195 unsigned in_n_samples
, out_n_samples
, n_frames
;
1200 pa_assert(input
->memblock
);
1202 /* Remap channels and place the result int buf2 */
1204 if (!r
->map_required
|| !input
->length
)
1207 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1208 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1209 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1212 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
1214 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
1215 if (r
->buf2
.memblock
)
1216 pa_memblock_unref(r
->buf2
.memblock
);
1218 r
->buf2_samples
= out_n_samples
;
1219 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
1222 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1223 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
1225 pa_assert (r
->do_remap
);
1226 r
->do_remap (r
, dst
, src
, n_frames
);
1228 pa_memblock_release(input
->memblock
);
1229 pa_memblock_release(r
->buf2
.memblock
);
1234 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1235 unsigned in_n_frames
, in_n_samples
;
1236 unsigned out_n_frames
, out_n_samples
;
1241 /* Resample the data and place the result in buf3 */
1243 if (!r
->impl_resample
|| !input
->length
)
1246 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1247 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1249 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1250 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1253 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1255 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1256 if (r
->buf3
.memblock
)
1257 pa_memblock_unref(r
->buf3
.memblock
);
1259 r
->buf3_samples
= out_n_samples
;
1260 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1263 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1264 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1269 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1270 unsigned n_samples
, n_frames
;
1276 /* Convert the data into the correct sample type and place the result in buf4 */
1278 if (!r
->from_work_format_func
|| !input
->length
)
1281 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1282 n_frames
= n_samples
/ r
->o_ss
.channels
;
1285 r
->buf4
.length
= r
->o_fz
* n_frames
;
1287 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1288 if (r
->buf4
.memblock
)
1289 pa_memblock_unref(r
->buf4
.memblock
);
1291 r
->buf4_samples
= n_samples
;
1292 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1295 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1296 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1297 r
->from_work_format_func(n_samples
, src
, dst
);
1298 pa_memblock_release(input
->memblock
);
1299 pa_memblock_release(r
->buf4
.memblock
);
1301 r
->buf4
.length
= r
->o_fz
* n_frames
;
1306 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1312 pa_assert(in
->length
);
1313 pa_assert(in
->memblock
);
1314 pa_assert(in
->length
% r
->i_fz
== 0);
1316 buf
= (pa_memchunk
*) in
;
1317 buf
= convert_to_work_format(r
, buf
);
1318 buf
= remap_channels(r
, buf
);
1319 buf
= resample(r
, buf
);
1322 buf
= convert_from_work_format(r
, buf
);
1326 pa_memblock_ref(buf
->memblock
);
1328 pa_memchunk_reset(buf
);
1330 pa_memchunk_reset(out
);
1333 /*** libsamplerate based implementation ***/
1335 #ifdef HAVE_LIBSAMPLERATE
1336 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1342 pa_assert(out_n_frames
);
1344 memset(&data
, 0, sizeof(data
));
1346 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1347 data
.input_frames
= (long int) in_n_frames
;
1349 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1350 data
.output_frames
= (long int) *out_n_frames
;
1352 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1353 data
.end_of_input
= 0;
1355 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1356 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1358 pa_memblock_release(input
->memblock
);
1359 pa_memblock_release(output
->memblock
);
1361 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1364 static void libsamplerate_update_rates(pa_resampler
*r
) {
1367 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1370 static void libsamplerate_reset(pa_resampler
*r
) {
1373 pa_assert_se(src_reset(r
->src
.state
) == 0);
1376 static void libsamplerate_free(pa_resampler
*r
) {
1380 src_delete(r
->src
.state
);
1383 static int libsamplerate_init(pa_resampler
*r
) {
1388 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1391 r
->impl_free
= libsamplerate_free
;
1392 r
->impl_update_rates
= libsamplerate_update_rates
;
1393 r
->impl_resample
= libsamplerate_resample
;
1394 r
->impl_reset
= libsamplerate_reset
;
1400 /*** speex based implementation ***/
1402 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1404 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1409 pa_assert(out_n_frames
);
1411 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1412 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1414 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1416 pa_memblock_release(input
->memblock
);
1417 pa_memblock_release(output
->memblock
);
1419 pa_assert(inf
== in_n_frames
);
1420 *out_n_frames
= outf
;
1423 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1425 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1430 pa_assert(out_n_frames
);
1432 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1433 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1435 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1437 pa_memblock_release(input
->memblock
);
1438 pa_memblock_release(output
->memblock
);
1440 pa_assert(inf
== in_n_frames
);
1441 *out_n_frames
= outf
;
1444 static void speex_update_rates(pa_resampler
*r
) {
1447 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1450 static void speex_reset(pa_resampler
*r
) {
1453 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1456 static void speex_free(pa_resampler
*r
) {
1459 if (!r
->speex
.state
)
1462 speex_resampler_destroy(r
->speex
.state
);
1465 static int speex_init(pa_resampler
*r
) {
1470 r
->impl_free
= speex_free
;
1471 r
->impl_update_rates
= speex_update_rates
;
1472 r
->impl_reset
= speex_reset
;
1474 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1476 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1477 r
->impl_resample
= speex_resample_int
;
1480 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1482 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1483 r
->impl_resample
= speex_resample_float
;
1486 pa_log_info("Choosing speex quality setting %i.", q
);
1488 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1494 /* Trivial implementation */
1496 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1504 pa_assert(out_n_frames
);
1506 fz
= r
->w_sz
* r
->o_ss
.channels
;
1508 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1509 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1511 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1514 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1515 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1517 if (j
>= in_n_frames
)
1520 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1522 memcpy((uint8_t*) dst
+ fz
* o_index
,
1523 (uint8_t*) src
+ fz
* j
, (int) fz
);
1526 pa_memblock_release(input
->memblock
);
1527 pa_memblock_release(output
->memblock
);
1529 *out_n_frames
= o_index
;
1531 r
->trivial
.i_counter
+= in_n_frames
;
1533 /* Normalize counters */
1534 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1535 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1537 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1538 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1542 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1545 r
->trivial
.i_counter
= 0;
1546 r
->trivial
.o_counter
= 0;
1549 static int trivial_init(pa_resampler
*r
) {
1552 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1554 r
->impl_resample
= trivial_resample
;
1555 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1556 r
->impl_reset
= trivial_update_rates_or_reset
;
1561 /* Peak finder implementation */
1563 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1572 pa_assert(out_n_frames
);
1574 fz
= r
->w_sz
* r
->o_ss
.channels
;
1576 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1577 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1579 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1582 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1584 if (j
> r
->peaks
.i_counter
)
1585 j
-= r
->peaks
.i_counter
;
1589 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1591 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1593 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* start
);
1594 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1596 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1598 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1601 n
= (int16_t) (*s
< 0 ? -*s
: *s
);
1603 if (PA_UNLIKELY(n
> r
->peaks
.max_i
[c
]))
1604 r
->peaks
.max_i
[c
] = n
;
1607 if (i
>= in_n_frames
)
1610 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1611 *d
= r
->peaks
.max_i
[c
];
1612 r
->peaks
.max_i
[c
] = 0;
1617 float *s
= (float*) ((uint8_t*) src
+ fz
* start
);
1618 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1620 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1622 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1623 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1624 float n
= fabsf(*s
);
1626 if (n
> r
->peaks
.max_f
[c
])
1627 r
->peaks
.max_f
[c
] = n
;
1630 if (i
>= in_n_frames
)
1633 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1634 *d
= r
->peaks
.max_f
[c
];
1635 r
->peaks
.max_f
[c
] = 0;
1642 pa_memblock_release(input
->memblock
);
1643 pa_memblock_release(output
->memblock
);
1645 *out_n_frames
= o_index
;
1647 r
->peaks
.i_counter
+= in_n_frames
;
1649 /* Normalize counters */
1650 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1651 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1653 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1654 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1658 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1661 r
->peaks
.i_counter
= 0;
1662 r
->peaks
.o_counter
= 0;
1665 static int peaks_init(pa_resampler
*r
) {
1668 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1669 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1670 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1672 r
->impl_resample
= peaks_resample
;
1673 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1674 r
->impl_reset
= peaks_update_rates_or_reset
;
1679 /*** ffmpeg based implementation ***/
1681 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1682 unsigned used_frames
= 0, c
;
1687 pa_assert(out_n_frames
);
1689 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1692 int16_t *p
, *t
, *k
, *q
, *s
;
1693 int consumed_frames
;
1696 /* Allocate a new block */
1697 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1698 p
= pa_memblock_acquire(b
);
1700 /* Copy the remaining data into it */
1701 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1702 if (r
->ffmpeg
.buf
[c
].memblock
) {
1703 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1705 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1706 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1707 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1710 /* Now append the new data, splitting up channels */
1711 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1712 k
= (int16_t*) ((uint8_t*) p
+ l
);
1713 for (u
= 0; u
< in_n_frames
; u
++) {
1715 t
+= r
->o_ss
.channels
;
1718 pa_memblock_release(input
->memblock
);
1720 /* Calculate the resulting number of frames */
1721 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1723 /* Allocate buffer for the result */
1724 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1725 q
= pa_memblock_acquire(w
);
1728 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1731 (int) in
, (int) *out_n_frames
,
1732 c
>= (unsigned) (r
->o_ss
.channels
-1));
1734 pa_memblock_release(b
);
1736 /* Now store the remaining samples away */
1737 pa_assert(consumed_frames
<= (int) in
);
1738 if (consumed_frames
< (int) in
) {
1739 r
->ffmpeg
.buf
[c
].memblock
= b
;
1740 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1741 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1743 pa_memblock_unref(b
);
1745 /* And place the results in the output buffer */
1746 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1747 for (u
= 0; u
< used_frames
; u
++) {
1750 s
+= r
->o_ss
.channels
;
1752 pa_memblock_release(output
->memblock
);
1753 pa_memblock_release(w
);
1754 pa_memblock_unref(w
);
1757 *out_n_frames
= used_frames
;
1760 static void ffmpeg_free(pa_resampler
*r
) {
1765 if (r
->ffmpeg
.state
)
1766 av_resample_close(r
->ffmpeg
.state
);
1768 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1769 if (r
->ffmpeg
.buf
[c
].memblock
)
1770 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1773 static int ffmpeg_init(pa_resampler
*r
) {
1778 /* We could probably implement different quality levels by
1779 * adjusting the filter parameters here. However, ffmpeg
1780 * internally only uses these hardcoded values, so let's use them
1781 * here for now as well until ffmpeg makes this configurable. */
1783 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1786 r
->impl_free
= ffmpeg_free
;
1787 r
->impl_resample
= ffmpeg_resample
;
1789 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1790 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1795 /*** copy (noop) implementation ***/
1797 static int copy_init(pa_resampler
*r
) {
1800 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);