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 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 <liboil/liboilfuncs.h>
35 #include <liboil/liboil.h>
37 #include <pulse/xmalloc.h>
38 #include <pulsecore/sconv.h>
39 #include <pulsecore/log.h>
40 #include <pulsecore/macro.h>
41 #include <pulsecore/strbuf.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
;
67 float map_table
[PA_CHANNELS_MAX
][PA_CHANNELS_MAX
];
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 */
95 struct { /* data specific to speex */
96 SpeexResamplerState
* state
;
99 struct { /* data specific to ffmpeg */
100 struct AVResampleContext
*state
;
101 pa_memchunk buf
[PA_CHANNELS_MAX
];
105 static int copy_init(pa_resampler
*r
);
106 static int trivial_init(pa_resampler
*r
);
107 static int speex_init(pa_resampler
*r
);
108 static int ffmpeg_init(pa_resampler
*r
);
109 static int peaks_init(pa_resampler
*r
);
110 #ifdef HAVE_LIBSAMPLERATE
111 static int libsamplerate_init(pa_resampler
*r
);
114 static void calc_map_table(pa_resampler
*r
);
116 static int (* const init_table
[])(pa_resampler
*r
) = {
117 #ifdef HAVE_LIBSAMPLERATE
118 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = libsamplerate_init
,
119 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = libsamplerate_init
,
120 [PA_RESAMPLER_SRC_SINC_FASTEST
] = libsamplerate_init
,
121 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = libsamplerate_init
,
122 [PA_RESAMPLER_SRC_LINEAR
] = libsamplerate_init
,
124 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = NULL
,
125 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = NULL
,
126 [PA_RESAMPLER_SRC_SINC_FASTEST
] = NULL
,
127 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = NULL
,
128 [PA_RESAMPLER_SRC_LINEAR
] = NULL
,
130 [PA_RESAMPLER_TRIVIAL
] = trivial_init
,
131 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+0] = speex_init
,
132 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+1] = speex_init
,
133 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+2] = speex_init
,
134 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+3] = speex_init
,
135 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+4] = speex_init
,
136 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+5] = speex_init
,
137 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+6] = speex_init
,
138 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+7] = speex_init
,
139 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+8] = speex_init
,
140 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+9] = speex_init
,
141 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+10] = speex_init
,
142 [PA_RESAMPLER_SPEEX_FIXED_BASE
+0] = speex_init
,
143 [PA_RESAMPLER_SPEEX_FIXED_BASE
+1] = speex_init
,
144 [PA_RESAMPLER_SPEEX_FIXED_BASE
+2] = speex_init
,
145 [PA_RESAMPLER_SPEEX_FIXED_BASE
+3] = speex_init
,
146 [PA_RESAMPLER_SPEEX_FIXED_BASE
+4] = speex_init
,
147 [PA_RESAMPLER_SPEEX_FIXED_BASE
+5] = speex_init
,
148 [PA_RESAMPLER_SPEEX_FIXED_BASE
+6] = speex_init
,
149 [PA_RESAMPLER_SPEEX_FIXED_BASE
+7] = speex_init
,
150 [PA_RESAMPLER_SPEEX_FIXED_BASE
+8] = speex_init
,
151 [PA_RESAMPLER_SPEEX_FIXED_BASE
+9] = speex_init
,
152 [PA_RESAMPLER_SPEEX_FIXED_BASE
+10] = speex_init
,
153 [PA_RESAMPLER_FFMPEG
] = ffmpeg_init
,
154 [PA_RESAMPLER_AUTO
] = NULL
,
155 [PA_RESAMPLER_COPY
] = copy_init
,
156 [PA_RESAMPLER_PEAKS
] = peaks_init
,
159 pa_resampler
* pa_resampler_new(
161 const pa_sample_spec
*a
,
162 const pa_channel_map
*am
,
163 const pa_sample_spec
*b
,
164 const pa_channel_map
*bm
,
165 pa_resample_method_t method
,
166 pa_resample_flags_t flags
) {
168 pa_resampler
*r
= NULL
;
173 pa_assert(pa_sample_spec_valid(a
));
174 pa_assert(pa_sample_spec_valid(b
));
175 pa_assert(method
>= 0);
176 pa_assert(method
< PA_RESAMPLER_MAX
);
180 if (!(flags
& PA_RESAMPLER_VARIABLE_RATE
) && a
->rate
== b
->rate
) {
181 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
182 method
= PA_RESAMPLER_COPY
;
185 if (!pa_resample_method_supported(method
)) {
186 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method
));
187 method
= PA_RESAMPLER_AUTO
;
190 if (method
== PA_RESAMPLER_FFMPEG
&& (flags
& PA_RESAMPLER_VARIABLE_RATE
)) {
191 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
192 method
= PA_RESAMPLER_AUTO
;
195 if (method
== PA_RESAMPLER_COPY
&& ((flags
& PA_RESAMPLER_VARIABLE_RATE
) || a
->rate
!= b
->rate
)) {
196 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
197 method
= PA_RESAMPLER_AUTO
;
200 if (method
== PA_RESAMPLER_AUTO
)
201 method
= PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
203 r
= pa_xnew(pa_resampler
, 1);
209 r
->impl_update_rates
= NULL
;
210 r
->impl_resample
= NULL
;
211 r
->impl_reset
= NULL
;
213 /* Fill sample specs */
219 else if (!pa_channel_map_init_auto(&r
->i_cm
, r
->i_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
224 else if (!pa_channel_map_init_auto(&r
->o_cm
, r
->o_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
227 r
->i_fz
= pa_frame_size(a
);
228 r
->o_fz
= pa_frame_size(b
);
230 pa_memchunk_reset(&r
->buf1
);
231 pa_memchunk_reset(&r
->buf2
);
232 pa_memchunk_reset(&r
->buf3
);
233 pa_memchunk_reset(&r
->buf4
);
235 r
->buf1_samples
= r
->buf2_samples
= r
->buf3_samples
= r
->buf4_samples
= 0;
239 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method
));
241 if ((method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) ||
242 (method
== PA_RESAMPLER_FFMPEG
))
243 r
->work_format
= PA_SAMPLE_S16NE
;
244 else if (method
== PA_RESAMPLER_TRIVIAL
|| method
== PA_RESAMPLER_COPY
|| method
== PA_RESAMPLER_PEAKS
) {
246 if (r
->map_required
|| a
->format
!= b
->format
|| method
== PA_RESAMPLER_PEAKS
) {
248 if (a
->format
== PA_SAMPLE_S32NE
|| a
->format
== PA_SAMPLE_S32RE
||
249 a
->format
== PA_SAMPLE_FLOAT32NE
|| a
->format
== PA_SAMPLE_FLOAT32RE
||
250 a
->format
== PA_SAMPLE_S24NE
|| a
->format
== PA_SAMPLE_S24RE
||
251 a
->format
== PA_SAMPLE_S24_32NE
|| a
->format
== PA_SAMPLE_S24_32RE
||
252 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
253 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
||
254 b
->format
== PA_SAMPLE_S24NE
|| b
->format
== PA_SAMPLE_S24RE
||
255 b
->format
== PA_SAMPLE_S24_32NE
|| b
->format
== PA_SAMPLE_S24_32RE
)
256 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
258 r
->work_format
= PA_SAMPLE_S16NE
;
261 r
->work_format
= a
->format
;
264 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
266 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
268 r
->w_sz
= pa_sample_size_of_format(r
->work_format
);
270 if (r
->i_ss
.format
== r
->work_format
)
271 r
->to_work_format_func
= NULL
;
272 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
273 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
276 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
277 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
281 if (r
->o_ss
.format
== r
->work_format
)
282 r
->from_work_format_func
= NULL
;
283 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
284 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
287 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
288 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
292 /* initialize implementation */
293 if (init_table
[method
](r
) < 0)
305 void pa_resampler_free(pa_resampler
*r
) {
311 if (r
->buf1
.memblock
)
312 pa_memblock_unref(r
->buf1
.memblock
);
313 if (r
->buf2
.memblock
)
314 pa_memblock_unref(r
->buf2
.memblock
);
315 if (r
->buf3
.memblock
)
316 pa_memblock_unref(r
->buf3
.memblock
);
317 if (r
->buf4
.memblock
)
318 pa_memblock_unref(r
->buf4
.memblock
);
323 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
327 if (r
->i_ss
.rate
== rate
)
332 r
->impl_update_rates(r
);
335 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
339 if (r
->o_ss
.rate
== rate
)
344 r
->impl_update_rates(r
);
347 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
350 return (((out_length
/ r
->o_fz
)*r
->i_ss
.rate
)/r
->o_ss
.rate
) * r
->i_fz
;
353 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
356 return (((in_length
/ r
->i_fz
)*r
->o_ss
.rate
)/r
->i_ss
.rate
) * r
->o_fz
;
359 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
360 size_t block_size_max
;
366 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
368 /* We deduce the "largest" sample spec we're using during the
370 ss
.channels
= (uint8_t) (PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
));
372 /* We silently assume that the format enum is ordered by size */
373 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
374 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
376 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
378 fs
= pa_frame_size(&ss
);
380 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
383 void pa_resampler_reset(pa_resampler
*r
) {
390 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
396 const pa_channel_map
* pa_resampler_input_channel_map(pa_resampler
*r
) {
402 const pa_sample_spec
* pa_resampler_input_sample_spec(pa_resampler
*r
) {
408 const pa_channel_map
* pa_resampler_output_channel_map(pa_resampler
*r
) {
414 const pa_sample_spec
* pa_resampler_output_sample_spec(pa_resampler
*r
) {
420 static const char * const resample_methods
[] = {
421 "src-sinc-best-quality",
422 "src-sinc-medium-quality",
424 "src-zero-order-hold",
455 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
457 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
460 return resample_methods
[m
];
463 int pa_resample_method_supported(pa_resample_method_t m
) {
465 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
468 #ifndef HAVE_LIBSAMPLERATE
469 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
476 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
477 pa_resample_method_t m
;
481 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
482 if (!strcmp(string
, resample_methods
[m
]))
485 if (!strcmp(string
, "speex-fixed"))
486 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
488 if (!strcmp(string
, "speex-float"))
489 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
491 return PA_RESAMPLER_INVALID
;
494 static pa_bool_t
on_left(pa_channel_position_t p
) {
497 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
498 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
499 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
500 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
501 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
502 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
505 static pa_bool_t
on_right(pa_channel_position_t p
) {
508 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
509 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
510 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
511 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
512 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
513 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
516 static pa_bool_t
on_center(pa_channel_position_t p
) {
519 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
520 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
521 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
522 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
523 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
526 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
528 p
== PA_CHANNEL_POSITION_LFE
;
531 static pa_bool_t
on_front(pa_channel_position_t p
) {
533 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
534 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
535 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
536 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
537 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
538 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
539 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
540 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
543 static pa_bool_t
on_rear(pa_channel_position_t p
) {
545 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
546 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
547 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
548 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
549 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
550 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
553 static pa_bool_t
on_side(pa_channel_position_t p
) {
555 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
556 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
557 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
567 static int front_rear_side(pa_channel_position_t p
) {
577 static void calc_map_table(pa_resampler
*r
) {
579 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
586 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
)))))
589 memset(r
->map_table
, 0, sizeof(r
->map_table
));
590 memset(ic_connected
, 0, sizeof(ic_connected
));
591 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
593 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
594 pa_bool_t oc_connected
= FALSE
;
595 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
597 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
598 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
600 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
601 /* We shall not do any remapping. Hence, just check by index */
604 r
->map_table
[oc
][ic
] = 1.0;
609 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
610 /* We shall not do any remixing. Hence, just check by name */
613 r
->map_table
[oc
][ic
] = 1.0;
620 /* OK, we shall do the full monty: upmixing and
621 * downmixing. Our algorithm is relatively simple, does
622 * not do spacialization, delay elements or apply lowpass
623 * filters for LFE. Patches are always welcome,
624 * though. Oh, and it doesn't do any matrix
625 * decoding. (Which probably wouldn't make any sense
628 * This code is not idempotent: downmixing an upmixed
629 * stereo stream is not identical to the original. The
630 * volume will not match, and the two channels will be a
631 * linear combination of both.
633 * This is losely based on random suggestions found on the
634 * Internet, such as this:
635 * http://www.halfgaar.net/surround-sound-in-linux and the
638 * The algorithm works basically like this:
640 * 1) Connect all channels with matching names.
643 * S:Mono: Copy into all D:channels
644 * D:Mono: Copy in all S:channels
646 * 3) Mix D:Left, D:Right:
647 * D:Left: If not connected, avg all S:Left
648 * D:Right: If not connected, avg all S:Right
651 * If not connected, avg all S:Center
652 * If still not connected, avg all S:Left, S:Right
655 * If not connected, avg all S:*
657 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
658 * not connected, mix into all D:left and all D:right
659 * channels. Gain is 0.1, the current left and right
660 * should be multiplied by 0.9.
662 * 7) Make sure S:Center, S:LFE is used:
664 * S:Center, S:LFE: If not connected, mix into all
665 * D:left, all D:right, all D:center channels, gain is
666 * 0.375. The current (as result of 1..6) factors
667 * should be multiplied by 0.75. (Alt. suggestion: 0.25
668 * vs. 0.5) If C-front is only mixed into
669 * L-front/R-front if available, otherwise into all L/R
670 * channels. Similarly for C-rear.
672 * S: and D: shall relate to the source resp. destination channels.
674 * Rationale: 1, 2 are probably obvious. For 3: this
675 * copies front to rear if needed. For 4: we try to find
676 * some suitable C source for C, if we don't find any, we
677 * avg L and R. For 5: LFE is mixed from all channels. For
678 * 6: the rear channels should not be dropped entirely,
679 * however have only minimal impact. For 7: movies usually
680 * encode speech on the center channel. Thus we have to
681 * make sure this channel is distributed to L and R if not
682 * available in the output. Also, LFE is used to achieve a
683 * greater dynamic range, and thus we should try to do our
684 * best to pass it to L+R.
687 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
688 r
->map_table
[oc
][ic
] = 1.0;
691 ic_connected
[ic
] = TRUE
;
695 if (!oc_connected
&& remix
) {
696 /* OK, we shall remix */
698 /* Try to find matching input ports for this output port */
703 /* We are not connected and on the left side, let's
704 * average all left side input channels. */
706 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
707 if (on_left(r
->i_cm
.map
[ic
]))
711 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
712 if (on_left(r
->i_cm
.map
[ic
])) {
713 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
714 ic_connected
[ic
] = TRUE
;
717 /* We ignore the case where there is no left input
718 * channel. Something is really wrong in this case
721 } else if (on_right(b
)) {
724 /* We are not connected and on the right side, let's
725 * average all right side input channels. */
727 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
728 if (on_right(r
->i_cm
.map
[ic
]))
732 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
733 if (on_right(r
->i_cm
.map
[ic
])) {
734 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
735 ic_connected
[ic
] = TRUE
;
738 /* We ignore the case where there is no right input
739 * channel. Something is really wrong in this case
742 } else if (on_center(b
)) {
745 /* We are not connected and at the center. Let's
746 * average all center input channels. */
748 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
749 if (on_center(r
->i_cm
.map
[ic
]))
753 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
754 if (on_center(r
->i_cm
.map
[ic
])) {
755 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
756 ic_connected
[ic
] = TRUE
;
760 /* Hmm, no center channel around, let's synthesize
761 * it by mixing L and R.*/
765 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
766 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
770 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
771 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
772 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
773 ic_connected
[ic
] = TRUE
;
776 /* We ignore the case where there is not even a
777 * left or right input channel. Something is
778 * really wrong in this case anyway. */
781 } else if (on_lfe(b
)) {
783 /* We are not connected and an LFE. Let's average all
784 * channels for LFE. */
786 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
788 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
789 r
->map_table
[oc
][ic
] = 1.0f
/ (float) r
->i_ss
.channels
;
791 r
->map_table
[oc
][ic
] = 0;
793 /* Please note that a channel connected to LFE
794 * doesn't really count as connected. */
802 ic_unconnected_left
= 0,
803 ic_unconnected_right
= 0,
804 ic_unconnected_center
= 0,
805 ic_unconnected_lfe
= 0;
807 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
808 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
810 if (ic_connected
[ic
])
814 ic_unconnected_left
++;
815 else if (on_right(a
))
816 ic_unconnected_right
++;
817 else if (on_center(a
))
818 ic_unconnected_center
++;
820 ic_unconnected_lfe
++;
823 if (ic_unconnected_left
> 0) {
825 /* OK, so there are unconnected input channels on the
826 * left. Let's multiply all already connected channels on
827 * the left side by .9 and add in our averaged unconnected
828 * channels multplied by .1 */
830 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
832 if (!on_left(r
->o_cm
.map
[oc
]))
835 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
837 if (ic_connected
[ic
]) {
838 r
->map_table
[oc
][ic
] *= .9f
;
842 if (on_left(r
->i_cm
.map
[ic
]))
843 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
848 if (ic_unconnected_right
> 0) {
850 /* OK, so there are unconnected input channels on the
851 * right. Let's multiply all already connected channels on
852 * the right side by .9 and add in our averaged unconnected
853 * channels multplied by .1 */
855 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
857 if (!on_right(r
->o_cm
.map
[oc
]))
860 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
862 if (ic_connected
[ic
]) {
863 r
->map_table
[oc
][ic
] *= .9f
;
867 if (on_right(r
->i_cm
.map
[ic
]))
868 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
873 if (ic_unconnected_center
> 0) {
874 pa_bool_t mixed_in
= FALSE
;
876 /* OK, so there are unconnected input channels on the
877 * center. Let's multiply all already connected channels on
878 * the center side by .9 and add in our averaged unconnected
879 * channels multplied by .1 */
881 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
883 if (!on_center(r
->o_cm
.map
[oc
]))
886 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
888 if (ic_connected
[ic
]) {
889 r
->map_table
[oc
][ic
] *= .9f
;
893 if (on_center(r
->i_cm
.map
[ic
])) {
894 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
901 unsigned ncenter
[PA_CHANNELS_MAX
];
902 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
904 memset(ncenter
, 0, sizeof(ncenter
));
905 memset(found_frs
, 0, sizeof(found_frs
));
907 /* Hmm, as it appears there was no center channel we
908 could mix our center channel in. In this case, mix
909 it into left and right. Using .375 and 0.75 as
912 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
914 if (ic_connected
[ic
])
917 if (!on_center(r
->i_cm
.map
[ic
]))
920 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
922 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
925 if (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
926 found_frs
[ic
] = TRUE
;
931 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
933 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
936 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
941 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
943 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
946 if (ncenter
[oc
] <= 0)
949 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
951 if (ic_connected
[ic
]) {
952 r
->map_table
[oc
][ic
] *= .75f
;
956 if (!on_center(r
->i_cm
.map
[ic
]))
959 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
960 r
->map_table
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
966 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
968 /* OK, so there is an unconnected LFE channel. Let's mix
969 * it into all channels, with factor 0.375 */
971 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
973 if (!on_lfe(r
->i_cm
.map
[ic
]))
976 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
977 r
->map_table
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
985 pa_strbuf_printf(s
, " ");
986 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
987 pa_strbuf_printf(s
, " I%02u ", ic
);
988 pa_strbuf_puts(s
, "\n +");
990 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
991 pa_strbuf_printf(s
, "------");
992 pa_strbuf_puts(s
, "\n");
994 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
995 pa_strbuf_printf(s
, "O%02u |", oc
);
997 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
998 pa_strbuf_printf(s
, " %1.3f", r
->map_table
[oc
][ic
]);
1000 pa_strbuf_puts(s
, "\n");
1003 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
1007 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1013 pa_assert(input
->memblock
);
1015 /* Convert the incoming sample into the work sample format and place them in buf1 */
1017 if (!r
->to_work_format_func
|| !input
->length
)
1020 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1023 r
->buf1
.length
= r
->w_sz
* n_samples
;
1025 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
1026 if (r
->buf1
.memblock
)
1027 pa_memblock_unref(r
->buf1
.memblock
);
1029 r
->buf1_samples
= n_samples
;
1030 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
1033 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1034 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
1036 r
->to_work_format_func(n_samples
, src
, dst
);
1038 pa_memblock_release(input
->memblock
);
1039 pa_memblock_release(r
->buf1
.memblock
);
1044 static void vectoradd_s16_with_fraction(
1045 int16_t *d
, int dstr
,
1046 const int16_t *s1
, int sstr1
,
1047 const int16_t *s2
, int sstr2
,
1049 float s3
, float s4
) {
1053 i3
= (int32_t) (s3
* 0x10000);
1054 i4
= (int32_t) (s4
* 0x10000);
1056 for (; n
> 0; n
--) {
1062 a
= (a
* i3
) / 0x10000;
1063 b
= (b
* i4
) / 0x10000;
1065 *d
= (int16_t) (a
+ b
);
1067 s1
= (const int16_t*) ((const uint8_t*) s1
+ sstr1
);
1068 s2
= (const int16_t*) ((const uint8_t*) s2
+ sstr2
);
1069 d
= (int16_t*) ((uint8_t*) d
+ dstr
);
1074 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1075 unsigned in_n_samples
, out_n_samples
, n_frames
;
1082 pa_assert(input
->memblock
);
1084 /* Remap channels and place the result int buf2 */
1086 if (!r
->map_required
|| !input
->length
)
1089 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1090 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1091 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1094 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
1096 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
1097 if (r
->buf2
.memblock
)
1098 pa_memblock_unref(r
->buf2
.memblock
);
1100 r
->buf2_samples
= out_n_samples
;
1101 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
1104 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1105 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
1107 memset(dst
, 0, r
->buf2
.length
);
1109 o_skip
= (int) (r
->w_sz
* r
->o_ss
.channels
);
1110 i_skip
= (int) (r
->w_sz
* r
->i_ss
.channels
);
1112 switch (r
->work_format
) {
1113 case PA_SAMPLE_FLOAT32NE
:
1115 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1117 static const float one
= 1.0;
1119 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1121 if (r
->map_table
[oc
][ic
] <= 0.0)
1125 (float*) dst
+ oc
, o_skip
,
1126 (float*) dst
+ oc
, o_skip
,
1127 (float*) src
+ ic
, i_skip
,
1129 &one
, &r
->map_table
[oc
][ic
]);
1135 case PA_SAMPLE_S16NE
:
1137 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1140 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1142 if (r
->map_table
[oc
][ic
] <= 0.0)
1145 if (r
->map_table
[oc
][ic
] >= 1.0) {
1146 static const int16_t one
= 1;
1149 (int16_t*) dst
+ oc
, o_skip
,
1150 (int16_t*) dst
+ oc
, o_skip
,
1151 (int16_t*) src
+ ic
, i_skip
,
1157 vectoradd_s16_with_fraction(
1158 (int16_t*) dst
+ oc
, o_skip
,
1159 (int16_t*) dst
+ oc
, o_skip
,
1160 (int16_t*) src
+ ic
, i_skip
,
1162 1.0f
, r
->map_table
[oc
][ic
]);
1169 pa_assert_not_reached();
1172 pa_memblock_release(input
->memblock
);
1173 pa_memblock_release(r
->buf2
.memblock
);
1175 r
->buf2
.length
= out_n_samples
* r
->w_sz
;
1180 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1181 unsigned in_n_frames
, in_n_samples
;
1182 unsigned out_n_frames
, out_n_samples
;
1187 /* Resample the data and place the result in buf3 */
1189 if (!r
->impl_resample
|| !input
->length
)
1192 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1193 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1195 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1196 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1199 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1201 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1202 if (r
->buf3
.memblock
)
1203 pa_memblock_unref(r
->buf3
.memblock
);
1205 r
->buf3_samples
= out_n_samples
;
1206 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1209 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1210 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1215 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1216 unsigned n_samples
, n_frames
;
1222 /* Convert the data into the correct sample type and place the result in buf4 */
1224 if (!r
->from_work_format_func
|| !input
->length
)
1227 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1228 n_frames
= n_samples
/ r
->o_ss
.channels
;
1231 r
->buf4
.length
= r
->o_fz
* n_frames
;
1233 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1234 if (r
->buf4
.memblock
)
1235 pa_memblock_unref(r
->buf4
.memblock
);
1237 r
->buf4_samples
= n_samples
;
1238 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1241 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1242 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1243 r
->from_work_format_func(n_samples
, src
, dst
);
1244 pa_memblock_release(input
->memblock
);
1245 pa_memblock_release(r
->buf4
.memblock
);
1247 r
->buf4
.length
= r
->o_fz
* n_frames
;
1252 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1258 pa_assert(in
->length
);
1259 pa_assert(in
->memblock
);
1260 pa_assert(in
->length
% r
->i_fz
== 0);
1262 buf
= (pa_memchunk
*) in
;
1263 buf
= convert_to_work_format(r
, buf
);
1264 buf
= remap_channels(r
, buf
);
1265 buf
= resample(r
, buf
);
1268 buf
= convert_from_work_format(r
, buf
);
1272 pa_memblock_ref(buf
->memblock
);
1274 pa_memchunk_reset(buf
);
1276 pa_memchunk_reset(out
);
1279 /*** libsamplerate based implementation ***/
1281 #ifdef HAVE_LIBSAMPLERATE
1282 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1288 pa_assert(out_n_frames
);
1290 memset(&data
, 0, sizeof(data
));
1292 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1293 data
.input_frames
= (long int) in_n_frames
;
1295 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1296 data
.output_frames
= (long int) *out_n_frames
;
1298 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1299 data
.end_of_input
= 0;
1301 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1302 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1304 pa_memblock_release(input
->memblock
);
1305 pa_memblock_release(output
->memblock
);
1307 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1310 static void libsamplerate_update_rates(pa_resampler
*r
) {
1313 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1316 static void libsamplerate_reset(pa_resampler
*r
) {
1319 pa_assert_se(src_reset(r
->src
.state
) == 0);
1322 static void libsamplerate_free(pa_resampler
*r
) {
1326 src_delete(r
->src
.state
);
1329 static int libsamplerate_init(pa_resampler
*r
) {
1334 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1337 r
->impl_free
= libsamplerate_free
;
1338 r
->impl_update_rates
= libsamplerate_update_rates
;
1339 r
->impl_resample
= libsamplerate_resample
;
1340 r
->impl_reset
= libsamplerate_reset
;
1346 /*** speex based implementation ***/
1348 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1350 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1355 pa_assert(out_n_frames
);
1357 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1358 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1360 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1362 pa_memblock_release(input
->memblock
);
1363 pa_memblock_release(output
->memblock
);
1365 pa_assert(inf
== in_n_frames
);
1366 *out_n_frames
= outf
;
1369 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1371 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1376 pa_assert(out_n_frames
);
1378 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1379 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1381 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1383 pa_memblock_release(input
->memblock
);
1384 pa_memblock_release(output
->memblock
);
1386 pa_assert(inf
== in_n_frames
);
1387 *out_n_frames
= outf
;
1390 static void speex_update_rates(pa_resampler
*r
) {
1393 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1396 static void speex_reset(pa_resampler
*r
) {
1399 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1402 static void speex_free(pa_resampler
*r
) {
1405 if (!r
->speex
.state
)
1408 speex_resampler_destroy(r
->speex
.state
);
1411 static int speex_init(pa_resampler
*r
) {
1416 r
->impl_free
= speex_free
;
1417 r
->impl_update_rates
= speex_update_rates
;
1418 r
->impl_reset
= speex_reset
;
1420 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1422 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1423 r
->impl_resample
= speex_resample_int
;
1426 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1428 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1429 r
->impl_resample
= speex_resample_float
;
1432 pa_log_info("Choosing speex quality setting %i.", q
);
1434 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1440 /* Trivial implementation */
1442 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1450 pa_assert(out_n_frames
);
1452 fz
= r
->w_sz
* r
->o_ss
.channels
;
1454 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1455 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1457 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1460 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1461 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1463 if (j
>= in_n_frames
)
1466 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1468 oil_memcpy((uint8_t*) dst
+ fz
* o_index
,
1469 (uint8_t*) src
+ fz
* j
, (int) fz
);
1472 pa_memblock_release(input
->memblock
);
1473 pa_memblock_release(output
->memblock
);
1475 *out_n_frames
= o_index
;
1477 r
->trivial
.i_counter
+= in_n_frames
;
1479 /* Normalize counters */
1480 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1481 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1483 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1484 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1488 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1491 r
->trivial
.i_counter
= 0;
1492 r
->trivial
.o_counter
= 0;
1495 static int trivial_init(pa_resampler
*r
) {
1498 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1500 r
->impl_resample
= trivial_resample
;
1501 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1502 r
->impl_reset
= trivial_update_rates_or_reset
;
1507 /* Peak finder implementation */
1509 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1518 pa_assert(out_n_frames
);
1520 fz
= r
->w_sz
* r
->o_ss
.channels
;
1522 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1523 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1525 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1528 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1530 if (j
> r
->peaks
.i_counter
)
1531 j
-= r
->peaks
.i_counter
;
1535 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1537 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1539 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* start
);
1540 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1542 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1544 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1547 n
= (int16_t) (*s
< 0 ? -*s
: *s
);
1549 if (PA_UNLIKELY(n
> r
->peaks
.max_i
[c
]))
1550 r
->peaks
.max_i
[c
] = n
;
1553 if (i
>= in_n_frames
)
1556 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1557 *d
= r
->peaks
.max_i
[c
];
1558 r
->peaks
.max_i
[c
] = 0;
1563 float *s
= (float*) ((uint8_t*) src
+ fz
* start
);
1564 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1566 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1568 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1569 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1570 float n
= fabsf(*s
);
1572 if (n
> r
->peaks
.max_f
[c
])
1573 r
->peaks
.max_f
[c
] = n
;
1576 if (i
>= in_n_frames
)
1579 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1580 *d
= r
->peaks
.max_f
[c
];
1581 r
->peaks
.max_f
[c
] = 0;
1588 pa_memblock_release(input
->memblock
);
1589 pa_memblock_release(output
->memblock
);
1591 *out_n_frames
= o_index
;
1593 r
->peaks
.i_counter
+= in_n_frames
;
1595 /* Normalize counters */
1596 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1597 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1599 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1600 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1604 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1607 r
->peaks
.i_counter
= 0;
1608 r
->peaks
.o_counter
= 0;
1611 static int peaks_init(pa_resampler
*r
) {
1614 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1615 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1616 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1618 r
->impl_resample
= peaks_resample
;
1619 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1620 r
->impl_reset
= peaks_update_rates_or_reset
;
1625 /*** ffmpeg based implementation ***/
1627 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1628 unsigned used_frames
= 0, c
;
1633 pa_assert(out_n_frames
);
1635 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1638 int16_t *p
, *t
, *k
, *q
, *s
;
1639 int consumed_frames
;
1642 /* Allocate a new block */
1643 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1644 p
= pa_memblock_acquire(b
);
1646 /* Copy the remaining data into it */
1647 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1648 if (r
->ffmpeg
.buf
[c
].memblock
) {
1649 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1651 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1652 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1653 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1656 /* Now append the new data, splitting up channels */
1657 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1658 k
= (int16_t*) ((uint8_t*) p
+ l
);
1659 for (u
= 0; u
< in_n_frames
; u
++) {
1661 t
+= r
->o_ss
.channels
;
1664 pa_memblock_release(input
->memblock
);
1666 /* Calculate the resulting number of frames */
1667 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1669 /* Allocate buffer for the result */
1670 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1671 q
= pa_memblock_acquire(w
);
1674 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1677 (int) in
, (int) *out_n_frames
,
1678 c
>= (unsigned) (r
->o_ss
.channels
-1));
1680 pa_memblock_release(b
);
1682 /* Now store the remaining samples away */
1683 pa_assert(consumed_frames
<= (int) in
);
1684 if (consumed_frames
< (int) in
) {
1685 r
->ffmpeg
.buf
[c
].memblock
= b
;
1686 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1687 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1689 pa_memblock_unref(b
);
1691 /* And place the results in the output buffer */
1692 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1693 for (u
= 0; u
< used_frames
; u
++) {
1696 s
+= r
->o_ss
.channels
;
1698 pa_memblock_release(output
->memblock
);
1699 pa_memblock_release(w
);
1700 pa_memblock_unref(w
);
1703 *out_n_frames
= used_frames
;
1706 static void ffmpeg_free(pa_resampler
*r
) {
1711 if (r
->ffmpeg
.state
)
1712 av_resample_close(r
->ffmpeg
.state
);
1714 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1715 if (r
->ffmpeg
.buf
[c
].memblock
)
1716 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1719 static int ffmpeg_init(pa_resampler
*r
) {
1724 /* We could probably implement different quality levels by
1725 * adjusting the filter parameters here. However, ffmpeg
1726 * internally only uses these hardcoded values, so let's use them
1727 * here for now as well until ffmpeg makes this configurable. */
1729 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1732 r
->impl_free
= ffmpeg_free
;
1733 r
->impl_resample
= ffmpeg_resample
;
1735 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1736 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1741 /*** copy (noop) implementation ***/
1743 static int copy_init(pa_resampler
*r
) {
1746 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);