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>
33 #include <speex/speex_resampler.h>
36 #include <pulse/xmalloc.h>
37 #include <pulsecore/sconv.h>
38 #include <pulsecore/log.h>
39 #include <pulsecore/macro.h>
40 #include <pulsecore/strbuf.h>
41 #include <pulsecore/remap.h>
43 #include "ffmpeg/avcodec.h"
45 #include "resampler.h"
47 /* Number of samples of extra space we allow the resamplers to return */
48 #define EXTRA_FRAMES 128
51 pa_resample_method_t method
;
52 pa_resample_flags_t flags
;
54 pa_sample_spec i_ss
, o_ss
;
55 pa_channel_map i_cm
, o_cm
;
56 size_t i_fz
, o_fz
, w_sz
;
59 pa_memchunk to_work_format_buf
;
60 pa_memchunk remap_buf
;
61 pa_memchunk resample_buf
;
62 pa_memchunk from_work_format_buf
;
63 unsigned to_work_format_buf_samples
;
64 unsigned remap_buf_samples
;
65 unsigned resample_buf_samples
;
66 unsigned from_work_format_buf_samples
;
68 pa_sample_format_t work_format
;
70 pa_convert_func_t to_work_format_func
;
71 pa_convert_func_t from_work_format_func
;
74 pa_bool_t map_required
;
76 void (*impl_free
)(pa_resampler
*r
);
77 void (*impl_update_rates
)(pa_resampler
*r
);
78 void (*impl_resample
)(pa_resampler
*r
, const pa_memchunk
*in
, unsigned in_samples
, pa_memchunk
*out
, unsigned *out_samples
);
79 void (*impl_reset
)(pa_resampler
*r
);
81 struct { /* data specific to the trivial resampler */
86 struct { /* data specific to the peak finder pseudo resampler */
90 float max_f
[PA_CHANNELS_MAX
];
91 int16_t max_i
[PA_CHANNELS_MAX
];
95 #ifdef HAVE_LIBSAMPLERATE
96 struct { /* data specific to libsamplerate */
102 struct { /* data specific to speex */
103 SpeexResamplerState
* state
;
107 struct { /* data specific to ffmpeg */
108 struct AVResampleContext
*state
;
109 pa_memchunk buf
[PA_CHANNELS_MAX
];
113 static int copy_init(pa_resampler
*r
);
114 static int trivial_init(pa_resampler
*r
);
116 static int speex_init(pa_resampler
*r
);
118 static int ffmpeg_init(pa_resampler
*r
);
119 static int peaks_init(pa_resampler
*r
);
120 #ifdef HAVE_LIBSAMPLERATE
121 static int libsamplerate_init(pa_resampler
*r
);
124 static void calc_map_table(pa_resampler
*r
);
126 static int (* const init_table
[])(pa_resampler
*r
) = {
127 #ifdef HAVE_LIBSAMPLERATE
128 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = libsamplerate_init
,
129 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = libsamplerate_init
,
130 [PA_RESAMPLER_SRC_SINC_FASTEST
] = libsamplerate_init
,
131 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = libsamplerate_init
,
132 [PA_RESAMPLER_SRC_LINEAR
] = libsamplerate_init
,
134 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = NULL
,
135 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = NULL
,
136 [PA_RESAMPLER_SRC_SINC_FASTEST
] = NULL
,
137 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = NULL
,
138 [PA_RESAMPLER_SRC_LINEAR
] = NULL
,
140 [PA_RESAMPLER_TRIVIAL
] = trivial_init
,
142 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+0] = speex_init
,
143 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+1] = speex_init
,
144 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+2] = speex_init
,
145 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+3] = speex_init
,
146 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+4] = speex_init
,
147 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+5] = speex_init
,
148 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+6] = speex_init
,
149 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+7] = speex_init
,
150 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+8] = speex_init
,
151 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+9] = speex_init
,
152 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+10] = speex_init
,
153 [PA_RESAMPLER_SPEEX_FIXED_BASE
+0] = speex_init
,
154 [PA_RESAMPLER_SPEEX_FIXED_BASE
+1] = speex_init
,
155 [PA_RESAMPLER_SPEEX_FIXED_BASE
+2] = speex_init
,
156 [PA_RESAMPLER_SPEEX_FIXED_BASE
+3] = speex_init
,
157 [PA_RESAMPLER_SPEEX_FIXED_BASE
+4] = speex_init
,
158 [PA_RESAMPLER_SPEEX_FIXED_BASE
+5] = speex_init
,
159 [PA_RESAMPLER_SPEEX_FIXED_BASE
+6] = speex_init
,
160 [PA_RESAMPLER_SPEEX_FIXED_BASE
+7] = speex_init
,
161 [PA_RESAMPLER_SPEEX_FIXED_BASE
+8] = speex_init
,
162 [PA_RESAMPLER_SPEEX_FIXED_BASE
+9] = speex_init
,
163 [PA_RESAMPLER_SPEEX_FIXED_BASE
+10] = speex_init
,
165 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+0] = NULL
,
166 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+1] = NULL
,
167 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+2] = NULL
,
168 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+3] = NULL
,
169 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+4] = NULL
,
170 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+5] = NULL
,
171 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+6] = NULL
,
172 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+7] = NULL
,
173 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+8] = NULL
,
174 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+9] = NULL
,
175 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+10] = NULL
,
176 [PA_RESAMPLER_SPEEX_FIXED_BASE
+0] = NULL
,
177 [PA_RESAMPLER_SPEEX_FIXED_BASE
+1] = NULL
,
178 [PA_RESAMPLER_SPEEX_FIXED_BASE
+2] = NULL
,
179 [PA_RESAMPLER_SPEEX_FIXED_BASE
+3] = NULL
,
180 [PA_RESAMPLER_SPEEX_FIXED_BASE
+4] = NULL
,
181 [PA_RESAMPLER_SPEEX_FIXED_BASE
+5] = NULL
,
182 [PA_RESAMPLER_SPEEX_FIXED_BASE
+6] = NULL
,
183 [PA_RESAMPLER_SPEEX_FIXED_BASE
+7] = NULL
,
184 [PA_RESAMPLER_SPEEX_FIXED_BASE
+8] = NULL
,
185 [PA_RESAMPLER_SPEEX_FIXED_BASE
+9] = NULL
,
186 [PA_RESAMPLER_SPEEX_FIXED_BASE
+10] = NULL
,
188 [PA_RESAMPLER_FFMPEG
] = ffmpeg_init
,
189 [PA_RESAMPLER_AUTO
] = NULL
,
190 [PA_RESAMPLER_COPY
] = copy_init
,
191 [PA_RESAMPLER_PEAKS
] = peaks_init
,
194 pa_resampler
* pa_resampler_new(
196 const pa_sample_spec
*a
,
197 const pa_channel_map
*am
,
198 const pa_sample_spec
*b
,
199 const pa_channel_map
*bm
,
200 pa_resample_method_t method
,
201 pa_resample_flags_t flags
) {
203 pa_resampler
*r
= NULL
;
208 pa_assert(pa_sample_spec_valid(a
));
209 pa_assert(pa_sample_spec_valid(b
));
210 pa_assert(method
>= 0);
211 pa_assert(method
< PA_RESAMPLER_MAX
);
215 if (!(flags
& PA_RESAMPLER_VARIABLE_RATE
) && a
->rate
== b
->rate
) {
216 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
217 method
= PA_RESAMPLER_COPY
;
220 if (!pa_resample_method_supported(method
)) {
221 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method
));
222 method
= PA_RESAMPLER_AUTO
;
225 if (method
== PA_RESAMPLER_FFMPEG
&& (flags
& PA_RESAMPLER_VARIABLE_RATE
)) {
226 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
227 method
= PA_RESAMPLER_AUTO
;
230 if (method
== PA_RESAMPLER_COPY
&& ((flags
& PA_RESAMPLER_VARIABLE_RATE
) || a
->rate
!= b
->rate
)) {
231 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
232 method
= PA_RESAMPLER_AUTO
;
235 if (method
== PA_RESAMPLER_AUTO
) {
237 method
= PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
239 method
= PA_RESAMPLER_FFMPEG
;
243 r
= pa_xnew0(pa_resampler
, 1);
248 /* Fill sample specs */
252 /* set up the remap structure */
253 r
->remap
.i_ss
= &r
->i_ss
;
254 r
->remap
.o_ss
= &r
->o_ss
;
255 r
->remap
.format
= &r
->work_format
;
259 else if (!pa_channel_map_init_auto(&r
->i_cm
, r
->i_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
264 else if (!pa_channel_map_init_auto(&r
->o_cm
, r
->o_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
267 r
->i_fz
= pa_frame_size(a
);
268 r
->o_fz
= pa_frame_size(b
);
272 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method
));
274 if ((method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) ||
275 (method
== PA_RESAMPLER_FFMPEG
))
276 r
->work_format
= PA_SAMPLE_S16NE
;
277 else if (method
== PA_RESAMPLER_TRIVIAL
|| method
== PA_RESAMPLER_COPY
|| method
== PA_RESAMPLER_PEAKS
) {
279 if (r
->map_required
|| a
->format
!= b
->format
|| method
== PA_RESAMPLER_PEAKS
) {
281 if (a
->format
== PA_SAMPLE_S32NE
|| a
->format
== PA_SAMPLE_S32RE
||
282 a
->format
== PA_SAMPLE_FLOAT32NE
|| a
->format
== PA_SAMPLE_FLOAT32RE
||
283 a
->format
== PA_SAMPLE_S24NE
|| a
->format
== PA_SAMPLE_S24RE
||
284 a
->format
== PA_SAMPLE_S24_32NE
|| a
->format
== PA_SAMPLE_S24_32RE
||
285 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
286 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
||
287 b
->format
== PA_SAMPLE_S24NE
|| b
->format
== PA_SAMPLE_S24RE
||
288 b
->format
== PA_SAMPLE_S24_32NE
|| b
->format
== PA_SAMPLE_S24_32RE
)
289 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
291 r
->work_format
= PA_SAMPLE_S16NE
;
294 r
->work_format
= a
->format
;
297 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
299 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
301 r
->w_sz
= pa_sample_size_of_format(r
->work_format
);
303 if (r
->i_ss
.format
!= r
->work_format
) {
304 if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
305 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
308 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
309 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
314 if (r
->o_ss
.format
!= r
->work_format
) {
315 if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
316 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
319 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
320 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
325 /* initialize implementation */
326 if (init_table
[method
](r
) < 0)
337 void pa_resampler_free(pa_resampler
*r
) {
343 if (r
->to_work_format_buf
.memblock
)
344 pa_memblock_unref(r
->to_work_format_buf
.memblock
);
345 if (r
->remap_buf
.memblock
)
346 pa_memblock_unref(r
->remap_buf
.memblock
);
347 if (r
->resample_buf
.memblock
)
348 pa_memblock_unref(r
->resample_buf
.memblock
);
349 if (r
->from_work_format_buf
.memblock
)
350 pa_memblock_unref(r
->from_work_format_buf
.memblock
);
355 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
359 if (r
->i_ss
.rate
== rate
)
364 r
->impl_update_rates(r
);
367 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
371 if (r
->o_ss
.rate
== rate
)
376 r
->impl_update_rates(r
);
379 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
382 /* Let's round up here */
384 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
;
387 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
390 /* Let's round up here */
392 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
;
395 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
396 size_t block_size_max
;
402 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
404 /* We deduce the "largest" sample spec we're using during the
406 ss
.channels
= (uint8_t) (PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
));
408 /* We silently assume that the format enum is ordered by size */
409 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
410 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
412 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
414 fs
= pa_frame_size(&ss
);
416 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
419 void pa_resampler_reset(pa_resampler
*r
) {
426 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
432 const pa_channel_map
* pa_resampler_input_channel_map(pa_resampler
*r
) {
438 const pa_sample_spec
* pa_resampler_input_sample_spec(pa_resampler
*r
) {
444 const pa_channel_map
* pa_resampler_output_channel_map(pa_resampler
*r
) {
450 const pa_sample_spec
* pa_resampler_output_sample_spec(pa_resampler
*r
) {
456 static const char * const resample_methods
[] = {
457 "src-sinc-best-quality",
458 "src-sinc-medium-quality",
460 "src-zero-order-hold",
491 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
493 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
496 return resample_methods
[m
];
499 int pa_resample_method_supported(pa_resample_method_t m
) {
501 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
504 #ifndef HAVE_LIBSAMPLERATE
505 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
510 if (m
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& m
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
)
512 if (m
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& m
<= PA_RESAMPLER_SPEEX_FIXED_MAX
)
519 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
520 pa_resample_method_t m
;
524 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
525 if (!strcmp(string
, resample_methods
[m
]))
528 if (!strcmp(string
, "speex-fixed"))
529 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
531 if (!strcmp(string
, "speex-float"))
532 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
534 return PA_RESAMPLER_INVALID
;
537 static pa_bool_t
on_left(pa_channel_position_t p
) {
540 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
541 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
542 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
543 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
544 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
545 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
548 static pa_bool_t
on_right(pa_channel_position_t p
) {
551 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
552 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
553 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
554 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
555 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
556 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
559 static pa_bool_t
on_center(pa_channel_position_t p
) {
562 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
563 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
564 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
565 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
566 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
569 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
571 p
== PA_CHANNEL_POSITION_LFE
;
574 static pa_bool_t
on_front(pa_channel_position_t p
) {
576 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
577 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
578 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
579 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
580 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
581 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
582 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
583 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
586 static pa_bool_t
on_rear(pa_channel_position_t p
) {
588 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
589 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
590 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
591 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
592 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
593 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
596 static pa_bool_t
on_side(pa_channel_position_t p
) {
598 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
599 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
600 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
610 static int front_rear_side(pa_channel_position_t p
) {
620 static void calc_map_table(pa_resampler
*r
) {
623 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
631 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
)))))
636 n_oc
= r
->o_ss
.channels
;
637 n_ic
= r
->i_ss
.channels
;
639 memset(m
->map_table_f
, 0, sizeof(m
->map_table_f
));
640 memset(m
->map_table_i
, 0, sizeof(m
->map_table_i
));
642 memset(ic_connected
, 0, sizeof(ic_connected
));
643 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
645 for (oc
= 0; oc
< n_oc
; oc
++) {
646 pa_bool_t oc_connected
= FALSE
;
647 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
649 for (ic
= 0; ic
< n_ic
; ic
++) {
650 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
652 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
653 /* We shall not do any remapping. Hence, just check by index */
656 m
->map_table_f
[oc
][ic
] = 1.0;
661 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
662 /* We shall not do any remixing. Hence, just check by name */
665 m
->map_table_f
[oc
][ic
] = 1.0;
672 /* OK, we shall do the full monty: upmixing and
673 * downmixing. Our algorithm is relatively simple, does
674 * not do spacialization, delay elements or apply lowpass
675 * filters for LFE. Patches are always welcome,
676 * though. Oh, and it doesn't do any matrix
677 * decoding. (Which probably wouldn't make any sense
680 * This code is not idempotent: downmixing an upmixed
681 * stereo stream is not identical to the original. The
682 * volume will not match, and the two channels will be a
683 * linear combination of both.
685 * This is loosely based on random suggestions found on the
686 * Internet, such as this:
687 * http://www.halfgaar.net/surround-sound-in-linux and the
690 * The algorithm works basically like this:
692 * 1) Connect all channels with matching names.
695 * S:Mono: Copy into all D:channels
696 * D:Mono: Copy in all S:channels
698 * 3) Mix D:Left, D:Right:
699 * D:Left: If not connected, avg all S:Left
700 * D:Right: If not connected, avg all S:Right
703 * If not connected, avg all S:Center
704 * If still not connected, avg all S:Left, S:Right
707 * If not connected, avg all S:*
709 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
710 * not connected, mix into all D:left and all D:right
711 * channels. Gain is 0.1, the current left and right
712 * should be multiplied by 0.9.
714 * 7) Make sure S:Center, S:LFE is used:
716 * S:Center, S:LFE: If not connected, mix into all
717 * D:left, all D:right, all D:center channels, gain is
718 * 0.375. The current (as result of 1..6) factors
719 * should be multiplied by 0.75. (Alt. suggestion: 0.25
720 * vs. 0.5) If C-front is only mixed into
721 * L-front/R-front if available, otherwise into all L/R
722 * channels. Similarly for C-rear.
724 * S: and D: shall relate to the source resp. destination channels.
726 * Rationale: 1, 2 are probably obvious. For 3: this
727 * copies front to rear if needed. For 4: we try to find
728 * some suitable C source for C, if we don't find any, we
729 * avg L and R. For 5: LFE is mixed from all channels. For
730 * 6: the rear channels should not be dropped entirely,
731 * however have only minimal impact. For 7: movies usually
732 * encode speech on the center channel. Thus we have to
733 * make sure this channel is distributed to L and R if not
734 * available in the output. Also, LFE is used to achieve a
735 * greater dynamic range, and thus we should try to do our
736 * best to pass it to L+R.
739 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
740 m
->map_table_f
[oc
][ic
] = 1.0;
743 ic_connected
[ic
] = TRUE
;
747 if (!oc_connected
&& remix
) {
748 /* OK, we shall remix */
750 /* Try to find matching input ports for this output port */
755 /* We are not connected and on the left side, let's
756 * average all left side input channels. */
758 for (ic
= 0; ic
< n_ic
; ic
++)
759 if (on_left(r
->i_cm
.map
[ic
]))
763 for (ic
= 0; ic
< n_ic
; ic
++)
764 if (on_left(r
->i_cm
.map
[ic
])) {
765 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
766 ic_connected
[ic
] = TRUE
;
769 /* We ignore the case where there is no left input
770 * channel. Something is really wrong in this case
773 } else if (on_right(b
)) {
776 /* We are not connected and on the right side, let's
777 * average all right side input channels. */
779 for (ic
= 0; ic
< n_ic
; ic
++)
780 if (on_right(r
->i_cm
.map
[ic
]))
784 for (ic
= 0; ic
< n_ic
; ic
++)
785 if (on_right(r
->i_cm
.map
[ic
])) {
786 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
787 ic_connected
[ic
] = TRUE
;
790 /* We ignore the case where there is no right input
791 * channel. Something is really wrong in this case
794 } else if (on_center(b
)) {
797 /* We are not connected and at the center. Let's
798 * average all center input channels. */
800 for (ic
= 0; ic
< n_ic
; ic
++)
801 if (on_center(r
->i_cm
.map
[ic
]))
805 for (ic
= 0; ic
< n_ic
; ic
++)
806 if (on_center(r
->i_cm
.map
[ic
])) {
807 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
808 ic_connected
[ic
] = TRUE
;
812 /* Hmm, no center channel around, let's synthesize
813 * it by mixing L and R.*/
817 for (ic
= 0; ic
< n_ic
; ic
++)
818 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
822 for (ic
= 0; ic
< n_ic
; ic
++)
823 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
824 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
825 ic_connected
[ic
] = TRUE
;
828 /* We ignore the case where there is not even a
829 * left or right input channel. Something is
830 * really wrong in this case anyway. */
833 } else if (on_lfe(b
)) {
835 /* We are not connected and an LFE. Let's average all
836 * channels for LFE. */
838 for (ic
= 0; ic
< n_ic
; ic
++) {
840 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
841 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n_ic
;
843 m
->map_table_f
[oc
][ic
] = 0;
845 /* Please note that a channel connected to LFE
846 * doesn't really count as connected. */
854 ic_unconnected_left
= 0,
855 ic_unconnected_right
= 0,
856 ic_unconnected_center
= 0,
857 ic_unconnected_lfe
= 0;
859 for (ic
= 0; ic
< n_ic
; ic
++) {
860 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
862 if (ic_connected
[ic
])
866 ic_unconnected_left
++;
867 else if (on_right(a
))
868 ic_unconnected_right
++;
869 else if (on_center(a
))
870 ic_unconnected_center
++;
872 ic_unconnected_lfe
++;
875 if (ic_unconnected_left
> 0) {
877 /* OK, so there are unconnected input channels on the
878 * left. Let's multiply all already connected channels on
879 * the left side by .9 and add in our averaged unconnected
880 * channels multiplied by .1 */
882 for (oc
= 0; oc
< n_oc
; oc
++) {
884 if (!on_left(r
->o_cm
.map
[oc
]))
887 for (ic
= 0; ic
< n_ic
; ic
++) {
889 if (ic_connected
[ic
]) {
890 m
->map_table_f
[oc
][ic
] *= .9f
;
894 if (on_left(r
->i_cm
.map
[ic
]))
895 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
900 if (ic_unconnected_right
> 0) {
902 /* OK, so there are unconnected input channels on the
903 * right. Let's multiply all already connected channels on
904 * the right side by .9 and add in our averaged unconnected
905 * channels multiplied by .1 */
907 for (oc
= 0; oc
< n_oc
; oc
++) {
909 if (!on_right(r
->o_cm
.map
[oc
]))
912 for (ic
= 0; ic
< n_ic
; ic
++) {
914 if (ic_connected
[ic
]) {
915 m
->map_table_f
[oc
][ic
] *= .9f
;
919 if (on_right(r
->i_cm
.map
[ic
]))
920 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
925 if (ic_unconnected_center
> 0) {
926 pa_bool_t mixed_in
= FALSE
;
928 /* OK, so there are unconnected input channels on the
929 * center. Let's multiply all already connected channels on
930 * the center side by .9 and add in our averaged unconnected
931 * channels multiplied by .1 */
933 for (oc
= 0; oc
< n_oc
; oc
++) {
935 if (!on_center(r
->o_cm
.map
[oc
]))
938 for (ic
= 0; ic
< n_ic
; ic
++) {
940 if (ic_connected
[ic
]) {
941 m
->map_table_f
[oc
][ic
] *= .9f
;
945 if (on_center(r
->i_cm
.map
[ic
])) {
946 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
953 unsigned ncenter
[PA_CHANNELS_MAX
];
954 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
956 memset(ncenter
, 0, sizeof(ncenter
));
957 memset(found_frs
, 0, sizeof(found_frs
));
959 /* Hmm, as it appears there was no center channel we
960 could mix our center channel in. In this case, mix
961 it into left and right. Using .375 and 0.75 as
964 for (ic
= 0; ic
< n_ic
; ic
++) {
966 if (ic_connected
[ic
])
969 if (!on_center(r
->i_cm
.map
[ic
]))
972 for (oc
= 0; oc
< n_oc
; oc
++) {
974 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
977 if (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
978 found_frs
[ic
] = TRUE
;
983 for (oc
= 0; oc
< n_oc
; oc
++) {
985 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
988 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
993 for (oc
= 0; oc
< n_oc
; oc
++) {
995 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
998 if (ncenter
[oc
] <= 0)
1001 for (ic
= 0; ic
< n_ic
; ic
++) {
1003 if (ic_connected
[ic
]) {
1004 m
->map_table_f
[oc
][ic
] *= .75f
;
1008 if (!on_center(r
->i_cm
.map
[ic
]))
1011 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
1012 m
->map_table_f
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
1018 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
1020 /* OK, so there is an unconnected LFE channel. Let's mix
1021 * it into all channels, with factor 0.375 */
1023 for (ic
= 0; ic
< n_ic
; ic
++) {
1025 if (!on_lfe(r
->i_cm
.map
[ic
]))
1028 for (oc
= 0; oc
< n_oc
; oc
++)
1029 m
->map_table_f
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
1033 /* make an 16:16 int version of the matrix */
1034 for (oc
= 0; oc
< n_oc
; oc
++)
1035 for (ic
= 0; ic
< n_ic
; ic
++)
1036 m
->map_table_i
[oc
][ic
] = (int32_t) (m
->map_table_f
[oc
][ic
] * 0x10000);
1038 s
= pa_strbuf_new();
1040 pa_strbuf_printf(s
, " ");
1041 for (ic
= 0; ic
< n_ic
; ic
++)
1042 pa_strbuf_printf(s
, " I%02u ", ic
);
1043 pa_strbuf_puts(s
, "\n +");
1045 for (ic
= 0; ic
< n_ic
; ic
++)
1046 pa_strbuf_printf(s
, "------");
1047 pa_strbuf_puts(s
, "\n");
1049 for (oc
= 0; oc
< n_oc
; oc
++) {
1050 pa_strbuf_printf(s
, "O%02u |", oc
);
1052 for (ic
= 0; ic
< n_ic
; ic
++)
1053 pa_strbuf_printf(s
, " %1.3f", m
->map_table_f
[oc
][ic
]);
1055 pa_strbuf_puts(s
, "\n");
1058 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
1061 /* initialize the remapping function */
1065 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1071 pa_assert(input
->memblock
);
1073 /* Convert the incoming sample into the work sample format and place them
1074 * in to_work_format_buf. */
1076 if (!r
->to_work_format_func
|| !input
->length
)
1079 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1081 r
->to_work_format_buf
.index
= 0;
1082 r
->to_work_format_buf
.length
= r
->w_sz
* n_samples
;
1084 if (!r
->to_work_format_buf
.memblock
|| r
->to_work_format_buf_samples
< n_samples
) {
1085 if (r
->to_work_format_buf
.memblock
)
1086 pa_memblock_unref(r
->to_work_format_buf
.memblock
);
1088 r
->to_work_format_buf_samples
= n_samples
;
1089 r
->to_work_format_buf
.memblock
= pa_memblock_new(r
->mempool
, r
->to_work_format_buf
.length
);
1092 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1093 dst
= (uint8_t*) pa_memblock_acquire(r
->to_work_format_buf
.memblock
);
1095 r
->to_work_format_func(n_samples
, src
, dst
);
1097 pa_memblock_release(input
->memblock
);
1098 pa_memblock_release(r
->to_work_format_buf
.memblock
);
1100 return &r
->to_work_format_buf
;
1103 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1104 unsigned in_n_samples
, out_n_samples
, n_frames
;
1110 pa_assert(input
->memblock
);
1112 /* Remap channels and place the result in remap_buf. */
1114 if (!r
->map_required
|| !input
->length
)
1117 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1118 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1119 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1121 r
->remap_buf
.index
= 0;
1122 r
->remap_buf
.length
= r
->w_sz
* out_n_samples
;
1124 if (!r
->remap_buf
.memblock
|| r
->remap_buf_samples
< out_n_samples
) {
1125 if (r
->remap_buf
.memblock
)
1126 pa_memblock_unref(r
->remap_buf
.memblock
);
1128 r
->remap_buf_samples
= out_n_samples
;
1129 r
->remap_buf
.memblock
= pa_memblock_new(r
->mempool
, r
->remap_buf
.length
);
1132 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1133 dst
= pa_memblock_acquire(r
->remap_buf
.memblock
);
1137 pa_assert(remap
->do_remap
);
1138 remap
->do_remap(remap
, dst
, src
, n_frames
);
1140 pa_memblock_release(input
->memblock
);
1141 pa_memblock_release(r
->remap_buf
.memblock
);
1143 return &r
->remap_buf
;
1146 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1147 unsigned in_n_frames
, in_n_samples
;
1148 unsigned out_n_frames
, out_n_samples
;
1153 /* Resample the data and place the result in resample_buf. */
1155 if (!r
->impl_resample
|| !input
->length
)
1158 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1159 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1161 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1162 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1164 r
->resample_buf
.index
= 0;
1165 r
->resample_buf
.length
= r
->w_sz
* out_n_samples
;
1167 if (!r
->resample_buf
.memblock
|| r
->resample_buf_samples
< out_n_samples
) {
1168 if (r
->resample_buf
.memblock
)
1169 pa_memblock_unref(r
->resample_buf
.memblock
);
1171 r
->resample_buf_samples
= out_n_samples
;
1172 r
->resample_buf
.memblock
= pa_memblock_new(r
->mempool
, r
->resample_buf
.length
);
1175 r
->impl_resample(r
, input
, in_n_frames
, &r
->resample_buf
, &out_n_frames
);
1176 r
->resample_buf
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1178 return &r
->resample_buf
;
1181 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1182 unsigned n_samples
, n_frames
;
1188 /* Convert the data into the correct sample type and place the result in
1189 * from_work_format_buf. */
1191 if (!r
->from_work_format_func
|| !input
->length
)
1194 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1195 n_frames
= n_samples
/ r
->o_ss
.channels
;
1197 r
->from_work_format_buf
.index
= 0;
1198 r
->from_work_format_buf
.length
= r
->o_fz
* n_frames
;
1200 if (!r
->from_work_format_buf
.memblock
|| r
->from_work_format_buf_samples
< n_samples
) {
1201 if (r
->from_work_format_buf
.memblock
)
1202 pa_memblock_unref(r
->from_work_format_buf
.memblock
);
1204 r
->from_work_format_buf_samples
= n_samples
;
1205 r
->from_work_format_buf
.memblock
= pa_memblock_new(r
->mempool
, r
->from_work_format_buf
.length
);
1208 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1209 dst
= pa_memblock_acquire(r
->from_work_format_buf
.memblock
);
1210 r
->from_work_format_func(n_samples
, src
, dst
);
1211 pa_memblock_release(input
->memblock
);
1212 pa_memblock_release(r
->from_work_format_buf
.memblock
);
1214 r
->from_work_format_buf
.length
= r
->o_fz
* n_frames
;
1216 return &r
->from_work_format_buf
;
1219 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1225 pa_assert(in
->length
);
1226 pa_assert(in
->memblock
);
1227 pa_assert(in
->length
% r
->i_fz
== 0);
1229 buf
= (pa_memchunk
*) in
;
1230 buf
= convert_to_work_format(r
, buf
);
1231 buf
= remap_channels(r
, buf
);
1232 buf
= resample(r
, buf
);
1235 buf
= convert_from_work_format(r
, buf
);
1239 pa_memblock_ref(buf
->memblock
);
1241 pa_memchunk_reset(buf
);
1243 pa_memchunk_reset(out
);
1246 /*** libsamplerate based implementation ***/
1248 #ifdef HAVE_LIBSAMPLERATE
1249 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1255 pa_assert(out_n_frames
);
1257 memset(&data
, 0, sizeof(data
));
1259 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1260 data
.input_frames
= (long int) in_n_frames
;
1262 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1263 data
.output_frames
= (long int) *out_n_frames
;
1265 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1266 data
.end_of_input
= 0;
1268 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1269 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1271 pa_memblock_release(input
->memblock
);
1272 pa_memblock_release(output
->memblock
);
1274 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1277 static void libsamplerate_update_rates(pa_resampler
*r
) {
1280 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1283 static void libsamplerate_reset(pa_resampler
*r
) {
1286 pa_assert_se(src_reset(r
->src
.state
) == 0);
1289 static void libsamplerate_free(pa_resampler
*r
) {
1293 src_delete(r
->src
.state
);
1296 static int libsamplerate_init(pa_resampler
*r
) {
1301 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1304 r
->impl_free
= libsamplerate_free
;
1305 r
->impl_update_rates
= libsamplerate_update_rates
;
1306 r
->impl_resample
= libsamplerate_resample
;
1307 r
->impl_reset
= libsamplerate_reset
;
1314 /*** speex based implementation ***/
1316 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1318 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1323 pa_assert(out_n_frames
);
1325 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1326 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1328 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1330 pa_memblock_release(input
->memblock
);
1331 pa_memblock_release(output
->memblock
);
1333 pa_assert(inf
== in_n_frames
);
1334 *out_n_frames
= outf
;
1337 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1339 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1344 pa_assert(out_n_frames
);
1346 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1347 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1349 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1351 pa_memblock_release(input
->memblock
);
1352 pa_memblock_release(output
->memblock
);
1354 pa_assert(inf
== in_n_frames
);
1355 *out_n_frames
= outf
;
1358 static void speex_update_rates(pa_resampler
*r
) {
1361 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1364 static void speex_reset(pa_resampler
*r
) {
1367 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1370 static void speex_free(pa_resampler
*r
) {
1373 if (!r
->speex
.state
)
1376 speex_resampler_destroy(r
->speex
.state
);
1379 static int speex_init(pa_resampler
*r
) {
1384 r
->impl_free
= speex_free
;
1385 r
->impl_update_rates
= speex_update_rates
;
1386 r
->impl_reset
= speex_reset
;
1388 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1390 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1391 r
->impl_resample
= speex_resample_int
;
1394 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1396 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1397 r
->impl_resample
= speex_resample_float
;
1400 pa_log_info("Choosing speex quality setting %i.", q
);
1402 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1409 /* Trivial implementation */
1411 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1413 unsigned i_index
, o_index
;
1419 pa_assert(out_n_frames
);
1421 fz
= r
->w_sz
* r
->o_ss
.channels
;
1423 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1424 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1426 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1427 i_index
= (r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
;
1428 i_index
= i_index
> r
->trivial
.i_counter
? i_index
- r
->trivial
.i_counter
: 0;
1430 if (i_index
>= in_n_frames
)
1433 pa_assert_fp(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1435 memcpy((uint8_t*) dst
+ fz
* o_index
, (uint8_t*) src
+ fz
* i_index
, (int) fz
);
1438 pa_memblock_release(input
->memblock
);
1439 pa_memblock_release(output
->memblock
);
1441 *out_n_frames
= o_index
;
1443 r
->trivial
.i_counter
+= in_n_frames
;
1445 /* Normalize counters */
1446 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1447 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1449 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1450 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1454 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1457 r
->trivial
.i_counter
= 0;
1458 r
->trivial
.o_counter
= 0;
1461 static int trivial_init(pa_resampler
*r
) {
1464 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1466 r
->impl_resample
= trivial_resample
;
1467 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1468 r
->impl_reset
= trivial_update_rates_or_reset
;
1473 /* Peak finder implementation */
1475 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1476 unsigned c
, o_index
= 0;
1477 unsigned i
, i_end
= 0;
1483 pa_assert(out_n_frames
);
1485 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1486 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1488 i
= (r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
;
1489 i
= i
> r
->peaks
.i_counter
? i
- r
->peaks
.i_counter
: 0;
1491 while (i_end
< in_n_frames
) {
1492 i_end
= ((r
->peaks
.o_counter
+1) * r
->i_ss
.rate
) / r
->o_ss
.rate
;
1493 i_end
= i_end
> r
->peaks
.i_counter
? i_end
- r
->peaks
.i_counter
: 0;
1495 pa_assert_fp(o_index
* r
->w_sz
* r
->o_ss
.channels
< pa_memblock_get_length(output
->memblock
));
1497 /* 1ch float is treated separately, because that is the common case */
1498 if (r
->o_ss
.channels
== 1 && r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
1499 float *s
= (float*) src
+ i
;
1500 float *d
= (float*) dst
+ o_index
;
1502 for (; i
< i_end
&& i
< in_n_frames
; i
++) {
1503 float n
= fabsf(*s
++);
1505 if (n
> r
->peaks
.max_f
[0])
1506 r
->peaks
.max_f
[0] = n
;
1510 *d
= r
->peaks
.max_f
[0];
1511 r
->peaks
.max_f
[0] = 0;
1512 o_index
++, r
->peaks
.o_counter
++;
1514 } else if (r
->work_format
== PA_SAMPLE_S16NE
) {
1515 int16_t *s
= (int16_t*) src
+ r
->i_ss
.channels
* i
;
1516 int16_t *d
= (int16_t*) dst
+ r
->o_ss
.channels
* o_index
;
1518 for (; i
< i_end
&& i
< in_n_frames
; i
++)
1519 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1520 int16_t n
= abs(*s
++);
1522 if (n
> r
->peaks
.max_i
[c
])
1523 r
->peaks
.max_i
[c
] = n
;
1527 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1528 *d
= r
->peaks
.max_i
[c
];
1529 r
->peaks
.max_i
[c
] = 0;
1531 o_index
++, r
->peaks
.o_counter
++;
1534 float *s
= (float*) src
+ r
->i_ss
.channels
* i
;
1535 float *d
= (float*) dst
+ r
->o_ss
.channels
* o_index
;
1537 for (; i
< i_end
&& i
< in_n_frames
; i
++)
1538 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1539 float n
= fabsf(*s
++);
1541 if (n
> r
->peaks
.max_f
[c
])
1542 r
->peaks
.max_f
[c
] = n
;
1546 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1547 *d
= r
->peaks
.max_f
[c
];
1548 r
->peaks
.max_f
[c
] = 0;
1550 o_index
++, r
->peaks
.o_counter
++;
1555 pa_memblock_release(input
->memblock
);
1556 pa_memblock_release(output
->memblock
);
1558 *out_n_frames
= o_index
;
1560 r
->peaks
.i_counter
+= in_n_frames
;
1562 /* Normalize counters */
1563 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1564 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1566 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1567 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1571 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1574 r
->peaks
.i_counter
= 0;
1575 r
->peaks
.o_counter
= 0;
1578 static int peaks_init(pa_resampler
*r
) {
1580 pa_assert(r
->i_ss
.rate
>= r
->o_ss
.rate
);
1581 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
|| r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1583 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1584 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1585 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1587 r
->impl_resample
= peaks_resample
;
1588 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1589 r
->impl_reset
= peaks_update_rates_or_reset
;
1594 /*** ffmpeg based implementation ***/
1596 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1597 unsigned used_frames
= 0, c
;
1602 pa_assert(out_n_frames
);
1604 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1607 int16_t *p
, *t
, *k
, *q
, *s
;
1608 int consumed_frames
;
1611 /* Allocate a new block */
1612 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1613 p
= pa_memblock_acquire(b
);
1615 /* Copy the remaining data into it */
1616 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1617 if (r
->ffmpeg
.buf
[c
].memblock
) {
1618 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1620 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1621 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1622 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1625 /* Now append the new data, splitting up channels */
1626 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1627 k
= (int16_t*) ((uint8_t*) p
+ l
);
1628 for (u
= 0; u
< in_n_frames
; u
++) {
1630 t
+= r
->o_ss
.channels
;
1633 pa_memblock_release(input
->memblock
);
1635 /* Calculate the resulting number of frames */
1636 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1638 /* Allocate buffer for the result */
1639 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1640 q
= pa_memblock_acquire(w
);
1643 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1646 (int) in
, (int) *out_n_frames
,
1647 c
>= (unsigned) (r
->o_ss
.channels
-1));
1649 pa_memblock_release(b
);
1651 /* Now store the remaining samples away */
1652 pa_assert(consumed_frames
<= (int) in
);
1653 if (consumed_frames
< (int) in
) {
1654 r
->ffmpeg
.buf
[c
].memblock
= b
;
1655 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1656 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1658 pa_memblock_unref(b
);
1660 /* And place the results in the output buffer */
1661 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1662 for (u
= 0; u
< used_frames
; u
++) {
1665 s
+= r
->o_ss
.channels
;
1667 pa_memblock_release(output
->memblock
);
1668 pa_memblock_release(w
);
1669 pa_memblock_unref(w
);
1672 *out_n_frames
= used_frames
;
1675 static void ffmpeg_free(pa_resampler
*r
) {
1680 if (r
->ffmpeg
.state
)
1681 av_resample_close(r
->ffmpeg
.state
);
1683 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1684 if (r
->ffmpeg
.buf
[c
].memblock
)
1685 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1688 static int ffmpeg_init(pa_resampler
*r
) {
1693 /* We could probably implement different quality levels by
1694 * adjusting the filter parameters here. However, ffmpeg
1695 * internally only uses these hardcoded values, so let's use them
1696 * here for now as well until ffmpeg makes this configurable. */
1698 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1701 r
->impl_free
= ffmpeg_free
;
1702 r
->impl_resample
= ffmpeg_resample
;
1704 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1705 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1710 /*** copy (noop) implementation ***/
1712 static int copy_init(pa_resampler
*r
) {
1715 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);