2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2.1 of the License,
9 or (at your option) any later version.
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 #ifdef HAVE_LIBSAMPLERATE
29 #include <samplerate.h>
32 #include <speex/speex_resampler.h>
34 #include <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 /* Let's round up here */
352 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
;
355 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
358 /* Let's round up here */
360 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
;
363 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
364 size_t block_size_max
;
370 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
372 /* We deduce the "largest" sample spec we're using during the
374 ss
.channels
= (uint8_t) (PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
));
376 /* We silently assume that the format enum is ordered by size */
377 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
378 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
380 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
382 fs
= pa_frame_size(&ss
);
384 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
387 void pa_resampler_reset(pa_resampler
*r
) {
394 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
400 const pa_channel_map
* pa_resampler_input_channel_map(pa_resampler
*r
) {
406 const pa_sample_spec
* pa_resampler_input_sample_spec(pa_resampler
*r
) {
412 const pa_channel_map
* pa_resampler_output_channel_map(pa_resampler
*r
) {
418 const pa_sample_spec
* pa_resampler_output_sample_spec(pa_resampler
*r
) {
424 static const char * const resample_methods
[] = {
425 "src-sinc-best-quality",
426 "src-sinc-medium-quality",
428 "src-zero-order-hold",
459 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
461 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
464 return resample_methods
[m
];
467 int pa_resample_method_supported(pa_resample_method_t m
) {
469 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
472 #ifndef HAVE_LIBSAMPLERATE
473 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
480 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
481 pa_resample_method_t m
;
485 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
486 if (!strcmp(string
, resample_methods
[m
]))
489 if (!strcmp(string
, "speex-fixed"))
490 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
492 if (!strcmp(string
, "speex-float"))
493 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
495 return PA_RESAMPLER_INVALID
;
498 static pa_bool_t
on_left(pa_channel_position_t p
) {
501 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
502 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
503 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
504 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
505 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
506 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
509 static pa_bool_t
on_right(pa_channel_position_t p
) {
512 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
513 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
514 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
515 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
516 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
517 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
520 static pa_bool_t
on_center(pa_channel_position_t p
) {
523 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
524 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
525 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
526 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
527 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
530 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
532 p
== PA_CHANNEL_POSITION_LFE
;
535 static pa_bool_t
on_front(pa_channel_position_t p
) {
537 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
538 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
539 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
540 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
541 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
542 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
543 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
544 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
547 static pa_bool_t
on_rear(pa_channel_position_t p
) {
549 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
550 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
551 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
552 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
553 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
554 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
557 static pa_bool_t
on_side(pa_channel_position_t p
) {
559 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
560 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
561 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
571 static int front_rear_side(pa_channel_position_t p
) {
581 static void calc_map_table(pa_resampler
*r
) {
583 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
590 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
)))))
593 memset(r
->map_table
, 0, sizeof(r
->map_table
));
594 memset(ic_connected
, 0, sizeof(ic_connected
));
595 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
597 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
598 pa_bool_t oc_connected
= FALSE
;
599 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
601 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
602 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
604 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
605 /* We shall not do any remapping. Hence, just check by index */
608 r
->map_table
[oc
][ic
] = 1.0;
613 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
614 /* We shall not do any remixing. Hence, just check by name */
617 r
->map_table
[oc
][ic
] = 1.0;
624 /* OK, we shall do the full monty: upmixing and
625 * downmixing. Our algorithm is relatively simple, does
626 * not do spacialization, delay elements or apply lowpass
627 * filters for LFE. Patches are always welcome,
628 * though. Oh, and it doesn't do any matrix
629 * decoding. (Which probably wouldn't make any sense
632 * This code is not idempotent: downmixing an upmixed
633 * stereo stream is not identical to the original. The
634 * volume will not match, and the two channels will be a
635 * linear combination of both.
637 * This is losely based on random suggestions found on the
638 * Internet, such as this:
639 * http://www.halfgaar.net/surround-sound-in-linux and the
642 * The algorithm works basically like this:
644 * 1) Connect all channels with matching names.
647 * S:Mono: Copy into all D:channels
648 * D:Mono: Copy in all S:channels
650 * 3) Mix D:Left, D:Right:
651 * D:Left: If not connected, avg all S:Left
652 * D:Right: If not connected, avg all S:Right
655 * If not connected, avg all S:Center
656 * If still not connected, avg all S:Left, S:Right
659 * If not connected, avg all S:*
661 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
662 * not connected, mix into all D:left and all D:right
663 * channels. Gain is 0.1, the current left and right
664 * should be multiplied by 0.9.
666 * 7) Make sure S:Center, S:LFE is used:
668 * S:Center, S:LFE: If not connected, mix into all
669 * D:left, all D:right, all D:center channels, gain is
670 * 0.375. The current (as result of 1..6) factors
671 * should be multiplied by 0.75. (Alt. suggestion: 0.25
672 * vs. 0.5) If C-front is only mixed into
673 * L-front/R-front if available, otherwise into all L/R
674 * channels. Similarly for C-rear.
676 * S: and D: shall relate to the source resp. destination channels.
678 * Rationale: 1, 2 are probably obvious. For 3: this
679 * copies front to rear if needed. For 4: we try to find
680 * some suitable C source for C, if we don't find any, we
681 * avg L and R. For 5: LFE is mixed from all channels. For
682 * 6: the rear channels should not be dropped entirely,
683 * however have only minimal impact. For 7: movies usually
684 * encode speech on the center channel. Thus we have to
685 * make sure this channel is distributed to L and R if not
686 * available in the output. Also, LFE is used to achieve a
687 * greater dynamic range, and thus we should try to do our
688 * best to pass it to L+R.
691 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
692 r
->map_table
[oc
][ic
] = 1.0;
695 ic_connected
[ic
] = TRUE
;
699 if (!oc_connected
&& remix
) {
700 /* OK, we shall remix */
702 /* Try to find matching input ports for this output port */
707 /* We are not connected and on the left side, let's
708 * average all left side input channels. */
710 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
711 if (on_left(r
->i_cm
.map
[ic
]))
715 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
716 if (on_left(r
->i_cm
.map
[ic
])) {
717 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
718 ic_connected
[ic
] = TRUE
;
721 /* We ignore the case where there is no left input
722 * channel. Something is really wrong in this case
725 } else if (on_right(b
)) {
728 /* We are not connected and on the right side, let's
729 * average all right side input channels. */
731 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
732 if (on_right(r
->i_cm
.map
[ic
]))
736 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
737 if (on_right(r
->i_cm
.map
[ic
])) {
738 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
739 ic_connected
[ic
] = TRUE
;
742 /* We ignore the case where there is no right input
743 * channel. Something is really wrong in this case
746 } else if (on_center(b
)) {
749 /* We are not connected and at the center. Let's
750 * average all center input channels. */
752 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
753 if (on_center(r
->i_cm
.map
[ic
]))
757 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
758 if (on_center(r
->i_cm
.map
[ic
])) {
759 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
760 ic_connected
[ic
] = TRUE
;
764 /* Hmm, no center channel around, let's synthesize
765 * it by mixing L and R.*/
769 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
770 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
774 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
775 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
776 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
777 ic_connected
[ic
] = TRUE
;
780 /* We ignore the case where there is not even a
781 * left or right input channel. Something is
782 * really wrong in this case anyway. */
785 } else if (on_lfe(b
)) {
787 /* We are not connected and an LFE. Let's average all
788 * channels for LFE. */
790 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
792 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
793 r
->map_table
[oc
][ic
] = 1.0f
/ (float) r
->i_ss
.channels
;
795 r
->map_table
[oc
][ic
] = 0;
797 /* Please note that a channel connected to LFE
798 * doesn't really count as connected. */
806 ic_unconnected_left
= 0,
807 ic_unconnected_right
= 0,
808 ic_unconnected_center
= 0,
809 ic_unconnected_lfe
= 0;
811 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
812 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
814 if (ic_connected
[ic
])
818 ic_unconnected_left
++;
819 else if (on_right(a
))
820 ic_unconnected_right
++;
821 else if (on_center(a
))
822 ic_unconnected_center
++;
824 ic_unconnected_lfe
++;
827 if (ic_unconnected_left
> 0) {
829 /* OK, so there are unconnected input channels on the
830 * left. Let's multiply all already connected channels on
831 * the left side by .9 and add in our averaged unconnected
832 * channels multplied by .1 */
834 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
836 if (!on_left(r
->o_cm
.map
[oc
]))
839 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
841 if (ic_connected
[ic
]) {
842 r
->map_table
[oc
][ic
] *= .9f
;
846 if (on_left(r
->i_cm
.map
[ic
]))
847 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
852 if (ic_unconnected_right
> 0) {
854 /* OK, so there are unconnected input channels on the
855 * right. Let's multiply all already connected channels on
856 * the right side by .9 and add in our averaged unconnected
857 * channels multplied by .1 */
859 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
861 if (!on_right(r
->o_cm
.map
[oc
]))
864 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
866 if (ic_connected
[ic
]) {
867 r
->map_table
[oc
][ic
] *= .9f
;
871 if (on_right(r
->i_cm
.map
[ic
]))
872 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
877 if (ic_unconnected_center
> 0) {
878 pa_bool_t mixed_in
= FALSE
;
880 /* OK, so there are unconnected input channels on the
881 * center. Let's multiply all already connected channels on
882 * the center side by .9 and add in our averaged unconnected
883 * channels multplied by .1 */
885 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
887 if (!on_center(r
->o_cm
.map
[oc
]))
890 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
892 if (ic_connected
[ic
]) {
893 r
->map_table
[oc
][ic
] *= .9f
;
897 if (on_center(r
->i_cm
.map
[ic
])) {
898 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
905 unsigned ncenter
[PA_CHANNELS_MAX
];
906 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
908 memset(ncenter
, 0, sizeof(ncenter
));
909 memset(found_frs
, 0, sizeof(found_frs
));
911 /* Hmm, as it appears there was no center channel we
912 could mix our center channel in. In this case, mix
913 it into left and right. Using .375 and 0.75 as
916 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
918 if (ic_connected
[ic
])
921 if (!on_center(r
->i_cm
.map
[ic
]))
924 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
926 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
929 if (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
930 found_frs
[ic
] = TRUE
;
935 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
937 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
940 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
945 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
947 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
950 if (ncenter
[oc
] <= 0)
953 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
955 if (ic_connected
[ic
]) {
956 r
->map_table
[oc
][ic
] *= .75f
;
960 if (!on_center(r
->i_cm
.map
[ic
]))
963 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
964 r
->map_table
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
970 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
972 /* OK, so there is an unconnected LFE channel. Let's mix
973 * it into all channels, with factor 0.375 */
975 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
977 if (!on_lfe(r
->i_cm
.map
[ic
]))
980 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
981 r
->map_table
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
989 pa_strbuf_printf(s
, " ");
990 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
991 pa_strbuf_printf(s
, " I%02u ", ic
);
992 pa_strbuf_puts(s
, "\n +");
994 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
995 pa_strbuf_printf(s
, "------");
996 pa_strbuf_puts(s
, "\n");
998 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
999 pa_strbuf_printf(s
, "O%02u |", oc
);
1001 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
1002 pa_strbuf_printf(s
, " %1.3f", r
->map_table
[oc
][ic
]);
1004 pa_strbuf_puts(s
, "\n");
1007 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
1011 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1017 pa_assert(input
->memblock
);
1019 /* Convert the incoming sample into the work sample format and place them in buf1 */
1021 if (!r
->to_work_format_func
|| !input
->length
)
1024 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1027 r
->buf1
.length
= r
->w_sz
* n_samples
;
1029 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
1030 if (r
->buf1
.memblock
)
1031 pa_memblock_unref(r
->buf1
.memblock
);
1033 r
->buf1_samples
= n_samples
;
1034 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
1037 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1038 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
1040 r
->to_work_format_func(n_samples
, src
, dst
);
1042 pa_memblock_release(input
->memblock
);
1043 pa_memblock_release(r
->buf1
.memblock
);
1048 static void vectoradd_s16_with_fraction(
1049 int16_t *d
, int dstr
,
1050 const int16_t *s1
, int sstr1
,
1051 const int16_t *s2
, int sstr2
,
1053 float s3
, float s4
) {
1057 i3
= (int32_t) (s3
* 0x10000);
1058 i4
= (int32_t) (s4
* 0x10000);
1060 for (; n
> 0; n
--) {
1066 a
= (a
* i3
) / 0x10000;
1067 b
= (b
* i4
) / 0x10000;
1069 *d
= (int16_t) (a
+ b
);
1071 s1
= (const int16_t*) ((const uint8_t*) s1
+ sstr1
);
1072 s2
= (const int16_t*) ((const uint8_t*) s2
+ sstr2
);
1073 d
= (int16_t*) ((uint8_t*) d
+ dstr
);
1078 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1079 unsigned in_n_samples
, out_n_samples
, n_frames
;
1086 pa_assert(input
->memblock
);
1088 /* Remap channels and place the result int buf2 */
1090 if (!r
->map_required
|| !input
->length
)
1093 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1094 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1095 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1098 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
1100 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
1101 if (r
->buf2
.memblock
)
1102 pa_memblock_unref(r
->buf2
.memblock
);
1104 r
->buf2_samples
= out_n_samples
;
1105 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
1108 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1109 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
1111 memset(dst
, 0, r
->buf2
.length
);
1113 o_skip
= (int) (r
->w_sz
* r
->o_ss
.channels
);
1114 i_skip
= (int) (r
->w_sz
* r
->i_ss
.channels
);
1116 switch (r
->work_format
) {
1117 case PA_SAMPLE_FLOAT32NE
:
1119 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1121 static const float one
= 1.0;
1123 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1125 if (r
->map_table
[oc
][ic
] <= 0.0)
1129 (float*) dst
+ oc
, o_skip
,
1130 (float*) dst
+ oc
, o_skip
,
1131 (float*) src
+ ic
, i_skip
,
1133 &one
, &r
->map_table
[oc
][ic
]);
1139 case PA_SAMPLE_S16NE
:
1141 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1144 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1146 if (r
->map_table
[oc
][ic
] <= 0.0)
1149 if (r
->map_table
[oc
][ic
] >= 1.0) {
1150 static const int16_t one
= 1;
1153 (int16_t*) dst
+ oc
, o_skip
,
1154 (int16_t*) dst
+ oc
, o_skip
,
1155 (int16_t*) src
+ ic
, i_skip
,
1161 vectoradd_s16_with_fraction(
1162 (int16_t*) dst
+ oc
, o_skip
,
1163 (int16_t*) dst
+ oc
, o_skip
,
1164 (int16_t*) src
+ ic
, i_skip
,
1166 1.0f
, r
->map_table
[oc
][ic
]);
1173 pa_assert_not_reached();
1176 pa_memblock_release(input
->memblock
);
1177 pa_memblock_release(r
->buf2
.memblock
);
1179 r
->buf2
.length
= out_n_samples
* r
->w_sz
;
1184 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1185 unsigned in_n_frames
, in_n_samples
;
1186 unsigned out_n_frames
, out_n_samples
;
1191 /* Resample the data and place the result in buf3 */
1193 if (!r
->impl_resample
|| !input
->length
)
1196 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1197 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1199 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1200 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1203 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1205 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1206 if (r
->buf3
.memblock
)
1207 pa_memblock_unref(r
->buf3
.memblock
);
1209 r
->buf3_samples
= out_n_samples
;
1210 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1213 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1214 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1219 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1220 unsigned n_samples
, n_frames
;
1226 /* Convert the data into the correct sample type and place the result in buf4 */
1228 if (!r
->from_work_format_func
|| !input
->length
)
1231 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1232 n_frames
= n_samples
/ r
->o_ss
.channels
;
1235 r
->buf4
.length
= r
->o_fz
* n_frames
;
1237 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1238 if (r
->buf4
.memblock
)
1239 pa_memblock_unref(r
->buf4
.memblock
);
1241 r
->buf4_samples
= n_samples
;
1242 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1245 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1246 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1247 r
->from_work_format_func(n_samples
, src
, dst
);
1248 pa_memblock_release(input
->memblock
);
1249 pa_memblock_release(r
->buf4
.memblock
);
1251 r
->buf4
.length
= r
->o_fz
* n_frames
;
1256 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1262 pa_assert(in
->length
);
1263 pa_assert(in
->memblock
);
1264 pa_assert(in
->length
% r
->i_fz
== 0);
1266 buf
= (pa_memchunk
*) in
;
1267 buf
= convert_to_work_format(r
, buf
);
1268 buf
= remap_channels(r
, buf
);
1269 buf
= resample(r
, buf
);
1272 buf
= convert_from_work_format(r
, buf
);
1276 pa_memblock_ref(buf
->memblock
);
1278 pa_memchunk_reset(buf
);
1280 pa_memchunk_reset(out
);
1283 /*** libsamplerate based implementation ***/
1285 #ifdef HAVE_LIBSAMPLERATE
1286 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1292 pa_assert(out_n_frames
);
1294 memset(&data
, 0, sizeof(data
));
1296 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1297 data
.input_frames
= (long int) in_n_frames
;
1299 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1300 data
.output_frames
= (long int) *out_n_frames
;
1302 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1303 data
.end_of_input
= 0;
1305 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1306 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1308 pa_memblock_release(input
->memblock
);
1309 pa_memblock_release(output
->memblock
);
1311 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1314 static void libsamplerate_update_rates(pa_resampler
*r
) {
1317 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1320 static void libsamplerate_reset(pa_resampler
*r
) {
1323 pa_assert_se(src_reset(r
->src
.state
) == 0);
1326 static void libsamplerate_free(pa_resampler
*r
) {
1330 src_delete(r
->src
.state
);
1333 static int libsamplerate_init(pa_resampler
*r
) {
1338 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1341 r
->impl_free
= libsamplerate_free
;
1342 r
->impl_update_rates
= libsamplerate_update_rates
;
1343 r
->impl_resample
= libsamplerate_resample
;
1344 r
->impl_reset
= libsamplerate_reset
;
1350 /*** speex based implementation ***/
1352 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1354 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1359 pa_assert(out_n_frames
);
1361 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1362 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1364 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1366 pa_memblock_release(input
->memblock
);
1367 pa_memblock_release(output
->memblock
);
1369 pa_assert(inf
== in_n_frames
);
1370 *out_n_frames
= outf
;
1373 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1375 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1380 pa_assert(out_n_frames
);
1382 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1383 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1385 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1387 pa_memblock_release(input
->memblock
);
1388 pa_memblock_release(output
->memblock
);
1390 pa_assert(inf
== in_n_frames
);
1391 *out_n_frames
= outf
;
1394 static void speex_update_rates(pa_resampler
*r
) {
1397 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1400 static void speex_reset(pa_resampler
*r
) {
1403 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1406 static void speex_free(pa_resampler
*r
) {
1409 if (!r
->speex
.state
)
1412 speex_resampler_destroy(r
->speex
.state
);
1415 static int speex_init(pa_resampler
*r
) {
1420 r
->impl_free
= speex_free
;
1421 r
->impl_update_rates
= speex_update_rates
;
1422 r
->impl_reset
= speex_reset
;
1424 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1426 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1427 r
->impl_resample
= speex_resample_int
;
1430 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1432 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1433 r
->impl_resample
= speex_resample_float
;
1436 pa_log_info("Choosing speex quality setting %i.", q
);
1438 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1444 /* Trivial implementation */
1446 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1454 pa_assert(out_n_frames
);
1456 fz
= r
->w_sz
* r
->o_ss
.channels
;
1458 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1459 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1461 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1464 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1465 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1467 if (j
>= in_n_frames
)
1470 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1472 oil_memcpy((uint8_t*) dst
+ fz
* o_index
,
1473 (uint8_t*) src
+ fz
* j
, (int) fz
);
1476 pa_memblock_release(input
->memblock
);
1477 pa_memblock_release(output
->memblock
);
1479 *out_n_frames
= o_index
;
1481 r
->trivial
.i_counter
+= in_n_frames
;
1483 /* Normalize counters */
1484 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1485 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1487 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1488 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1492 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1495 r
->trivial
.i_counter
= 0;
1496 r
->trivial
.o_counter
= 0;
1499 static int trivial_init(pa_resampler
*r
) {
1502 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1504 r
->impl_resample
= trivial_resample
;
1505 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1506 r
->impl_reset
= trivial_update_rates_or_reset
;
1511 /* Peak finder implementation */
1513 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1522 pa_assert(out_n_frames
);
1524 fz
= r
->w_sz
* r
->o_ss
.channels
;
1526 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1527 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1529 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1532 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1534 if (j
> r
->peaks
.i_counter
)
1535 j
-= r
->peaks
.i_counter
;
1539 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1541 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1543 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* start
);
1544 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1546 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1548 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1551 n
= (int16_t) (*s
< 0 ? -*s
: *s
);
1553 if (PA_UNLIKELY(n
> r
->peaks
.max_i
[c
]))
1554 r
->peaks
.max_i
[c
] = n
;
1557 if (i
>= in_n_frames
)
1560 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1561 *d
= r
->peaks
.max_i
[c
];
1562 r
->peaks
.max_i
[c
] = 0;
1567 float *s
= (float*) ((uint8_t*) src
+ fz
* start
);
1568 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1570 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1572 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1573 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1574 float n
= fabsf(*s
);
1576 if (n
> r
->peaks
.max_f
[c
])
1577 r
->peaks
.max_f
[c
] = n
;
1580 if (i
>= in_n_frames
)
1583 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1584 *d
= r
->peaks
.max_f
[c
];
1585 r
->peaks
.max_f
[c
] = 0;
1592 pa_memblock_release(input
->memblock
);
1593 pa_memblock_release(output
->memblock
);
1595 *out_n_frames
= o_index
;
1597 r
->peaks
.i_counter
+= in_n_frames
;
1599 /* Normalize counters */
1600 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1601 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1603 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1604 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1608 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1611 r
->peaks
.i_counter
= 0;
1612 r
->peaks
.o_counter
= 0;
1615 static int peaks_init(pa_resampler
*r
) {
1618 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1619 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1620 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1622 r
->impl_resample
= peaks_resample
;
1623 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1624 r
->impl_reset
= peaks_update_rates_or_reset
;
1629 /*** ffmpeg based implementation ***/
1631 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1632 unsigned used_frames
= 0, c
;
1637 pa_assert(out_n_frames
);
1639 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1642 int16_t *p
, *t
, *k
, *q
, *s
;
1643 int consumed_frames
;
1646 /* Allocate a new block */
1647 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1648 p
= pa_memblock_acquire(b
);
1650 /* Copy the remaining data into it */
1651 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1652 if (r
->ffmpeg
.buf
[c
].memblock
) {
1653 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1655 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1656 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1657 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1660 /* Now append the new data, splitting up channels */
1661 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1662 k
= (int16_t*) ((uint8_t*) p
+ l
);
1663 for (u
= 0; u
< in_n_frames
; u
++) {
1665 t
+= r
->o_ss
.channels
;
1668 pa_memblock_release(input
->memblock
);
1670 /* Calculate the resulting number of frames */
1671 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1673 /* Allocate buffer for the result */
1674 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1675 q
= pa_memblock_acquire(w
);
1678 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1681 (int) in
, (int) *out_n_frames
,
1682 c
>= (unsigned) (r
->o_ss
.channels
-1));
1684 pa_memblock_release(b
);
1686 /* Now store the remaining samples away */
1687 pa_assert(consumed_frames
<= (int) in
);
1688 if (consumed_frames
< (int) in
) {
1689 r
->ffmpeg
.buf
[c
].memblock
= b
;
1690 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1691 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1693 pa_memblock_unref(b
);
1695 /* And place the results in the output buffer */
1696 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1697 for (u
= 0; u
< used_frames
; u
++) {
1700 s
+= r
->o_ss
.channels
;
1702 pa_memblock_release(output
->memblock
);
1703 pa_memblock_release(w
);
1704 pa_memblock_unref(w
);
1707 *out_n_frames
= used_frames
;
1710 static void ffmpeg_free(pa_resampler
*r
) {
1715 if (r
->ffmpeg
.state
)
1716 av_resample_close(r
->ffmpeg
.state
);
1718 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1719 if (r
->ffmpeg
.buf
[c
].memblock
)
1720 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1723 static int ffmpeg_init(pa_resampler
*r
) {
1728 /* We could probably implement different quality levels by
1729 * adjusting the filter parameters here. However, ffmpeg
1730 * internally only uses these hardcoded values, so let's use them
1731 * here for now as well until ffmpeg makes this configurable. */
1733 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1736 r
->impl_free
= ffmpeg_free
;
1737 r
->impl_resample
= ffmpeg_resample
;
1739 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1740 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1745 /*** copy (noop) implementation ***/
1747 static int copy_init(pa_resampler
*r
) {
1750 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);