2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 #ifdef HAVE_LIBSAMPLERATE
29 #include <samplerate.h>
32 #include <speex/speex_resampler.h>
34 #include <liboil/liboilfuncs.h>
35 #include <liboil/liboil.h>
37 #include <pulse/xmalloc.h>
38 #include <pulsecore/sconv.h>
39 #include <pulsecore/log.h>
40 #include <pulsecore/macro.h>
41 #include <pulsecore/strbuf.h>
43 #include "ffmpeg/avcodec.h"
45 #include "resampler.h"
47 /* Number of samples of extra space we allow the resamplers to return */
48 #define EXTRA_FRAMES 128
51 pa_resample_method_t method
;
52 pa_resample_flags_t flags
;
54 pa_sample_spec i_ss
, o_ss
;
55 pa_channel_map i_cm
, o_cm
;
56 size_t i_fz
, o_fz
, w_sz
;
59 pa_memchunk buf1
, buf2
, buf3
, buf4
;
60 unsigned buf1_samples
, buf2_samples
, buf3_samples
, buf4_samples
;
62 pa_sample_format_t work_format
;
64 pa_convert_func_t to_work_format_func
;
65 pa_convert_func_t from_work_format_func
;
67 float map_table
[PA_CHANNELS_MAX
][PA_CHANNELS_MAX
];
68 pa_bool_t map_required
;
70 void (*impl_free
)(pa_resampler
*r
);
71 void (*impl_update_rates
)(pa_resampler
*r
);
72 void (*impl_resample
)(pa_resampler
*r
, const pa_memchunk
*in
, unsigned in_samples
, pa_memchunk
*out
, unsigned *out_samples
);
73 void (*impl_reset
)(pa_resampler
*r
);
75 struct { /* data specific to the trivial resampler */
80 struct { /* data specific to the peak finder pseudo resampler */
84 float max_f
[PA_CHANNELS_MAX
];
85 int16_t max_i
[PA_CHANNELS_MAX
];
89 #ifdef HAVE_LIBSAMPLERATE
90 struct { /* data specific to libsamplerate */
95 struct { /* data specific to speex */
96 SpeexResamplerState
* state
;
99 struct { /* data specific to ffmpeg */
100 struct AVResampleContext
*state
;
101 pa_memchunk buf
[PA_CHANNELS_MAX
];
105 static int copy_init(pa_resampler
*r
);
106 static int trivial_init(pa_resampler
*r
);
107 static int speex_init(pa_resampler
*r
);
108 static int ffmpeg_init(pa_resampler
*r
);
109 static int peaks_init(pa_resampler
*r
);
110 #ifdef HAVE_LIBSAMPLERATE
111 static int libsamplerate_init(pa_resampler
*r
);
114 static void calc_map_table(pa_resampler
*r
);
116 static int (* const init_table
[])(pa_resampler
*r
) = {
117 #ifdef HAVE_LIBSAMPLERATE
118 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = libsamplerate_init
,
119 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = libsamplerate_init
,
120 [PA_RESAMPLER_SRC_SINC_FASTEST
] = libsamplerate_init
,
121 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = libsamplerate_init
,
122 [PA_RESAMPLER_SRC_LINEAR
] = libsamplerate_init
,
124 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = NULL
,
125 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = NULL
,
126 [PA_RESAMPLER_SRC_SINC_FASTEST
] = NULL
,
127 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = NULL
,
128 [PA_RESAMPLER_SRC_LINEAR
] = NULL
,
130 [PA_RESAMPLER_TRIVIAL
] = trivial_init
,
131 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+0] = speex_init
,
132 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+1] = speex_init
,
133 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+2] = speex_init
,
134 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+3] = speex_init
,
135 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+4] = speex_init
,
136 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+5] = speex_init
,
137 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+6] = speex_init
,
138 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+7] = speex_init
,
139 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+8] = speex_init
,
140 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+9] = speex_init
,
141 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+10] = speex_init
,
142 [PA_RESAMPLER_SPEEX_FIXED_BASE
+0] = speex_init
,
143 [PA_RESAMPLER_SPEEX_FIXED_BASE
+1] = speex_init
,
144 [PA_RESAMPLER_SPEEX_FIXED_BASE
+2] = speex_init
,
145 [PA_RESAMPLER_SPEEX_FIXED_BASE
+3] = speex_init
,
146 [PA_RESAMPLER_SPEEX_FIXED_BASE
+4] = speex_init
,
147 [PA_RESAMPLER_SPEEX_FIXED_BASE
+5] = speex_init
,
148 [PA_RESAMPLER_SPEEX_FIXED_BASE
+6] = speex_init
,
149 [PA_RESAMPLER_SPEEX_FIXED_BASE
+7] = speex_init
,
150 [PA_RESAMPLER_SPEEX_FIXED_BASE
+8] = speex_init
,
151 [PA_RESAMPLER_SPEEX_FIXED_BASE
+9] = speex_init
,
152 [PA_RESAMPLER_SPEEX_FIXED_BASE
+10] = speex_init
,
153 [PA_RESAMPLER_FFMPEG
] = ffmpeg_init
,
154 [PA_RESAMPLER_AUTO
] = NULL
,
155 [PA_RESAMPLER_COPY
] = copy_init
,
156 [PA_RESAMPLER_PEAKS
] = peaks_init
,
159 static inline size_t sample_size(pa_sample_format_t f
) {
160 pa_sample_spec ss
= {
166 return pa_sample_size(&ss
);
169 pa_resampler
* pa_resampler_new(
171 const pa_sample_spec
*a
,
172 const pa_channel_map
*am
,
173 const pa_sample_spec
*b
,
174 const pa_channel_map
*bm
,
175 pa_resample_method_t method
,
176 pa_resample_flags_t flags
) {
178 pa_resampler
*r
= NULL
;
183 pa_assert(pa_sample_spec_valid(a
));
184 pa_assert(pa_sample_spec_valid(b
));
185 pa_assert(method
>= 0);
186 pa_assert(method
< PA_RESAMPLER_MAX
);
190 if (!(flags
& PA_RESAMPLER_VARIABLE_RATE
) && a
->rate
== b
->rate
) {
191 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
192 method
= PA_RESAMPLER_COPY
;
195 if (!pa_resample_method_supported(method
)) {
196 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method
));
197 method
= PA_RESAMPLER_AUTO
;
200 if (method
== PA_RESAMPLER_FFMPEG
&& (flags
& PA_RESAMPLER_VARIABLE_RATE
)) {
201 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
202 method
= PA_RESAMPLER_AUTO
;
205 if (method
== PA_RESAMPLER_COPY
&& ((flags
& PA_RESAMPLER_VARIABLE_RATE
) || a
->rate
!= b
->rate
)) {
206 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
207 method
= PA_RESAMPLER_AUTO
;
210 if (method
== PA_RESAMPLER_AUTO
)
211 method
= PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
213 r
= pa_xnew(pa_resampler
, 1);
219 r
->impl_update_rates
= NULL
;
220 r
->impl_resample
= NULL
;
221 r
->impl_reset
= NULL
;
223 /* Fill sample specs */
229 else if (!pa_channel_map_init_auto(&r
->i_cm
, r
->i_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
234 else if (!pa_channel_map_init_auto(&r
->o_cm
, r
->o_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
237 r
->i_fz
= pa_frame_size(a
);
238 r
->o_fz
= pa_frame_size(b
);
240 pa_memchunk_reset(&r
->buf1
);
241 pa_memchunk_reset(&r
->buf2
);
242 pa_memchunk_reset(&r
->buf3
);
243 pa_memchunk_reset(&r
->buf4
);
245 r
->buf1_samples
= r
->buf2_samples
= r
->buf3_samples
= r
->buf4_samples
= 0;
249 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method
));
251 if ((method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) ||
252 (method
== PA_RESAMPLER_FFMPEG
))
253 r
->work_format
= PA_SAMPLE_S16NE
;
254 else if (method
== PA_RESAMPLER_TRIVIAL
|| method
== PA_RESAMPLER_COPY
|| method
== PA_RESAMPLER_PEAKS
) {
256 if (r
->map_required
|| a
->format
!= b
->format
|| method
== PA_RESAMPLER_PEAKS
) {
258 if (a
->format
== PA_SAMPLE_S32NE
|| a
->format
== PA_SAMPLE_S32RE
||
259 a
->format
== PA_SAMPLE_FLOAT32NE
|| a
->format
== PA_SAMPLE_FLOAT32RE
||
260 a
->format
== PA_SAMPLE_S24NE
|| a
->format
== PA_SAMPLE_S24RE
||
261 a
->format
== PA_SAMPLE_S24_32NE
|| a
->format
== PA_SAMPLE_S24_32RE
||
262 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
263 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
||
264 b
->format
== PA_SAMPLE_S24NE
|| b
->format
== PA_SAMPLE_S24RE
||
265 b
->format
== PA_SAMPLE_S24_32NE
|| b
->format
== PA_SAMPLE_S24_32RE
)
266 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
268 r
->work_format
= PA_SAMPLE_S16NE
;
271 r
->work_format
= a
->format
;
274 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
276 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
278 r
->w_sz
= sample_size(r
->work_format
);
280 if (r
->i_ss
.format
== r
->work_format
)
281 r
->to_work_format_func
= NULL
;
282 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
283 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
286 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
287 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
291 if (r
->o_ss
.format
== r
->work_format
)
292 r
->from_work_format_func
= NULL
;
293 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
294 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
297 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
298 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
302 /* initialize implementation */
303 if (init_table
[method
](r
) < 0)
315 void pa_resampler_free(pa_resampler
*r
) {
321 if (r
->buf1
.memblock
)
322 pa_memblock_unref(r
->buf1
.memblock
);
323 if (r
->buf2
.memblock
)
324 pa_memblock_unref(r
->buf2
.memblock
);
325 if (r
->buf3
.memblock
)
326 pa_memblock_unref(r
->buf3
.memblock
);
327 if (r
->buf4
.memblock
)
328 pa_memblock_unref(r
->buf4
.memblock
);
333 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
337 if (r
->i_ss
.rate
== rate
)
342 r
->impl_update_rates(r
);
345 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
349 if (r
->o_ss
.rate
== rate
)
354 r
->impl_update_rates(r
);
357 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
360 return (((out_length
/ r
->o_fz
)*r
->i_ss
.rate
)/r
->o_ss
.rate
) * r
->i_fz
;
363 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
366 return (((in_length
/ r
->i_fz
)*r
->o_ss
.rate
)/r
->i_ss
.rate
) * r
->o_fz
;
369 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
370 size_t block_size_max
;
376 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
378 /* We deduce the "largest" sample spec we're using during the
380 ss
.channels
= (uint8_t) (PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
));
382 /* We silently assume that the format enum is ordered by size */
383 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
384 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
386 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
388 fs
= pa_frame_size(&ss
);
390 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
393 void pa_resampler_reset(pa_resampler
*r
) {
400 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
406 static const char * const resample_methods
[] = {
407 "src-sinc-best-quality",
408 "src-sinc-medium-quality",
410 "src-zero-order-hold",
441 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
443 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
446 return resample_methods
[m
];
449 int pa_resample_method_supported(pa_resample_method_t m
) {
451 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
454 #ifndef HAVE_LIBSAMPLERATE
455 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
462 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
463 pa_resample_method_t m
;
467 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
468 if (!strcmp(string
, resample_methods
[m
]))
471 if (!strcmp(string
, "speex-fixed"))
472 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
474 if (!strcmp(string
, "speex-float"))
475 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
477 return PA_RESAMPLER_INVALID
;
480 static pa_bool_t
on_left(pa_channel_position_t p
) {
483 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
484 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
485 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
486 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
487 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
488 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
491 static pa_bool_t
on_right(pa_channel_position_t p
) {
494 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
495 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
496 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
497 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
498 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
499 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
502 static pa_bool_t
on_center(pa_channel_position_t p
) {
505 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
506 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
507 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
508 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
509 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
512 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
514 p
== PA_CHANNEL_POSITION_LFE
;
517 static pa_bool_t
on_front(pa_channel_position_t p
) {
519 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
520 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
521 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
522 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
523 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
524 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
525 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
526 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
529 static pa_bool_t
on_rear(pa_channel_position_t p
) {
531 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
532 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
533 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
534 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
535 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
536 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
539 static pa_bool_t
on_side(pa_channel_position_t p
) {
541 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
542 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
543 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
553 static int front_rear_side(pa_channel_position_t p
) {
563 static void calc_map_table(pa_resampler
*r
) {
565 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
572 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
)))))
575 memset(r
->map_table
, 0, sizeof(r
->map_table
));
576 memset(ic_connected
, 0, sizeof(ic_connected
));
577 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
579 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
580 pa_bool_t oc_connected
= FALSE
;
581 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
583 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
584 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
586 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
587 /* We shall not do any remapping. Hence, just check by index */
590 r
->map_table
[oc
][ic
] = 1.0;
595 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
596 /* We shall not do any remixing. Hence, just check by name */
599 r
->map_table
[oc
][ic
] = 1.0;
606 /* OK, we shall do the full monty: upmixing and
607 * downmixing. Our algorithm is relatively simple, does
608 * not do spacialization, delay elements or apply lowpass
609 * filters for LFE. Patches are always welcome,
610 * though. Oh, and it doesn't do any matrix
611 * decoding. (Which probably wouldn't make any sense
614 * This code is not idempotent: downmixing an upmixed
615 * stereo stream is not identical to the original. The
616 * volume will not match, and the two channels will be a
617 * linear combination of both.
619 * This is losely based on random suggestions found on the
620 * Internet, such as this:
621 * http://www.halfgaar.net/surround-sound-in-linux and the
624 * The algorithm works basically like this:
626 * 1) Connect all channels with matching names.
629 * S:Mono: Copy into all D:channels
630 * D:Mono: Copy in all S:channels
632 * 3) Mix D:Left, D:Right:
633 * D:Left: If not connected, avg all S:Left
634 * D:Right: If not connected, avg all S:Right
637 * If not connected, avg all S:Center
638 * If still not connected, avg all S:Left, S:Right
641 * If not connected, avg all S:*
643 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
644 * not connected, mix into all D:left and all D:right
645 * channels. Gain is 0.1, the current left and right
646 * should be multiplied by 0.9.
648 * 7) Make sure S:Center, S:LFE is used:
650 * S:Center, S:LFE: If not connected, mix into all
651 * D:left, all D:right, all D:center channels, gain is
652 * 0.375. The current (as result of 1..6) factors
653 * should be multiplied by 0.75. (Alt. suggestion: 0.25
654 * vs. 0.5) If C-front is only mixed into
655 * L-front/R-front if available, otherwise into all L/R
656 * channels. Similarly for C-rear.
658 * S: and D: shall relate to the source resp. destination channels.
660 * Rationale: 1, 2 are probably obvious. For 3: this
661 * copies front to rear if needed. For 4: we try to find
662 * some suitable C source for C, if we don't find any, we
663 * avg L and R. For 5: LFE is mixed from all channels. For
664 * 6: the rear channels should not be dropped entirely,
665 * however have only minimal impact. For 7: movies usually
666 * encode speech on the center channel. Thus we have to
667 * make sure this channel is distributed to L and R if not
668 * available in the output. Also, LFE is used to achieve a
669 * greater dynamic range, and thus we should try to do our
670 * best to pass it to L+R.
673 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
674 r
->map_table
[oc
][ic
] = 1.0;
677 ic_connected
[ic
] = TRUE
;
681 if (!oc_connected
&& remix
) {
682 /* OK, we shall remix */
684 /* Try to find matching input ports for this output port */
689 /* We are not connected and on the left side, let's
690 * average all left side input channels. */
692 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
693 if (on_left(r
->i_cm
.map
[ic
]))
697 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
698 if (on_left(r
->i_cm
.map
[ic
])) {
699 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
700 ic_connected
[ic
] = TRUE
;
703 /* We ignore the case where there is no left input
704 * channel. Something is really wrong in this case
707 } else if (on_right(b
)) {
710 /* We are not connected and on the right side, let's
711 * average all right side input channels. */
713 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
714 if (on_right(r
->i_cm
.map
[ic
]))
718 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
719 if (on_right(r
->i_cm
.map
[ic
])) {
720 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
721 ic_connected
[ic
] = TRUE
;
724 /* We ignore the case where there is no right input
725 * channel. Something is really wrong in this case
728 } else if (on_center(b
)) {
731 /* We are not connected and at the center. Let's
732 * average all center input channels. */
734 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
735 if (on_center(r
->i_cm
.map
[ic
]))
739 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
740 if (on_center(r
->i_cm
.map
[ic
])) {
741 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
742 ic_connected
[ic
] = TRUE
;
746 /* Hmm, no center channel around, let's synthesize
747 * it by mixing L and R.*/
751 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
752 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
756 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
757 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
758 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
759 ic_connected
[ic
] = TRUE
;
762 /* We ignore the case where there is not even a
763 * left or right input channel. Something is
764 * really wrong in this case anyway. */
767 } else if (on_lfe(b
)) {
769 /* We are not connected and an LFE. Let's average all
770 * channels for LFE. */
772 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
774 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
775 r
->map_table
[oc
][ic
] = 1.0f
/ (float) r
->i_ss
.channels
;
777 r
->map_table
[oc
][ic
] = 0;
779 /* Please note that a channel connected to LFE
780 * doesn't really count as connected. */
788 ic_unconnected_left
= 0,
789 ic_unconnected_right
= 0,
790 ic_unconnected_center
= 0,
791 ic_unconnected_lfe
= 0;
793 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
794 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
796 if (ic_connected
[ic
])
800 ic_unconnected_left
++;
801 else if (on_right(a
))
802 ic_unconnected_right
++;
803 else if (on_center(a
))
804 ic_unconnected_center
++;
806 ic_unconnected_lfe
++;
809 if (ic_unconnected_left
> 0) {
811 /* OK, so there are unconnected input channels on the
812 * left. Let's multiply all already connected channels on
813 * the left side by .9 and add in our averaged unconnected
814 * channels multplied by .1 */
816 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
818 if (!on_left(r
->o_cm
.map
[oc
]))
821 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
823 if (ic_connected
[ic
]) {
824 r
->map_table
[oc
][ic
] *= .9f
;
828 if (on_left(r
->i_cm
.map
[ic
]))
829 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
834 if (ic_unconnected_right
> 0) {
836 /* OK, so there are unconnected input channels on the
837 * right. Let's multiply all already connected channels on
838 * the right side by .9 and add in our averaged unconnected
839 * channels multplied by .1 */
841 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
843 if (!on_right(r
->o_cm
.map
[oc
]))
846 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
848 if (ic_connected
[ic
]) {
849 r
->map_table
[oc
][ic
] *= .9f
;
853 if (on_right(r
->i_cm
.map
[ic
]))
854 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
859 if (ic_unconnected_center
> 0) {
860 pa_bool_t mixed_in
= FALSE
;
862 /* OK, so there are unconnected input channels on the
863 * center. Let's multiply all already connected channels on
864 * the center side by .9 and add in our averaged unconnected
865 * channels multplied by .1 */
867 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
869 if (!on_center(r
->o_cm
.map
[oc
]))
872 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
874 if (ic_connected
[ic
]) {
875 r
->map_table
[oc
][ic
] *= .9f
;
879 if (on_center(r
->i_cm
.map
[ic
])) {
880 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
887 unsigned ncenter
[PA_CHANNELS_MAX
];
888 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
890 memset(ncenter
, 0, sizeof(ncenter
));
891 memset(found_frs
, 0, sizeof(found_frs
));
893 /* Hmm, as it appears there was no center channel we
894 could mix our center channel in. In this case, mix
895 it into left and right. Using .375 and 0.75 as
898 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
900 if (ic_connected
[ic
])
903 if (!on_center(r
->i_cm
.map
[ic
]))
906 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
908 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
911 if (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
912 found_frs
[ic
] = TRUE
;
917 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
919 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
922 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
927 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
929 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
932 if (ncenter
[oc
] <= 0)
935 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
937 if (ic_connected
[ic
]) {
938 r
->map_table
[oc
][ic
] *= .75f
;
942 if (!on_center(r
->i_cm
.map
[ic
]))
945 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
946 r
->map_table
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
952 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
954 /* OK, so there is an unconnected LFE channel. Let's mix
955 * it into all channels, with factor 0.375 */
957 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
959 if (!on_lfe(r
->i_cm
.map
[ic
]))
962 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
963 r
->map_table
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
971 pa_strbuf_printf(s
, " ");
972 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
973 pa_strbuf_printf(s
, " I%02u ", ic
);
974 pa_strbuf_puts(s
, "\n +");
976 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
977 pa_strbuf_printf(s
, "------");
978 pa_strbuf_puts(s
, "\n");
980 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
981 pa_strbuf_printf(s
, "O%02u |", oc
);
983 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
984 pa_strbuf_printf(s
, " %1.3f", r
->map_table
[oc
][ic
]);
986 pa_strbuf_puts(s
, "\n");
989 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
993 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
999 pa_assert(input
->memblock
);
1001 /* Convert the incoming sample into the work sample format and place them in buf1 */
1003 if (!r
->to_work_format_func
|| !input
->length
)
1006 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1009 r
->buf1
.length
= r
->w_sz
* n_samples
;
1011 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
1012 if (r
->buf1
.memblock
)
1013 pa_memblock_unref(r
->buf1
.memblock
);
1015 r
->buf1_samples
= n_samples
;
1016 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
1019 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1020 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
1022 r
->to_work_format_func(n_samples
, src
, dst
);
1024 pa_memblock_release(input
->memblock
);
1025 pa_memblock_release(r
->buf1
.memblock
);
1030 static void vectoradd_s16_with_fraction(
1031 int16_t *d
, int dstr
,
1032 const int16_t *s1
, int sstr1
,
1033 const int16_t *s2
, int sstr2
,
1035 float s3
, float s4
) {
1039 i3
= (int32_t) (s3
* 0x10000);
1040 i4
= (int32_t) (s4
* 0x10000);
1042 for (; n
> 0; n
--) {
1048 a
= (a
* i3
) / 0x10000;
1049 b
= (b
* i4
) / 0x10000;
1051 *d
= (int16_t) (a
+ b
);
1053 s1
= (const int16_t*) ((const uint8_t*) s1
+ sstr1
);
1054 s2
= (const int16_t*) ((const uint8_t*) s2
+ sstr2
);
1055 d
= (int16_t*) ((uint8_t*) d
+ dstr
);
1060 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1061 unsigned in_n_samples
, out_n_samples
, n_frames
;
1068 pa_assert(input
->memblock
);
1070 /* Remap channels and place the result int buf2 */
1072 if (!r
->map_required
|| !input
->length
)
1075 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1076 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1077 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1080 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
1082 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
1083 if (r
->buf2
.memblock
)
1084 pa_memblock_unref(r
->buf2
.memblock
);
1086 r
->buf2_samples
= out_n_samples
;
1087 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
1090 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1091 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
1093 memset(dst
, 0, r
->buf2
.length
);
1095 o_skip
= (int) (r
->w_sz
* r
->o_ss
.channels
);
1096 i_skip
= (int) (r
->w_sz
* r
->i_ss
.channels
);
1098 switch (r
->work_format
) {
1099 case PA_SAMPLE_FLOAT32NE
:
1101 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1103 static const float one
= 1.0;
1105 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1107 if (r
->map_table
[oc
][ic
] <= 0.0)
1111 (float*) dst
+ oc
, o_skip
,
1112 (float*) dst
+ oc
, o_skip
,
1113 (float*) src
+ ic
, i_skip
,
1115 &one
, &r
->map_table
[oc
][ic
]);
1121 case PA_SAMPLE_S16NE
:
1123 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1126 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1128 if (r
->map_table
[oc
][ic
] <= 0.0)
1131 if (r
->map_table
[oc
][ic
] >= 1.0) {
1132 static const int16_t one
= 1;
1135 (int16_t*) dst
+ oc
, o_skip
,
1136 (int16_t*) dst
+ oc
, o_skip
,
1137 (int16_t*) src
+ ic
, i_skip
,
1143 vectoradd_s16_with_fraction(
1144 (int16_t*) dst
+ oc
, o_skip
,
1145 (int16_t*) dst
+ oc
, o_skip
,
1146 (int16_t*) src
+ ic
, i_skip
,
1148 1.0f
, r
->map_table
[oc
][ic
]);
1155 pa_assert_not_reached();
1158 pa_memblock_release(input
->memblock
);
1159 pa_memblock_release(r
->buf2
.memblock
);
1161 r
->buf2
.length
= out_n_samples
* r
->w_sz
;
1166 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1167 unsigned in_n_frames
, in_n_samples
;
1168 unsigned out_n_frames
, out_n_samples
;
1173 /* Resample the data and place the result in buf3 */
1175 if (!r
->impl_resample
|| !input
->length
)
1178 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1179 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1181 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1182 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1185 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1187 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1188 if (r
->buf3
.memblock
)
1189 pa_memblock_unref(r
->buf3
.memblock
);
1191 r
->buf3_samples
= out_n_samples
;
1192 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1195 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1196 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1201 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1202 unsigned n_samples
, n_frames
;
1208 /* Convert the data into the correct sample type and place the result in buf4 */
1210 if (!r
->from_work_format_func
|| !input
->length
)
1213 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1214 n_frames
= n_samples
/ r
->o_ss
.channels
;
1217 r
->buf4
.length
= r
->o_fz
* n_frames
;
1219 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1220 if (r
->buf4
.memblock
)
1221 pa_memblock_unref(r
->buf4
.memblock
);
1223 r
->buf4_samples
= n_samples
;
1224 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1227 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1228 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1229 r
->from_work_format_func(n_samples
, src
, dst
);
1230 pa_memblock_release(input
->memblock
);
1231 pa_memblock_release(r
->buf4
.memblock
);
1233 r
->buf4
.length
= r
->o_fz
* n_frames
;
1238 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1244 pa_assert(in
->length
);
1245 pa_assert(in
->memblock
);
1246 pa_assert(in
->length
% r
->i_fz
== 0);
1248 buf
= (pa_memchunk
*) in
;
1249 buf
= convert_to_work_format(r
, buf
);
1250 buf
= remap_channels(r
, buf
);
1251 buf
= resample(r
, buf
);
1254 buf
= convert_from_work_format(r
, buf
);
1258 pa_memblock_ref(buf
->memblock
);
1260 pa_memchunk_reset(buf
);
1262 pa_memchunk_reset(out
);
1265 /*** libsamplerate based implementation ***/
1267 #ifdef HAVE_LIBSAMPLERATE
1268 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1274 pa_assert(out_n_frames
);
1276 memset(&data
, 0, sizeof(data
));
1278 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1279 data
.input_frames
= (long int) in_n_frames
;
1281 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1282 data
.output_frames
= (long int) *out_n_frames
;
1284 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1285 data
.end_of_input
= 0;
1287 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1288 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1290 pa_memblock_release(input
->memblock
);
1291 pa_memblock_release(output
->memblock
);
1293 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1296 static void libsamplerate_update_rates(pa_resampler
*r
) {
1299 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1302 static void libsamplerate_reset(pa_resampler
*r
) {
1305 pa_assert_se(src_reset(r
->src
.state
) == 0);
1308 static void libsamplerate_free(pa_resampler
*r
) {
1312 src_delete(r
->src
.state
);
1315 static int libsamplerate_init(pa_resampler
*r
) {
1320 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1323 r
->impl_free
= libsamplerate_free
;
1324 r
->impl_update_rates
= libsamplerate_update_rates
;
1325 r
->impl_resample
= libsamplerate_resample
;
1326 r
->impl_reset
= libsamplerate_reset
;
1332 /*** speex based implementation ***/
1334 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1336 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1341 pa_assert(out_n_frames
);
1343 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1344 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1346 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1348 pa_memblock_release(input
->memblock
);
1349 pa_memblock_release(output
->memblock
);
1351 pa_assert(inf
== in_n_frames
);
1352 *out_n_frames
= outf
;
1355 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1357 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1362 pa_assert(out_n_frames
);
1364 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1365 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1367 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1369 pa_memblock_release(input
->memblock
);
1370 pa_memblock_release(output
->memblock
);
1372 pa_assert(inf
== in_n_frames
);
1373 *out_n_frames
= outf
;
1376 static void speex_update_rates(pa_resampler
*r
) {
1379 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1382 static void speex_reset(pa_resampler
*r
) {
1385 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1388 static void speex_free(pa_resampler
*r
) {
1391 if (!r
->speex
.state
)
1394 speex_resampler_destroy(r
->speex
.state
);
1397 static int speex_init(pa_resampler
*r
) {
1402 r
->impl_free
= speex_free
;
1403 r
->impl_update_rates
= speex_update_rates
;
1404 r
->impl_reset
= speex_reset
;
1406 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1408 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1409 r
->impl_resample
= speex_resample_int
;
1412 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1414 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1415 r
->impl_resample
= speex_resample_float
;
1418 pa_log_info("Choosing speex quality setting %i.", q
);
1420 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1426 /* Trivial implementation */
1428 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1436 pa_assert(out_n_frames
);
1438 fz
= r
->w_sz
* r
->o_ss
.channels
;
1440 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1441 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1443 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1446 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1447 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1449 if (j
>= in_n_frames
)
1452 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1454 oil_memcpy((uint8_t*) dst
+ fz
* o_index
,
1455 (uint8_t*) src
+ fz
* j
, (int) fz
);
1458 pa_memblock_release(input
->memblock
);
1459 pa_memblock_release(output
->memblock
);
1461 *out_n_frames
= o_index
;
1463 r
->trivial
.i_counter
+= in_n_frames
;
1465 /* Normalize counters */
1466 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1467 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1469 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1470 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1474 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1477 r
->trivial
.i_counter
= 0;
1478 r
->trivial
.o_counter
= 0;
1481 static int trivial_init(pa_resampler
*r
) {
1484 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1486 r
->impl_resample
= trivial_resample
;
1487 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1488 r
->impl_reset
= trivial_update_rates_or_reset
;
1493 /* Peak finder implementation */
1495 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1504 pa_assert(out_n_frames
);
1506 fz
= r
->w_sz
* r
->o_ss
.channels
;
1508 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1509 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1511 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1514 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1516 if (j
> r
->peaks
.i_counter
)
1517 j
-= r
->peaks
.i_counter
;
1521 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1523 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1525 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* start
);
1526 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1528 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1530 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1533 n
= (int16_t) (*s
< 0 ? -*s
: *s
);
1535 if (PA_UNLIKELY(n
> r
->peaks
.max_i
[c
]))
1536 r
->peaks
.max_i
[c
] = n
;
1539 if (i
>= in_n_frames
)
1542 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1543 *d
= r
->peaks
.max_i
[c
];
1544 r
->peaks
.max_i
[c
] = 0;
1549 float *s
= (float*) ((uint8_t*) src
+ fz
* start
);
1550 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1552 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1554 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1555 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1556 float n
= fabsf(*s
);
1558 if (n
> r
->peaks
.max_f
[c
])
1559 r
->peaks
.max_f
[c
] = n
;
1562 if (i
>= in_n_frames
)
1565 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1566 *d
= r
->peaks
.max_f
[c
];
1567 r
->peaks
.max_f
[c
] = 0;
1574 pa_memblock_release(input
->memblock
);
1575 pa_memblock_release(output
->memblock
);
1577 *out_n_frames
= o_index
;
1579 r
->peaks
.i_counter
+= in_n_frames
;
1581 /* Normalize counters */
1582 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1583 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1585 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1586 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1590 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1593 r
->peaks
.i_counter
= 0;
1594 r
->peaks
.o_counter
= 0;
1597 static int peaks_init(pa_resampler
*r
) {
1600 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1601 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1602 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1604 r
->impl_resample
= peaks_resample
;
1605 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1606 r
->impl_reset
= peaks_update_rates_or_reset
;
1611 /*** ffmpeg based implementation ***/
1613 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1614 unsigned used_frames
= 0, c
;
1619 pa_assert(out_n_frames
);
1621 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1624 int16_t *p
, *t
, *k
, *q
, *s
;
1625 int consumed_frames
;
1628 /* Allocate a new block */
1629 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1630 p
= pa_memblock_acquire(b
);
1632 /* Copy the remaining data into it */
1633 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1634 if (r
->ffmpeg
.buf
[c
].memblock
) {
1635 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1637 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1638 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1639 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1642 /* Now append the new data, splitting up channels */
1643 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1644 k
= (int16_t*) ((uint8_t*) p
+ l
);
1645 for (u
= 0; u
< in_n_frames
; u
++) {
1647 t
+= r
->o_ss
.channels
;
1650 pa_memblock_release(input
->memblock
);
1652 /* Calculate the resulting number of frames */
1653 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1655 /* Allocate buffer for the result */
1656 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1657 q
= pa_memblock_acquire(w
);
1660 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1663 (int) in
, (int) *out_n_frames
,
1664 c
>= (unsigned) (r
->o_ss
.channels
-1));
1666 pa_memblock_release(b
);
1668 /* Now store the remaining samples away */
1669 pa_assert(consumed_frames
<= (int) in
);
1670 if (consumed_frames
< (int) in
) {
1671 r
->ffmpeg
.buf
[c
].memblock
= b
;
1672 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1673 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1675 pa_memblock_unref(b
);
1677 /* And place the results in the output buffer */
1678 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1679 for (u
= 0; u
< used_frames
; u
++) {
1682 s
+= r
->o_ss
.channels
;
1684 pa_memblock_release(output
->memblock
);
1685 pa_memblock_release(w
);
1686 pa_memblock_unref(w
);
1689 *out_n_frames
= used_frames
;
1692 static void ffmpeg_free(pa_resampler
*r
) {
1697 if (r
->ffmpeg
.state
)
1698 av_resample_close(r
->ffmpeg
.state
);
1700 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1701 if (r
->ffmpeg
.buf
[c
].memblock
)
1702 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1705 static int ffmpeg_init(pa_resampler
*r
) {
1710 /* We could probably implement different quality levels by
1711 * adjusting the filter parameters here. However, ffmpeg
1712 * internally only uses these hardcoded values, so let's use them
1713 * here for now as well until ffmpeg makes this configurable. */
1715 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1718 r
->impl_free
= ffmpeg_free
;
1719 r
->impl_resample
= ffmpeg_resample
;
1721 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1722 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1727 /*** copy (noop) implementation ***/
1729 static int copy_init(pa_resampler
*r
) {
1732 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);