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 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
261 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
)
262 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
264 r
->work_format
= PA_SAMPLE_S16NE
;
267 r
->work_format
= a
->format
;
270 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
272 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
274 r
->w_sz
= sample_size(r
->work_format
);
276 if (r
->i_ss
.format
== r
->work_format
)
277 r
->to_work_format_func
= NULL
;
278 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
279 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
282 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
283 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
287 if (r
->o_ss
.format
== r
->work_format
)
288 r
->from_work_format_func
= NULL
;
289 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
290 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
293 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
294 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
298 /* initialize implementation */
299 if (init_table
[method
](r
) < 0)
311 void pa_resampler_free(pa_resampler
*r
) {
317 if (r
->buf1
.memblock
)
318 pa_memblock_unref(r
->buf1
.memblock
);
319 if (r
->buf2
.memblock
)
320 pa_memblock_unref(r
->buf2
.memblock
);
321 if (r
->buf3
.memblock
)
322 pa_memblock_unref(r
->buf3
.memblock
);
323 if (r
->buf4
.memblock
)
324 pa_memblock_unref(r
->buf4
.memblock
);
329 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
333 if (r
->i_ss
.rate
== rate
)
338 r
->impl_update_rates(r
);
341 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
345 if (r
->o_ss
.rate
== rate
)
350 r
->impl_update_rates(r
);
353 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
356 return (((out_length
/ r
->o_fz
)*r
->i_ss
.rate
)/r
->o_ss
.rate
) * r
->i_fz
;
359 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
362 return (((in_length
/ r
->i_fz
)*r
->o_ss
.rate
)/r
->i_ss
.rate
) * r
->o_fz
;
365 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
366 size_t block_size_max
;
372 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
374 /* We deduce the "largest" sample spec we're using during the
376 ss
.channels
= (uint8_t) (PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
));
378 /* We silently assume that the format enum is ordered by size */
379 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
380 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
382 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
384 fs
= pa_frame_size(&ss
);
386 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
389 void pa_resampler_reset(pa_resampler
*r
) {
396 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
402 static const char * const resample_methods
[] = {
403 "src-sinc-best-quality",
404 "src-sinc-medium-quality",
406 "src-zero-order-hold",
437 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
439 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
442 return resample_methods
[m
];
445 int pa_resample_method_supported(pa_resample_method_t m
) {
447 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
450 #ifndef HAVE_LIBSAMPLERATE
451 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
458 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
459 pa_resample_method_t m
;
463 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
464 if (!strcmp(string
, resample_methods
[m
]))
467 if (!strcmp(string
, "speex-fixed"))
468 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
470 if (!strcmp(string
, "speex-float"))
471 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
473 return PA_RESAMPLER_INVALID
;
476 static pa_bool_t
on_left(pa_channel_position_t p
) {
479 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
480 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
481 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
482 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
483 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
484 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
487 static pa_bool_t
on_right(pa_channel_position_t p
) {
490 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
491 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
492 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
493 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
494 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
495 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
498 static pa_bool_t
on_center(pa_channel_position_t p
) {
501 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
502 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
503 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
504 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
505 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
508 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
510 p
== PA_CHANNEL_POSITION_LFE
;
513 static pa_bool_t
on_front(pa_channel_position_t p
) {
515 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
516 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
517 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
518 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
519 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
520 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
521 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
522 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
525 static pa_bool_t
on_rear(pa_channel_position_t p
) {
527 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
528 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
529 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
530 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
531 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
532 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
535 static pa_bool_t
on_side(pa_channel_position_t p
) {
537 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
538 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
539 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
549 static int front_rear_side(pa_channel_position_t p
) {
559 static void calc_map_table(pa_resampler
*r
) {
561 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
568 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
)))))
571 memset(r
->map_table
, 0, sizeof(r
->map_table
));
572 memset(ic_connected
, 0, sizeof(ic_connected
));
573 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
575 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
576 pa_bool_t oc_connected
= FALSE
;
577 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
579 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
580 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
582 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
583 /* We shall not do any remapping. Hence, just check by index */
586 r
->map_table
[oc
][ic
] = 1.0;
591 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
592 /* We shall not do any remixing. Hence, just check by name */
595 r
->map_table
[oc
][ic
] = 1.0;
602 /* OK, we shall do the full monty: upmixing and
603 * downmixing. Our algorithm is relatively simple, does
604 * not do spacialization, delay elements or apply lowpass
605 * filters for LFE. Patches are always welcome,
606 * though. Oh, and it doesn't do any matrix
607 * decoding. (Which probably wouldn't make any sense
610 * This code is not idempotent: downmixing an upmixed
611 * stereo stream is not identical to the original. The
612 * volume will not match, and the two channels will be a
613 * linear combination of both.
615 * This is losely based on random suggestions found on the
616 * Internet, such as this:
617 * http://www.halfgaar.net/surround-sound-in-linux and the
620 * The algorithm works basically like this:
622 * 1) Connect all channels with matching names.
625 * S:Mono: Copy into all D:channels
626 * D:Mono: Copy in all S:channels
628 * 3) Mix D:Left, D:Right:
629 * D:Left: If not connected, avg all S:Left
630 * D:Right: If not connected, avg all S:Right
633 * If not connected, avg all S:Center
634 * If still not connected, avg all S:Left, S:Right
637 * If not connected, avg all S:*
639 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
640 * not connected, mix into all D:left and all D:right
641 * channels. Gain is 0.1, the current left and right
642 * should be multiplied by 0.9.
644 * 7) Make sure S:Center, S:LFE is used:
646 * S:Center, S:LFE: If not connected, mix into all
647 * D:left, all D:right, all D:center channels, gain is
648 * 0.375. The current (as result of 1..6) factors
649 * should be multiplied by 0.75. (Alt. suggestion: 0.25
650 * vs. 0.5) If C-front is only mixed into
651 * L-front/R-front if available, otherwise into all L/R
652 * channels. Similarly for C-rear.
654 * S: and D: shall relate to the source resp. destination channels.
656 * Rationale: 1, 2 are probably obvious. For 3: this
657 * copies front to rear if needed. For 4: we try to find
658 * some suitable C source for C, if we don't find any, we
659 * avg L and R. For 5: LFE is mixed from all channels. For
660 * 6: the rear channels should not be dropped entirely,
661 * however have only minimal impact. For 7: movies usually
662 * encode speech on the center channel. Thus we have to
663 * make sure this channel is distributed to L and R if not
664 * available in the output. Also, LFE is used to achieve a
665 * greater dynamic range, and thus we should try to do our
666 * best to pass it to L+R.
669 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
670 r
->map_table
[oc
][ic
] = 1.0;
673 ic_connected
[ic
] = TRUE
;
677 if (!oc_connected
&& remix
) {
678 /* OK, we shall remix */
680 /* Try to find matching input ports for this output port */
685 /* We are not connected and on the left side, let's
686 * average all left side input channels. */
688 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
689 if (on_left(r
->i_cm
.map
[ic
]))
693 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
694 if (on_left(r
->i_cm
.map
[ic
])) {
695 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
696 ic_connected
[ic
] = TRUE
;
699 /* We ignore the case where there is no left input
700 * channel. Something is really wrong in this case
703 } else if (on_right(b
)) {
706 /* We are not connected and on the right side, let's
707 * average all right side input channels. */
709 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
710 if (on_right(r
->i_cm
.map
[ic
]))
714 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
715 if (on_right(r
->i_cm
.map
[ic
])) {
716 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
717 ic_connected
[ic
] = TRUE
;
720 /* We ignore the case where there is no right input
721 * channel. Something is really wrong in this case
724 } else if (on_center(b
)) {
727 /* We are not connected and at the center. Let's
728 * average all center input channels. */
730 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
731 if (on_center(r
->i_cm
.map
[ic
]))
735 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
736 if (on_center(r
->i_cm
.map
[ic
])) {
737 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
738 ic_connected
[ic
] = TRUE
;
742 /* Hmm, no center channel around, let's synthesize
743 * it by mixing L and R.*/
747 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
748 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
752 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
753 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
754 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
755 ic_connected
[ic
] = TRUE
;
758 /* We ignore the case where there is not even a
759 * left or right input channel. Something is
760 * really wrong in this case anyway. */
763 } else if (on_lfe(b
)) {
765 /* We are not connected and an LFE. Let's average all
766 * channels for LFE. */
768 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
770 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
771 r
->map_table
[oc
][ic
] = 1.0f
/ (float) r
->i_ss
.channels
;
773 r
->map_table
[oc
][ic
] = 0;
775 /* Please note that a channel connected to LFE
776 * doesn't really count as connected. */
784 ic_unconnected_left
= 0,
785 ic_unconnected_right
= 0,
786 ic_unconnected_center
= 0,
787 ic_unconnected_lfe
= 0;
789 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
790 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
792 if (ic_connected
[ic
])
796 ic_unconnected_left
++;
797 else if (on_right(a
))
798 ic_unconnected_right
++;
799 else if (on_center(a
))
800 ic_unconnected_center
++;
802 ic_unconnected_lfe
++;
805 if (ic_unconnected_left
> 0) {
807 /* OK, so there are unconnected input channels on the
808 * left. Let's multiply all already connected channels on
809 * the left side by .9 and add in our averaged unconnected
810 * channels multplied by .1 */
812 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
814 if (!on_left(r
->o_cm
.map
[oc
]))
817 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
819 if (ic_connected
[ic
]) {
820 r
->map_table
[oc
][ic
] *= .9f
;
824 if (on_left(r
->i_cm
.map
[ic
]))
825 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
830 if (ic_unconnected_right
> 0) {
832 /* OK, so there are unconnected input channels on the
833 * right. Let's multiply all already connected channels on
834 * the right side by .9 and add in our averaged unconnected
835 * channels multplied by .1 */
837 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
839 if (!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
] *= .9f
;
849 if (on_right(r
->i_cm
.map
[ic
]))
850 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
855 if (ic_unconnected_center
> 0) {
856 pa_bool_t mixed_in
= FALSE
;
858 /* OK, so there are unconnected input channels on the
859 * center. Let's multiply all already connected channels on
860 * the center side by .9 and add in our averaged unconnected
861 * channels multplied by .1 */
863 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
865 if (!on_center(r
->o_cm
.map
[oc
]))
868 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
870 if (ic_connected
[ic
]) {
871 r
->map_table
[oc
][ic
] *= .9f
;
875 if (on_center(r
->i_cm
.map
[ic
])) {
876 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
883 unsigned ncenter
[PA_CHANNELS_MAX
];
884 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
886 memset(ncenter
, 0, sizeof(ncenter
));
887 memset(found_frs
, 0, sizeof(found_frs
));
889 /* Hmm, as it appears there was no center channel we
890 could mix our center channel in. In this case, mix
891 it into left and right. Using .375 and 0.75 as
894 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
896 if (ic_connected
[ic
])
899 if (!on_center(r
->i_cm
.map
[ic
]))
902 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
904 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
907 if (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
908 found_frs
[ic
] = TRUE
;
913 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
915 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
918 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
923 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
925 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
928 if (ncenter
[oc
] <= 0)
931 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
933 if (ic_connected
[ic
]) {
934 r
->map_table
[oc
][ic
] *= .75f
;
938 if (!on_center(r
->i_cm
.map
[ic
]))
941 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
942 r
->map_table
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
948 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
950 /* OK, so there is an unconnected LFE channel. Let's mix
951 * it into all channels, with factor 0.375 */
953 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
955 if (!on_lfe(r
->i_cm
.map
[ic
]))
958 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
959 r
->map_table
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
967 pa_strbuf_printf(s
, " ");
968 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
969 pa_strbuf_printf(s
, " I%02u ", ic
);
970 pa_strbuf_puts(s
, "\n +");
972 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
973 pa_strbuf_printf(s
, "------");
974 pa_strbuf_puts(s
, "\n");
976 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
977 pa_strbuf_printf(s
, "O%02u |", oc
);
979 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
980 pa_strbuf_printf(s
, " %1.3f", r
->map_table
[oc
][ic
]);
982 pa_strbuf_puts(s
, "\n");
985 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
989 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
995 pa_assert(input
->memblock
);
997 /* Convert the incoming sample into the work sample format and place them in buf1 */
999 if (!r
->to_work_format_func
|| !input
->length
)
1002 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1005 r
->buf1
.length
= r
->w_sz
* n_samples
;
1007 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
1008 if (r
->buf1
.memblock
)
1009 pa_memblock_unref(r
->buf1
.memblock
);
1011 r
->buf1_samples
= n_samples
;
1012 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
1015 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1016 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
1018 r
->to_work_format_func(n_samples
, src
, dst
);
1020 pa_memblock_release(input
->memblock
);
1021 pa_memblock_release(r
->buf1
.memblock
);
1026 static void vectoradd_s16_with_fraction(
1027 int16_t *d
, int dstr
,
1028 const int16_t *s1
, int sstr1
,
1029 const int16_t *s2
, int sstr2
,
1031 float s3
, float s4
) {
1035 i3
= (int32_t) (s3
* 0x10000);
1036 i4
= (int32_t) (s4
* 0x10000);
1038 for (; n
> 0; n
--) {
1044 a
= (a
* i3
) / 0x10000;
1045 b
= (b
* i4
) / 0x10000;
1047 *d
= (int16_t) (a
+ b
);
1049 s1
= (const int16_t*) ((const uint8_t*) s1
+ sstr1
);
1050 s2
= (const int16_t*) ((const uint8_t*) s2
+ sstr2
);
1051 d
= (int16_t*) ((uint8_t*) d
+ dstr
);
1056 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1057 unsigned in_n_samples
, out_n_samples
, n_frames
;
1064 pa_assert(input
->memblock
);
1066 /* Remap channels and place the result int buf2 */
1068 if (!r
->map_required
|| !input
->length
)
1071 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1072 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1073 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1076 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
1078 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
1079 if (r
->buf2
.memblock
)
1080 pa_memblock_unref(r
->buf2
.memblock
);
1082 r
->buf2_samples
= out_n_samples
;
1083 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
1086 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1087 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
1089 memset(dst
, 0, r
->buf2
.length
);
1091 o_skip
= (int) (r
->w_sz
* r
->o_ss
.channels
);
1092 i_skip
= (int) (r
->w_sz
* r
->i_ss
.channels
);
1094 switch (r
->work_format
) {
1095 case PA_SAMPLE_FLOAT32NE
:
1097 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1099 static const float one
= 1.0;
1101 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1103 if (r
->map_table
[oc
][ic
] <= 0.0)
1107 (float*) dst
+ oc
, o_skip
,
1108 (float*) dst
+ oc
, o_skip
,
1109 (float*) src
+ ic
, i_skip
,
1111 &one
, &r
->map_table
[oc
][ic
]);
1117 case PA_SAMPLE_S16NE
:
1119 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1122 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1124 if (r
->map_table
[oc
][ic
] <= 0.0)
1127 if (r
->map_table
[oc
][ic
] >= 1.0) {
1128 static const int16_t one
= 1;
1131 (int16_t*) dst
+ oc
, o_skip
,
1132 (int16_t*) dst
+ oc
, o_skip
,
1133 (int16_t*) src
+ ic
, i_skip
,
1139 vectoradd_s16_with_fraction(
1140 (int16_t*) dst
+ oc
, o_skip
,
1141 (int16_t*) dst
+ oc
, o_skip
,
1142 (int16_t*) src
+ ic
, i_skip
,
1144 1.0f
, r
->map_table
[oc
][ic
]);
1151 pa_assert_not_reached();
1154 pa_memblock_release(input
->memblock
);
1155 pa_memblock_release(r
->buf2
.memblock
);
1157 r
->buf2
.length
= out_n_samples
* r
->w_sz
;
1162 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1163 unsigned in_n_frames
, in_n_samples
;
1164 unsigned out_n_frames
, out_n_samples
;
1169 /* Resample the data and place the result in buf3 */
1171 if (!r
->impl_resample
|| !input
->length
)
1174 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1175 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1177 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1178 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1181 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1183 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1184 if (r
->buf3
.memblock
)
1185 pa_memblock_unref(r
->buf3
.memblock
);
1187 r
->buf3_samples
= out_n_samples
;
1188 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1191 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1192 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1197 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1198 unsigned n_samples
, n_frames
;
1204 /* Convert the data into the correct sample type and place the result in buf4 */
1206 if (!r
->from_work_format_func
|| !input
->length
)
1209 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1210 n_frames
= n_samples
/ r
->o_ss
.channels
;
1213 r
->buf4
.length
= r
->o_fz
* n_frames
;
1215 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1216 if (r
->buf4
.memblock
)
1217 pa_memblock_unref(r
->buf4
.memblock
);
1219 r
->buf4_samples
= n_samples
;
1220 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1223 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1224 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1225 r
->from_work_format_func(n_samples
, src
, dst
);
1226 pa_memblock_release(input
->memblock
);
1227 pa_memblock_release(r
->buf4
.memblock
);
1229 r
->buf4
.length
= r
->o_fz
* n_frames
;
1234 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1240 pa_assert(in
->length
);
1241 pa_assert(in
->memblock
);
1242 pa_assert(in
->length
% r
->i_fz
== 0);
1244 buf
= (pa_memchunk
*) in
;
1245 buf
= convert_to_work_format(r
, buf
);
1246 buf
= remap_channels(r
, buf
);
1247 buf
= resample(r
, buf
);
1250 buf
= convert_from_work_format(r
, buf
);
1254 pa_memblock_ref(buf
->memblock
);
1256 pa_memchunk_reset(buf
);
1258 pa_memchunk_reset(out
);
1261 /*** libsamplerate based implementation ***/
1263 #ifdef HAVE_LIBSAMPLERATE
1264 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1270 pa_assert(out_n_frames
);
1272 memset(&data
, 0, sizeof(data
));
1274 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1275 data
.input_frames
= (long int) in_n_frames
;
1277 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1278 data
.output_frames
= (long int) *out_n_frames
;
1280 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1281 data
.end_of_input
= 0;
1283 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1284 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1286 pa_memblock_release(input
->memblock
);
1287 pa_memblock_release(output
->memblock
);
1289 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1292 static void libsamplerate_update_rates(pa_resampler
*r
) {
1295 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1298 static void libsamplerate_reset(pa_resampler
*r
) {
1301 pa_assert_se(src_reset(r
->src
.state
) == 0);
1304 static void libsamplerate_free(pa_resampler
*r
) {
1308 src_delete(r
->src
.state
);
1311 static int libsamplerate_init(pa_resampler
*r
) {
1316 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1319 r
->impl_free
= libsamplerate_free
;
1320 r
->impl_update_rates
= libsamplerate_update_rates
;
1321 r
->impl_resample
= libsamplerate_resample
;
1322 r
->impl_reset
= libsamplerate_reset
;
1328 /*** speex based implementation ***/
1330 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1332 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1337 pa_assert(out_n_frames
);
1339 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1340 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1342 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1344 pa_memblock_release(input
->memblock
);
1345 pa_memblock_release(output
->memblock
);
1347 pa_assert(inf
== in_n_frames
);
1348 *out_n_frames
= outf
;
1351 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1353 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1358 pa_assert(out_n_frames
);
1360 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1361 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1363 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1365 pa_memblock_release(input
->memblock
);
1366 pa_memblock_release(output
->memblock
);
1368 pa_assert(inf
== in_n_frames
);
1369 *out_n_frames
= outf
;
1372 static void speex_update_rates(pa_resampler
*r
) {
1375 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1378 static void speex_reset(pa_resampler
*r
) {
1381 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1384 static void speex_free(pa_resampler
*r
) {
1387 if (!r
->speex
.state
)
1390 speex_resampler_destroy(r
->speex
.state
);
1393 static int speex_init(pa_resampler
*r
) {
1398 r
->impl_free
= speex_free
;
1399 r
->impl_update_rates
= speex_update_rates
;
1400 r
->impl_reset
= speex_reset
;
1402 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1404 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1405 r
->impl_resample
= speex_resample_int
;
1408 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1410 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1411 r
->impl_resample
= speex_resample_float
;
1414 pa_log_info("Choosing speex quality setting %i.", q
);
1416 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1422 /* Trivial implementation */
1424 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1432 pa_assert(out_n_frames
);
1434 fz
= r
->w_sz
* r
->o_ss
.channels
;
1436 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1437 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1439 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1442 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1443 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1445 if (j
>= in_n_frames
)
1448 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1450 oil_memcpy((uint8_t*) dst
+ fz
* o_index
,
1451 (uint8_t*) src
+ fz
* j
, (int) fz
);
1454 pa_memblock_release(input
->memblock
);
1455 pa_memblock_release(output
->memblock
);
1457 *out_n_frames
= o_index
;
1459 r
->trivial
.i_counter
+= in_n_frames
;
1461 /* Normalize counters */
1462 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1463 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1465 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1466 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1470 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1473 r
->trivial
.i_counter
= 0;
1474 r
->trivial
.o_counter
= 0;
1477 static int trivial_init(pa_resampler
*r
) {
1480 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1482 r
->impl_resample
= trivial_resample
;
1483 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1484 r
->impl_reset
= trivial_update_rates_or_reset
;
1489 /* Peak finder implementation */
1491 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1500 pa_assert(out_n_frames
);
1502 fz
= r
->w_sz
* r
->o_ss
.channels
;
1504 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1505 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1507 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1510 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1512 if (j
> r
->peaks
.i_counter
)
1513 j
-= r
->peaks
.i_counter
;
1517 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1519 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1521 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* start
);
1522 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1524 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1526 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1529 n
= (int16_t) (*s
< 0 ? -*s
: *s
);
1531 if (PA_UNLIKELY(n
> r
->peaks
.max_i
[c
]))
1532 r
->peaks
.max_i
[c
] = n
;
1535 if (i
>= in_n_frames
)
1538 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1539 *d
= r
->peaks
.max_i
[c
];
1540 r
->peaks
.max_i
[c
] = 0;
1545 float *s
= (float*) ((uint8_t*) src
+ fz
* start
);
1546 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1548 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1550 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1551 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1552 float n
= fabsf(*s
);
1554 if (n
> r
->peaks
.max_f
[c
])
1555 r
->peaks
.max_f
[c
] = n
;
1558 if (i
>= in_n_frames
)
1561 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1562 *d
= r
->peaks
.max_f
[c
];
1563 r
->peaks
.max_f
[c
] = 0;
1570 pa_memblock_release(input
->memblock
);
1571 pa_memblock_release(output
->memblock
);
1573 *out_n_frames
= o_index
;
1575 r
->peaks
.i_counter
+= in_n_frames
;
1577 /* Normalize counters */
1578 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1579 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1581 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1582 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1586 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1589 r
->peaks
.i_counter
= 0;
1590 r
->peaks
.o_counter
= 0;
1593 static int peaks_init(pa_resampler
*r
) {
1596 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1597 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1598 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1600 r
->impl_resample
= peaks_resample
;
1601 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1602 r
->impl_reset
= peaks_update_rates_or_reset
;
1607 /*** ffmpeg based implementation ***/
1609 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1610 unsigned used_frames
= 0, c
;
1615 pa_assert(out_n_frames
);
1617 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1620 int16_t *p
, *t
, *k
, *q
, *s
;
1621 int consumed_frames
;
1624 /* Allocate a new block */
1625 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1626 p
= pa_memblock_acquire(b
);
1628 /* Copy the remaining data into it */
1629 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1630 if (r
->ffmpeg
.buf
[c
].memblock
) {
1631 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1633 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1634 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1635 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1638 /* Now append the new data, splitting up channels */
1639 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1640 k
= (int16_t*) ((uint8_t*) p
+ l
);
1641 for (u
= 0; u
< in_n_frames
; u
++) {
1643 t
+= r
->o_ss
.channels
;
1646 pa_memblock_release(input
->memblock
);
1648 /* Calculate the resulting number of frames */
1649 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1651 /* Allocate buffer for the result */
1652 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1653 q
= pa_memblock_acquire(w
);
1656 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1659 (int) in
, (int) *out_n_frames
,
1660 c
>= (unsigned) (r
->o_ss
.channels
-1));
1662 pa_memblock_release(b
);
1664 /* Now store the remaining samples away */
1665 pa_assert(consumed_frames
<= (int) in
);
1666 if (consumed_frames
< (int) in
) {
1667 r
->ffmpeg
.buf
[c
].memblock
= b
;
1668 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1669 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1671 pa_memblock_unref(b
);
1673 /* And place the results in the output buffer */
1674 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1675 for (u
= 0; u
< used_frames
; u
++) {
1678 s
+= r
->o_ss
.channels
;
1680 pa_memblock_release(output
->memblock
);
1681 pa_memblock_release(w
);
1682 pa_memblock_unref(w
);
1685 *out_n_frames
= used_frames
;
1688 static void ffmpeg_free(pa_resampler
*r
) {
1693 if (r
->ffmpeg
.state
)
1694 av_resample_close(r
->ffmpeg
.state
);
1696 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1697 if (r
->ffmpeg
.buf
[c
].memblock
)
1698 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1701 static int ffmpeg_init(pa_resampler
*r
) {
1706 /* We could probably implement different quality levels by
1707 * adjusting the filter parameters here. However, ffmpeg
1708 * internally only uses these hardcoded values, so let's use them
1709 * here for now as well until ffmpeg makes this configurable. */
1711 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1714 r
->impl_free
= ffmpeg_free
;
1715 r
->impl_resample
= ffmpeg_resample
;
1717 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1718 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1723 /*** copy (noop) implementation ***/
1725 static int copy_init(pa_resampler
*r
) {
1728 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);