4 This file is part of PulseAudio.
6 Copyright 2004-2006 Lennart Poettering
8 PulseAudio is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published
10 by the Free Software Foundation; either version 2 of the License,
11 or (at your option) any later version.
13 PulseAudio is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with PulseAudio; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
30 #if HAVE_LIBSAMPLERATE
31 #include <samplerate.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 "speexwrap.h"
45 #include "ffmpeg/avcodec.h"
47 #include "resampler.h"
49 /* Number of samples of extra space we allow the resamplers to return */
50 #define EXTRA_FRAMES 128
53 pa_resample_method_t method
;
54 pa_resample_flags_t flags
;
56 pa_sample_spec i_ss
, o_ss
;
57 pa_channel_map i_cm
, o_cm
;
58 size_t i_fz
, o_fz
, w_sz
;
61 pa_memchunk buf1
, buf2
, buf3
, buf4
;
62 unsigned buf1_samples
, buf2_samples
, buf3_samples
, buf4_samples
;
64 pa_sample_format_t work_format
;
66 pa_convert_func_t to_work_format_func
;
67 pa_convert_func_t from_work_format_func
;
69 float map_table
[PA_CHANNELS_MAX
][PA_CHANNELS_MAX
];
70 pa_bool_t map_required
;
72 void (*impl_free
)(pa_resampler
*r
);
73 void (*impl_update_rates
)(pa_resampler
*r
);
74 void (*impl_resample
)(pa_resampler
*r
, const pa_memchunk
*in
, unsigned in_samples
, pa_memchunk
*out
, unsigned *out_samples
);
75 void (*impl_reset
)(pa_resampler
*r
);
77 struct { /* data specific to the trivial resampler */
82 struct { /* data specific to the peak finder pseudo resampler */
86 float max_f
[PA_CHANNELS_MAX
];
87 int16_t max_i
[PA_CHANNELS_MAX
];
91 #ifdef HAVE_LIBSAMPLERATE
92 struct { /* data specific to libsamplerate */
97 struct { /* data specific to speex */
98 SpeexResamplerState
* state
;
101 struct { /* data specific to ffmpeg */
102 struct AVResampleContext
*state
;
103 pa_memchunk buf
[PA_CHANNELS_MAX
];
107 static int copy_init(pa_resampler
*r
);
108 static int trivial_init(pa_resampler
*r
);
109 static int speex_init(pa_resampler
*r
);
110 static int ffmpeg_init(pa_resampler
*r
);
111 static int peaks_init(pa_resampler
*r
);
112 #ifdef HAVE_LIBSAMPLERATE
113 static int libsamplerate_init(pa_resampler
*r
);
116 static void calc_map_table(pa_resampler
*r
);
118 static int (* const init_table
[])(pa_resampler
*r
) = {
119 #ifdef HAVE_LIBSAMPLERATE
120 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = libsamplerate_init
,
121 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = libsamplerate_init
,
122 [PA_RESAMPLER_SRC_SINC_FASTEST
] = libsamplerate_init
,
123 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = libsamplerate_init
,
124 [PA_RESAMPLER_SRC_LINEAR
] = libsamplerate_init
,
126 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = NULL
,
127 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = NULL
,
128 [PA_RESAMPLER_SRC_SINC_FASTEST
] = NULL
,
129 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = NULL
,
130 [PA_RESAMPLER_SRC_LINEAR
] = NULL
,
132 [PA_RESAMPLER_TRIVIAL
] = trivial_init
,
133 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+0] = speex_init
,
134 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+1] = speex_init
,
135 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+2] = speex_init
,
136 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+3] = speex_init
,
137 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+4] = speex_init
,
138 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+5] = speex_init
,
139 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+6] = speex_init
,
140 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+7] = speex_init
,
141 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+8] = speex_init
,
142 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+9] = speex_init
,
143 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+10] = speex_init
,
144 [PA_RESAMPLER_SPEEX_FIXED_BASE
+0] = speex_init
,
145 [PA_RESAMPLER_SPEEX_FIXED_BASE
+1] = speex_init
,
146 [PA_RESAMPLER_SPEEX_FIXED_BASE
+2] = speex_init
,
147 [PA_RESAMPLER_SPEEX_FIXED_BASE
+3] = speex_init
,
148 [PA_RESAMPLER_SPEEX_FIXED_BASE
+4] = speex_init
,
149 [PA_RESAMPLER_SPEEX_FIXED_BASE
+5] = speex_init
,
150 [PA_RESAMPLER_SPEEX_FIXED_BASE
+6] = speex_init
,
151 [PA_RESAMPLER_SPEEX_FIXED_BASE
+7] = speex_init
,
152 [PA_RESAMPLER_SPEEX_FIXED_BASE
+8] = speex_init
,
153 [PA_RESAMPLER_SPEEX_FIXED_BASE
+9] = speex_init
,
154 [PA_RESAMPLER_SPEEX_FIXED_BASE
+10] = speex_init
,
155 [PA_RESAMPLER_FFMPEG
] = ffmpeg_init
,
156 [PA_RESAMPLER_AUTO
] = NULL
,
157 [PA_RESAMPLER_COPY
] = copy_init
,
158 [PA_RESAMPLER_PEAKS
] = peaks_init
,
161 static inline size_t sample_size(pa_sample_format_t f
) {
162 pa_sample_spec ss
= {
168 return pa_sample_size(&ss
);
171 pa_resampler
* pa_resampler_new(
173 const pa_sample_spec
*a
,
174 const pa_channel_map
*am
,
175 const pa_sample_spec
*b
,
176 const pa_channel_map
*bm
,
177 pa_resample_method_t method
,
178 pa_resample_flags_t flags
) {
180 pa_resampler
*r
= NULL
;
185 pa_assert(pa_sample_spec_valid(a
));
186 pa_assert(pa_sample_spec_valid(b
));
187 pa_assert(method
>= 0);
188 pa_assert(method
< PA_RESAMPLER_MAX
);
192 if (!(flags
& PA_RESAMPLER_VARIABLE_RATE
) && a
->rate
== b
->rate
) {
193 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
194 method
= PA_RESAMPLER_COPY
;
197 if (!pa_resample_method_supported(method
)) {
198 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method
));
199 method
= PA_RESAMPLER_AUTO
;
202 if (method
== PA_RESAMPLER_FFMPEG
&& (flags
& PA_RESAMPLER_VARIABLE_RATE
)) {
203 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
204 method
= PA_RESAMPLER_AUTO
;
207 if (method
== PA_RESAMPLER_COPY
&& ((flags
& PA_RESAMPLER_VARIABLE_RATE
) || a
->rate
!= b
->rate
)) {
208 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
209 method
= PA_RESAMPLER_AUTO
;
212 if (method
== PA_RESAMPLER_AUTO
)
213 method
= PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
215 r
= pa_xnew(pa_resampler
, 1);
221 r
->impl_update_rates
= NULL
;
222 r
->impl_resample
= NULL
;
223 r
->impl_reset
= NULL
;
225 /* Fill sample specs */
231 else if (!pa_channel_map_init_auto(&r
->i_cm
, r
->i_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
236 else if (!pa_channel_map_init_auto(&r
->o_cm
, r
->o_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
239 r
->i_fz
= pa_frame_size(a
);
240 r
->o_fz
= pa_frame_size(b
);
242 pa_memchunk_reset(&r
->buf1
);
243 pa_memchunk_reset(&r
->buf2
);
244 pa_memchunk_reset(&r
->buf3
);
245 pa_memchunk_reset(&r
->buf4
);
247 r
->buf1_samples
= r
->buf2_samples
= r
->buf3_samples
= r
->buf4_samples
= 0;
251 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method
));
253 if ((method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) ||
254 (method
== PA_RESAMPLER_FFMPEG
))
255 r
->work_format
= PA_SAMPLE_S16NE
;
256 else if (method
== PA_RESAMPLER_TRIVIAL
|| method
== PA_RESAMPLER_COPY
|| method
== PA_RESAMPLER_PEAKS
) {
258 if (r
->map_required
|| a
->format
!= b
->format
|| method
== PA_RESAMPLER_PEAKS
) {
260 if (a
->format
== PA_SAMPLE_S32NE
|| a
->format
== PA_SAMPLE_S32RE
||
261 a
->format
== PA_SAMPLE_FLOAT32NE
|| a
->format
== PA_SAMPLE_FLOAT32RE
||
262 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
263 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
)
264 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
266 r
->work_format
= PA_SAMPLE_S16NE
;
269 r
->work_format
= a
->format
;
272 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
274 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
276 r
->w_sz
= sample_size(r
->work_format
);
278 if (r
->i_ss
.format
== r
->work_format
)
279 r
->to_work_format_func
= NULL
;
280 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
281 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
284 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
285 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
289 if (r
->o_ss
.format
== r
->work_format
)
290 r
->from_work_format_func
= NULL
;
291 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
292 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
295 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
296 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
300 /* initialize implementation */
301 if (init_table
[method
](r
) < 0)
313 void pa_resampler_free(pa_resampler
*r
) {
319 if (r
->buf1
.memblock
)
320 pa_memblock_unref(r
->buf1
.memblock
);
321 if (r
->buf2
.memblock
)
322 pa_memblock_unref(r
->buf2
.memblock
);
323 if (r
->buf3
.memblock
)
324 pa_memblock_unref(r
->buf3
.memblock
);
325 if (r
->buf4
.memblock
)
326 pa_memblock_unref(r
->buf4
.memblock
);
331 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
335 if (r
->i_ss
.rate
== rate
)
340 r
->impl_update_rates(r
);
343 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
347 if (r
->o_ss
.rate
== rate
)
352 r
->impl_update_rates(r
);
355 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
358 return (((out_length
/ r
->o_fz
)*r
->i_ss
.rate
)/r
->o_ss
.rate
) * r
->i_fz
;
361 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
364 return (((in_length
/ r
->i_fz
)*r
->o_ss
.rate
)/r
->i_ss
.rate
) * r
->o_fz
;
367 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
368 size_t block_size_max
;
374 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
376 /* We deduce the "largest" sample spec we're using during the
378 ss
.channels
= PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
);
380 /* We silently assume that the format enum is ordered by size */
381 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
382 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
384 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
386 fs
= pa_frame_size(&ss
);
388 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
391 void pa_resampler_reset(pa_resampler
*r
) {
398 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
404 static const char * const resample_methods
[] = {
405 "src-sinc-best-quality",
406 "src-sinc-medium-quality",
408 "src-zero-order-hold",
439 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
441 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
444 return resample_methods
[m
];
447 int pa_resample_method_supported(pa_resample_method_t m
) {
449 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
452 #ifndef HAVE_LIBSAMPLERATE
453 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
460 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
461 pa_resample_method_t m
;
465 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
466 if (!strcmp(string
, resample_methods
[m
]))
469 if (!strcmp(string
, "speex-fixed"))
470 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
472 if (!strcmp(string
, "speex-float"))
473 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
475 return PA_RESAMPLER_INVALID
;
478 static pa_bool_t
on_left(pa_channel_position_t p
) {
481 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
482 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
483 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
484 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
485 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
486 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
489 static pa_bool_t
on_right(pa_channel_position_t p
) {
492 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
493 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
494 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
495 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
496 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
497 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
500 static pa_bool_t
on_center(pa_channel_position_t p
) {
503 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
504 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
505 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
506 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
507 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
510 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
512 p
== PA_CHANNEL_POSITION_LFE
;
515 static void calc_map_table(pa_resampler
*r
) {
517 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
524 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
)))))
527 memset(r
->map_table
, 0, sizeof(r
->map_table
));
528 memset(ic_connected
, 0, sizeof(ic_connected
));
529 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
531 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
532 pa_bool_t oc_connected
= FALSE
;
533 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
535 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
536 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
538 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
539 /* We shall not do any remapping. Hence, just check by index */
542 r
->map_table
[oc
][ic
] = 1.0;
547 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
548 /* We shall not do any remixing. Hence, just check by name */
551 r
->map_table
[oc
][ic
] = 1.0;
558 /* OK, we shall do the full monty: upmixing and
559 * downmixing. Our algorithm is relatively simple, does
560 * not do spacialization, delay elements or apply lowpass
561 * filters for LFE. Patches are always welcome,
562 * though. Oh, and it doesn't do any matrix
563 * decoding. (Which probably wouldn't make any sense
566 * This code is not idempotent: downmixing an upmixed
567 * stereo stream is not identical to the original. The
568 * volume will not match, and the two channels will be a
569 * linear combination of both.
571 * This is losely based on random suggestions found on the
572 * Internet, such as this:
573 * http://www.halfgaar.net/surround-sound-in-linux and the
576 * The algorithm works basically like this:
578 * 1) Connect all channels with matching names.
581 * S:Mono: Copy into all D:channels
582 * D:Mono: Copy in all S:channels
584 * 3) Mix D:Left, D:Right:
585 * D:Left: If not connected, avg all S:Left
586 * D:Right: If not connected, avg all S:Right
589 * If not connected, avg all S:Center
590 * If still not connected, avg all S:Left, S:Right
593 * If not connected, avg all S:*
595 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
596 * not connected, mix into all D:left and all D:right
597 * channels. Gain is 0.1, the current left and right
598 * should be multiplied by 0.9.
600 * 7) Make sure S:Center, S:LFE is used:
602 * S:Center, S:LFE: If not connected, mix into all
603 * D:left, all D:right, all D:center channels, gain is
604 * 0.375. The current (as result of 1..6) factors
605 * should be multiplied by 0.75. (Alt. suggestion: 0.25
608 * S: and D: shall relate to the source resp. destination channels.
610 * Rationale: 1, 2 are probably obvious. For 3: this
611 * copies front to rear if needed. For 4: we try to find
612 * some suitable C source for C, if we don't find any, we
613 * avg L and R. For 5: LFE is mixed from all channels. For
614 * 6: the rear channels should not be dropped entirely,
615 * however have only minimal impact. For 7: movies usually
616 * encode speech on the center channel. Thus we have to
617 * make sure this channel is distributed to L and R if not
618 * available in the output. Also, LFE is used to achieve a
619 * greater dynamic range, and thus we should try to do our
620 * best to pass it to L+R.
623 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
624 r
->map_table
[oc
][ic
] = 1.0;
627 ic_connected
[ic
] = TRUE
;
631 if (!oc_connected
&& remix
) {
632 /* OK, we shall remix */
637 /* We are not connected and on the left side, let's
638 * average all left side input channels. */
640 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
641 if (on_left(r
->i_cm
.map
[ic
]))
645 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
646 if (on_left(r
->i_cm
.map
[ic
])) {
647 r
->map_table
[oc
][ic
] = 1.0 / n
;
648 ic_connected
[ic
] = TRUE
;
651 /* We ignore the case where there is no left input
652 * channel. Something is really wrong in this case
655 } else if (on_right(b
)) {
658 /* We are not connected and on the right side, let's
659 * average all right side input channels. */
661 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
662 if (on_right(r
->i_cm
.map
[ic
]))
666 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
667 if (on_right(r
->i_cm
.map
[ic
])) {
668 r
->map_table
[oc
][ic
] = 1.0 / n
;
669 ic_connected
[ic
] = TRUE
;
672 /* We ignore the case where there is no right input
673 * channel. Something is really wrong in this case
676 } else if (on_center(b
)) {
679 /* We are not connected and at the center. Let's
680 * average all center input channels. */
682 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
683 if (on_center(r
->i_cm
.map
[ic
]))
687 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
688 if (on_center(r
->i_cm
.map
[ic
])) {
689 r
->map_table
[oc
][ic
] = 1.0 / n
;
690 ic_connected
[ic
] = TRUE
;
694 /* Hmm, no center channel around, let's synthesize
695 * it by mixing L and R.*/
699 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
700 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
704 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
705 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
706 r
->map_table
[oc
][ic
] = 1.0 / n
;
707 ic_connected
[ic
] = TRUE
;
710 /* We ignore the case where there is not even a
711 * left or right input channel. Something is
712 * really wrong in this case anyway. */
715 } else if (on_lfe(b
)) {
717 /* We are not connected and an LFE. Let's average all
718 * channels for LFE. */
720 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
721 r
->map_table
[oc
][ic
] = 1.0 / r
->i_ss
.channels
;
723 /* Please note that a channel connected to LFE
724 * doesn't really count as connected. */
732 ic_unconnected_left
= 0,
733 ic_unconnected_right
= 0,
734 ic_unconnected_center
= 0,
735 ic_unconnected_lfe
= 0;
737 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
738 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
740 if (ic_connected
[ic
])
744 ic_unconnected_left
++;
745 else if (on_right(a
))
746 ic_unconnected_right
++;
747 else if (on_center(a
))
748 ic_unconnected_center
++;
750 ic_unconnected_lfe
++;
753 if (ic_unconnected_left
> 0) {
755 /* OK, so there are unconnected input channels on the
756 * left. Let's multiply all already connected channels on
757 * the left side by .9 and add in our averaged unconnected
758 * channels multplied by .1 */
760 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
762 if (!on_left(r
->o_cm
.map
[oc
]))
765 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
767 if (ic_connected
[ic
]) {
768 r
->map_table
[oc
][ic
] *= .9;
772 if (on_left(r
->i_cm
.map
[ic
]))
773 r
->map_table
[oc
][ic
] = .1 / ic_unconnected_left
;
778 if (ic_unconnected_right
> 0) {
780 /* OK, so there are unconnected input channels on the
781 * right. Let's multiply all already connected channels on
782 * the right side by .9 and add in our averaged unconnected
783 * channels multplied by .1 */
785 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
787 if (!on_right(r
->o_cm
.map
[oc
]))
790 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
792 if (ic_connected
[ic
]) {
793 r
->map_table
[oc
][ic
] *= .9;
797 if (on_right(r
->i_cm
.map
[ic
]))
798 r
->map_table
[oc
][ic
] = .1 / ic_unconnected_right
;
803 if (ic_unconnected_center
> 0) {
804 pa_bool_t mixed_in
= FALSE
;
806 /* OK, so there are unconnected input channels on the
807 * center. Let's multiply all already connected channels on
808 * the center side by .9 and add in our averaged unconnected
809 * channels multplied by .1 */
811 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
813 if (!on_center(r
->o_cm
.map
[oc
]))
816 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
818 if (ic_connected
[ic
]) {
819 r
->map_table
[oc
][ic
] *= .9;
823 if (on_center(r
->i_cm
.map
[ic
])) {
824 r
->map_table
[oc
][ic
] = .1 / ic_unconnected_center
;
832 /* Hmm, as it appears there was no center channel we
833 could mix our center channel in. In this case, mix
834 it into left and right. Using .375 and 0.75 as
837 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
839 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
842 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
844 if (ic_connected
[ic
]) {
845 r
->map_table
[oc
][ic
] *= .75;
849 if (on_center(r
->i_cm
.map
[ic
]))
850 r
->map_table
[oc
][ic
] = .375 / ic_unconnected_center
;
856 if (ic_unconnected_lfe
> 0) {
858 /* OK, so there is an unconnected LFE channel. Let's mix
859 * it into all channels, with factor 0.375 */
861 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
863 if (!on_lfe(r
->i_cm
.map
[ic
]))
866 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
867 r
->map_table
[oc
][ic
] = 0.375 / ic_unconnected_lfe
;
875 pa_strbuf_printf(s
, " ");
876 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
877 pa_strbuf_printf(s
, " I%02u ", ic
);
878 pa_strbuf_puts(s
, "\n +");
880 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
881 pa_strbuf_printf(s
, "------");
882 pa_strbuf_puts(s
, "\n");
884 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
885 pa_strbuf_printf(s
, "O%02u |", oc
);
887 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
888 pa_strbuf_printf(s
, " %1.3f", r
->map_table
[oc
][ic
]);
890 pa_strbuf_puts(s
, "\n");
893 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
897 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
903 pa_assert(input
->memblock
);
905 /* Convert the incoming sample into the work sample format and place them in buf1 */
907 if (!r
->to_work_format_func
|| !input
->length
)
910 n_samples
= (input
->length
/ r
->i_fz
) * r
->i_ss
.channels
;
913 r
->buf1
.length
= r
->w_sz
* n_samples
;
915 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
916 if (r
->buf1
.memblock
)
917 pa_memblock_unref(r
->buf1
.memblock
);
919 r
->buf1_samples
= n_samples
;
920 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
923 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
924 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
926 r
->to_work_format_func(n_samples
, src
, dst
);
928 pa_memblock_release(input
->memblock
);
929 pa_memblock_release(r
->buf1
.memblock
);
934 static void vectoradd_s16_with_fraction(
935 int16_t *d
, int dstr
,
936 const int16_t *s1
, int sstr1
,
937 const int16_t *s2
, int sstr2
,
939 float s3
, float s4
) {
943 i3
= (int32_t) (s3
* 0x10000);
944 i4
= (int32_t) (s4
* 0x10000);
952 a
= (a
* i3
) / 0x10000;
953 b
= (b
* i4
) / 0x10000;
955 *d
= (int16_t) (a
+ b
);
957 s1
= (const int16_t*) ((const uint8_t*) s1
+ sstr1
);
958 s2
= (const int16_t*) ((const uint8_t*) s2
+ sstr2
);
959 d
= (int16_t*) ((uint8_t*) d
+ dstr
);
964 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
965 unsigned in_n_samples
, out_n_samples
, n_frames
;
972 pa_assert(input
->memblock
);
974 /* Remap channels and place the result int buf2 */
976 if (!r
->map_required
|| !input
->length
)
979 in_n_samples
= input
->length
/ r
->w_sz
;
980 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
981 out_n_samples
= n_frames
* r
->o_ss
.channels
;
984 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
986 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
987 if (r
->buf2
.memblock
)
988 pa_memblock_unref(r
->buf2
.memblock
);
990 r
->buf2_samples
= out_n_samples
;
991 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
994 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
995 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
997 memset(dst
, 0, r
->buf2
.length
);
999 o_skip
= r
->w_sz
* r
->o_ss
.channels
;
1000 i_skip
= r
->w_sz
* r
->i_ss
.channels
;
1002 switch (r
->work_format
) {
1003 case PA_SAMPLE_FLOAT32NE
:
1005 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1007 static const float one
= 1.0;
1009 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1011 if (r
->map_table
[oc
][ic
] <= 0.0)
1015 (float*) dst
+ oc
, o_skip
,
1016 (float*) dst
+ oc
, o_skip
,
1017 (float*) src
+ ic
, i_skip
,
1019 &one
, &r
->map_table
[oc
][ic
]);
1025 case PA_SAMPLE_S16NE
:
1027 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1030 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1032 if (r
->map_table
[oc
][ic
] <= 0.0)
1035 if (r
->map_table
[oc
][ic
] >= 1.0) {
1036 static const int16_t one
= 1;
1039 (int16_t*) dst
+ oc
, o_skip
,
1040 (int16_t*) dst
+ oc
, o_skip
,
1041 (int16_t*) src
+ ic
, i_skip
,
1047 vectoradd_s16_with_fraction(
1048 (int16_t*) dst
+ oc
, o_skip
,
1049 (int16_t*) dst
+ oc
, o_skip
,
1050 (int16_t*) src
+ ic
, i_skip
,
1052 1.0, r
->map_table
[oc
][ic
]);
1059 pa_assert_not_reached();
1062 pa_memblock_release(input
->memblock
);
1063 pa_memblock_release(r
->buf2
.memblock
);
1065 r
->buf2
.length
= out_n_samples
* r
->w_sz
;
1070 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1071 unsigned in_n_frames
, in_n_samples
;
1072 unsigned out_n_frames
, out_n_samples
;
1077 /* Resample the data and place the result in buf3 */
1079 if (!r
->impl_resample
|| !input
->length
)
1082 in_n_samples
= input
->length
/ r
->w_sz
;
1083 in_n_frames
= in_n_samples
/ r
->o_ss
.channels
;
1085 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1086 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1089 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1091 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1092 if (r
->buf3
.memblock
)
1093 pa_memblock_unref(r
->buf3
.memblock
);
1095 r
->buf3_samples
= out_n_samples
;
1096 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1099 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1100 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1105 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1106 unsigned n_samples
, n_frames
;
1112 /* Convert the data into the correct sample type and place the result in buf4 */
1114 if (!r
->from_work_format_func
|| !input
->length
)
1117 n_samples
= input
->length
/ r
->w_sz
;
1118 n_frames
= n_samples
/ r
->o_ss
.channels
;
1121 r
->buf4
.length
= r
->o_fz
* n_frames
;
1123 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1124 if (r
->buf4
.memblock
)
1125 pa_memblock_unref(r
->buf4
.memblock
);
1127 r
->buf4_samples
= n_samples
;
1128 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1131 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1132 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1133 r
->from_work_format_func(n_samples
, src
, dst
);
1134 pa_memblock_release(input
->memblock
);
1135 pa_memblock_release(r
->buf4
.memblock
);
1137 r
->buf4
.length
= r
->o_fz
* n_frames
;
1142 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1148 pa_assert(in
->length
);
1149 pa_assert(in
->memblock
);
1150 pa_assert(in
->length
% r
->i_fz
== 0);
1152 buf
= (pa_memchunk
*) in
;
1153 buf
= convert_to_work_format(r
, buf
);
1154 buf
= remap_channels(r
, buf
);
1155 buf
= resample(r
, buf
);
1158 buf
= convert_from_work_format(r
, buf
);
1162 pa_memblock_ref(buf
->memblock
);
1164 pa_memchunk_reset(buf
);
1166 pa_memchunk_reset(out
);
1169 /*** libsamplerate based implementation ***/
1171 #ifdef HAVE_LIBSAMPLERATE
1172 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1178 pa_assert(out_n_frames
);
1180 memset(&data
, 0, sizeof(data
));
1182 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1183 data
.input_frames
= in_n_frames
;
1185 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1186 data
.output_frames
= *out_n_frames
;
1188 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1189 data
.end_of_input
= 0;
1191 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1192 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1194 pa_memblock_release(input
->memblock
);
1195 pa_memblock_release(output
->memblock
);
1197 *out_n_frames
= data
.output_frames_gen
;
1200 static void libsamplerate_update_rates(pa_resampler
*r
) {
1203 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1206 static void libsamplerate_reset(pa_resampler
*r
) {
1209 pa_assert_se(src_reset(r
->src
.state
) == 0);
1212 static void libsamplerate_free(pa_resampler
*r
) {
1216 src_delete(r
->src
.state
);
1219 static int libsamplerate_init(pa_resampler
*r
) {
1224 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1227 r
->impl_free
= libsamplerate_free
;
1228 r
->impl_update_rates
= libsamplerate_update_rates
;
1229 r
->impl_resample
= libsamplerate_resample
;
1230 r
->impl_reset
= libsamplerate_reset
;
1236 /*** speex based implementation ***/
1238 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1240 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1245 pa_assert(out_n_frames
);
1247 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1248 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1250 pa_assert_se(paspfl_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1252 pa_memblock_release(input
->memblock
);
1253 pa_memblock_release(output
->memblock
);
1255 pa_assert(inf
== in_n_frames
);
1256 *out_n_frames
= outf
;
1259 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1261 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1266 pa_assert(out_n_frames
);
1268 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1269 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1271 pa_assert_se(paspfx_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1273 pa_memblock_release(input
->memblock
);
1274 pa_memblock_release(output
->memblock
);
1276 pa_assert(inf
== in_n_frames
);
1277 *out_n_frames
= outf
;
1280 static void speex_update_rates(pa_resampler
*r
) {
1283 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
)
1284 pa_assert_se(paspfx_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1286 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1287 pa_assert_se(paspfl_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1291 static void speex_reset(pa_resampler
*r
) {
1294 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
)
1295 pa_assert_se(paspfx_resampler_reset_mem(r
->speex
.state
) == 0);
1297 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1298 pa_assert_se(paspfl_resampler_reset_mem(r
->speex
.state
) == 0);
1302 static void speex_free(pa_resampler
*r
) {
1305 if (!r
->speex
.state
)
1308 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
)
1309 paspfx_resampler_destroy(r
->speex
.state
);
1311 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1312 paspfl_resampler_destroy(r
->speex
.state
);
1316 static int speex_init(pa_resampler
*r
) {
1321 r
->impl_free
= speex_free
;
1322 r
->impl_update_rates
= speex_update_rates
;
1323 r
->impl_reset
= speex_reset
;
1325 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1326 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1328 pa_log_info("Choosing speex quality setting %i.", q
);
1330 if (!(r
->speex
.state
= paspfx_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1333 r
->impl_resample
= speex_resample_int
;
1335 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1336 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1338 pa_log_info("Choosing speex quality setting %i.", q
);
1340 if (!(r
->speex
.state
= paspfl_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1343 r
->impl_resample
= speex_resample_float
;
1349 /* Trivial implementation */
1351 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1359 pa_assert(out_n_frames
);
1361 fz
= r
->w_sz
* r
->o_ss
.channels
;
1363 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1364 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1366 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1369 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1370 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1372 if (j
>= in_n_frames
)
1375 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1377 oil_memcpy((uint8_t*) dst
+ fz
* o_index
,
1378 (uint8_t*) src
+ fz
* j
, fz
);
1381 pa_memblock_release(input
->memblock
);
1382 pa_memblock_release(output
->memblock
);
1384 *out_n_frames
= o_index
;
1386 r
->trivial
.i_counter
+= in_n_frames
;
1388 /* Normalize counters */
1389 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1390 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1392 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1393 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1397 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1400 r
->trivial
.i_counter
= 0;
1401 r
->trivial
.o_counter
= 0;
1404 static int trivial_init(pa_resampler
*r
) {
1407 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1409 r
->impl_resample
= trivial_resample
;
1410 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1411 r
->impl_reset
= trivial_update_rates_or_reset
;
1416 /* Peak finder implementation */
1418 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1427 pa_assert(out_n_frames
);
1429 fz
= r
->w_sz
* r
->o_ss
.channels
;
1431 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1432 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1434 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1437 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1438 j
= j
> r
->peaks
.i_counter
? j
- r
->peaks
.i_counter
: 0;
1440 if (j
>= in_n_frames
)
1443 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1445 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1447 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* j
);
1448 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1450 for (i
= start
; i
<= j
; i
++)
1451 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1454 n
= *s
< 0 ? -*s
: *s
;
1456 if (n
> r
->peaks
.max_i
[c
])
1457 r
->peaks
.max_i
[c
] = n
;
1460 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1461 *d
= r
->peaks
.max_i
[c
];
1462 r
->peaks
.max_i
[c
] = 0;
1466 float *s
= (float*) ((uint8_t*) src
+ fz
* j
);
1467 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1469 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1471 for (i
= start
; i
<= j
; i
++)
1472 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1473 float n
= fabsf(*s
);
1475 if (n
> r
->peaks
.max_f
[c
])
1476 r
->peaks
.max_f
[c
] = n
;
1479 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1480 *d
= r
->peaks
.max_f
[c
];
1481 r
->peaks
.max_f
[c
] = 0;
1488 pa_memblock_release(input
->memblock
);
1489 pa_memblock_release(output
->memblock
);
1491 *out_n_frames
= o_index
;
1493 r
->peaks
.i_counter
+= in_n_frames
;
1495 /* Normalize counters */
1496 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1497 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1499 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1500 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1504 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1507 r
->peaks
.i_counter
= 0;
1508 r
->peaks
.o_counter
= 0;
1511 static int peaks_init(pa_resampler
*r
) {
1514 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1515 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1516 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1518 r
->impl_resample
= peaks_resample
;
1519 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1520 r
->impl_reset
= peaks_update_rates_or_reset
;
1525 /*** ffmpeg based implementation ***/
1527 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1528 unsigned used_frames
= 0, c
;
1533 pa_assert(out_n_frames
);
1535 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1538 int16_t *p
, *t
, *k
, *q
, *s
;
1539 int consumed_frames
;
1542 /* Allocate a new block */
1543 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1544 p
= pa_memblock_acquire(b
);
1546 /* Copy the remaining data into it */
1547 l
= r
->ffmpeg
.buf
[c
].length
;
1548 if (r
->ffmpeg
.buf
[c
].memblock
) {
1549 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1551 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1552 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1553 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1556 /* Now append the new data, splitting up channels */
1557 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1558 k
= (int16_t*) ((uint8_t*) p
+ l
);
1559 for (u
= 0; u
< in_n_frames
; u
++) {
1561 t
+= r
->o_ss
.channels
;
1564 pa_memblock_release(input
->memblock
);
1566 /* Calculate the resulting number of frames */
1567 in
= in_n_frames
+ l
/ sizeof(int16_t);
1569 /* Allocate buffer for the result */
1570 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1571 q
= pa_memblock_acquire(w
);
1574 used_frames
= av_resample(r
->ffmpeg
.state
,
1578 c
>= (unsigned) r
->o_ss
.channels
-1);
1580 pa_memblock_release(b
);
1582 /* Now store the remaining samples away */
1583 pa_assert(consumed_frames
<= (int) in
);
1584 if (consumed_frames
< (int) in
) {
1585 r
->ffmpeg
.buf
[c
].memblock
= b
;
1586 r
->ffmpeg
.buf
[c
].index
= consumed_frames
* sizeof(int16_t);
1587 r
->ffmpeg
.buf
[c
].length
= (in
- consumed_frames
) * sizeof(int16_t);
1589 pa_memblock_unref(b
);
1591 /* And place the results in the output buffer */
1592 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1593 for (u
= 0; u
< used_frames
; u
++) {
1596 s
+= r
->o_ss
.channels
;
1598 pa_memblock_release(output
->memblock
);
1599 pa_memblock_release(w
);
1600 pa_memblock_unref(w
);
1603 *out_n_frames
= used_frames
;
1606 static void ffmpeg_free(pa_resampler
*r
) {
1611 if (r
->ffmpeg
.state
)
1612 av_resample_close(r
->ffmpeg
.state
);
1614 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1615 if (r
->ffmpeg
.buf
[c
].memblock
)
1616 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1619 static int ffmpeg_init(pa_resampler
*r
) {
1624 /* We could probably implement different quality levels by
1625 * adjusting the filter parameters here. However, ffmpeg
1626 * internally only uses these hardcoded values, so let's use them
1627 * here for now as well until ffmpeg makes this configurable. */
1629 if (!(r
->ffmpeg
.state
= av_resample_init(r
->o_ss
.rate
, r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1632 r
->impl_free
= ffmpeg_free
;
1633 r
->impl_resample
= ffmpeg_resample
;
1635 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1636 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1641 /*** copy (noop) implementation ***/
1643 static int copy_init(pa_resampler
*r
) {
1646 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);