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 static inline size_t sample_size(pa_sample_format_t f
) {
160 pa_sample_spec ss
= {
166 return pa_sample_size(&ss
);
169 pa_resampler
* pa_resampler_new(
171 const pa_sample_spec
*a
,
172 const pa_channel_map
*am
,
173 const pa_sample_spec
*b
,
174 const pa_channel_map
*bm
,
175 pa_resample_method_t method
,
176 pa_resample_flags_t flags
) {
178 pa_resampler
*r
= NULL
;
183 pa_assert(pa_sample_spec_valid(a
));
184 pa_assert(pa_sample_spec_valid(b
));
185 pa_assert(method
>= 0);
186 pa_assert(method
< PA_RESAMPLER_MAX
);
190 if (!(flags
& PA_RESAMPLER_VARIABLE_RATE
) && a
->rate
== b
->rate
) {
191 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
192 method
= PA_RESAMPLER_COPY
;
195 if (!pa_resample_method_supported(method
)) {
196 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method
));
197 method
= PA_RESAMPLER_AUTO
;
200 if (method
== PA_RESAMPLER_FFMPEG
&& (flags
& PA_RESAMPLER_VARIABLE_RATE
)) {
201 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
202 method
= PA_RESAMPLER_AUTO
;
205 if (method
== PA_RESAMPLER_COPY
&& ((flags
& PA_RESAMPLER_VARIABLE_RATE
) || a
->rate
!= b
->rate
)) {
206 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
207 method
= PA_RESAMPLER_AUTO
;
210 if (method
== PA_RESAMPLER_AUTO
)
211 method
= PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
213 r
= pa_xnew(pa_resampler
, 1);
219 r
->impl_update_rates
= NULL
;
220 r
->impl_resample
= NULL
;
221 r
->impl_reset
= NULL
;
223 /* Fill sample specs */
229 else if (!pa_channel_map_init_auto(&r
->i_cm
, r
->i_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
234 else if (!pa_channel_map_init_auto(&r
->o_cm
, r
->o_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
237 r
->i_fz
= pa_frame_size(a
);
238 r
->o_fz
= pa_frame_size(b
);
240 pa_memchunk_reset(&r
->buf1
);
241 pa_memchunk_reset(&r
->buf2
);
242 pa_memchunk_reset(&r
->buf3
);
243 pa_memchunk_reset(&r
->buf4
);
245 r
->buf1_samples
= r
->buf2_samples
= r
->buf3_samples
= r
->buf4_samples
= 0;
249 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method
));
251 if ((method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) ||
252 (method
== PA_RESAMPLER_FFMPEG
))
253 r
->work_format
= PA_SAMPLE_S16NE
;
254 else if (method
== PA_RESAMPLER_TRIVIAL
|| method
== PA_RESAMPLER_COPY
|| method
== PA_RESAMPLER_PEAKS
) {
256 if (r
->map_required
|| a
->format
!= b
->format
|| method
== PA_RESAMPLER_PEAKS
) {
258 if (a
->format
== PA_SAMPLE_S32NE
|| a
->format
== PA_SAMPLE_S32RE
||
259 a
->format
== PA_SAMPLE_FLOAT32NE
|| a
->format
== PA_SAMPLE_FLOAT32RE
||
260 a
->format
== PA_SAMPLE_S24NE
|| a
->format
== PA_SAMPLE_S24RE
||
261 a
->format
== PA_SAMPLE_S24_32NE
|| a
->format
== PA_SAMPLE_S24_32RE
||
262 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
263 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
||
264 b
->format
== PA_SAMPLE_S24NE
|| b
->format
== PA_SAMPLE_S24RE
||
265 b
->format
== PA_SAMPLE_S24_32NE
|| b
->format
== PA_SAMPLE_S24_32RE
)
266 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
268 r
->work_format
= PA_SAMPLE_S16NE
;
271 r
->work_format
= a
->format
;
274 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
276 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
278 r
->w_sz
= sample_size(r
->work_format
);
280 if (r
->i_ss
.format
== r
->work_format
)
281 r
->to_work_format_func
= NULL
;
282 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
283 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
286 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
287 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
291 if (r
->o_ss
.format
== r
->work_format
)
292 r
->from_work_format_func
= NULL
;
293 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
294 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
297 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
298 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
302 /* initialize implementation */
303 if (init_table
[method
](r
) < 0)
315 void pa_resampler_free(pa_resampler
*r
) {
321 if (r
->buf1
.memblock
)
322 pa_memblock_unref(r
->buf1
.memblock
);
323 if (r
->buf2
.memblock
)
324 pa_memblock_unref(r
->buf2
.memblock
);
325 if (r
->buf3
.memblock
)
326 pa_memblock_unref(r
->buf3
.memblock
);
327 if (r
->buf4
.memblock
)
328 pa_memblock_unref(r
->buf4
.memblock
);
333 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
337 if (r
->i_ss
.rate
== rate
)
342 r
->impl_update_rates(r
);
345 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
349 if (r
->o_ss
.rate
== rate
)
354 r
->impl_update_rates(r
);
357 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
360 return (((out_length
/ r
->o_fz
)*r
->i_ss
.rate
)/r
->o_ss
.rate
) * r
->i_fz
;
363 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
366 return (((in_length
/ r
->i_fz
)*r
->o_ss
.rate
)/r
->i_ss
.rate
) * r
->o_fz
;
369 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
370 size_t block_size_max
;
376 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
378 /* We deduce the "largest" sample spec we're using during the
380 ss
.channels
= (uint8_t) (PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
));
382 /* We silently assume that the format enum is ordered by size */
383 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
384 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
386 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
388 fs
= pa_frame_size(&ss
);
390 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
393 void pa_resampler_reset(pa_resampler
*r
) {
400 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
406 const pa_channel_map
* pa_resampler_input_channel_map(pa_resampler
*r
) {
412 const pa_sample_spec
* pa_resampler_input_sample_spec(pa_resampler
*r
) {
418 const pa_channel_map
* pa_resampler_output_channel_map(pa_resampler
*r
) {
424 const pa_sample_spec
* pa_resampler_output_sample_spec(pa_resampler
*r
) {
430 static const char * const resample_methods
[] = {
431 "src-sinc-best-quality",
432 "src-sinc-medium-quality",
434 "src-zero-order-hold",
465 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
467 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
470 return resample_methods
[m
];
473 int pa_resample_method_supported(pa_resample_method_t m
) {
475 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
478 #ifndef HAVE_LIBSAMPLERATE
479 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
486 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
487 pa_resample_method_t m
;
491 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
492 if (!strcmp(string
, resample_methods
[m
]))
495 if (!strcmp(string
, "speex-fixed"))
496 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
498 if (!strcmp(string
, "speex-float"))
499 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
501 return PA_RESAMPLER_INVALID
;
504 static pa_bool_t
on_left(pa_channel_position_t p
) {
507 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
508 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
509 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
510 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
511 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
512 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
515 static pa_bool_t
on_right(pa_channel_position_t p
) {
518 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
519 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
520 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
521 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
522 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
523 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
526 static pa_bool_t
on_center(pa_channel_position_t p
) {
529 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
530 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
531 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
532 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
533 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
536 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
538 p
== PA_CHANNEL_POSITION_LFE
;
541 static pa_bool_t
on_front(pa_channel_position_t p
) {
543 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
544 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
545 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
546 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
547 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
548 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
549 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
550 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
553 static pa_bool_t
on_rear(pa_channel_position_t p
) {
555 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
556 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
557 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
558 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
559 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
560 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
563 static pa_bool_t
on_side(pa_channel_position_t p
) {
565 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
566 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
567 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
577 static int front_rear_side(pa_channel_position_t p
) {
587 static void calc_map_table(pa_resampler
*r
) {
589 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
596 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
)))))
599 memset(r
->map_table
, 0, sizeof(r
->map_table
));
600 memset(ic_connected
, 0, sizeof(ic_connected
));
601 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
603 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
604 pa_bool_t oc_connected
= FALSE
;
605 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
607 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
608 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
610 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
611 /* We shall not do any remapping. Hence, just check by index */
614 r
->map_table
[oc
][ic
] = 1.0;
619 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
620 /* We shall not do any remixing. Hence, just check by name */
623 r
->map_table
[oc
][ic
] = 1.0;
630 /* OK, we shall do the full monty: upmixing and
631 * downmixing. Our algorithm is relatively simple, does
632 * not do spacialization, delay elements or apply lowpass
633 * filters for LFE. Patches are always welcome,
634 * though. Oh, and it doesn't do any matrix
635 * decoding. (Which probably wouldn't make any sense
638 * This code is not idempotent: downmixing an upmixed
639 * stereo stream is not identical to the original. The
640 * volume will not match, and the two channels will be a
641 * linear combination of both.
643 * This is losely based on random suggestions found on the
644 * Internet, such as this:
645 * http://www.halfgaar.net/surround-sound-in-linux and the
648 * The algorithm works basically like this:
650 * 1) Connect all channels with matching names.
653 * S:Mono: Copy into all D:channels
654 * D:Mono: Copy in all S:channels
656 * 3) Mix D:Left, D:Right:
657 * D:Left: If not connected, avg all S:Left
658 * D:Right: If not connected, avg all S:Right
661 * If not connected, avg all S:Center
662 * If still not connected, avg all S:Left, S:Right
665 * If not connected, avg all S:*
667 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
668 * not connected, mix into all D:left and all D:right
669 * channels. Gain is 0.1, the current left and right
670 * should be multiplied by 0.9.
672 * 7) Make sure S:Center, S:LFE is used:
674 * S:Center, S:LFE: If not connected, mix into all
675 * D:left, all D:right, all D:center channels, gain is
676 * 0.375. The current (as result of 1..6) factors
677 * should be multiplied by 0.75. (Alt. suggestion: 0.25
678 * vs. 0.5) If C-front is only mixed into
679 * L-front/R-front if available, otherwise into all L/R
680 * channels. Similarly for C-rear.
682 * S: and D: shall relate to the source resp. destination channels.
684 * Rationale: 1, 2 are probably obvious. For 3: this
685 * copies front to rear if needed. For 4: we try to find
686 * some suitable C source for C, if we don't find any, we
687 * avg L and R. For 5: LFE is mixed from all channels. For
688 * 6: the rear channels should not be dropped entirely,
689 * however have only minimal impact. For 7: movies usually
690 * encode speech on the center channel. Thus we have to
691 * make sure this channel is distributed to L and R if not
692 * available in the output. Also, LFE is used to achieve a
693 * greater dynamic range, and thus we should try to do our
694 * best to pass it to L+R.
697 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
698 r
->map_table
[oc
][ic
] = 1.0;
701 ic_connected
[ic
] = TRUE
;
705 if (!oc_connected
&& remix
) {
706 /* OK, we shall remix */
708 /* Try to find matching input ports for this output port */
713 /* We are not connected and on the left side, let's
714 * average all left side input channels. */
716 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
717 if (on_left(r
->i_cm
.map
[ic
]))
721 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
722 if (on_left(r
->i_cm
.map
[ic
])) {
723 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
724 ic_connected
[ic
] = TRUE
;
727 /* We ignore the case where there is no left input
728 * channel. Something is really wrong in this case
731 } else if (on_right(b
)) {
734 /* We are not connected and on the right side, let's
735 * average all right side input channels. */
737 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
738 if (on_right(r
->i_cm
.map
[ic
]))
742 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
743 if (on_right(r
->i_cm
.map
[ic
])) {
744 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
745 ic_connected
[ic
] = TRUE
;
748 /* We ignore the case where there is no right input
749 * channel. Something is really wrong in this case
752 } else if (on_center(b
)) {
755 /* We are not connected and at the center. Let's
756 * average all center input channels. */
758 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
759 if (on_center(r
->i_cm
.map
[ic
]))
763 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
764 if (on_center(r
->i_cm
.map
[ic
])) {
765 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
766 ic_connected
[ic
] = TRUE
;
770 /* Hmm, no center channel around, let's synthesize
771 * it by mixing L and R.*/
775 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
776 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
780 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
781 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
782 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
783 ic_connected
[ic
] = TRUE
;
786 /* We ignore the case where there is not even a
787 * left or right input channel. Something is
788 * really wrong in this case anyway. */
791 } else if (on_lfe(b
)) {
793 /* We are not connected and an LFE. Let's average all
794 * channels for LFE. */
796 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
798 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
799 r
->map_table
[oc
][ic
] = 1.0f
/ (float) r
->i_ss
.channels
;
801 r
->map_table
[oc
][ic
] = 0;
803 /* Please note that a channel connected to LFE
804 * doesn't really count as connected. */
812 ic_unconnected_left
= 0,
813 ic_unconnected_right
= 0,
814 ic_unconnected_center
= 0,
815 ic_unconnected_lfe
= 0;
817 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
818 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
820 if (ic_connected
[ic
])
824 ic_unconnected_left
++;
825 else if (on_right(a
))
826 ic_unconnected_right
++;
827 else if (on_center(a
))
828 ic_unconnected_center
++;
830 ic_unconnected_lfe
++;
833 if (ic_unconnected_left
> 0) {
835 /* OK, so there are unconnected input channels on the
836 * left. Let's multiply all already connected channels on
837 * the left side by .9 and add in our averaged unconnected
838 * channels multplied by .1 */
840 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
842 if (!on_left(r
->o_cm
.map
[oc
]))
845 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
847 if (ic_connected
[ic
]) {
848 r
->map_table
[oc
][ic
] *= .9f
;
852 if (on_left(r
->i_cm
.map
[ic
]))
853 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
858 if (ic_unconnected_right
> 0) {
860 /* OK, so there are unconnected input channels on the
861 * right. Let's multiply all already connected channels on
862 * the right side by .9 and add in our averaged unconnected
863 * channels multplied by .1 */
865 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
867 if (!on_right(r
->o_cm
.map
[oc
]))
870 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
872 if (ic_connected
[ic
]) {
873 r
->map_table
[oc
][ic
] *= .9f
;
877 if (on_right(r
->i_cm
.map
[ic
]))
878 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
883 if (ic_unconnected_center
> 0) {
884 pa_bool_t mixed_in
= FALSE
;
886 /* OK, so there are unconnected input channels on the
887 * center. Let's multiply all already connected channels on
888 * the center side by .9 and add in our averaged unconnected
889 * channels multplied by .1 */
891 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
893 if (!on_center(r
->o_cm
.map
[oc
]))
896 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
898 if (ic_connected
[ic
]) {
899 r
->map_table
[oc
][ic
] *= .9f
;
903 if (on_center(r
->i_cm
.map
[ic
])) {
904 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
911 unsigned ncenter
[PA_CHANNELS_MAX
];
912 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
914 memset(ncenter
, 0, sizeof(ncenter
));
915 memset(found_frs
, 0, sizeof(found_frs
));
917 /* Hmm, as it appears there was no center channel we
918 could mix our center channel in. In this case, mix
919 it into left and right. Using .375 and 0.75 as
922 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
924 if (ic_connected
[ic
])
927 if (!on_center(r
->i_cm
.map
[ic
]))
930 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
932 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
935 if (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
936 found_frs
[ic
] = TRUE
;
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 (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
951 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
953 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
956 if (ncenter
[oc
] <= 0)
959 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
961 if (ic_connected
[ic
]) {
962 r
->map_table
[oc
][ic
] *= .75f
;
966 if (!on_center(r
->i_cm
.map
[ic
]))
969 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
970 r
->map_table
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
976 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
978 /* OK, so there is an unconnected LFE channel. Let's mix
979 * it into all channels, with factor 0.375 */
981 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
983 if (!on_lfe(r
->i_cm
.map
[ic
]))
986 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
987 r
->map_table
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
995 pa_strbuf_printf(s
, " ");
996 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
997 pa_strbuf_printf(s
, " I%02u ", ic
);
998 pa_strbuf_puts(s
, "\n +");
1000 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
1001 pa_strbuf_printf(s
, "------");
1002 pa_strbuf_puts(s
, "\n");
1004 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1005 pa_strbuf_printf(s
, "O%02u |", oc
);
1007 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
1008 pa_strbuf_printf(s
, " %1.3f", r
->map_table
[oc
][ic
]);
1010 pa_strbuf_puts(s
, "\n");
1013 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
1017 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1023 pa_assert(input
->memblock
);
1025 /* Convert the incoming sample into the work sample format and place them in buf1 */
1027 if (!r
->to_work_format_func
|| !input
->length
)
1030 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1033 r
->buf1
.length
= r
->w_sz
* n_samples
;
1035 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
1036 if (r
->buf1
.memblock
)
1037 pa_memblock_unref(r
->buf1
.memblock
);
1039 r
->buf1_samples
= n_samples
;
1040 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
1043 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1044 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
1046 r
->to_work_format_func(n_samples
, src
, dst
);
1048 pa_memblock_release(input
->memblock
);
1049 pa_memblock_release(r
->buf1
.memblock
);
1054 static void vectoradd_s16_with_fraction(
1055 int16_t *d
, int dstr
,
1056 const int16_t *s1
, int sstr1
,
1057 const int16_t *s2
, int sstr2
,
1059 float s3
, float s4
) {
1063 i3
= (int32_t) (s3
* 0x10000);
1064 i4
= (int32_t) (s4
* 0x10000);
1066 for (; n
> 0; n
--) {
1072 a
= (a
* i3
) / 0x10000;
1073 b
= (b
* i4
) / 0x10000;
1075 *d
= (int16_t) (a
+ b
);
1077 s1
= (const int16_t*) ((const uint8_t*) s1
+ sstr1
);
1078 s2
= (const int16_t*) ((const uint8_t*) s2
+ sstr2
);
1079 d
= (int16_t*) ((uint8_t*) d
+ dstr
);
1084 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1085 unsigned in_n_samples
, out_n_samples
, n_frames
;
1092 pa_assert(input
->memblock
);
1094 /* Remap channels and place the result int buf2 */
1096 if (!r
->map_required
|| !input
->length
)
1099 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1100 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1101 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1104 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
1106 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
1107 if (r
->buf2
.memblock
)
1108 pa_memblock_unref(r
->buf2
.memblock
);
1110 r
->buf2_samples
= out_n_samples
;
1111 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
1114 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1115 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
1117 memset(dst
, 0, r
->buf2
.length
);
1119 o_skip
= (int) (r
->w_sz
* r
->o_ss
.channels
);
1120 i_skip
= (int) (r
->w_sz
* r
->i_ss
.channels
);
1122 switch (r
->work_format
) {
1123 case PA_SAMPLE_FLOAT32NE
:
1125 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1127 static const float one
= 1.0;
1129 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1131 if (r
->map_table
[oc
][ic
] <= 0.0)
1135 (float*) dst
+ oc
, o_skip
,
1136 (float*) dst
+ oc
, o_skip
,
1137 (float*) src
+ ic
, i_skip
,
1139 &one
, &r
->map_table
[oc
][ic
]);
1145 case PA_SAMPLE_S16NE
:
1147 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1150 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1152 if (r
->map_table
[oc
][ic
] <= 0.0)
1155 if (r
->map_table
[oc
][ic
] >= 1.0) {
1156 static const int16_t one
= 1;
1159 (int16_t*) dst
+ oc
, o_skip
,
1160 (int16_t*) dst
+ oc
, o_skip
,
1161 (int16_t*) src
+ ic
, i_skip
,
1167 vectoradd_s16_with_fraction(
1168 (int16_t*) dst
+ oc
, o_skip
,
1169 (int16_t*) dst
+ oc
, o_skip
,
1170 (int16_t*) src
+ ic
, i_skip
,
1172 1.0f
, r
->map_table
[oc
][ic
]);
1179 pa_assert_not_reached();
1182 pa_memblock_release(input
->memblock
);
1183 pa_memblock_release(r
->buf2
.memblock
);
1185 r
->buf2
.length
= out_n_samples
* r
->w_sz
;
1190 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1191 unsigned in_n_frames
, in_n_samples
;
1192 unsigned out_n_frames
, out_n_samples
;
1197 /* Resample the data and place the result in buf3 */
1199 if (!r
->impl_resample
|| !input
->length
)
1202 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1203 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1205 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1206 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1209 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1211 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1212 if (r
->buf3
.memblock
)
1213 pa_memblock_unref(r
->buf3
.memblock
);
1215 r
->buf3_samples
= out_n_samples
;
1216 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1219 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1220 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1225 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1226 unsigned n_samples
, n_frames
;
1232 /* Convert the data into the correct sample type and place the result in buf4 */
1234 if (!r
->from_work_format_func
|| !input
->length
)
1237 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1238 n_frames
= n_samples
/ r
->o_ss
.channels
;
1241 r
->buf4
.length
= r
->o_fz
* n_frames
;
1243 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1244 if (r
->buf4
.memblock
)
1245 pa_memblock_unref(r
->buf4
.memblock
);
1247 r
->buf4_samples
= n_samples
;
1248 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1251 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1252 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1253 r
->from_work_format_func(n_samples
, src
, dst
);
1254 pa_memblock_release(input
->memblock
);
1255 pa_memblock_release(r
->buf4
.memblock
);
1257 r
->buf4
.length
= r
->o_fz
* n_frames
;
1262 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1268 pa_assert(in
->length
);
1269 pa_assert(in
->memblock
);
1270 pa_assert(in
->length
% r
->i_fz
== 0);
1272 buf
= (pa_memchunk
*) in
;
1273 buf
= convert_to_work_format(r
, buf
);
1274 buf
= remap_channels(r
, buf
);
1275 buf
= resample(r
, buf
);
1278 buf
= convert_from_work_format(r
, buf
);
1282 pa_memblock_ref(buf
->memblock
);
1284 pa_memchunk_reset(buf
);
1286 pa_memchunk_reset(out
);
1289 /*** libsamplerate based implementation ***/
1291 #ifdef HAVE_LIBSAMPLERATE
1292 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1298 pa_assert(out_n_frames
);
1300 memset(&data
, 0, sizeof(data
));
1302 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1303 data
.input_frames
= (long int) in_n_frames
;
1305 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1306 data
.output_frames
= (long int) *out_n_frames
;
1308 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1309 data
.end_of_input
= 0;
1311 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1312 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1314 pa_memblock_release(input
->memblock
);
1315 pa_memblock_release(output
->memblock
);
1317 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1320 static void libsamplerate_update_rates(pa_resampler
*r
) {
1323 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1326 static void libsamplerate_reset(pa_resampler
*r
) {
1329 pa_assert_se(src_reset(r
->src
.state
) == 0);
1332 static void libsamplerate_free(pa_resampler
*r
) {
1336 src_delete(r
->src
.state
);
1339 static int libsamplerate_init(pa_resampler
*r
) {
1344 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1347 r
->impl_free
= libsamplerate_free
;
1348 r
->impl_update_rates
= libsamplerate_update_rates
;
1349 r
->impl_resample
= libsamplerate_resample
;
1350 r
->impl_reset
= libsamplerate_reset
;
1356 /*** speex based implementation ***/
1358 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1360 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1365 pa_assert(out_n_frames
);
1367 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1368 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1370 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1372 pa_memblock_release(input
->memblock
);
1373 pa_memblock_release(output
->memblock
);
1375 pa_assert(inf
== in_n_frames
);
1376 *out_n_frames
= outf
;
1379 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1381 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1386 pa_assert(out_n_frames
);
1388 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1389 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1391 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1393 pa_memblock_release(input
->memblock
);
1394 pa_memblock_release(output
->memblock
);
1396 pa_assert(inf
== in_n_frames
);
1397 *out_n_frames
= outf
;
1400 static void speex_update_rates(pa_resampler
*r
) {
1403 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1406 static void speex_reset(pa_resampler
*r
) {
1409 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1412 static void speex_free(pa_resampler
*r
) {
1415 if (!r
->speex
.state
)
1418 speex_resampler_destroy(r
->speex
.state
);
1421 static int speex_init(pa_resampler
*r
) {
1426 r
->impl_free
= speex_free
;
1427 r
->impl_update_rates
= speex_update_rates
;
1428 r
->impl_reset
= speex_reset
;
1430 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1432 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1433 r
->impl_resample
= speex_resample_int
;
1436 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1438 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1439 r
->impl_resample
= speex_resample_float
;
1442 pa_log_info("Choosing speex quality setting %i.", q
);
1444 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1450 /* Trivial implementation */
1452 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1460 pa_assert(out_n_frames
);
1462 fz
= r
->w_sz
* r
->o_ss
.channels
;
1464 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1465 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1467 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1470 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1471 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1473 if (j
>= in_n_frames
)
1476 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1478 oil_memcpy((uint8_t*) dst
+ fz
* o_index
,
1479 (uint8_t*) src
+ fz
* j
, (int) fz
);
1482 pa_memblock_release(input
->memblock
);
1483 pa_memblock_release(output
->memblock
);
1485 *out_n_frames
= o_index
;
1487 r
->trivial
.i_counter
+= in_n_frames
;
1489 /* Normalize counters */
1490 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1491 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1493 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1494 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1498 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1501 r
->trivial
.i_counter
= 0;
1502 r
->trivial
.o_counter
= 0;
1505 static int trivial_init(pa_resampler
*r
) {
1508 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1510 r
->impl_resample
= trivial_resample
;
1511 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1512 r
->impl_reset
= trivial_update_rates_or_reset
;
1517 /* Peak finder implementation */
1519 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1528 pa_assert(out_n_frames
);
1530 fz
= r
->w_sz
* r
->o_ss
.channels
;
1532 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1533 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1535 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1538 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1540 if (j
> r
->peaks
.i_counter
)
1541 j
-= r
->peaks
.i_counter
;
1545 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1547 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1549 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* start
);
1550 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1552 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1554 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1557 n
= (int16_t) (*s
< 0 ? -*s
: *s
);
1559 if (PA_UNLIKELY(n
> r
->peaks
.max_i
[c
]))
1560 r
->peaks
.max_i
[c
] = n
;
1563 if (i
>= in_n_frames
)
1566 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1567 *d
= r
->peaks
.max_i
[c
];
1568 r
->peaks
.max_i
[c
] = 0;
1573 float *s
= (float*) ((uint8_t*) src
+ fz
* start
);
1574 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1576 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1578 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1579 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1580 float n
= fabsf(*s
);
1582 if (n
> r
->peaks
.max_f
[c
])
1583 r
->peaks
.max_f
[c
] = n
;
1586 if (i
>= in_n_frames
)
1589 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1590 *d
= r
->peaks
.max_f
[c
];
1591 r
->peaks
.max_f
[c
] = 0;
1598 pa_memblock_release(input
->memblock
);
1599 pa_memblock_release(output
->memblock
);
1601 *out_n_frames
= o_index
;
1603 r
->peaks
.i_counter
+= in_n_frames
;
1605 /* Normalize counters */
1606 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1607 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1609 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1610 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1614 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1617 r
->peaks
.i_counter
= 0;
1618 r
->peaks
.o_counter
= 0;
1621 static int peaks_init(pa_resampler
*r
) {
1624 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1625 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1626 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1628 r
->impl_resample
= peaks_resample
;
1629 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1630 r
->impl_reset
= peaks_update_rates_or_reset
;
1635 /*** ffmpeg based implementation ***/
1637 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1638 unsigned used_frames
= 0, c
;
1643 pa_assert(out_n_frames
);
1645 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1648 int16_t *p
, *t
, *k
, *q
, *s
;
1649 int consumed_frames
;
1652 /* Allocate a new block */
1653 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1654 p
= pa_memblock_acquire(b
);
1656 /* Copy the remaining data into it */
1657 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1658 if (r
->ffmpeg
.buf
[c
].memblock
) {
1659 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1661 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1662 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1663 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1666 /* Now append the new data, splitting up channels */
1667 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1668 k
= (int16_t*) ((uint8_t*) p
+ l
);
1669 for (u
= 0; u
< in_n_frames
; u
++) {
1671 t
+= r
->o_ss
.channels
;
1674 pa_memblock_release(input
->memblock
);
1676 /* Calculate the resulting number of frames */
1677 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1679 /* Allocate buffer for the result */
1680 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1681 q
= pa_memblock_acquire(w
);
1684 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1687 (int) in
, (int) *out_n_frames
,
1688 c
>= (unsigned) (r
->o_ss
.channels
-1));
1690 pa_memblock_release(b
);
1692 /* Now store the remaining samples away */
1693 pa_assert(consumed_frames
<= (int) in
);
1694 if (consumed_frames
< (int) in
) {
1695 r
->ffmpeg
.buf
[c
].memblock
= b
;
1696 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1697 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1699 pa_memblock_unref(b
);
1701 /* And place the results in the output buffer */
1702 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1703 for (u
= 0; u
< used_frames
; u
++) {
1706 s
+= r
->o_ss
.channels
;
1708 pa_memblock_release(output
->memblock
);
1709 pa_memblock_release(w
);
1710 pa_memblock_unref(w
);
1713 *out_n_frames
= used_frames
;
1716 static void ffmpeg_free(pa_resampler
*r
) {
1721 if (r
->ffmpeg
.state
)
1722 av_resample_close(r
->ffmpeg
.state
);
1724 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1725 if (r
->ffmpeg
.buf
[c
].memblock
)
1726 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1729 static int ffmpeg_init(pa_resampler
*r
) {
1734 /* We could probably implement different quality levels by
1735 * adjusting the filter parameters here. However, ffmpeg
1736 * internally only uses these hardcoded values, so let's use them
1737 * here for now as well until ffmpeg makes this configurable. */
1739 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1742 r
->impl_free
= ffmpeg_free
;
1743 r
->impl_resample
= ffmpeg_resample
;
1745 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1746 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1751 /*** copy (noop) implementation ***/
1753 static int copy_init(pa_resampler
*r
) {
1756 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);