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 #if 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 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
262 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
||
263 b
->format
== PA_SAMPLE_S24NE
|| b
->format
== PA_SAMPLE_S24RE
)
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
= (uint8_t) (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 pa_bool_t
on_front(pa_channel_position_t p
) {
517 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
518 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
519 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
520 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
521 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
522 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
523 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
524 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
527 static pa_bool_t
on_rear(pa_channel_position_t p
) {
529 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
530 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
531 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
532 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
533 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
534 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
537 static pa_bool_t
on_side(pa_channel_position_t p
) {
539 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
540 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
541 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
551 static int front_rear_side(pa_channel_position_t p
) {
561 static void calc_map_table(pa_resampler
*r
) {
563 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
570 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
)))))
573 memset(r
->map_table
, 0, sizeof(r
->map_table
));
574 memset(ic_connected
, 0, sizeof(ic_connected
));
575 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
577 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
578 pa_bool_t oc_connected
= FALSE
;
579 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
581 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
582 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
584 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
585 /* We shall not do any remapping. Hence, just check by index */
588 r
->map_table
[oc
][ic
] = 1.0;
593 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
594 /* We shall not do any remixing. Hence, just check by name */
597 r
->map_table
[oc
][ic
] = 1.0;
604 /* OK, we shall do the full monty: upmixing and
605 * downmixing. Our algorithm is relatively simple, does
606 * not do spacialization, delay elements or apply lowpass
607 * filters for LFE. Patches are always welcome,
608 * though. Oh, and it doesn't do any matrix
609 * decoding. (Which probably wouldn't make any sense
612 * This code is not idempotent: downmixing an upmixed
613 * stereo stream is not identical to the original. The
614 * volume will not match, and the two channels will be a
615 * linear combination of both.
617 * This is losely based on random suggestions found on the
618 * Internet, such as this:
619 * http://www.halfgaar.net/surround-sound-in-linux and the
622 * The algorithm works basically like this:
624 * 1) Connect all channels with matching names.
627 * S:Mono: Copy into all D:channels
628 * D:Mono: Copy in all S:channels
630 * 3) Mix D:Left, D:Right:
631 * D:Left: If not connected, avg all S:Left
632 * D:Right: If not connected, avg all S:Right
635 * If not connected, avg all S:Center
636 * If still not connected, avg all S:Left, S:Right
639 * If not connected, avg all S:*
641 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
642 * not connected, mix into all D:left and all D:right
643 * channels. Gain is 0.1, the current left and right
644 * should be multiplied by 0.9.
646 * 7) Make sure S:Center, S:LFE is used:
648 * S:Center, S:LFE: If not connected, mix into all
649 * D:left, all D:right, all D:center channels, gain is
650 * 0.375. The current (as result of 1..6) factors
651 * should be multiplied by 0.75. (Alt. suggestion: 0.25
652 * vs. 0.5) If C-front is only mixed into
653 * L-front/R-front if available, otherwise into all L/R
654 * channels. Similarly for C-rear.
656 * S: and D: shall relate to the source resp. destination channels.
658 * Rationale: 1, 2 are probably obvious. For 3: this
659 * copies front to rear if needed. For 4: we try to find
660 * some suitable C source for C, if we don't find any, we
661 * avg L and R. For 5: LFE is mixed from all channels. For
662 * 6: the rear channels should not be dropped entirely,
663 * however have only minimal impact. For 7: movies usually
664 * encode speech on the center channel. Thus we have to
665 * make sure this channel is distributed to L and R if not
666 * available in the output. Also, LFE is used to achieve a
667 * greater dynamic range, and thus we should try to do our
668 * best to pass it to L+R.
671 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
672 r
->map_table
[oc
][ic
] = 1.0;
675 ic_connected
[ic
] = TRUE
;
679 if (!oc_connected
&& remix
) {
680 /* OK, we shall remix */
682 /* Try to find matching input ports for this output port */
687 /* We are not connected and on the left side, let's
688 * average all left side input channels. */
690 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
691 if (on_left(r
->i_cm
.map
[ic
]))
695 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
696 if (on_left(r
->i_cm
.map
[ic
])) {
697 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
698 ic_connected
[ic
] = TRUE
;
701 /* We ignore the case where there is no left input
702 * channel. Something is really wrong in this case
705 } else if (on_right(b
)) {
708 /* We are not connected and on the right side, let's
709 * average all right side input channels. */
711 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
712 if (on_right(r
->i_cm
.map
[ic
]))
716 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
717 if (on_right(r
->i_cm
.map
[ic
])) {
718 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
719 ic_connected
[ic
] = TRUE
;
722 /* We ignore the case where there is no right input
723 * channel. Something is really wrong in this case
726 } else if (on_center(b
)) {
729 /* We are not connected and at the center. Let's
730 * average all center input channels. */
732 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
733 if (on_center(r
->i_cm
.map
[ic
]))
737 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
738 if (on_center(r
->i_cm
.map
[ic
])) {
739 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
740 ic_connected
[ic
] = TRUE
;
744 /* Hmm, no center channel around, let's synthesize
745 * it by mixing L and R.*/
749 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
750 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
754 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
755 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
756 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
757 ic_connected
[ic
] = TRUE
;
760 /* We ignore the case where there is not even a
761 * left or right input channel. Something is
762 * really wrong in this case anyway. */
765 } else if (on_lfe(b
)) {
767 /* We are not connected and an LFE. Let's average all
768 * channels for LFE. */
770 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
772 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
773 r
->map_table
[oc
][ic
] = 1.0f
/ (float) r
->i_ss
.channels
;
775 r
->map_table
[oc
][ic
] = 0;
777 /* Please note that a channel connected to LFE
778 * doesn't really count as connected. */
786 ic_unconnected_left
= 0,
787 ic_unconnected_right
= 0,
788 ic_unconnected_center
= 0,
789 ic_unconnected_lfe
= 0;
791 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
792 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
794 if (ic_connected
[ic
])
798 ic_unconnected_left
++;
799 else if (on_right(a
))
800 ic_unconnected_right
++;
801 else if (on_center(a
))
802 ic_unconnected_center
++;
804 ic_unconnected_lfe
++;
807 if (ic_unconnected_left
> 0) {
809 /* OK, so there are unconnected input channels on the
810 * left. Let's multiply all already connected channels on
811 * the left side by .9 and add in our averaged unconnected
812 * channels multplied by .1 */
814 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
816 if (!on_left(r
->o_cm
.map
[oc
]))
819 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
821 if (ic_connected
[ic
]) {
822 r
->map_table
[oc
][ic
] *= .9f
;
826 if (on_left(r
->i_cm
.map
[ic
]))
827 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
832 if (ic_unconnected_right
> 0) {
834 /* OK, so there are unconnected input channels on the
835 * right. Let's multiply all already connected channels on
836 * the right side by .9 and add in our averaged unconnected
837 * channels multplied by .1 */
839 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
841 if (!on_right(r
->o_cm
.map
[oc
]))
844 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
846 if (ic_connected
[ic
]) {
847 r
->map_table
[oc
][ic
] *= .9f
;
851 if (on_right(r
->i_cm
.map
[ic
]))
852 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
857 if (ic_unconnected_center
> 0) {
858 pa_bool_t mixed_in
= FALSE
;
860 /* OK, so there are unconnected input channels on the
861 * center. Let's multiply all already connected channels on
862 * the center 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_center(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_center(r
->i_cm
.map
[ic
])) {
878 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
885 unsigned ncenter
[PA_CHANNELS_MAX
];
886 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
888 memset(ncenter
, 0, sizeof(ncenter
));
889 memset(found_frs
, 0, sizeof(found_frs
));
891 /* Hmm, as it appears there was no center channel we
892 could mix our center channel in. In this case, mix
893 it into left and right. Using .375 and 0.75 as
896 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
898 if (ic_connected
[ic
])
901 if (!on_center(r
->i_cm
.map
[ic
]))
904 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
906 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
909 if (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
910 found_frs
[ic
] = TRUE
;
915 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
917 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
920 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
925 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
927 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
930 if (ncenter
[oc
] <= 0)
933 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
935 if (ic_connected
[ic
]) {
936 r
->map_table
[oc
][ic
] *= .75f
;
940 if (!on_center(r
->i_cm
.map
[ic
]))
943 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
944 r
->map_table
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
950 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
952 /* OK, so there is an unconnected LFE channel. Let's mix
953 * it into all channels, with factor 0.375 */
955 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
957 if (!on_lfe(r
->i_cm
.map
[ic
]))
960 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
961 r
->map_table
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
969 pa_strbuf_printf(s
, " ");
970 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
971 pa_strbuf_printf(s
, " I%02u ", ic
);
972 pa_strbuf_puts(s
, "\n +");
974 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
975 pa_strbuf_printf(s
, "------");
976 pa_strbuf_puts(s
, "\n");
978 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
979 pa_strbuf_printf(s
, "O%02u |", oc
);
981 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
982 pa_strbuf_printf(s
, " %1.3f", r
->map_table
[oc
][ic
]);
984 pa_strbuf_puts(s
, "\n");
987 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
991 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
997 pa_assert(input
->memblock
);
999 /* Convert the incoming sample into the work sample format and place them in buf1 */
1001 if (!r
->to_work_format_func
|| !input
->length
)
1004 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1007 r
->buf1
.length
= r
->w_sz
* n_samples
;
1009 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
1010 if (r
->buf1
.memblock
)
1011 pa_memblock_unref(r
->buf1
.memblock
);
1013 r
->buf1_samples
= n_samples
;
1014 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
1017 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1018 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
1020 r
->to_work_format_func(n_samples
, src
, dst
);
1022 pa_memblock_release(input
->memblock
);
1023 pa_memblock_release(r
->buf1
.memblock
);
1028 static void vectoradd_s16_with_fraction(
1029 int16_t *d
, int dstr
,
1030 const int16_t *s1
, int sstr1
,
1031 const int16_t *s2
, int sstr2
,
1033 float s3
, float s4
) {
1037 i3
= (int32_t) (s3
* 0x10000);
1038 i4
= (int32_t) (s4
* 0x10000);
1040 for (; n
> 0; n
--) {
1046 a
= (a
* i3
) / 0x10000;
1047 b
= (b
* i4
) / 0x10000;
1049 *d
= (int16_t) (a
+ b
);
1051 s1
= (const int16_t*) ((const uint8_t*) s1
+ sstr1
);
1052 s2
= (const int16_t*) ((const uint8_t*) s2
+ sstr2
);
1053 d
= (int16_t*) ((uint8_t*) d
+ dstr
);
1058 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1059 unsigned in_n_samples
, out_n_samples
, n_frames
;
1066 pa_assert(input
->memblock
);
1068 /* Remap channels and place the result int buf2 */
1070 if (!r
->map_required
|| !input
->length
)
1073 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1074 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1075 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1078 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
1080 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
1081 if (r
->buf2
.memblock
)
1082 pa_memblock_unref(r
->buf2
.memblock
);
1084 r
->buf2_samples
= out_n_samples
;
1085 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
1088 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1089 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
1091 memset(dst
, 0, r
->buf2
.length
);
1093 o_skip
= (int) (r
->w_sz
* r
->o_ss
.channels
);
1094 i_skip
= (int) (r
->w_sz
* r
->i_ss
.channels
);
1096 switch (r
->work_format
) {
1097 case PA_SAMPLE_FLOAT32NE
:
1099 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1101 static const float one
= 1.0;
1103 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1105 if (r
->map_table
[oc
][ic
] <= 0.0)
1109 (float*) dst
+ oc
, o_skip
,
1110 (float*) dst
+ oc
, o_skip
,
1111 (float*) src
+ ic
, i_skip
,
1113 &one
, &r
->map_table
[oc
][ic
]);
1119 case PA_SAMPLE_S16NE
:
1121 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1124 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1126 if (r
->map_table
[oc
][ic
] <= 0.0)
1129 if (r
->map_table
[oc
][ic
] >= 1.0) {
1130 static const int16_t one
= 1;
1133 (int16_t*) dst
+ oc
, o_skip
,
1134 (int16_t*) dst
+ oc
, o_skip
,
1135 (int16_t*) src
+ ic
, i_skip
,
1141 vectoradd_s16_with_fraction(
1142 (int16_t*) dst
+ oc
, o_skip
,
1143 (int16_t*) dst
+ oc
, o_skip
,
1144 (int16_t*) src
+ ic
, i_skip
,
1146 1.0f
, r
->map_table
[oc
][ic
]);
1153 pa_assert_not_reached();
1156 pa_memblock_release(input
->memblock
);
1157 pa_memblock_release(r
->buf2
.memblock
);
1159 r
->buf2
.length
= out_n_samples
* r
->w_sz
;
1164 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1165 unsigned in_n_frames
, in_n_samples
;
1166 unsigned out_n_frames
, out_n_samples
;
1171 /* Resample the data and place the result in buf3 */
1173 if (!r
->impl_resample
|| !input
->length
)
1176 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1177 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1179 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1180 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1183 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1185 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1186 if (r
->buf3
.memblock
)
1187 pa_memblock_unref(r
->buf3
.memblock
);
1189 r
->buf3_samples
= out_n_samples
;
1190 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1193 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1194 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1199 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1200 unsigned n_samples
, n_frames
;
1206 /* Convert the data into the correct sample type and place the result in buf4 */
1208 if (!r
->from_work_format_func
|| !input
->length
)
1211 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1212 n_frames
= n_samples
/ r
->o_ss
.channels
;
1215 r
->buf4
.length
= r
->o_fz
* n_frames
;
1217 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1218 if (r
->buf4
.memblock
)
1219 pa_memblock_unref(r
->buf4
.memblock
);
1221 r
->buf4_samples
= n_samples
;
1222 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1225 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1226 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1227 r
->from_work_format_func(n_samples
, src
, dst
);
1228 pa_memblock_release(input
->memblock
);
1229 pa_memblock_release(r
->buf4
.memblock
);
1231 r
->buf4
.length
= r
->o_fz
* n_frames
;
1236 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1242 pa_assert(in
->length
);
1243 pa_assert(in
->memblock
);
1244 pa_assert(in
->length
% r
->i_fz
== 0);
1246 buf
= (pa_memchunk
*) in
;
1247 buf
= convert_to_work_format(r
, buf
);
1248 buf
= remap_channels(r
, buf
);
1249 buf
= resample(r
, buf
);
1252 buf
= convert_from_work_format(r
, buf
);
1256 pa_memblock_ref(buf
->memblock
);
1258 pa_memchunk_reset(buf
);
1260 pa_memchunk_reset(out
);
1263 /*** libsamplerate based implementation ***/
1265 #ifdef HAVE_LIBSAMPLERATE
1266 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1272 pa_assert(out_n_frames
);
1274 memset(&data
, 0, sizeof(data
));
1276 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1277 data
.input_frames
= (long int) in_n_frames
;
1279 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1280 data
.output_frames
= (long int) *out_n_frames
;
1282 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1283 data
.end_of_input
= 0;
1285 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1286 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1288 pa_memblock_release(input
->memblock
);
1289 pa_memblock_release(output
->memblock
);
1291 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1294 static void libsamplerate_update_rates(pa_resampler
*r
) {
1297 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1300 static void libsamplerate_reset(pa_resampler
*r
) {
1303 pa_assert_se(src_reset(r
->src
.state
) == 0);
1306 static void libsamplerate_free(pa_resampler
*r
) {
1310 src_delete(r
->src
.state
);
1313 static int libsamplerate_init(pa_resampler
*r
) {
1318 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1321 r
->impl_free
= libsamplerate_free
;
1322 r
->impl_update_rates
= libsamplerate_update_rates
;
1323 r
->impl_resample
= libsamplerate_resample
;
1324 r
->impl_reset
= libsamplerate_reset
;
1330 /*** speex based implementation ***/
1332 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1334 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1339 pa_assert(out_n_frames
);
1341 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1342 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1344 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1346 pa_memblock_release(input
->memblock
);
1347 pa_memblock_release(output
->memblock
);
1349 pa_assert(inf
== in_n_frames
);
1350 *out_n_frames
= outf
;
1353 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1355 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1360 pa_assert(out_n_frames
);
1362 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1363 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1365 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1367 pa_memblock_release(input
->memblock
);
1368 pa_memblock_release(output
->memblock
);
1370 pa_assert(inf
== in_n_frames
);
1371 *out_n_frames
= outf
;
1374 static void speex_update_rates(pa_resampler
*r
) {
1377 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1380 static void speex_reset(pa_resampler
*r
) {
1383 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1386 static void speex_free(pa_resampler
*r
) {
1389 if (!r
->speex
.state
)
1392 speex_resampler_destroy(r
->speex
.state
);
1395 static int speex_init(pa_resampler
*r
) {
1400 r
->impl_free
= speex_free
;
1401 r
->impl_update_rates
= speex_update_rates
;
1402 r
->impl_reset
= speex_reset
;
1404 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1406 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1407 r
->impl_resample
= speex_resample_int
;
1410 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1412 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1413 r
->impl_resample
= speex_resample_float
;
1416 pa_log_info("Choosing speex quality setting %i.", q
);
1418 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1424 /* Trivial implementation */
1426 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1434 pa_assert(out_n_frames
);
1436 fz
= r
->w_sz
* r
->o_ss
.channels
;
1438 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1439 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1441 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1444 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1445 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1447 if (j
>= in_n_frames
)
1450 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1452 oil_memcpy((uint8_t*) dst
+ fz
* o_index
,
1453 (uint8_t*) src
+ fz
* j
, (int) fz
);
1456 pa_memblock_release(input
->memblock
);
1457 pa_memblock_release(output
->memblock
);
1459 *out_n_frames
= o_index
;
1461 r
->trivial
.i_counter
+= in_n_frames
;
1463 /* Normalize counters */
1464 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1465 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1467 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1468 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1472 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1475 r
->trivial
.i_counter
= 0;
1476 r
->trivial
.o_counter
= 0;
1479 static int trivial_init(pa_resampler
*r
) {
1482 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1484 r
->impl_resample
= trivial_resample
;
1485 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1486 r
->impl_reset
= trivial_update_rates_or_reset
;
1491 /* Peak finder implementation */
1493 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1502 pa_assert(out_n_frames
);
1504 fz
= r
->w_sz
* r
->o_ss
.channels
;
1506 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1507 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1509 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1512 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1514 if (j
> r
->peaks
.i_counter
)
1515 j
-= r
->peaks
.i_counter
;
1519 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1521 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1523 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* start
);
1524 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1526 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1528 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1531 n
= (int16_t) (*s
< 0 ? -*s
: *s
);
1533 if (PA_UNLIKELY(n
> r
->peaks
.max_i
[c
]))
1534 r
->peaks
.max_i
[c
] = n
;
1537 if (i
>= in_n_frames
)
1540 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1541 *d
= r
->peaks
.max_i
[c
];
1542 r
->peaks
.max_i
[c
] = 0;
1547 float *s
= (float*) ((uint8_t*) src
+ fz
* start
);
1548 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1550 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1552 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1553 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1554 float n
= fabsf(*s
);
1556 if (n
> r
->peaks
.max_f
[c
])
1557 r
->peaks
.max_f
[c
] = n
;
1560 if (i
>= in_n_frames
)
1563 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1564 *d
= r
->peaks
.max_f
[c
];
1565 r
->peaks
.max_f
[c
] = 0;
1572 pa_memblock_release(input
->memblock
);
1573 pa_memblock_release(output
->memblock
);
1575 *out_n_frames
= o_index
;
1577 r
->peaks
.i_counter
+= in_n_frames
;
1579 /* Normalize counters */
1580 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1581 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1583 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1584 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1588 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1591 r
->peaks
.i_counter
= 0;
1592 r
->peaks
.o_counter
= 0;
1595 static int peaks_init(pa_resampler
*r
) {
1598 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1599 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1600 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1602 r
->impl_resample
= peaks_resample
;
1603 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1604 r
->impl_reset
= peaks_update_rates_or_reset
;
1609 /*** ffmpeg based implementation ***/
1611 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1612 unsigned used_frames
= 0, c
;
1617 pa_assert(out_n_frames
);
1619 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1622 int16_t *p
, *t
, *k
, *q
, *s
;
1623 int consumed_frames
;
1626 /* Allocate a new block */
1627 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1628 p
= pa_memblock_acquire(b
);
1630 /* Copy the remaining data into it */
1631 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1632 if (r
->ffmpeg
.buf
[c
].memblock
) {
1633 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1635 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1636 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1637 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1640 /* Now append the new data, splitting up channels */
1641 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1642 k
= (int16_t*) ((uint8_t*) p
+ l
);
1643 for (u
= 0; u
< in_n_frames
; u
++) {
1645 t
+= r
->o_ss
.channels
;
1648 pa_memblock_release(input
->memblock
);
1650 /* Calculate the resulting number of frames */
1651 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1653 /* Allocate buffer for the result */
1654 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1655 q
= pa_memblock_acquire(w
);
1658 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1661 (int) in
, (int) *out_n_frames
,
1662 c
>= (unsigned) (r
->o_ss
.channels
-1));
1664 pa_memblock_release(b
);
1666 /* Now store the remaining samples away */
1667 pa_assert(consumed_frames
<= (int) in
);
1668 if (consumed_frames
< (int) in
) {
1669 r
->ffmpeg
.buf
[c
].memblock
= b
;
1670 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1671 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1673 pa_memblock_unref(b
);
1675 /* And place the results in the output buffer */
1676 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1677 for (u
= 0; u
< used_frames
; u
++) {
1680 s
+= r
->o_ss
.channels
;
1682 pa_memblock_release(output
->memblock
);
1683 pa_memblock_release(w
);
1684 pa_memblock_unref(w
);
1687 *out_n_frames
= used_frames
;
1690 static void ffmpeg_free(pa_resampler
*r
) {
1695 if (r
->ffmpeg
.state
)
1696 av_resample_close(r
->ffmpeg
.state
);
1698 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1699 if (r
->ffmpeg
.buf
[c
].memblock
)
1700 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1703 static int ffmpeg_init(pa_resampler
*r
) {
1708 /* We could probably implement different quality levels by
1709 * adjusting the filter parameters here. However, ffmpeg
1710 * internally only uses these hardcoded values, so let's use them
1711 * here for now as well until ffmpeg makes this configurable. */
1713 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1716 r
->impl_free
= ffmpeg_free
;
1717 r
->impl_resample
= ffmpeg_resample
;
1719 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1720 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1725 /*** copy (noop) implementation ***/
1727 static int copy_init(pa_resampler
*r
) {
1730 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);