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 buf1
, buf2
, buf3
, buf4
;
60 unsigned buf1_samples
, buf2_samples
, buf3_samples
, buf4_samples
;
62 pa_sample_format_t work_format
;
64 pa_convert_func_t to_work_format_func
;
65 pa_convert_func_t from_work_format_func
;
68 pa_bool_t map_required
;
70 void (*impl_free
)(pa_resampler
*r
);
71 void (*impl_update_rates
)(pa_resampler
*r
);
72 void (*impl_resample
)(pa_resampler
*r
, const pa_memchunk
*in
, unsigned in_samples
, pa_memchunk
*out
, unsigned *out_samples
);
73 void (*impl_reset
)(pa_resampler
*r
);
75 struct { /* data specific to the trivial resampler */
80 struct { /* data specific to the peak finder pseudo resampler */
84 float max_f
[PA_CHANNELS_MAX
];
85 int16_t max_i
[PA_CHANNELS_MAX
];
89 #ifdef HAVE_LIBSAMPLERATE
90 struct { /* data specific to libsamplerate */
96 struct { /* data specific to speex */
97 SpeexResamplerState
* state
;
101 struct { /* data specific to ffmpeg */
102 struct AVResampleContext
*state
;
103 pa_memchunk buf
[PA_CHANNELS_MAX
];
107 static int copy_init(pa_resampler
*r
);
108 static int trivial_init(pa_resampler
*r
);
110 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
,
136 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+0] = speex_init
,
137 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+1] = speex_init
,
138 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+2] = speex_init
,
139 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+3] = speex_init
,
140 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+4] = speex_init
,
141 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+5] = speex_init
,
142 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+6] = speex_init
,
143 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+7] = speex_init
,
144 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+8] = speex_init
,
145 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+9] = speex_init
,
146 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+10] = speex_init
,
147 [PA_RESAMPLER_SPEEX_FIXED_BASE
+0] = speex_init
,
148 [PA_RESAMPLER_SPEEX_FIXED_BASE
+1] = speex_init
,
149 [PA_RESAMPLER_SPEEX_FIXED_BASE
+2] = speex_init
,
150 [PA_RESAMPLER_SPEEX_FIXED_BASE
+3] = speex_init
,
151 [PA_RESAMPLER_SPEEX_FIXED_BASE
+4] = speex_init
,
152 [PA_RESAMPLER_SPEEX_FIXED_BASE
+5] = speex_init
,
153 [PA_RESAMPLER_SPEEX_FIXED_BASE
+6] = speex_init
,
154 [PA_RESAMPLER_SPEEX_FIXED_BASE
+7] = speex_init
,
155 [PA_RESAMPLER_SPEEX_FIXED_BASE
+8] = speex_init
,
156 [PA_RESAMPLER_SPEEX_FIXED_BASE
+9] = speex_init
,
157 [PA_RESAMPLER_SPEEX_FIXED_BASE
+10] = speex_init
,
159 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+0] = NULL
,
160 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+1] = NULL
,
161 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+2] = NULL
,
162 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+3] = NULL
,
163 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+4] = NULL
,
164 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+5] = NULL
,
165 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+6] = NULL
,
166 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+7] = NULL
,
167 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+8] = NULL
,
168 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+9] = NULL
,
169 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+10] = NULL
,
170 [PA_RESAMPLER_SPEEX_FIXED_BASE
+0] = NULL
,
171 [PA_RESAMPLER_SPEEX_FIXED_BASE
+1] = NULL
,
172 [PA_RESAMPLER_SPEEX_FIXED_BASE
+2] = NULL
,
173 [PA_RESAMPLER_SPEEX_FIXED_BASE
+3] = NULL
,
174 [PA_RESAMPLER_SPEEX_FIXED_BASE
+4] = NULL
,
175 [PA_RESAMPLER_SPEEX_FIXED_BASE
+5] = NULL
,
176 [PA_RESAMPLER_SPEEX_FIXED_BASE
+6] = NULL
,
177 [PA_RESAMPLER_SPEEX_FIXED_BASE
+7] = NULL
,
178 [PA_RESAMPLER_SPEEX_FIXED_BASE
+8] = NULL
,
179 [PA_RESAMPLER_SPEEX_FIXED_BASE
+9] = NULL
,
180 [PA_RESAMPLER_SPEEX_FIXED_BASE
+10] = NULL
,
182 [PA_RESAMPLER_FFMPEG
] = ffmpeg_init
,
183 [PA_RESAMPLER_AUTO
] = NULL
,
184 [PA_RESAMPLER_COPY
] = copy_init
,
185 [PA_RESAMPLER_PEAKS
] = peaks_init
,
188 pa_resampler
* pa_resampler_new(
190 const pa_sample_spec
*a
,
191 const pa_channel_map
*am
,
192 const pa_sample_spec
*b
,
193 const pa_channel_map
*bm
,
194 pa_resample_method_t method
,
195 pa_resample_flags_t flags
) {
197 pa_resampler
*r
= NULL
;
202 pa_assert(pa_sample_spec_valid(a
));
203 pa_assert(pa_sample_spec_valid(b
));
204 pa_assert(method
>= 0);
205 pa_assert(method
< PA_RESAMPLER_MAX
);
209 if (!(flags
& PA_RESAMPLER_VARIABLE_RATE
) && a
->rate
== b
->rate
) {
210 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
211 method
= PA_RESAMPLER_COPY
;
214 if (!pa_resample_method_supported(method
)) {
215 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method
));
216 method
= PA_RESAMPLER_AUTO
;
219 if (method
== PA_RESAMPLER_FFMPEG
&& (flags
& PA_RESAMPLER_VARIABLE_RATE
)) {
220 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
221 method
= PA_RESAMPLER_AUTO
;
224 if (method
== PA_RESAMPLER_COPY
&& ((flags
& PA_RESAMPLER_VARIABLE_RATE
) || a
->rate
!= b
->rate
)) {
225 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
226 method
= PA_RESAMPLER_AUTO
;
229 if (method
== PA_RESAMPLER_AUTO
) {
231 method
= PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
233 method
= PA_RESAMPLER_FFMPEG
;
237 r
= pa_xnew0(pa_resampler
, 1);
242 /* Fill sample specs */
246 /* set up the remap structure */
247 r
->remap
.i_ss
= &r
->i_ss
;
248 r
->remap
.o_ss
= &r
->o_ss
;
249 r
->remap
.format
= &r
->work_format
;
253 else if (!pa_channel_map_init_auto(&r
->i_cm
, r
->i_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
258 else if (!pa_channel_map_init_auto(&r
->o_cm
, r
->o_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
261 r
->i_fz
= pa_frame_size(a
);
262 r
->o_fz
= pa_frame_size(b
);
266 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method
));
268 if ((method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) ||
269 (method
== PA_RESAMPLER_FFMPEG
))
270 r
->work_format
= PA_SAMPLE_S16NE
;
271 else if (method
== PA_RESAMPLER_TRIVIAL
|| method
== PA_RESAMPLER_COPY
|| method
== PA_RESAMPLER_PEAKS
) {
273 if (r
->map_required
|| a
->format
!= b
->format
|| method
== PA_RESAMPLER_PEAKS
) {
275 if (a
->format
== PA_SAMPLE_S32NE
|| a
->format
== PA_SAMPLE_S32RE
||
276 a
->format
== PA_SAMPLE_FLOAT32NE
|| a
->format
== PA_SAMPLE_FLOAT32RE
||
277 a
->format
== PA_SAMPLE_S24NE
|| a
->format
== PA_SAMPLE_S24RE
||
278 a
->format
== PA_SAMPLE_S24_32NE
|| a
->format
== PA_SAMPLE_S24_32RE
||
279 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
280 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
||
281 b
->format
== PA_SAMPLE_S24NE
|| b
->format
== PA_SAMPLE_S24RE
||
282 b
->format
== PA_SAMPLE_S24_32NE
|| b
->format
== PA_SAMPLE_S24_32RE
)
283 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
285 r
->work_format
= PA_SAMPLE_S16NE
;
288 r
->work_format
= a
->format
;
291 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
293 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
295 r
->w_sz
= pa_sample_size_of_format(r
->work_format
);
297 if (r
->i_ss
.format
!= r
->work_format
) {
298 if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
299 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
302 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
303 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
308 if (r
->o_ss
.format
!= r
->work_format
) {
309 if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
310 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
313 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
314 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
319 /* initialize implementation */
320 if (init_table
[method
](r
) < 0)
331 void pa_resampler_free(pa_resampler
*r
) {
337 if (r
->buf1
.memblock
)
338 pa_memblock_unref(r
->buf1
.memblock
);
339 if (r
->buf2
.memblock
)
340 pa_memblock_unref(r
->buf2
.memblock
);
341 if (r
->buf3
.memblock
)
342 pa_memblock_unref(r
->buf3
.memblock
);
343 if (r
->buf4
.memblock
)
344 pa_memblock_unref(r
->buf4
.memblock
);
349 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
353 if (r
->i_ss
.rate
== rate
)
358 r
->impl_update_rates(r
);
361 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
365 if (r
->o_ss
.rate
== rate
)
370 r
->impl_update_rates(r
);
373 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
376 /* Let's round up here */
378 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
;
381 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
384 /* Let's round up here */
386 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
;
389 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
390 size_t block_size_max
;
396 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
398 /* We deduce the "largest" sample spec we're using during the
400 ss
.channels
= (uint8_t) (PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
));
402 /* We silently assume that the format enum is ordered by size */
403 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
404 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
406 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
408 fs
= pa_frame_size(&ss
);
410 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
413 void pa_resampler_reset(pa_resampler
*r
) {
420 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
426 const pa_channel_map
* pa_resampler_input_channel_map(pa_resampler
*r
) {
432 const pa_sample_spec
* pa_resampler_input_sample_spec(pa_resampler
*r
) {
438 const pa_channel_map
* pa_resampler_output_channel_map(pa_resampler
*r
) {
444 const pa_sample_spec
* pa_resampler_output_sample_spec(pa_resampler
*r
) {
450 static const char * const resample_methods
[] = {
451 "src-sinc-best-quality",
452 "src-sinc-medium-quality",
454 "src-zero-order-hold",
485 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
487 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
490 return resample_methods
[m
];
493 int pa_resample_method_supported(pa_resample_method_t m
) {
495 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
498 #ifndef HAVE_LIBSAMPLERATE
499 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
504 if (m
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& m
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
)
506 if (m
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& m
<= PA_RESAMPLER_SPEEX_FIXED_MAX
)
513 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
514 pa_resample_method_t m
;
518 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
519 if (!strcmp(string
, resample_methods
[m
]))
522 if (!strcmp(string
, "speex-fixed"))
523 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
525 if (!strcmp(string
, "speex-float"))
526 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
528 return PA_RESAMPLER_INVALID
;
531 static pa_bool_t
on_left(pa_channel_position_t p
) {
534 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
535 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
536 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
537 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
538 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
539 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
542 static pa_bool_t
on_right(pa_channel_position_t p
) {
545 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
546 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
547 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
548 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
549 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
550 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
553 static pa_bool_t
on_center(pa_channel_position_t p
) {
556 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
557 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
558 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
559 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
560 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
563 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
565 p
== PA_CHANNEL_POSITION_LFE
;
568 static pa_bool_t
on_front(pa_channel_position_t p
) {
570 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
571 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
572 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
573 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
574 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
575 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
576 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
577 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
580 static pa_bool_t
on_rear(pa_channel_position_t p
) {
582 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
583 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
584 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
585 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
586 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
587 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
590 static pa_bool_t
on_side(pa_channel_position_t p
) {
592 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
593 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
594 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
604 static int front_rear_side(pa_channel_position_t p
) {
614 static void calc_map_table(pa_resampler
*r
) {
617 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
625 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
)))))
630 n_oc
= r
->o_ss
.channels
;
631 n_ic
= r
->i_ss
.channels
;
633 memset(m
->map_table_f
, 0, sizeof(m
->map_table_f
));
634 memset(m
->map_table_i
, 0, sizeof(m
->map_table_i
));
636 memset(ic_connected
, 0, sizeof(ic_connected
));
637 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
639 for (oc
= 0; oc
< n_oc
; oc
++) {
640 pa_bool_t oc_connected
= FALSE
;
641 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
643 for (ic
= 0; ic
< n_ic
; ic
++) {
644 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
646 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
647 /* We shall not do any remapping. Hence, just check by index */
650 m
->map_table_f
[oc
][ic
] = 1.0;
655 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
656 /* We shall not do any remixing. Hence, just check by name */
659 m
->map_table_f
[oc
][ic
] = 1.0;
666 /* OK, we shall do the full monty: upmixing and
667 * downmixing. Our algorithm is relatively simple, does
668 * not do spacialization, delay elements or apply lowpass
669 * filters for LFE. Patches are always welcome,
670 * though. Oh, and it doesn't do any matrix
671 * decoding. (Which probably wouldn't make any sense
674 * This code is not idempotent: downmixing an upmixed
675 * stereo stream is not identical to the original. The
676 * volume will not match, and the two channels will be a
677 * linear combination of both.
679 * This is loosely based on random suggestions found on the
680 * Internet, such as this:
681 * http://www.halfgaar.net/surround-sound-in-linux and the
684 * The algorithm works basically like this:
686 * 1) Connect all channels with matching names.
689 * S:Mono: Copy into all D:channels
690 * D:Mono: Copy in all S:channels
692 * 3) Mix D:Left, D:Right:
693 * D:Left: If not connected, avg all S:Left
694 * D:Right: If not connected, avg all S:Right
697 * If not connected, avg all S:Center
698 * If still not connected, avg all S:Left, S:Right
701 * If not connected, avg all S:*
703 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
704 * not connected, mix into all D:left and all D:right
705 * channels. Gain is 0.1, the current left and right
706 * should be multiplied by 0.9.
708 * 7) Make sure S:Center, S:LFE is used:
710 * S:Center, S:LFE: If not connected, mix into all
711 * D:left, all D:right, all D:center channels, gain is
712 * 0.375. The current (as result of 1..6) factors
713 * should be multiplied by 0.75. (Alt. suggestion: 0.25
714 * vs. 0.5) If C-front is only mixed into
715 * L-front/R-front if available, otherwise into all L/R
716 * channels. Similarly for C-rear.
718 * S: and D: shall relate to the source resp. destination channels.
720 * Rationale: 1, 2 are probably obvious. For 3: this
721 * copies front to rear if needed. For 4: we try to find
722 * some suitable C source for C, if we don't find any, we
723 * avg L and R. For 5: LFE is mixed from all channels. For
724 * 6: the rear channels should not be dropped entirely,
725 * however have only minimal impact. For 7: movies usually
726 * encode speech on the center channel. Thus we have to
727 * make sure this channel is distributed to L and R if not
728 * available in the output. Also, LFE is used to achieve a
729 * greater dynamic range, and thus we should try to do our
730 * best to pass it to L+R.
733 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
734 m
->map_table_f
[oc
][ic
] = 1.0;
737 ic_connected
[ic
] = TRUE
;
741 if (!oc_connected
&& remix
) {
742 /* OK, we shall remix */
744 /* Try to find matching input ports for this output port */
749 /* We are not connected and on the left side, let's
750 * average all left side input channels. */
752 for (ic
= 0; ic
< n_ic
; ic
++)
753 if (on_left(r
->i_cm
.map
[ic
]))
757 for (ic
= 0; ic
< n_ic
; ic
++)
758 if (on_left(r
->i_cm
.map
[ic
])) {
759 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
760 ic_connected
[ic
] = TRUE
;
763 /* We ignore the case where there is no left input
764 * channel. Something is really wrong in this case
767 } else if (on_right(b
)) {
770 /* We are not connected and on the right side, let's
771 * average all right side input channels. */
773 for (ic
= 0; ic
< n_ic
; ic
++)
774 if (on_right(r
->i_cm
.map
[ic
]))
778 for (ic
= 0; ic
< n_ic
; ic
++)
779 if (on_right(r
->i_cm
.map
[ic
])) {
780 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
781 ic_connected
[ic
] = TRUE
;
784 /* We ignore the case where there is no right input
785 * channel. Something is really wrong in this case
788 } else if (on_center(b
)) {
791 /* We are not connected and at the center. Let's
792 * average all center input channels. */
794 for (ic
= 0; ic
< n_ic
; ic
++)
795 if (on_center(r
->i_cm
.map
[ic
]))
799 for (ic
= 0; ic
< n_ic
; ic
++)
800 if (on_center(r
->i_cm
.map
[ic
])) {
801 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
802 ic_connected
[ic
] = TRUE
;
806 /* Hmm, no center channel around, let's synthesize
807 * it by mixing L and R.*/
811 for (ic
= 0; ic
< n_ic
; ic
++)
812 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
816 for (ic
= 0; ic
< n_ic
; ic
++)
817 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
818 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
819 ic_connected
[ic
] = TRUE
;
822 /* We ignore the case where there is not even a
823 * left or right input channel. Something is
824 * really wrong in this case anyway. */
827 } else if (on_lfe(b
)) {
829 /* We are not connected and an LFE. Let's average all
830 * channels for LFE. */
832 for (ic
= 0; ic
< n_ic
; ic
++) {
834 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
835 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n_ic
;
837 m
->map_table_f
[oc
][ic
] = 0;
839 /* Please note that a channel connected to LFE
840 * doesn't really count as connected. */
848 ic_unconnected_left
= 0,
849 ic_unconnected_right
= 0,
850 ic_unconnected_center
= 0,
851 ic_unconnected_lfe
= 0;
853 for (ic
= 0; ic
< n_ic
; ic
++) {
854 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
856 if (ic_connected
[ic
])
860 ic_unconnected_left
++;
861 else if (on_right(a
))
862 ic_unconnected_right
++;
863 else if (on_center(a
))
864 ic_unconnected_center
++;
866 ic_unconnected_lfe
++;
869 if (ic_unconnected_left
> 0) {
871 /* OK, so there are unconnected input channels on the
872 * left. Let's multiply all already connected channels on
873 * the left side by .9 and add in our averaged unconnected
874 * channels multiplied by .1 */
876 for (oc
= 0; oc
< n_oc
; oc
++) {
878 if (!on_left(r
->o_cm
.map
[oc
]))
881 for (ic
= 0; ic
< n_ic
; ic
++) {
883 if (ic_connected
[ic
]) {
884 m
->map_table_f
[oc
][ic
] *= .9f
;
888 if (on_left(r
->i_cm
.map
[ic
]))
889 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
894 if (ic_unconnected_right
> 0) {
896 /* OK, so there are unconnected input channels on the
897 * right. Let's multiply all already connected channels on
898 * the right side by .9 and add in our averaged unconnected
899 * channels multiplied by .1 */
901 for (oc
= 0; oc
< n_oc
; oc
++) {
903 if (!on_right(r
->o_cm
.map
[oc
]))
906 for (ic
= 0; ic
< n_ic
; ic
++) {
908 if (ic_connected
[ic
]) {
909 m
->map_table_f
[oc
][ic
] *= .9f
;
913 if (on_right(r
->i_cm
.map
[ic
]))
914 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
919 if (ic_unconnected_center
> 0) {
920 pa_bool_t mixed_in
= FALSE
;
922 /* OK, so there are unconnected input channels on the
923 * center. Let's multiply all already connected channels on
924 * the center side by .9 and add in our averaged unconnected
925 * channels multiplied by .1 */
927 for (oc
= 0; oc
< n_oc
; oc
++) {
929 if (!on_center(r
->o_cm
.map
[oc
]))
932 for (ic
= 0; ic
< n_ic
; ic
++) {
934 if (ic_connected
[ic
]) {
935 m
->map_table_f
[oc
][ic
] *= .9f
;
939 if (on_center(r
->i_cm
.map
[ic
])) {
940 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
947 unsigned ncenter
[PA_CHANNELS_MAX
];
948 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
950 memset(ncenter
, 0, sizeof(ncenter
));
951 memset(found_frs
, 0, sizeof(found_frs
));
953 /* Hmm, as it appears there was no center channel we
954 could mix our center channel in. In this case, mix
955 it into left and right. Using .375 and 0.75 as
958 for (ic
= 0; ic
< n_ic
; ic
++) {
960 if (ic_connected
[ic
])
963 if (!on_center(r
->i_cm
.map
[ic
]))
966 for (oc
= 0; oc
< n_oc
; oc
++) {
968 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
971 if (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
972 found_frs
[ic
] = TRUE
;
977 for (oc
= 0; oc
< n_oc
; oc
++) {
979 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
982 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
987 for (oc
= 0; oc
< n_oc
; oc
++) {
989 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
992 if (ncenter
[oc
] <= 0)
995 for (ic
= 0; ic
< n_ic
; ic
++) {
997 if (ic_connected
[ic
]) {
998 m
->map_table_f
[oc
][ic
] *= .75f
;
1002 if (!on_center(r
->i_cm
.map
[ic
]))
1005 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
1006 m
->map_table_f
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
1012 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
1014 /* OK, so there is an unconnected LFE channel. Let's mix
1015 * it into all channels, with factor 0.375 */
1017 for (ic
= 0; ic
< n_ic
; ic
++) {
1019 if (!on_lfe(r
->i_cm
.map
[ic
]))
1022 for (oc
= 0; oc
< n_oc
; oc
++)
1023 m
->map_table_f
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
1027 /* make an 16:16 int version of the matrix */
1028 for (oc
= 0; oc
< n_oc
; oc
++)
1029 for (ic
= 0; ic
< n_ic
; ic
++)
1030 m
->map_table_i
[oc
][ic
] = (int32_t) (m
->map_table_f
[oc
][ic
] * 0x10000);
1032 s
= pa_strbuf_new();
1034 pa_strbuf_printf(s
, " ");
1035 for (ic
= 0; ic
< n_ic
; ic
++)
1036 pa_strbuf_printf(s
, " I%02u ", ic
);
1037 pa_strbuf_puts(s
, "\n +");
1039 for (ic
= 0; ic
< n_ic
; ic
++)
1040 pa_strbuf_printf(s
, "------");
1041 pa_strbuf_puts(s
, "\n");
1043 for (oc
= 0; oc
< n_oc
; oc
++) {
1044 pa_strbuf_printf(s
, "O%02u |", oc
);
1046 for (ic
= 0; ic
< n_ic
; ic
++)
1047 pa_strbuf_printf(s
, " %1.3f", m
->map_table_f
[oc
][ic
]);
1049 pa_strbuf_puts(s
, "\n");
1052 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
1055 /* initialize the remapping function */
1059 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1065 pa_assert(input
->memblock
);
1067 /* Convert the incoming sample into the work sample format and place them in buf1 */
1069 if (!r
->to_work_format_func
|| !input
->length
)
1072 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1075 r
->buf1
.length
= r
->w_sz
* n_samples
;
1077 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
1078 if (r
->buf1
.memblock
)
1079 pa_memblock_unref(r
->buf1
.memblock
);
1081 r
->buf1_samples
= n_samples
;
1082 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
1085 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1086 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
1088 r
->to_work_format_func(n_samples
, src
, dst
);
1090 pa_memblock_release(input
->memblock
);
1091 pa_memblock_release(r
->buf1
.memblock
);
1096 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1097 unsigned in_n_samples
, out_n_samples
, n_frames
;
1103 pa_assert(input
->memblock
);
1105 /* Remap channels and place the result int buf2 */
1107 if (!r
->map_required
|| !input
->length
)
1110 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1111 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1112 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1115 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
1117 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
1118 if (r
->buf2
.memblock
)
1119 pa_memblock_unref(r
->buf2
.memblock
);
1121 r
->buf2_samples
= out_n_samples
;
1122 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
1125 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1126 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
1130 pa_assert(remap
->do_remap
);
1131 remap
->do_remap(remap
, dst
, src
, n_frames
);
1133 pa_memblock_release(input
->memblock
);
1134 pa_memblock_release(r
->buf2
.memblock
);
1139 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1140 unsigned in_n_frames
, in_n_samples
;
1141 unsigned out_n_frames
, out_n_samples
;
1146 /* Resample the data and place the result in buf3 */
1148 if (!r
->impl_resample
|| !input
->length
)
1151 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1152 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1154 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1155 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1158 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1160 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1161 if (r
->buf3
.memblock
)
1162 pa_memblock_unref(r
->buf3
.memblock
);
1164 r
->buf3_samples
= out_n_samples
;
1165 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1168 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1169 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1174 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1175 unsigned n_samples
, n_frames
;
1181 /* Convert the data into the correct sample type and place the result in buf4 */
1183 if (!r
->from_work_format_func
|| !input
->length
)
1186 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1187 n_frames
= n_samples
/ r
->o_ss
.channels
;
1190 r
->buf4
.length
= r
->o_fz
* n_frames
;
1192 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1193 if (r
->buf4
.memblock
)
1194 pa_memblock_unref(r
->buf4
.memblock
);
1196 r
->buf4_samples
= n_samples
;
1197 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1200 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1201 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1202 r
->from_work_format_func(n_samples
, src
, dst
);
1203 pa_memblock_release(input
->memblock
);
1204 pa_memblock_release(r
->buf4
.memblock
);
1206 r
->buf4
.length
= r
->o_fz
* n_frames
;
1211 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1217 pa_assert(in
->length
);
1218 pa_assert(in
->memblock
);
1219 pa_assert(in
->length
% r
->i_fz
== 0);
1221 buf
= (pa_memchunk
*) in
;
1222 buf
= convert_to_work_format(r
, buf
);
1223 buf
= remap_channels(r
, buf
);
1224 buf
= resample(r
, buf
);
1227 buf
= convert_from_work_format(r
, buf
);
1231 pa_memblock_ref(buf
->memblock
);
1233 pa_memchunk_reset(buf
);
1235 pa_memchunk_reset(out
);
1238 /*** libsamplerate based implementation ***/
1240 #ifdef HAVE_LIBSAMPLERATE
1241 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1247 pa_assert(out_n_frames
);
1249 memset(&data
, 0, sizeof(data
));
1251 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1252 data
.input_frames
= (long int) in_n_frames
;
1254 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1255 data
.output_frames
= (long int) *out_n_frames
;
1257 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1258 data
.end_of_input
= 0;
1260 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1261 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1263 pa_memblock_release(input
->memblock
);
1264 pa_memblock_release(output
->memblock
);
1266 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1269 static void libsamplerate_update_rates(pa_resampler
*r
) {
1272 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1275 static void libsamplerate_reset(pa_resampler
*r
) {
1278 pa_assert_se(src_reset(r
->src
.state
) == 0);
1281 static void libsamplerate_free(pa_resampler
*r
) {
1285 src_delete(r
->src
.state
);
1288 static int libsamplerate_init(pa_resampler
*r
) {
1293 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1296 r
->impl_free
= libsamplerate_free
;
1297 r
->impl_update_rates
= libsamplerate_update_rates
;
1298 r
->impl_resample
= libsamplerate_resample
;
1299 r
->impl_reset
= libsamplerate_reset
;
1306 /*** speex based implementation ***/
1308 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1310 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1315 pa_assert(out_n_frames
);
1317 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1318 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1320 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1322 pa_memblock_release(input
->memblock
);
1323 pa_memblock_release(output
->memblock
);
1325 pa_assert(inf
== in_n_frames
);
1326 *out_n_frames
= outf
;
1329 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1331 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1336 pa_assert(out_n_frames
);
1338 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1339 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1341 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1343 pa_memblock_release(input
->memblock
);
1344 pa_memblock_release(output
->memblock
);
1346 pa_assert(inf
== in_n_frames
);
1347 *out_n_frames
= outf
;
1350 static void speex_update_rates(pa_resampler
*r
) {
1353 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1356 static void speex_reset(pa_resampler
*r
) {
1359 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1362 static void speex_free(pa_resampler
*r
) {
1365 if (!r
->speex
.state
)
1368 speex_resampler_destroy(r
->speex
.state
);
1371 static int speex_init(pa_resampler
*r
) {
1376 r
->impl_free
= speex_free
;
1377 r
->impl_update_rates
= speex_update_rates
;
1378 r
->impl_reset
= speex_reset
;
1380 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1382 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1383 r
->impl_resample
= speex_resample_int
;
1386 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1388 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1389 r
->impl_resample
= speex_resample_float
;
1392 pa_log_info("Choosing speex quality setting %i.", q
);
1394 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1401 /* Trivial implementation */
1403 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1405 unsigned i_index
, o_index
;
1411 pa_assert(out_n_frames
);
1413 fz
= r
->w_sz
* r
->o_ss
.channels
;
1415 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1416 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1418 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1419 i_index
= (r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
;
1420 i_index
= i_index
> r
->trivial
.i_counter
? i_index
- r
->trivial
.i_counter
: 0;
1422 if (i_index
>= in_n_frames
)
1425 pa_assert_fp(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1427 memcpy((uint8_t*) dst
+ fz
* o_index
, (uint8_t*) src
+ fz
* i_index
, (int) fz
);
1430 pa_memblock_release(input
->memblock
);
1431 pa_memblock_release(output
->memblock
);
1433 *out_n_frames
= o_index
;
1435 r
->trivial
.i_counter
+= in_n_frames
;
1437 /* Normalize counters */
1438 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1439 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1441 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1442 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1446 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1449 r
->trivial
.i_counter
= 0;
1450 r
->trivial
.o_counter
= 0;
1453 static int trivial_init(pa_resampler
*r
) {
1456 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1458 r
->impl_resample
= trivial_resample
;
1459 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1460 r
->impl_reset
= trivial_update_rates_or_reset
;
1465 /* Peak finder implementation */
1467 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1468 unsigned c
, o_index
= 0;
1469 unsigned i
, i_end
= 0;
1475 pa_assert(out_n_frames
);
1477 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1478 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1480 i
= (r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
;
1481 i
= i
> r
->peaks
.i_counter
? i
- r
->peaks
.i_counter
: 0;
1483 while (i_end
< in_n_frames
) {
1484 i_end
= ((r
->peaks
.o_counter
+1) * r
->i_ss
.rate
) / r
->o_ss
.rate
;
1485 i_end
= i_end
> r
->peaks
.i_counter
? i_end
- r
->peaks
.i_counter
: 0;
1487 pa_assert_fp(o_index
* r
->w_sz
* r
->o_ss
.channels
< pa_memblock_get_length(output
->memblock
));
1489 /* 1ch float is treated separately, because that is the common case */
1490 if (r
->o_ss
.channels
== 1 && r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
1491 float *s
= (float*) src
+ i
;
1492 float *d
= (float*) dst
+ o_index
;
1494 for (; i
< i_end
&& i
< in_n_frames
; i
++) {
1495 float n
= fabsf(*s
++);
1497 if (n
> r
->peaks
.max_f
[0])
1498 r
->peaks
.max_f
[0] = n
;
1502 *d
= r
->peaks
.max_f
[0];
1503 r
->peaks
.max_f
[0] = 0;
1504 o_index
++, r
->peaks
.o_counter
++;
1506 } else if (r
->work_format
== PA_SAMPLE_S16NE
) {
1507 int16_t *s
= (int16_t*) src
+ r
->i_ss
.channels
* i
;
1508 int16_t *d
= (int16_t*) dst
+ r
->o_ss
.channels
* o_index
;
1510 for (; i
< i_end
&& i
< in_n_frames
; i
++)
1511 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1512 int16_t n
= abs(*s
++);
1514 if (n
> r
->peaks
.max_i
[c
])
1515 r
->peaks
.max_i
[c
] = n
;
1519 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1520 *d
= r
->peaks
.max_i
[c
];
1521 r
->peaks
.max_i
[c
] = 0;
1523 o_index
++, r
->peaks
.o_counter
++;
1526 float *s
= (float*) src
+ r
->i_ss
.channels
* i
;
1527 float *d
= (float*) dst
+ r
->o_ss
.channels
* o_index
;
1529 for (; i
< i_end
&& i
< in_n_frames
; i
++)
1530 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1531 float n
= fabsf(*s
++);
1533 if (n
> r
->peaks
.max_f
[c
])
1534 r
->peaks
.max_f
[c
] = n
;
1538 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1539 *d
= r
->peaks
.max_f
[c
];
1540 r
->peaks
.max_f
[c
] = 0;
1542 o_index
++, r
->peaks
.o_counter
++;
1547 pa_memblock_release(input
->memblock
);
1548 pa_memblock_release(output
->memblock
);
1550 *out_n_frames
= o_index
;
1552 r
->peaks
.i_counter
+= in_n_frames
;
1554 /* Normalize counters */
1555 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1556 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1558 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1559 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1563 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1566 r
->peaks
.i_counter
= 0;
1567 r
->peaks
.o_counter
= 0;
1570 static int peaks_init(pa_resampler
*r
) {
1572 pa_assert(r
->i_ss
.rate
>= r
->o_ss
.rate
);
1573 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
|| r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1575 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1576 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1577 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1579 r
->impl_resample
= peaks_resample
;
1580 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1581 r
->impl_reset
= peaks_update_rates_or_reset
;
1586 /*** ffmpeg based implementation ***/
1588 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1589 unsigned used_frames
= 0, c
;
1594 pa_assert(out_n_frames
);
1596 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1599 int16_t *p
, *t
, *k
, *q
, *s
;
1600 int consumed_frames
;
1603 /* Allocate a new block */
1604 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1605 p
= pa_memblock_acquire(b
);
1607 /* Copy the remaining data into it */
1608 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1609 if (r
->ffmpeg
.buf
[c
].memblock
) {
1610 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1612 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1613 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1614 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1617 /* Now append the new data, splitting up channels */
1618 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1619 k
= (int16_t*) ((uint8_t*) p
+ l
);
1620 for (u
= 0; u
< in_n_frames
; u
++) {
1622 t
+= r
->o_ss
.channels
;
1625 pa_memblock_release(input
->memblock
);
1627 /* Calculate the resulting number of frames */
1628 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1630 /* Allocate buffer for the result */
1631 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1632 q
= pa_memblock_acquire(w
);
1635 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1638 (int) in
, (int) *out_n_frames
,
1639 c
>= (unsigned) (r
->o_ss
.channels
-1));
1641 pa_memblock_release(b
);
1643 /* Now store the remaining samples away */
1644 pa_assert(consumed_frames
<= (int) in
);
1645 if (consumed_frames
< (int) in
) {
1646 r
->ffmpeg
.buf
[c
].memblock
= b
;
1647 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1648 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1650 pa_memblock_unref(b
);
1652 /* And place the results in the output buffer */
1653 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1654 for (u
= 0; u
< used_frames
; u
++) {
1657 s
+= r
->o_ss
.channels
;
1659 pa_memblock_release(output
->memblock
);
1660 pa_memblock_release(w
);
1661 pa_memblock_unref(w
);
1664 *out_n_frames
= used_frames
;
1667 static void ffmpeg_free(pa_resampler
*r
) {
1672 if (r
->ffmpeg
.state
)
1673 av_resample_close(r
->ffmpeg
.state
);
1675 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1676 if (r
->ffmpeg
.buf
[c
].memblock
)
1677 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1680 static int ffmpeg_init(pa_resampler
*r
) {
1685 /* We could probably implement different quality levels by
1686 * adjusting the filter parameters here. However, ffmpeg
1687 * internally only uses these hardcoded values, so let's use them
1688 * here for now as well until ffmpeg makes this configurable. */
1690 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1693 r
->impl_free
= ffmpeg_free
;
1694 r
->impl_resample
= ffmpeg_resample
;
1696 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1697 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1702 /*** copy (noop) implementation ***/
1704 static int copy_init(pa_resampler
*r
) {
1707 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);