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"
44 /* Number of samples of extra space we allow the resamplers to return */
45 #define EXTRA_FRAMES 128
48 pa_resample_method_t method
;
49 pa_resample_flags_t flags
;
51 pa_sample_spec i_ss
, o_ss
;
52 pa_channel_map i_cm
, o_cm
;
53 size_t i_fz
, o_fz
, w_sz
;
56 pa_memchunk buf1
, buf2
, buf3
, buf4
;
57 unsigned buf1_samples
, buf2_samples
, buf3_samples
, buf4_samples
;
59 pa_sample_format_t work_format
;
61 pa_convert_func_t to_work_format_func
;
62 pa_convert_func_t from_work_format_func
;
64 float map_table_f
[PA_CHANNELS_MAX
][PA_CHANNELS_MAX
];
65 int32_t map_table_i
[PA_CHANNELS_MAX
][PA_CHANNELS_MAX
];
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 */
217 else if (!pa_channel_map_init_auto(&r
->i_cm
, r
->i_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
222 else if (!pa_channel_map_init_auto(&r
->o_cm
, r
->o_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
225 r
->i_fz
= pa_frame_size(a
);
226 r
->o_fz
= pa_frame_size(b
);
228 pa_memchunk_reset(&r
->buf1
);
229 pa_memchunk_reset(&r
->buf2
);
230 pa_memchunk_reset(&r
->buf3
);
231 pa_memchunk_reset(&r
->buf4
);
233 r
->buf1_samples
= r
->buf2_samples
= r
->buf3_samples
= r
->buf4_samples
= 0;
237 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method
));
239 if ((method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) ||
240 (method
== PA_RESAMPLER_FFMPEG
))
241 r
->work_format
= PA_SAMPLE_S16NE
;
242 else if (method
== PA_RESAMPLER_TRIVIAL
|| method
== PA_RESAMPLER_COPY
|| method
== PA_RESAMPLER_PEAKS
) {
244 if (r
->map_required
|| a
->format
!= b
->format
|| method
== PA_RESAMPLER_PEAKS
) {
246 if (a
->format
== PA_SAMPLE_S32NE
|| a
->format
== PA_SAMPLE_S32RE
||
247 a
->format
== PA_SAMPLE_FLOAT32NE
|| a
->format
== PA_SAMPLE_FLOAT32RE
||
248 a
->format
== PA_SAMPLE_S24NE
|| a
->format
== PA_SAMPLE_S24RE
||
249 a
->format
== PA_SAMPLE_S24_32NE
|| a
->format
== PA_SAMPLE_S24_32RE
||
250 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
251 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
||
252 b
->format
== PA_SAMPLE_S24NE
|| b
->format
== PA_SAMPLE_S24RE
||
253 b
->format
== PA_SAMPLE_S24_32NE
|| b
->format
== PA_SAMPLE_S24_32RE
)
254 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
256 r
->work_format
= PA_SAMPLE_S16NE
;
259 r
->work_format
= a
->format
;
262 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
264 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
266 r
->w_sz
= pa_sample_size_of_format(r
->work_format
);
268 if (r
->i_ss
.format
== r
->work_format
)
269 r
->to_work_format_func
= NULL
;
270 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
271 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
274 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
275 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
279 if (r
->o_ss
.format
== r
->work_format
)
280 r
->from_work_format_func
= NULL
;
281 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
282 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
285 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
286 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
290 /* initialize implementation */
291 if (init_table
[method
](r
) < 0)
303 void pa_resampler_free(pa_resampler
*r
) {
309 if (r
->buf1
.memblock
)
310 pa_memblock_unref(r
->buf1
.memblock
);
311 if (r
->buf2
.memblock
)
312 pa_memblock_unref(r
->buf2
.memblock
);
313 if (r
->buf3
.memblock
)
314 pa_memblock_unref(r
->buf3
.memblock
);
315 if (r
->buf4
.memblock
)
316 pa_memblock_unref(r
->buf4
.memblock
);
321 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
325 if (r
->i_ss
.rate
== rate
)
330 r
->impl_update_rates(r
);
333 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
337 if (r
->o_ss
.rate
== rate
)
342 r
->impl_update_rates(r
);
345 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
348 /* Let's round up here */
350 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
;
353 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
356 /* Let's round up here */
358 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
;
361 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
362 size_t block_size_max
;
368 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
370 /* We deduce the "largest" sample spec we're using during the
372 ss
.channels
= (uint8_t) (PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
));
374 /* We silently assume that the format enum is ordered by size */
375 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
376 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
378 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
380 fs
= pa_frame_size(&ss
);
382 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
385 void pa_resampler_reset(pa_resampler
*r
) {
392 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
398 const pa_channel_map
* pa_resampler_input_channel_map(pa_resampler
*r
) {
404 const pa_sample_spec
* pa_resampler_input_sample_spec(pa_resampler
*r
) {
410 const pa_channel_map
* pa_resampler_output_channel_map(pa_resampler
*r
) {
416 const pa_sample_spec
* pa_resampler_output_sample_spec(pa_resampler
*r
) {
422 static const char * const resample_methods
[] = {
423 "src-sinc-best-quality",
424 "src-sinc-medium-quality",
426 "src-zero-order-hold",
457 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
459 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
462 return resample_methods
[m
];
465 int pa_resample_method_supported(pa_resample_method_t m
) {
467 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
470 #ifndef HAVE_LIBSAMPLERATE
471 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
478 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
479 pa_resample_method_t m
;
483 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
484 if (!strcmp(string
, resample_methods
[m
]))
487 if (!strcmp(string
, "speex-fixed"))
488 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
490 if (!strcmp(string
, "speex-float"))
491 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
493 return PA_RESAMPLER_INVALID
;
496 static pa_bool_t
on_left(pa_channel_position_t p
) {
499 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
500 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
501 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
502 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
503 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
504 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
507 static pa_bool_t
on_right(pa_channel_position_t p
) {
510 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
511 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
512 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
513 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
514 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
515 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
518 static pa_bool_t
on_center(pa_channel_position_t p
) {
521 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
522 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
523 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
524 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
525 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
528 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
530 p
== PA_CHANNEL_POSITION_LFE
;
533 static pa_bool_t
on_front(pa_channel_position_t p
) {
535 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
536 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
537 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
538 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
539 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
540 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
541 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
542 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
545 static pa_bool_t
on_rear(pa_channel_position_t p
) {
547 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
548 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
549 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
550 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
551 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
552 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
555 static pa_bool_t
on_side(pa_channel_position_t p
) {
557 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
558 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
559 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
569 static int front_rear_side(pa_channel_position_t p
) {
579 static void calc_map_table(pa_resampler
*r
) {
581 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
588 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
)))))
591 memset(r
->map_table_f
, 0, sizeof(r
->map_table_f
));
592 memset(r
->map_table_i
, 0, sizeof(r
->map_table_i
));
593 memset(ic_connected
, 0, sizeof(ic_connected
));
594 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
596 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
597 pa_bool_t oc_connected
= FALSE
;
598 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
600 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
601 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
603 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
604 /* We shall not do any remapping. Hence, just check by index */
607 r
->map_table_f
[oc
][ic
] = 1.0;
612 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
613 /* We shall not do any remixing. Hence, just check by name */
616 r
->map_table_f
[oc
][ic
] = 1.0;
623 /* OK, we shall do the full monty: upmixing and
624 * downmixing. Our algorithm is relatively simple, does
625 * not do spacialization, delay elements or apply lowpass
626 * filters for LFE. Patches are always welcome,
627 * though. Oh, and it doesn't do any matrix
628 * decoding. (Which probably wouldn't make any sense
631 * This code is not idempotent: downmixing an upmixed
632 * stereo stream is not identical to the original. The
633 * volume will not match, and the two channels will be a
634 * linear combination of both.
636 * This is losely based on random suggestions found on the
637 * Internet, such as this:
638 * http://www.halfgaar.net/surround-sound-in-linux and the
641 * The algorithm works basically like this:
643 * 1) Connect all channels with matching names.
646 * S:Mono: Copy into all D:channels
647 * D:Mono: Copy in all S:channels
649 * 3) Mix D:Left, D:Right:
650 * D:Left: If not connected, avg all S:Left
651 * D:Right: If not connected, avg all S:Right
654 * If not connected, avg all S:Center
655 * If still not connected, avg all S:Left, S:Right
658 * If not connected, avg all S:*
660 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
661 * not connected, mix into all D:left and all D:right
662 * channels. Gain is 0.1, the current left and right
663 * should be multiplied by 0.9.
665 * 7) Make sure S:Center, S:LFE is used:
667 * S:Center, S:LFE: If not connected, mix into all
668 * D:left, all D:right, all D:center channels, gain is
669 * 0.375. The current (as result of 1..6) factors
670 * should be multiplied by 0.75. (Alt. suggestion: 0.25
671 * vs. 0.5) If C-front is only mixed into
672 * L-front/R-front if available, otherwise into all L/R
673 * channels. Similarly for C-rear.
675 * S: and D: shall relate to the source resp. destination channels.
677 * Rationale: 1, 2 are probably obvious. For 3: this
678 * copies front to rear if needed. For 4: we try to find
679 * some suitable C source for C, if we don't find any, we
680 * avg L and R. For 5: LFE is mixed from all channels. For
681 * 6: the rear channels should not be dropped entirely,
682 * however have only minimal impact. For 7: movies usually
683 * encode speech on the center channel. Thus we have to
684 * make sure this channel is distributed to L and R if not
685 * available in the output. Also, LFE is used to achieve a
686 * greater dynamic range, and thus we should try to do our
687 * best to pass it to L+R.
690 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
691 r
->map_table_f
[oc
][ic
] = 1.0;
694 ic_connected
[ic
] = TRUE
;
698 if (!oc_connected
&& remix
) {
699 /* OK, we shall remix */
701 /* Try to find matching input ports for this output port */
706 /* We are not connected and on the left side, let's
707 * average all left side input channels. */
709 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
710 if (on_left(r
->i_cm
.map
[ic
]))
714 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
715 if (on_left(r
->i_cm
.map
[ic
])) {
716 r
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
717 ic_connected
[ic
] = TRUE
;
720 /* We ignore the case where there is no left input
721 * channel. Something is really wrong in this case
724 } else if (on_right(b
)) {
727 /* We are not connected and on the right side, let's
728 * average all right side input channels. */
730 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
731 if (on_right(r
->i_cm
.map
[ic
]))
735 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
736 if (on_right(r
->i_cm
.map
[ic
])) {
737 r
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
738 ic_connected
[ic
] = TRUE
;
741 /* We ignore the case where there is no right input
742 * channel. Something is really wrong in this case
745 } else if (on_center(b
)) {
748 /* We are not connected and at the center. Let's
749 * average all center input channels. */
751 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
752 if (on_center(r
->i_cm
.map
[ic
]))
756 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
757 if (on_center(r
->i_cm
.map
[ic
])) {
758 r
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
759 ic_connected
[ic
] = TRUE
;
763 /* Hmm, no center channel around, let's synthesize
764 * it by mixing L and R.*/
768 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
769 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
773 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
774 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
775 r
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
776 ic_connected
[ic
] = TRUE
;
779 /* We ignore the case where there is not even a
780 * left or right input channel. Something is
781 * really wrong in this case anyway. */
784 } else if (on_lfe(b
)) {
786 /* We are not connected and an LFE. Let's average all
787 * channels for LFE. */
789 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
791 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
792 r
->map_table_f
[oc
][ic
] = 1.0f
/ (float) r
->i_ss
.channels
;
794 r
->map_table_f
[oc
][ic
] = 0;
796 /* Please note that a channel connected to LFE
797 * doesn't really count as connected. */
805 ic_unconnected_left
= 0,
806 ic_unconnected_right
= 0,
807 ic_unconnected_center
= 0,
808 ic_unconnected_lfe
= 0;
810 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
811 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
813 if (ic_connected
[ic
])
817 ic_unconnected_left
++;
818 else if (on_right(a
))
819 ic_unconnected_right
++;
820 else if (on_center(a
))
821 ic_unconnected_center
++;
823 ic_unconnected_lfe
++;
826 if (ic_unconnected_left
> 0) {
828 /* OK, so there are unconnected input channels on the
829 * left. Let's multiply all already connected channels on
830 * the left side by .9 and add in our averaged unconnected
831 * channels multplied by .1 */
833 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
835 if (!on_left(r
->o_cm
.map
[oc
]))
838 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
840 if (ic_connected
[ic
]) {
841 r
->map_table_f
[oc
][ic
] *= .9f
;
845 if (on_left(r
->i_cm
.map
[ic
]))
846 r
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
851 if (ic_unconnected_right
> 0) {
853 /* OK, so there are unconnected input channels on the
854 * right. Let's multiply all already connected channels on
855 * the right side by .9 and add in our averaged unconnected
856 * channels multplied by .1 */
858 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
860 if (!on_right(r
->o_cm
.map
[oc
]))
863 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
865 if (ic_connected
[ic
]) {
866 r
->map_table_f
[oc
][ic
] *= .9f
;
870 if (on_right(r
->i_cm
.map
[ic
]))
871 r
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
876 if (ic_unconnected_center
> 0) {
877 pa_bool_t mixed_in
= FALSE
;
879 /* OK, so there are unconnected input channels on the
880 * center. Let's multiply all already connected channels on
881 * the center side by .9 and add in our averaged unconnected
882 * channels multplied by .1 */
884 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
886 if (!on_center(r
->o_cm
.map
[oc
]))
889 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
891 if (ic_connected
[ic
]) {
892 r
->map_table_f
[oc
][ic
] *= .9f
;
896 if (on_center(r
->i_cm
.map
[ic
])) {
897 r
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
904 unsigned ncenter
[PA_CHANNELS_MAX
];
905 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
907 memset(ncenter
, 0, sizeof(ncenter
));
908 memset(found_frs
, 0, sizeof(found_frs
));
910 /* Hmm, as it appears there was no center channel we
911 could mix our center channel in. In this case, mix
912 it into left and right. Using .375 and 0.75 as
915 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
917 if (ic_connected
[ic
])
920 if (!on_center(r
->i_cm
.map
[ic
]))
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 (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
929 found_frs
[ic
] = TRUE
;
934 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
936 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
939 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
944 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
946 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
949 if (ncenter
[oc
] <= 0)
952 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
954 if (ic_connected
[ic
]) {
955 r
->map_table_f
[oc
][ic
] *= .75f
;
959 if (!on_center(r
->i_cm
.map
[ic
]))
962 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
963 r
->map_table_f
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
969 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
971 /* OK, so there is an unconnected LFE channel. Let's mix
972 * it into all channels, with factor 0.375 */
974 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
976 if (!on_lfe(r
->i_cm
.map
[ic
]))
979 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
980 r
->map_table_f
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
984 /* make an 16:16 int version of the matrix */
985 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
986 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
987 r
->map_table_i
[oc
][ic
] = (int32_t) (r
->map_table_f
[oc
][ic
] * 0x10000);
991 pa_strbuf_printf(s
, " ");
992 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
993 pa_strbuf_printf(s
, " I%02u ", ic
);
994 pa_strbuf_puts(s
, "\n +");
996 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
997 pa_strbuf_printf(s
, "------");
998 pa_strbuf_puts(s
, "\n");
1000 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1001 pa_strbuf_printf(s
, "O%02u |", oc
);
1003 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
1004 pa_strbuf_printf(s
, " %1.3f", r
->map_table_f
[oc
][ic
]);
1006 pa_strbuf_puts(s
, "\n");
1009 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
1013 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1019 pa_assert(input
->memblock
);
1021 /* Convert the incoming sample into the work sample format and place them in buf1 */
1023 if (!r
->to_work_format_func
|| !input
->length
)
1026 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1029 r
->buf1
.length
= r
->w_sz
* n_samples
;
1031 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
1032 if (r
->buf1
.memblock
)
1033 pa_memblock_unref(r
->buf1
.memblock
);
1035 r
->buf1_samples
= n_samples
;
1036 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
1039 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1040 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
1042 r
->to_work_format_func(n_samples
, src
, dst
);
1044 pa_memblock_release(input
->memblock
);
1045 pa_memblock_release(r
->buf1
.memblock
);
1050 static void vectoradd_f32(
1052 const float *s
, int sstr
,
1055 for (; n
> 0; n
--) {
1056 *d
= (float) (*d
+ (s4
* *s
));
1058 s
= (const float*) ((const uint8_t*) s
+ sstr
);
1059 d
= (float*) ((uint8_t*) d
+ dstr
);
1063 static void vectoradd_s16(
1064 int16_t *d
, int dstr
,
1065 const int16_t *s
, int sstr
,
1068 for (; n
> 0; n
--) {
1069 *d
= (int16_t) (*d
+ *s
);
1071 s
= (const int16_t*) ((const uint8_t*) s
+ sstr
);
1072 d
= (int16_t*) ((uint8_t*) d
+ dstr
);
1076 static void vectoradd_s16_with_fraction(
1077 int16_t *d
, int dstr
,
1078 const int16_t *s
, int sstr
,
1079 int n
, int32_t i4
) {
1081 for (; n
> 0; n
--) {
1082 *d
= (int16_t) (*d
+ (((int32_t)*s
* i4
) >> 16));
1084 s
= (const int16_t*) ((const uint8_t*) s
+ sstr
);
1085 d
= (int16_t*) ((uint8_t*) d
+ dstr
);
1089 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1090 unsigned in_n_samples
, out_n_samples
, n_frames
;
1097 pa_assert(input
->memblock
);
1099 /* Remap channels and place the result int buf2 */
1101 if (!r
->map_required
|| !input
->length
)
1104 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1105 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1106 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1109 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
1111 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
1112 if (r
->buf2
.memblock
)
1113 pa_memblock_unref(r
->buf2
.memblock
);
1115 r
->buf2_samples
= out_n_samples
;
1116 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
1119 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1120 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
1122 memset(dst
, 0, r
->buf2
.length
);
1124 o_skip
= (int) (r
->w_sz
* r
->o_ss
.channels
);
1125 i_skip
= (int) (r
->w_sz
* r
->i_ss
.channels
);
1127 switch (r
->work_format
) {
1128 case PA_SAMPLE_FLOAT32NE
:
1130 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1133 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1135 if (r
->map_table_f
[oc
][ic
] <= 0.0)
1139 (float*) dst
+ oc
, o_skip
,
1140 (float*) src
+ ic
, i_skip
,
1142 r
->map_table_f
[oc
][ic
]);
1148 case PA_SAMPLE_S16NE
:
1150 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1153 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1155 if (r
->map_table_f
[oc
][ic
] <= 0.0)
1158 if (r
->map_table_f
[oc
][ic
] >= 1.0) {
1161 (int16_t*) dst
+ oc
, o_skip
,
1162 (int16_t*) src
+ ic
, i_skip
,
1167 vectoradd_s16_with_fraction(
1168 (int16_t*) dst
+ oc
, o_skip
,
1169 (int16_t*) src
+ ic
, i_skip
,
1171 r
->map_table_i
[oc
][ic
]);
1178 pa_assert_not_reached();
1181 pa_memblock_release(input
->memblock
);
1182 pa_memblock_release(r
->buf2
.memblock
);
1184 r
->buf2
.length
= out_n_samples
* r
->w_sz
;
1189 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1190 unsigned in_n_frames
, in_n_samples
;
1191 unsigned out_n_frames
, out_n_samples
;
1196 /* Resample the data and place the result in buf3 */
1198 if (!r
->impl_resample
|| !input
->length
)
1201 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1202 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1204 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1205 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1208 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1210 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1211 if (r
->buf3
.memblock
)
1212 pa_memblock_unref(r
->buf3
.memblock
);
1214 r
->buf3_samples
= out_n_samples
;
1215 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1218 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1219 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1224 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1225 unsigned n_samples
, n_frames
;
1231 /* Convert the data into the correct sample type and place the result in buf4 */
1233 if (!r
->from_work_format_func
|| !input
->length
)
1236 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1237 n_frames
= n_samples
/ r
->o_ss
.channels
;
1240 r
->buf4
.length
= r
->o_fz
* n_frames
;
1242 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1243 if (r
->buf4
.memblock
)
1244 pa_memblock_unref(r
->buf4
.memblock
);
1246 r
->buf4_samples
= n_samples
;
1247 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1250 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1251 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1252 r
->from_work_format_func(n_samples
, src
, dst
);
1253 pa_memblock_release(input
->memblock
);
1254 pa_memblock_release(r
->buf4
.memblock
);
1256 r
->buf4
.length
= r
->o_fz
* n_frames
;
1261 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1267 pa_assert(in
->length
);
1268 pa_assert(in
->memblock
);
1269 pa_assert(in
->length
% r
->i_fz
== 0);
1271 buf
= (pa_memchunk
*) in
;
1272 buf
= convert_to_work_format(r
, buf
);
1273 buf
= remap_channels(r
, buf
);
1274 buf
= resample(r
, buf
);
1277 buf
= convert_from_work_format(r
, buf
);
1281 pa_memblock_ref(buf
->memblock
);
1283 pa_memchunk_reset(buf
);
1285 pa_memchunk_reset(out
);
1288 /*** libsamplerate based implementation ***/
1290 #ifdef HAVE_LIBSAMPLERATE
1291 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1297 pa_assert(out_n_frames
);
1299 memset(&data
, 0, sizeof(data
));
1301 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1302 data
.input_frames
= (long int) in_n_frames
;
1304 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1305 data
.output_frames
= (long int) *out_n_frames
;
1307 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1308 data
.end_of_input
= 0;
1310 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1311 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1313 pa_memblock_release(input
->memblock
);
1314 pa_memblock_release(output
->memblock
);
1316 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1319 static void libsamplerate_update_rates(pa_resampler
*r
) {
1322 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1325 static void libsamplerate_reset(pa_resampler
*r
) {
1328 pa_assert_se(src_reset(r
->src
.state
) == 0);
1331 static void libsamplerate_free(pa_resampler
*r
) {
1335 src_delete(r
->src
.state
);
1338 static int libsamplerate_init(pa_resampler
*r
) {
1343 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1346 r
->impl_free
= libsamplerate_free
;
1347 r
->impl_update_rates
= libsamplerate_update_rates
;
1348 r
->impl_resample
= libsamplerate_resample
;
1349 r
->impl_reset
= libsamplerate_reset
;
1355 /*** speex based implementation ***/
1357 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1359 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1364 pa_assert(out_n_frames
);
1366 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1367 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1369 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1371 pa_memblock_release(input
->memblock
);
1372 pa_memblock_release(output
->memblock
);
1374 pa_assert(inf
== in_n_frames
);
1375 *out_n_frames
= outf
;
1378 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1380 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1385 pa_assert(out_n_frames
);
1387 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1388 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1390 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1392 pa_memblock_release(input
->memblock
);
1393 pa_memblock_release(output
->memblock
);
1395 pa_assert(inf
== in_n_frames
);
1396 *out_n_frames
= outf
;
1399 static void speex_update_rates(pa_resampler
*r
) {
1402 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1405 static void speex_reset(pa_resampler
*r
) {
1408 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1411 static void speex_free(pa_resampler
*r
) {
1414 if (!r
->speex
.state
)
1417 speex_resampler_destroy(r
->speex
.state
);
1420 static int speex_init(pa_resampler
*r
) {
1425 r
->impl_free
= speex_free
;
1426 r
->impl_update_rates
= speex_update_rates
;
1427 r
->impl_reset
= speex_reset
;
1429 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1431 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1432 r
->impl_resample
= speex_resample_int
;
1435 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1437 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1438 r
->impl_resample
= speex_resample_float
;
1441 pa_log_info("Choosing speex quality setting %i.", q
);
1443 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1449 /* Trivial implementation */
1451 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1459 pa_assert(out_n_frames
);
1461 fz
= r
->w_sz
* r
->o_ss
.channels
;
1463 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1464 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1466 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1469 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1470 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1472 if (j
>= in_n_frames
)
1475 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1477 memcpy((uint8_t*) dst
+ fz
* o_index
,
1478 (uint8_t*) src
+ fz
* j
, (int) fz
);
1481 pa_memblock_release(input
->memblock
);
1482 pa_memblock_release(output
->memblock
);
1484 *out_n_frames
= o_index
;
1486 r
->trivial
.i_counter
+= in_n_frames
;
1488 /* Normalize counters */
1489 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1490 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1492 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1493 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1497 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1500 r
->trivial
.i_counter
= 0;
1501 r
->trivial
.o_counter
= 0;
1504 static int trivial_init(pa_resampler
*r
) {
1507 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1509 r
->impl_resample
= trivial_resample
;
1510 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1511 r
->impl_reset
= trivial_update_rates_or_reset
;
1516 /* Peak finder implementation */
1518 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1527 pa_assert(out_n_frames
);
1529 fz
= r
->w_sz
* r
->o_ss
.channels
;
1531 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1532 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1534 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1537 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1539 if (j
> r
->peaks
.i_counter
)
1540 j
-= r
->peaks
.i_counter
;
1544 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1546 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1548 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* start
);
1549 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1551 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1553 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1556 n
= (int16_t) (*s
< 0 ? -*s
: *s
);
1558 if (PA_UNLIKELY(n
> r
->peaks
.max_i
[c
]))
1559 r
->peaks
.max_i
[c
] = n
;
1562 if (i
>= in_n_frames
)
1565 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1566 *d
= r
->peaks
.max_i
[c
];
1567 r
->peaks
.max_i
[c
] = 0;
1572 float *s
= (float*) ((uint8_t*) src
+ fz
* start
);
1573 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1575 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1577 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1578 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1579 float n
= fabsf(*s
);
1581 if (n
> r
->peaks
.max_f
[c
])
1582 r
->peaks
.max_f
[c
] = n
;
1585 if (i
>= in_n_frames
)
1588 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1589 *d
= r
->peaks
.max_f
[c
];
1590 r
->peaks
.max_f
[c
] = 0;
1597 pa_memblock_release(input
->memblock
);
1598 pa_memblock_release(output
->memblock
);
1600 *out_n_frames
= o_index
;
1602 r
->peaks
.i_counter
+= in_n_frames
;
1604 /* Normalize counters */
1605 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1606 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1608 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1609 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1613 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1616 r
->peaks
.i_counter
= 0;
1617 r
->peaks
.o_counter
= 0;
1620 static int peaks_init(pa_resampler
*r
) {
1623 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1624 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1625 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1627 r
->impl_resample
= peaks_resample
;
1628 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1629 r
->impl_reset
= peaks_update_rates_or_reset
;
1634 /*** ffmpeg based implementation ***/
1636 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1637 unsigned used_frames
= 0, c
;
1642 pa_assert(out_n_frames
);
1644 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1647 int16_t *p
, *t
, *k
, *q
, *s
;
1648 int consumed_frames
;
1651 /* Allocate a new block */
1652 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1653 p
= pa_memblock_acquire(b
);
1655 /* Copy the remaining data into it */
1656 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1657 if (r
->ffmpeg
.buf
[c
].memblock
) {
1658 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1660 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1661 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1662 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1665 /* Now append the new data, splitting up channels */
1666 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1667 k
= (int16_t*) ((uint8_t*) p
+ l
);
1668 for (u
= 0; u
< in_n_frames
; u
++) {
1670 t
+= r
->o_ss
.channels
;
1673 pa_memblock_release(input
->memblock
);
1675 /* Calculate the resulting number of frames */
1676 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1678 /* Allocate buffer for the result */
1679 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1680 q
= pa_memblock_acquire(w
);
1683 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1686 (int) in
, (int) *out_n_frames
,
1687 c
>= (unsigned) (r
->o_ss
.channels
-1));
1689 pa_memblock_release(b
);
1691 /* Now store the remaining samples away */
1692 pa_assert(consumed_frames
<= (int) in
);
1693 if (consumed_frames
< (int) in
) {
1694 r
->ffmpeg
.buf
[c
].memblock
= b
;
1695 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1696 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1698 pa_memblock_unref(b
);
1700 /* And place the results in the output buffer */
1701 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1702 for (u
= 0; u
< used_frames
; u
++) {
1705 s
+= r
->o_ss
.channels
;
1707 pa_memblock_release(output
->memblock
);
1708 pa_memblock_release(w
);
1709 pa_memblock_unref(w
);
1712 *out_n_frames
= used_frames
;
1715 static void ffmpeg_free(pa_resampler
*r
) {
1720 if (r
->ffmpeg
.state
)
1721 av_resample_close(r
->ffmpeg
.state
);
1723 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1724 if (r
->ffmpeg
.buf
[c
].memblock
)
1725 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1728 static int ffmpeg_init(pa_resampler
*r
) {
1733 /* We could probably implement different quality levels by
1734 * adjusting the filter parameters here. However, ffmpeg
1735 * internally only uses these hardcoded values, so let's use them
1736 * here for now as well until ffmpeg makes this configurable. */
1738 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1741 r
->impl_free
= ffmpeg_free
;
1742 r
->impl_resample
= ffmpeg_resample
;
1744 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1745 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1750 /*** copy (noop) implementation ***/
1752 static int copy_init(pa_resampler
*r
) {
1755 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);