2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2.1 of the License,
9 or (at your option) any later version.
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 #ifdef HAVE_LIBSAMPLERATE
29 #include <samplerate.h>
32 #include <speex/speex_resampler.h>
34 #include <pulse/xmalloc.h>
35 #include <pulsecore/sconv.h>
36 #include <pulsecore/log.h>
37 #include <pulsecore/macro.h>
38 #include <pulsecore/strbuf.h>
40 #include "ffmpeg/avcodec.h"
42 #include "resampler.h"
45 /* Number of samples of extra space we allow the resamplers to return */
46 #define EXTRA_FRAMES 128
49 pa_resample_method_t method
;
50 pa_resample_flags_t flags
;
52 pa_sample_spec i_ss
, o_ss
;
53 pa_channel_map i_cm
, o_cm
;
54 size_t i_fz
, o_fz
, w_sz
;
57 pa_memchunk buf1
, buf2
, buf3
, buf4
;
58 unsigned buf1_samples
, buf2_samples
, buf3_samples
, buf4_samples
;
60 pa_sample_format_t work_format
;
62 pa_convert_func_t to_work_format_func
;
63 pa_convert_func_t from_work_format_func
;
66 pa_bool_t map_required
;
68 void (*impl_free
)(pa_resampler
*r
);
69 void (*impl_update_rates
)(pa_resampler
*r
);
70 void (*impl_resample
)(pa_resampler
*r
, const pa_memchunk
*in
, unsigned in_samples
, pa_memchunk
*out
, unsigned *out_samples
);
71 void (*impl_reset
)(pa_resampler
*r
);
73 struct { /* data specific to the trivial resampler */
78 struct { /* data specific to the peak finder pseudo resampler */
82 float max_f
[PA_CHANNELS_MAX
];
83 int16_t max_i
[PA_CHANNELS_MAX
];
87 #ifdef HAVE_LIBSAMPLERATE
88 struct { /* data specific to libsamplerate */
93 struct { /* data specific to speex */
94 SpeexResamplerState
* state
;
97 struct { /* data specific to ffmpeg */
98 struct AVResampleContext
*state
;
99 pa_memchunk buf
[PA_CHANNELS_MAX
];
103 static int copy_init(pa_resampler
*r
);
104 static int trivial_init(pa_resampler
*r
);
105 static int speex_init(pa_resampler
*r
);
106 static int ffmpeg_init(pa_resampler
*r
);
107 static int peaks_init(pa_resampler
*r
);
108 #ifdef HAVE_LIBSAMPLERATE
109 static int libsamplerate_init(pa_resampler
*r
);
112 static void calc_map_table(pa_resampler
*r
);
114 static int (* const init_table
[])(pa_resampler
*r
) = {
115 #ifdef HAVE_LIBSAMPLERATE
116 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = libsamplerate_init
,
117 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = libsamplerate_init
,
118 [PA_RESAMPLER_SRC_SINC_FASTEST
] = libsamplerate_init
,
119 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = libsamplerate_init
,
120 [PA_RESAMPLER_SRC_LINEAR
] = libsamplerate_init
,
122 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = NULL
,
123 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = NULL
,
124 [PA_RESAMPLER_SRC_SINC_FASTEST
] = NULL
,
125 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = NULL
,
126 [PA_RESAMPLER_SRC_LINEAR
] = NULL
,
128 [PA_RESAMPLER_TRIVIAL
] = trivial_init
,
129 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+0] = speex_init
,
130 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+1] = speex_init
,
131 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+2] = speex_init
,
132 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+3] = speex_init
,
133 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+4] = speex_init
,
134 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+5] = speex_init
,
135 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+6] = speex_init
,
136 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+7] = speex_init
,
137 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+8] = speex_init
,
138 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+9] = speex_init
,
139 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+10] = speex_init
,
140 [PA_RESAMPLER_SPEEX_FIXED_BASE
+0] = speex_init
,
141 [PA_RESAMPLER_SPEEX_FIXED_BASE
+1] = speex_init
,
142 [PA_RESAMPLER_SPEEX_FIXED_BASE
+2] = speex_init
,
143 [PA_RESAMPLER_SPEEX_FIXED_BASE
+3] = speex_init
,
144 [PA_RESAMPLER_SPEEX_FIXED_BASE
+4] = speex_init
,
145 [PA_RESAMPLER_SPEEX_FIXED_BASE
+5] = speex_init
,
146 [PA_RESAMPLER_SPEEX_FIXED_BASE
+6] = speex_init
,
147 [PA_RESAMPLER_SPEEX_FIXED_BASE
+7] = speex_init
,
148 [PA_RESAMPLER_SPEEX_FIXED_BASE
+8] = speex_init
,
149 [PA_RESAMPLER_SPEEX_FIXED_BASE
+9] = speex_init
,
150 [PA_RESAMPLER_SPEEX_FIXED_BASE
+10] = speex_init
,
151 [PA_RESAMPLER_FFMPEG
] = ffmpeg_init
,
152 [PA_RESAMPLER_AUTO
] = NULL
,
153 [PA_RESAMPLER_COPY
] = copy_init
,
154 [PA_RESAMPLER_PEAKS
] = peaks_init
,
157 pa_resampler
* pa_resampler_new(
159 const pa_sample_spec
*a
,
160 const pa_channel_map
*am
,
161 const pa_sample_spec
*b
,
162 const pa_channel_map
*bm
,
163 pa_resample_method_t method
,
164 pa_resample_flags_t flags
) {
166 pa_resampler
*r
= NULL
;
171 pa_assert(pa_sample_spec_valid(a
));
172 pa_assert(pa_sample_spec_valid(b
));
173 pa_assert(method
>= 0);
174 pa_assert(method
< PA_RESAMPLER_MAX
);
178 if (!(flags
& PA_RESAMPLER_VARIABLE_RATE
) && a
->rate
== b
->rate
) {
179 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
180 method
= PA_RESAMPLER_COPY
;
183 if (!pa_resample_method_supported(method
)) {
184 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method
));
185 method
= PA_RESAMPLER_AUTO
;
188 if (method
== PA_RESAMPLER_FFMPEG
&& (flags
& PA_RESAMPLER_VARIABLE_RATE
)) {
189 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
190 method
= PA_RESAMPLER_AUTO
;
193 if (method
== PA_RESAMPLER_COPY
&& ((flags
& PA_RESAMPLER_VARIABLE_RATE
) || a
->rate
!= b
->rate
)) {
194 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
195 method
= PA_RESAMPLER_AUTO
;
198 if (method
== PA_RESAMPLER_AUTO
)
199 method
= PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
201 r
= pa_xnew(pa_resampler
, 1);
207 r
->impl_update_rates
= NULL
;
208 r
->impl_resample
= NULL
;
209 r
->impl_reset
= NULL
;
211 /* Fill sample specs */
215 /* set up the remap structure */
216 r
->remap
.i_ss
= &r
->i_ss
;
217 r
->remap
.o_ss
= &r
->o_ss
;
218 r
->remap
.format
= &r
->work_format
;
222 else if (!pa_channel_map_init_auto(&r
->i_cm
, r
->i_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
227 else if (!pa_channel_map_init_auto(&r
->o_cm
, r
->o_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
230 r
->i_fz
= pa_frame_size(a
);
231 r
->o_fz
= pa_frame_size(b
);
233 pa_memchunk_reset(&r
->buf1
);
234 pa_memchunk_reset(&r
->buf2
);
235 pa_memchunk_reset(&r
->buf3
);
236 pa_memchunk_reset(&r
->buf4
);
238 r
->buf1_samples
= r
->buf2_samples
= r
->buf3_samples
= r
->buf4_samples
= 0;
242 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method
));
244 if ((method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) ||
245 (method
== PA_RESAMPLER_FFMPEG
))
246 r
->work_format
= PA_SAMPLE_S16NE
;
247 else if (method
== PA_RESAMPLER_TRIVIAL
|| method
== PA_RESAMPLER_COPY
|| method
== PA_RESAMPLER_PEAKS
) {
249 if (r
->map_required
|| a
->format
!= b
->format
|| method
== PA_RESAMPLER_PEAKS
) {
251 if (a
->format
== PA_SAMPLE_S32NE
|| a
->format
== PA_SAMPLE_S32RE
||
252 a
->format
== PA_SAMPLE_FLOAT32NE
|| a
->format
== PA_SAMPLE_FLOAT32RE
||
253 a
->format
== PA_SAMPLE_S24NE
|| a
->format
== PA_SAMPLE_S24RE
||
254 a
->format
== PA_SAMPLE_S24_32NE
|| a
->format
== PA_SAMPLE_S24_32RE
||
255 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
256 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
||
257 b
->format
== PA_SAMPLE_S24NE
|| b
->format
== PA_SAMPLE_S24RE
||
258 b
->format
== PA_SAMPLE_S24_32NE
|| b
->format
== PA_SAMPLE_S24_32RE
)
259 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
261 r
->work_format
= PA_SAMPLE_S16NE
;
264 r
->work_format
= a
->format
;
267 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
269 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
271 r
->w_sz
= pa_sample_size_of_format(r
->work_format
);
273 if (r
->i_ss
.format
== r
->work_format
)
274 r
->to_work_format_func
= NULL
;
275 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
276 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
279 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
280 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
284 if (r
->o_ss
.format
== r
->work_format
)
285 r
->from_work_format_func
= NULL
;
286 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
287 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
290 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
291 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
295 /* initialize implementation */
296 if (init_table
[method
](r
) < 0)
308 void pa_resampler_free(pa_resampler
*r
) {
314 if (r
->buf1
.memblock
)
315 pa_memblock_unref(r
->buf1
.memblock
);
316 if (r
->buf2
.memblock
)
317 pa_memblock_unref(r
->buf2
.memblock
);
318 if (r
->buf3
.memblock
)
319 pa_memblock_unref(r
->buf3
.memblock
);
320 if (r
->buf4
.memblock
)
321 pa_memblock_unref(r
->buf4
.memblock
);
326 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
330 if (r
->i_ss
.rate
== rate
)
335 r
->impl_update_rates(r
);
338 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
342 if (r
->o_ss
.rate
== rate
)
347 r
->impl_update_rates(r
);
350 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
353 /* Let's round up here */
355 return (((((out_length
+ r
->o_fz
-1) / r
->o_fz
) * r
->i_ss
.rate
) + r
->o_ss
.rate
-1) / r
->o_ss
.rate
) * r
->i_fz
;
358 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
361 /* Let's round up here */
363 return (((((in_length
+ r
->i_fz
-1) / r
->i_fz
) * r
->o_ss
.rate
) + r
->i_ss
.rate
-1) / r
->i_ss
.rate
) * r
->o_fz
;
366 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
367 size_t block_size_max
;
373 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
375 /* We deduce the "largest" sample spec we're using during the
377 ss
.channels
= (uint8_t) (PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
));
379 /* We silently assume that the format enum is ordered by size */
380 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
381 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
383 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
385 fs
= pa_frame_size(&ss
);
387 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
390 void pa_resampler_reset(pa_resampler
*r
) {
397 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
403 const pa_channel_map
* pa_resampler_input_channel_map(pa_resampler
*r
) {
409 const pa_sample_spec
* pa_resampler_input_sample_spec(pa_resampler
*r
) {
415 const pa_channel_map
* pa_resampler_output_channel_map(pa_resampler
*r
) {
421 const pa_sample_spec
* pa_resampler_output_sample_spec(pa_resampler
*r
) {
427 static const char * const resample_methods
[] = {
428 "src-sinc-best-quality",
429 "src-sinc-medium-quality",
431 "src-zero-order-hold",
462 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
464 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
467 return resample_methods
[m
];
470 int pa_resample_method_supported(pa_resample_method_t m
) {
472 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
475 #ifndef HAVE_LIBSAMPLERATE
476 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
483 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
484 pa_resample_method_t m
;
488 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
489 if (!strcmp(string
, resample_methods
[m
]))
492 if (!strcmp(string
, "speex-fixed"))
493 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
495 if (!strcmp(string
, "speex-float"))
496 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
498 return PA_RESAMPLER_INVALID
;
501 static pa_bool_t
on_left(pa_channel_position_t p
) {
504 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
505 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
506 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
507 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
508 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
509 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
512 static pa_bool_t
on_right(pa_channel_position_t p
) {
515 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
516 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
517 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
518 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
519 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
520 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
523 static pa_bool_t
on_center(pa_channel_position_t p
) {
526 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
527 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
528 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
529 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
530 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
533 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
535 p
== PA_CHANNEL_POSITION_LFE
;
538 static pa_bool_t
on_front(pa_channel_position_t p
) {
540 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
541 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
542 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
543 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
544 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
545 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
546 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
547 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
550 static pa_bool_t
on_rear(pa_channel_position_t p
) {
552 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
553 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
554 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
555 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
556 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
557 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
560 static pa_bool_t
on_side(pa_channel_position_t p
) {
562 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
563 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
564 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
574 static int front_rear_side(pa_channel_position_t p
) {
584 static void calc_map_table(pa_resampler
*r
) {
587 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
595 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
)))))
600 n_oc
= r
->o_ss
.channels
;
601 n_ic
= r
->i_ss
.channels
;
603 memset(m
->map_table_f
, 0, sizeof(m
->map_table_f
));
604 memset(m
->map_table_i
, 0, sizeof(m
->map_table_i
));
606 memset(ic_connected
, 0, sizeof(ic_connected
));
607 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
609 for (oc
= 0; oc
< n_oc
; oc
++) {
610 pa_bool_t oc_connected
= FALSE
;
611 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
613 for (ic
= 0; ic
< n_ic
; ic
++) {
614 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
616 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
617 /* We shall not do any remapping. Hence, just check by index */
620 m
->map_table_f
[oc
][ic
] = 1.0;
625 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
626 /* We shall not do any remixing. Hence, just check by name */
629 m
->map_table_f
[oc
][ic
] = 1.0;
636 /* OK, we shall do the full monty: upmixing and
637 * downmixing. Our algorithm is relatively simple, does
638 * not do spacialization, delay elements or apply lowpass
639 * filters for LFE. Patches are always welcome,
640 * though. Oh, and it doesn't do any matrix
641 * decoding. (Which probably wouldn't make any sense
644 * This code is not idempotent: downmixing an upmixed
645 * stereo stream is not identical to the original. The
646 * volume will not match, and the two channels will be a
647 * linear combination of both.
649 * This is losely based on random suggestions found on the
650 * Internet, such as this:
651 * http://www.halfgaar.net/surround-sound-in-linux and the
654 * The algorithm works basically like this:
656 * 1) Connect all channels with matching names.
659 * S:Mono: Copy into all D:channels
660 * D:Mono: Copy in all S:channels
662 * 3) Mix D:Left, D:Right:
663 * D:Left: If not connected, avg all S:Left
664 * D:Right: If not connected, avg all S:Right
667 * If not connected, avg all S:Center
668 * If still not connected, avg all S:Left, S:Right
671 * If not connected, avg all S:*
673 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
674 * not connected, mix into all D:left and all D:right
675 * channels. Gain is 0.1, the current left and right
676 * should be multiplied by 0.9.
678 * 7) Make sure S:Center, S:LFE is used:
680 * S:Center, S:LFE: If not connected, mix into all
681 * D:left, all D:right, all D:center channels, gain is
682 * 0.375. The current (as result of 1..6) factors
683 * should be multiplied by 0.75. (Alt. suggestion: 0.25
684 * vs. 0.5) If C-front is only mixed into
685 * L-front/R-front if available, otherwise into all L/R
686 * channels. Similarly for C-rear.
688 * S: and D: shall relate to the source resp. destination channels.
690 * Rationale: 1, 2 are probably obvious. For 3: this
691 * copies front to rear if needed. For 4: we try to find
692 * some suitable C source for C, if we don't find any, we
693 * avg L and R. For 5: LFE is mixed from all channels. For
694 * 6: the rear channels should not be dropped entirely,
695 * however have only minimal impact. For 7: movies usually
696 * encode speech on the center channel. Thus we have to
697 * make sure this channel is distributed to L and R if not
698 * available in the output. Also, LFE is used to achieve a
699 * greater dynamic range, and thus we should try to do our
700 * best to pass it to L+R.
703 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
704 m
->map_table_f
[oc
][ic
] = 1.0;
707 ic_connected
[ic
] = TRUE
;
711 if (!oc_connected
&& remix
) {
712 /* OK, we shall remix */
714 /* Try to find matching input ports for this output port */
719 /* We are not connected and on the left side, let's
720 * average all left side input channels. */
722 for (ic
= 0; ic
< n_ic
; ic
++)
723 if (on_left(r
->i_cm
.map
[ic
]))
727 for (ic
= 0; ic
< n_ic
; ic
++)
728 if (on_left(r
->i_cm
.map
[ic
])) {
729 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
730 ic_connected
[ic
] = TRUE
;
733 /* We ignore the case where there is no left input
734 * channel. Something is really wrong in this case
737 } else if (on_right(b
)) {
740 /* We are not connected and on the right side, let's
741 * average all right side input channels. */
743 for (ic
= 0; ic
< n_ic
; ic
++)
744 if (on_right(r
->i_cm
.map
[ic
]))
748 for (ic
= 0; ic
< n_ic
; ic
++)
749 if (on_right(r
->i_cm
.map
[ic
])) {
750 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
751 ic_connected
[ic
] = TRUE
;
754 /* We ignore the case where there is no right input
755 * channel. Something is really wrong in this case
758 } else if (on_center(b
)) {
761 /* We are not connected and at the center. Let's
762 * average all center input channels. */
764 for (ic
= 0; ic
< n_ic
; ic
++)
765 if (on_center(r
->i_cm
.map
[ic
]))
769 for (ic
= 0; ic
< n_ic
; ic
++)
770 if (on_center(r
->i_cm
.map
[ic
])) {
771 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
772 ic_connected
[ic
] = TRUE
;
776 /* Hmm, no center channel around, let's synthesize
777 * it by mixing L and R.*/
781 for (ic
= 0; ic
< n_ic
; ic
++)
782 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
786 for (ic
= 0; ic
< n_ic
; ic
++)
787 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
788 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
789 ic_connected
[ic
] = TRUE
;
792 /* We ignore the case where there is not even a
793 * left or right input channel. Something is
794 * really wrong in this case anyway. */
797 } else if (on_lfe(b
)) {
799 /* We are not connected and an LFE. Let's average all
800 * channels for LFE. */
802 for (ic
= 0; ic
< n_ic
; ic
++) {
804 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
805 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n_ic
;
807 m
->map_table_f
[oc
][ic
] = 0;
809 /* Please note that a channel connected to LFE
810 * doesn't really count as connected. */
818 ic_unconnected_left
= 0,
819 ic_unconnected_right
= 0,
820 ic_unconnected_center
= 0,
821 ic_unconnected_lfe
= 0;
823 for (ic
= 0; ic
< n_ic
; ic
++) {
824 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
826 if (ic_connected
[ic
])
830 ic_unconnected_left
++;
831 else if (on_right(a
))
832 ic_unconnected_right
++;
833 else if (on_center(a
))
834 ic_unconnected_center
++;
836 ic_unconnected_lfe
++;
839 if (ic_unconnected_left
> 0) {
841 /* OK, so there are unconnected input channels on the
842 * left. Let's multiply all already connected channels on
843 * the left side by .9 and add in our averaged unconnected
844 * channels multplied by .1 */
846 for (oc
= 0; oc
< n_oc
; oc
++) {
848 if (!on_left(r
->o_cm
.map
[oc
]))
851 for (ic
= 0; ic
< n_ic
; ic
++) {
853 if (ic_connected
[ic
]) {
854 m
->map_table_f
[oc
][ic
] *= .9f
;
858 if (on_left(r
->i_cm
.map
[ic
]))
859 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
864 if (ic_unconnected_right
> 0) {
866 /* OK, so there are unconnected input channels on the
867 * right. Let's multiply all already connected channels on
868 * the right side by .9 and add in our averaged unconnected
869 * channels multplied by .1 */
871 for (oc
= 0; oc
< n_oc
; oc
++) {
873 if (!on_right(r
->o_cm
.map
[oc
]))
876 for (ic
= 0; ic
< n_ic
; ic
++) {
878 if (ic_connected
[ic
]) {
879 m
->map_table_f
[oc
][ic
] *= .9f
;
883 if (on_right(r
->i_cm
.map
[ic
]))
884 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
889 if (ic_unconnected_center
> 0) {
890 pa_bool_t mixed_in
= FALSE
;
892 /* OK, so there are unconnected input channels on the
893 * center. Let's multiply all already connected channels on
894 * the center side by .9 and add in our averaged unconnected
895 * channels multplied by .1 */
897 for (oc
= 0; oc
< n_oc
; oc
++) {
899 if (!on_center(r
->o_cm
.map
[oc
]))
902 for (ic
= 0; ic
< n_ic
; ic
++) {
904 if (ic_connected
[ic
]) {
905 m
->map_table_f
[oc
][ic
] *= .9f
;
909 if (on_center(r
->i_cm
.map
[ic
])) {
910 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
917 unsigned ncenter
[PA_CHANNELS_MAX
];
918 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
920 memset(ncenter
, 0, sizeof(ncenter
));
921 memset(found_frs
, 0, sizeof(found_frs
));
923 /* Hmm, as it appears there was no center channel we
924 could mix our center channel in. In this case, mix
925 it into left and right. Using .375 and 0.75 as
928 for (ic
= 0; ic
< n_ic
; ic
++) {
930 if (ic_connected
[ic
])
933 if (!on_center(r
->i_cm
.map
[ic
]))
936 for (oc
= 0; oc
< n_oc
; oc
++) {
938 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
941 if (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
942 found_frs
[ic
] = TRUE
;
947 for (oc
= 0; oc
< n_oc
; oc
++) {
949 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
952 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
957 for (oc
= 0; oc
< n_oc
; oc
++) {
959 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
962 if (ncenter
[oc
] <= 0)
965 for (ic
= 0; ic
< n_ic
; ic
++) {
967 if (ic_connected
[ic
]) {
968 m
->map_table_f
[oc
][ic
] *= .75f
;
972 if (!on_center(r
->i_cm
.map
[ic
]))
975 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
976 m
->map_table_f
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
982 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
984 /* OK, so there is an unconnected LFE channel. Let's mix
985 * it into all channels, with factor 0.375 */
987 for (ic
= 0; ic
< n_ic
; ic
++) {
989 if (!on_lfe(r
->i_cm
.map
[ic
]))
992 for (oc
= 0; oc
< n_oc
; oc
++)
993 m
->map_table_f
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
997 /* make an 16:16 int version of the matrix */
998 for (oc
= 0; oc
< n_oc
; oc
++)
999 for (ic
= 0; ic
< n_ic
; ic
++)
1000 m
->map_table_i
[oc
][ic
] = (int32_t) (m
->map_table_f
[oc
][ic
] * 0x10000);
1002 s
= pa_strbuf_new();
1004 pa_strbuf_printf(s
, " ");
1005 for (ic
= 0; ic
< n_ic
; ic
++)
1006 pa_strbuf_printf(s
, " I%02u ", ic
);
1007 pa_strbuf_puts(s
, "\n +");
1009 for (ic
= 0; ic
< n_ic
; ic
++)
1010 pa_strbuf_printf(s
, "------");
1011 pa_strbuf_puts(s
, "\n");
1013 for (oc
= 0; oc
< n_oc
; oc
++) {
1014 pa_strbuf_printf(s
, "O%02u |", oc
);
1016 for (ic
= 0; ic
< n_ic
; ic
++)
1017 pa_strbuf_printf(s
, " %1.3f", m
->map_table_f
[oc
][ic
]);
1019 pa_strbuf_puts(s
, "\n");
1022 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
1025 /* initialize the remapping function */
1029 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1035 pa_assert(input
->memblock
);
1037 /* Convert the incoming sample into the work sample format and place them in buf1 */
1039 if (!r
->to_work_format_func
|| !input
->length
)
1042 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1045 r
->buf1
.length
= r
->w_sz
* n_samples
;
1047 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
1048 if (r
->buf1
.memblock
)
1049 pa_memblock_unref(r
->buf1
.memblock
);
1051 r
->buf1_samples
= n_samples
;
1052 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
1055 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1056 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
1058 r
->to_work_format_func(n_samples
, src
, dst
);
1060 pa_memblock_release(input
->memblock
);
1061 pa_memblock_release(r
->buf1
.memblock
);
1066 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1067 unsigned in_n_samples
, out_n_samples
, n_frames
;
1073 pa_assert(input
->memblock
);
1075 /* Remap channels and place the result int buf2 */
1077 if (!r
->map_required
|| !input
->length
)
1080 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1081 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1082 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1085 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
1087 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
1088 if (r
->buf2
.memblock
)
1089 pa_memblock_unref(r
->buf2
.memblock
);
1091 r
->buf2_samples
= out_n_samples
;
1092 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
1095 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1096 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
1100 pa_assert (remap
->do_remap
);
1101 remap
->do_remap (remap
, dst
, src
, n_frames
);
1103 pa_memblock_release(input
->memblock
);
1104 pa_memblock_release(r
->buf2
.memblock
);
1109 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1110 unsigned in_n_frames
, in_n_samples
;
1111 unsigned out_n_frames
, out_n_samples
;
1116 /* Resample the data and place the result in buf3 */
1118 if (!r
->impl_resample
|| !input
->length
)
1121 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1122 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1124 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1125 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1128 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1130 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1131 if (r
->buf3
.memblock
)
1132 pa_memblock_unref(r
->buf3
.memblock
);
1134 r
->buf3_samples
= out_n_samples
;
1135 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1138 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1139 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1144 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1145 unsigned n_samples
, n_frames
;
1151 /* Convert the data into the correct sample type and place the result in buf4 */
1153 if (!r
->from_work_format_func
|| !input
->length
)
1156 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1157 n_frames
= n_samples
/ r
->o_ss
.channels
;
1160 r
->buf4
.length
= r
->o_fz
* n_frames
;
1162 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1163 if (r
->buf4
.memblock
)
1164 pa_memblock_unref(r
->buf4
.memblock
);
1166 r
->buf4_samples
= n_samples
;
1167 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1170 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1171 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1172 r
->from_work_format_func(n_samples
, src
, dst
);
1173 pa_memblock_release(input
->memblock
);
1174 pa_memblock_release(r
->buf4
.memblock
);
1176 r
->buf4
.length
= r
->o_fz
* n_frames
;
1181 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1187 pa_assert(in
->length
);
1188 pa_assert(in
->memblock
);
1189 pa_assert(in
->length
% r
->i_fz
== 0);
1191 buf
= (pa_memchunk
*) in
;
1192 buf
= convert_to_work_format(r
, buf
);
1193 buf
= remap_channels(r
, buf
);
1194 buf
= resample(r
, buf
);
1197 buf
= convert_from_work_format(r
, buf
);
1201 pa_memblock_ref(buf
->memblock
);
1203 pa_memchunk_reset(buf
);
1205 pa_memchunk_reset(out
);
1208 /*** libsamplerate based implementation ***/
1210 #ifdef HAVE_LIBSAMPLERATE
1211 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1217 pa_assert(out_n_frames
);
1219 memset(&data
, 0, sizeof(data
));
1221 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1222 data
.input_frames
= (long int) in_n_frames
;
1224 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1225 data
.output_frames
= (long int) *out_n_frames
;
1227 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1228 data
.end_of_input
= 0;
1230 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1231 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1233 pa_memblock_release(input
->memblock
);
1234 pa_memblock_release(output
->memblock
);
1236 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1239 static void libsamplerate_update_rates(pa_resampler
*r
) {
1242 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1245 static void libsamplerate_reset(pa_resampler
*r
) {
1248 pa_assert_se(src_reset(r
->src
.state
) == 0);
1251 static void libsamplerate_free(pa_resampler
*r
) {
1255 src_delete(r
->src
.state
);
1258 static int libsamplerate_init(pa_resampler
*r
) {
1263 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1266 r
->impl_free
= libsamplerate_free
;
1267 r
->impl_update_rates
= libsamplerate_update_rates
;
1268 r
->impl_resample
= libsamplerate_resample
;
1269 r
->impl_reset
= libsamplerate_reset
;
1275 /*** speex based implementation ***/
1277 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1279 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1284 pa_assert(out_n_frames
);
1286 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1287 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1289 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1291 pa_memblock_release(input
->memblock
);
1292 pa_memblock_release(output
->memblock
);
1294 pa_assert(inf
== in_n_frames
);
1295 *out_n_frames
= outf
;
1298 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1300 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1305 pa_assert(out_n_frames
);
1307 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1308 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1310 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1312 pa_memblock_release(input
->memblock
);
1313 pa_memblock_release(output
->memblock
);
1315 pa_assert(inf
== in_n_frames
);
1316 *out_n_frames
= outf
;
1319 static void speex_update_rates(pa_resampler
*r
) {
1322 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1325 static void speex_reset(pa_resampler
*r
) {
1328 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1331 static void speex_free(pa_resampler
*r
) {
1334 if (!r
->speex
.state
)
1337 speex_resampler_destroy(r
->speex
.state
);
1340 static int speex_init(pa_resampler
*r
) {
1345 r
->impl_free
= speex_free
;
1346 r
->impl_update_rates
= speex_update_rates
;
1347 r
->impl_reset
= speex_reset
;
1349 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1351 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1352 r
->impl_resample
= speex_resample_int
;
1355 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1357 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1358 r
->impl_resample
= speex_resample_float
;
1361 pa_log_info("Choosing speex quality setting %i.", q
);
1363 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1369 /* Trivial implementation */
1371 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1379 pa_assert(out_n_frames
);
1381 fz
= r
->w_sz
* r
->o_ss
.channels
;
1383 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1384 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1386 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1389 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1390 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1392 if (j
>= in_n_frames
)
1395 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1397 memcpy((uint8_t*) dst
+ fz
* o_index
,
1398 (uint8_t*) src
+ fz
* j
, (int) fz
);
1401 pa_memblock_release(input
->memblock
);
1402 pa_memblock_release(output
->memblock
);
1404 *out_n_frames
= o_index
;
1406 r
->trivial
.i_counter
+= in_n_frames
;
1408 /* Normalize counters */
1409 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1410 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1412 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1413 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1417 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1420 r
->trivial
.i_counter
= 0;
1421 r
->trivial
.o_counter
= 0;
1424 static int trivial_init(pa_resampler
*r
) {
1427 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1429 r
->impl_resample
= trivial_resample
;
1430 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1431 r
->impl_reset
= trivial_update_rates_or_reset
;
1436 /* Peak finder implementation */
1438 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1447 pa_assert(out_n_frames
);
1449 fz
= r
->w_sz
* r
->o_ss
.channels
;
1451 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1452 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1454 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1457 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1459 if (j
> r
->peaks
.i_counter
)
1460 j
-= r
->peaks
.i_counter
;
1464 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1466 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1468 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* start
);
1469 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1471 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1473 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1476 n
= (int16_t) (*s
< 0 ? -*s
: *s
);
1478 if (PA_UNLIKELY(n
> r
->peaks
.max_i
[c
]))
1479 r
->peaks
.max_i
[c
] = n
;
1482 if (i
>= in_n_frames
)
1485 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1486 *d
= r
->peaks
.max_i
[c
];
1487 r
->peaks
.max_i
[c
] = 0;
1492 float *s
= (float*) ((uint8_t*) src
+ fz
* start
);
1493 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1495 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1497 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1498 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1499 float n
= fabsf(*s
);
1501 if (n
> r
->peaks
.max_f
[c
])
1502 r
->peaks
.max_f
[c
] = n
;
1505 if (i
>= in_n_frames
)
1508 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1509 *d
= r
->peaks
.max_f
[c
];
1510 r
->peaks
.max_f
[c
] = 0;
1517 pa_memblock_release(input
->memblock
);
1518 pa_memblock_release(output
->memblock
);
1520 *out_n_frames
= o_index
;
1522 r
->peaks
.i_counter
+= in_n_frames
;
1524 /* Normalize counters */
1525 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1526 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1528 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1529 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1533 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1536 r
->peaks
.i_counter
= 0;
1537 r
->peaks
.o_counter
= 0;
1540 static int peaks_init(pa_resampler
*r
) {
1543 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1544 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1545 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1547 r
->impl_resample
= peaks_resample
;
1548 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1549 r
->impl_reset
= peaks_update_rates_or_reset
;
1554 /*** ffmpeg based implementation ***/
1556 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1557 unsigned used_frames
= 0, c
;
1562 pa_assert(out_n_frames
);
1564 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1567 int16_t *p
, *t
, *k
, *q
, *s
;
1568 int consumed_frames
;
1571 /* Allocate a new block */
1572 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1573 p
= pa_memblock_acquire(b
);
1575 /* Copy the remaining data into it */
1576 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1577 if (r
->ffmpeg
.buf
[c
].memblock
) {
1578 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1580 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1581 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1582 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1585 /* Now append the new data, splitting up channels */
1586 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1587 k
= (int16_t*) ((uint8_t*) p
+ l
);
1588 for (u
= 0; u
< in_n_frames
; u
++) {
1590 t
+= r
->o_ss
.channels
;
1593 pa_memblock_release(input
->memblock
);
1595 /* Calculate the resulting number of frames */
1596 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1598 /* Allocate buffer for the result */
1599 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1600 q
= pa_memblock_acquire(w
);
1603 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1606 (int) in
, (int) *out_n_frames
,
1607 c
>= (unsigned) (r
->o_ss
.channels
-1));
1609 pa_memblock_release(b
);
1611 /* Now store the remaining samples away */
1612 pa_assert(consumed_frames
<= (int) in
);
1613 if (consumed_frames
< (int) in
) {
1614 r
->ffmpeg
.buf
[c
].memblock
= b
;
1615 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1616 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1618 pa_memblock_unref(b
);
1620 /* And place the results in the output buffer */
1621 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1622 for (u
= 0; u
< used_frames
; u
++) {
1625 s
+= r
->o_ss
.channels
;
1627 pa_memblock_release(output
->memblock
);
1628 pa_memblock_release(w
);
1629 pa_memblock_unref(w
);
1632 *out_n_frames
= used_frames
;
1635 static void ffmpeg_free(pa_resampler
*r
) {
1640 if (r
->ffmpeg
.state
)
1641 av_resample_close(r
->ffmpeg
.state
);
1643 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1644 if (r
->ffmpeg
.buf
[c
].memblock
)
1645 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1648 static int ffmpeg_init(pa_resampler
*r
) {
1653 /* We could probably implement different quality levels by
1654 * adjusting the filter parameters here. However, ffmpeg
1655 * internally only uses these hardcoded values, so let's use them
1656 * here for now as well until ffmpeg makes this configurable. */
1658 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1661 r
->impl_free
= ffmpeg_free
;
1662 r
->impl_resample
= ffmpeg_resample
;
1664 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1665 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1670 /*** copy (noop) implementation ***/
1672 static int copy_init(pa_resampler
*r
) {
1675 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);