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>
39 #include <pulsecore/remap.h>
41 #include "ffmpeg/avcodec.h"
43 #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)
307 void pa_resampler_free(pa_resampler
*r
) {
313 if (r
->buf1
.memblock
)
314 pa_memblock_unref(r
->buf1
.memblock
);
315 if (r
->buf2
.memblock
)
316 pa_memblock_unref(r
->buf2
.memblock
);
317 if (r
->buf3
.memblock
)
318 pa_memblock_unref(r
->buf3
.memblock
);
319 if (r
->buf4
.memblock
)
320 pa_memblock_unref(r
->buf4
.memblock
);
325 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
329 if (r
->i_ss
.rate
== rate
)
334 r
->impl_update_rates(r
);
337 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
341 if (r
->o_ss
.rate
== rate
)
346 r
->impl_update_rates(r
);
349 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
352 /* Let's round up here */
354 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
;
357 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
360 /* Let's round up here */
362 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
;
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 const pa_channel_map
* pa_resampler_input_channel_map(pa_resampler
*r
) {
408 const pa_sample_spec
* pa_resampler_input_sample_spec(pa_resampler
*r
) {
414 const pa_channel_map
* pa_resampler_output_channel_map(pa_resampler
*r
) {
420 const pa_sample_spec
* pa_resampler_output_sample_spec(pa_resampler
*r
) {
426 static const char * const resample_methods
[] = {
427 "src-sinc-best-quality",
428 "src-sinc-medium-quality",
430 "src-zero-order-hold",
461 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
463 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
466 return resample_methods
[m
];
469 int pa_resample_method_supported(pa_resample_method_t m
) {
471 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
474 #ifndef HAVE_LIBSAMPLERATE
475 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
482 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
483 pa_resample_method_t m
;
487 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
488 if (!strcmp(string
, resample_methods
[m
]))
491 if (!strcmp(string
, "speex-fixed"))
492 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
494 if (!strcmp(string
, "speex-float"))
495 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
497 return PA_RESAMPLER_INVALID
;
500 static pa_bool_t
on_left(pa_channel_position_t p
) {
503 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
504 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
505 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
506 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
507 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
508 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
511 static pa_bool_t
on_right(pa_channel_position_t p
) {
514 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
515 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
516 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
517 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
518 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
519 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
522 static pa_bool_t
on_center(pa_channel_position_t p
) {
525 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
526 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
527 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
528 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
529 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
532 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
534 p
== PA_CHANNEL_POSITION_LFE
;
537 static pa_bool_t
on_front(pa_channel_position_t p
) {
539 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
540 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
541 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
542 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
543 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
544 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
545 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
546 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
;
549 static pa_bool_t
on_rear(pa_channel_position_t p
) {
551 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
552 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
553 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
554 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
||
555 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
||
556 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
559 static pa_bool_t
on_side(pa_channel_position_t p
) {
561 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
562 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
563 p
== PA_CHANNEL_POSITION_TOP_CENTER
;
573 static int front_rear_side(pa_channel_position_t p
) {
583 static void calc_map_table(pa_resampler
*r
) {
586 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
594 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
)))))
599 n_oc
= r
->o_ss
.channels
;
600 n_ic
= r
->i_ss
.channels
;
602 memset(m
->map_table_f
, 0, sizeof(m
->map_table_f
));
603 memset(m
->map_table_i
, 0, sizeof(m
->map_table_i
));
605 memset(ic_connected
, 0, sizeof(ic_connected
));
606 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
608 for (oc
= 0; oc
< n_oc
; oc
++) {
609 pa_bool_t oc_connected
= FALSE
;
610 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
612 for (ic
= 0; ic
< n_ic
; ic
++) {
613 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
615 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
616 /* We shall not do any remapping. Hence, just check by index */
619 m
->map_table_f
[oc
][ic
] = 1.0;
624 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
625 /* We shall not do any remixing. Hence, just check by name */
628 m
->map_table_f
[oc
][ic
] = 1.0;
635 /* OK, we shall do the full monty: upmixing and
636 * downmixing. Our algorithm is relatively simple, does
637 * not do spacialization, delay elements or apply lowpass
638 * filters for LFE. Patches are always welcome,
639 * though. Oh, and it doesn't do any matrix
640 * decoding. (Which probably wouldn't make any sense
643 * This code is not idempotent: downmixing an upmixed
644 * stereo stream is not identical to the original. The
645 * volume will not match, and the two channels will be a
646 * linear combination of both.
648 * This is losely based on random suggestions found on the
649 * Internet, such as this:
650 * http://www.halfgaar.net/surround-sound-in-linux and the
653 * The algorithm works basically like this:
655 * 1) Connect all channels with matching names.
658 * S:Mono: Copy into all D:channels
659 * D:Mono: Copy in all S:channels
661 * 3) Mix D:Left, D:Right:
662 * D:Left: If not connected, avg all S:Left
663 * D:Right: If not connected, avg all S:Right
666 * If not connected, avg all S:Center
667 * If still not connected, avg all S:Left, S:Right
670 * If not connected, avg all S:*
672 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
673 * not connected, mix into all D:left and all D:right
674 * channels. Gain is 0.1, the current left and right
675 * should be multiplied by 0.9.
677 * 7) Make sure S:Center, S:LFE is used:
679 * S:Center, S:LFE: If not connected, mix into all
680 * D:left, all D:right, all D:center channels, gain is
681 * 0.375. The current (as result of 1..6) factors
682 * should be multiplied by 0.75. (Alt. suggestion: 0.25
683 * vs. 0.5) If C-front is only mixed into
684 * L-front/R-front if available, otherwise into all L/R
685 * channels. Similarly for C-rear.
687 * S: and D: shall relate to the source resp. destination channels.
689 * Rationale: 1, 2 are probably obvious. For 3: this
690 * copies front to rear if needed. For 4: we try to find
691 * some suitable C source for C, if we don't find any, we
692 * avg L and R. For 5: LFE is mixed from all channels. For
693 * 6: the rear channels should not be dropped entirely,
694 * however have only minimal impact. For 7: movies usually
695 * encode speech on the center channel. Thus we have to
696 * make sure this channel is distributed to L and R if not
697 * available in the output. Also, LFE is used to achieve a
698 * greater dynamic range, and thus we should try to do our
699 * best to pass it to L+R.
702 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
703 m
->map_table_f
[oc
][ic
] = 1.0;
706 ic_connected
[ic
] = TRUE
;
710 if (!oc_connected
&& remix
) {
711 /* OK, we shall remix */
713 /* Try to find matching input ports for this output port */
718 /* We are not connected and on the left side, let's
719 * average all left side input channels. */
721 for (ic
= 0; ic
< n_ic
; ic
++)
722 if (on_left(r
->i_cm
.map
[ic
]))
726 for (ic
= 0; ic
< n_ic
; ic
++)
727 if (on_left(r
->i_cm
.map
[ic
])) {
728 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
729 ic_connected
[ic
] = TRUE
;
732 /* We ignore the case where there is no left input
733 * channel. Something is really wrong in this case
736 } else if (on_right(b
)) {
739 /* We are not connected and on the right side, let's
740 * average all right side input channels. */
742 for (ic
= 0; ic
< n_ic
; ic
++)
743 if (on_right(r
->i_cm
.map
[ic
]))
747 for (ic
= 0; ic
< n_ic
; ic
++)
748 if (on_right(r
->i_cm
.map
[ic
])) {
749 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
750 ic_connected
[ic
] = TRUE
;
753 /* We ignore the case where there is no right input
754 * channel. Something is really wrong in this case
757 } else if (on_center(b
)) {
760 /* We are not connected and at the center. Let's
761 * average all center input channels. */
763 for (ic
= 0; ic
< n_ic
; ic
++)
764 if (on_center(r
->i_cm
.map
[ic
]))
768 for (ic
= 0; ic
< n_ic
; ic
++)
769 if (on_center(r
->i_cm
.map
[ic
])) {
770 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
771 ic_connected
[ic
] = TRUE
;
775 /* Hmm, no center channel around, let's synthesize
776 * it by mixing L and R.*/
780 for (ic
= 0; ic
< n_ic
; ic
++)
781 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
785 for (ic
= 0; ic
< n_ic
; ic
++)
786 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
787 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n
;
788 ic_connected
[ic
] = TRUE
;
791 /* We ignore the case where there is not even a
792 * left or right input channel. Something is
793 * really wrong in this case anyway. */
796 } else if (on_lfe(b
)) {
798 /* We are not connected and an LFE. Let's average all
799 * channels for LFE. */
801 for (ic
= 0; ic
< n_ic
; ic
++) {
803 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
804 m
->map_table_f
[oc
][ic
] = 1.0f
/ (float) n_ic
;
806 m
->map_table_f
[oc
][ic
] = 0;
808 /* Please note that a channel connected to LFE
809 * doesn't really count as connected. */
817 ic_unconnected_left
= 0,
818 ic_unconnected_right
= 0,
819 ic_unconnected_center
= 0,
820 ic_unconnected_lfe
= 0;
822 for (ic
= 0; ic
< n_ic
; ic
++) {
823 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
825 if (ic_connected
[ic
])
829 ic_unconnected_left
++;
830 else if (on_right(a
))
831 ic_unconnected_right
++;
832 else if (on_center(a
))
833 ic_unconnected_center
++;
835 ic_unconnected_lfe
++;
838 if (ic_unconnected_left
> 0) {
840 /* OK, so there are unconnected input channels on the
841 * left. Let's multiply all already connected channels on
842 * the left side by .9 and add in our averaged unconnected
843 * channels multplied by .1 */
845 for (oc
= 0; oc
< n_oc
; oc
++) {
847 if (!on_left(r
->o_cm
.map
[oc
]))
850 for (ic
= 0; ic
< n_ic
; ic
++) {
852 if (ic_connected
[ic
]) {
853 m
->map_table_f
[oc
][ic
] *= .9f
;
857 if (on_left(r
->i_cm
.map
[ic
]))
858 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
863 if (ic_unconnected_right
> 0) {
865 /* OK, so there are unconnected input channels on the
866 * right. Let's multiply all already connected channels on
867 * the right side by .9 and add in our averaged unconnected
868 * channels multplied by .1 */
870 for (oc
= 0; oc
< n_oc
; oc
++) {
872 if (!on_right(r
->o_cm
.map
[oc
]))
875 for (ic
= 0; ic
< n_ic
; ic
++) {
877 if (ic_connected
[ic
]) {
878 m
->map_table_f
[oc
][ic
] *= .9f
;
882 if (on_right(r
->i_cm
.map
[ic
]))
883 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
888 if (ic_unconnected_center
> 0) {
889 pa_bool_t mixed_in
= FALSE
;
891 /* OK, so there are unconnected input channels on the
892 * center. Let's multiply all already connected channels on
893 * the center side by .9 and add in our averaged unconnected
894 * channels multplied by .1 */
896 for (oc
= 0; oc
< n_oc
; oc
++) {
898 if (!on_center(r
->o_cm
.map
[oc
]))
901 for (ic
= 0; ic
< n_ic
; ic
++) {
903 if (ic_connected
[ic
]) {
904 m
->map_table_f
[oc
][ic
] *= .9f
;
908 if (on_center(r
->i_cm
.map
[ic
])) {
909 m
->map_table_f
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
916 unsigned ncenter
[PA_CHANNELS_MAX
];
917 pa_bool_t found_frs
[PA_CHANNELS_MAX
];
919 memset(ncenter
, 0, sizeof(ncenter
));
920 memset(found_frs
, 0, sizeof(found_frs
));
922 /* Hmm, as it appears there was no center channel we
923 could mix our center channel in. In this case, mix
924 it into left and right. Using .375 and 0.75 as
927 for (ic
= 0; ic
< n_ic
; ic
++) {
929 if (ic_connected
[ic
])
932 if (!on_center(r
->i_cm
.map
[ic
]))
935 for (oc
= 0; oc
< n_oc
; oc
++) {
937 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
940 if (front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
])) {
941 found_frs
[ic
] = TRUE
;
946 for (oc
= 0; oc
< n_oc
; oc
++) {
948 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
951 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
956 for (oc
= 0; oc
< n_oc
; oc
++) {
958 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
961 if (ncenter
[oc
] <= 0)
964 for (ic
= 0; ic
< n_ic
; ic
++) {
966 if (ic_connected
[ic
]) {
967 m
->map_table_f
[oc
][ic
] *= .75f
;
971 if (!on_center(r
->i_cm
.map
[ic
]))
974 if (!found_frs
[ic
] || front_rear_side(r
->i_cm
.map
[ic
]) == front_rear_side(r
->o_cm
.map
[oc
]))
975 m
->map_table_f
[oc
][ic
] = .375f
/ (float) ncenter
[oc
];
981 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
983 /* OK, so there is an unconnected LFE channel. Let's mix
984 * it into all channels, with factor 0.375 */
986 for (ic
= 0; ic
< n_ic
; ic
++) {
988 if (!on_lfe(r
->i_cm
.map
[ic
]))
991 for (oc
= 0; oc
< n_oc
; oc
++)
992 m
->map_table_f
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
996 /* make an 16:16 int version of the matrix */
997 for (oc
= 0; oc
< n_oc
; oc
++)
998 for (ic
= 0; ic
< n_ic
; ic
++)
999 m
->map_table_i
[oc
][ic
] = (int32_t) (m
->map_table_f
[oc
][ic
] * 0x10000);
1001 s
= pa_strbuf_new();
1003 pa_strbuf_printf(s
, " ");
1004 for (ic
= 0; ic
< n_ic
; ic
++)
1005 pa_strbuf_printf(s
, " I%02u ", ic
);
1006 pa_strbuf_puts(s
, "\n +");
1008 for (ic
= 0; ic
< n_ic
; ic
++)
1009 pa_strbuf_printf(s
, "------");
1010 pa_strbuf_puts(s
, "\n");
1012 for (oc
= 0; oc
< n_oc
; oc
++) {
1013 pa_strbuf_printf(s
, "O%02u |", oc
);
1015 for (ic
= 0; ic
< n_ic
; ic
++)
1016 pa_strbuf_printf(s
, " %1.3f", m
->map_table_f
[oc
][ic
]);
1018 pa_strbuf_puts(s
, "\n");
1021 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
1024 /* initialize the remapping function */
1028 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1034 pa_assert(input
->memblock
);
1036 /* Convert the incoming sample into the work sample format and place them in buf1 */
1038 if (!r
->to_work_format_func
|| !input
->length
)
1041 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
1044 r
->buf1
.length
= r
->w_sz
* n_samples
;
1046 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
1047 if (r
->buf1
.memblock
)
1048 pa_memblock_unref(r
->buf1
.memblock
);
1050 r
->buf1_samples
= n_samples
;
1051 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
1054 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1055 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
1057 r
->to_work_format_func(n_samples
, src
, dst
);
1059 pa_memblock_release(input
->memblock
);
1060 pa_memblock_release(r
->buf1
.memblock
);
1065 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
1066 unsigned in_n_samples
, out_n_samples
, n_frames
;
1072 pa_assert(input
->memblock
);
1074 /* Remap channels and place the result int buf2 */
1076 if (!r
->map_required
|| !input
->length
)
1079 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1080 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
1081 out_n_samples
= n_frames
* r
->o_ss
.channels
;
1084 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
1086 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
1087 if (r
->buf2
.memblock
)
1088 pa_memblock_unref(r
->buf2
.memblock
);
1090 r
->buf2_samples
= out_n_samples
;
1091 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
1094 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1095 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
1099 pa_assert(remap
->do_remap
);
1100 remap
->do_remap(remap
, dst
, src
, n_frames
);
1102 pa_memblock_release(input
->memblock
);
1103 pa_memblock_release(r
->buf2
.memblock
);
1108 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1109 unsigned in_n_frames
, in_n_samples
;
1110 unsigned out_n_frames
, out_n_samples
;
1115 /* Resample the data and place the result in buf3 */
1117 if (!r
->impl_resample
|| !input
->length
)
1120 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1121 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1123 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1124 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1127 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1129 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1130 if (r
->buf3
.memblock
)
1131 pa_memblock_unref(r
->buf3
.memblock
);
1133 r
->buf3_samples
= out_n_samples
;
1134 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1137 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1138 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1143 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1144 unsigned n_samples
, n_frames
;
1150 /* Convert the data into the correct sample type and place the result in buf4 */
1152 if (!r
->from_work_format_func
|| !input
->length
)
1155 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1156 n_frames
= n_samples
/ r
->o_ss
.channels
;
1159 r
->buf4
.length
= r
->o_fz
* n_frames
;
1161 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1162 if (r
->buf4
.memblock
)
1163 pa_memblock_unref(r
->buf4
.memblock
);
1165 r
->buf4_samples
= n_samples
;
1166 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1169 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1170 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1171 r
->from_work_format_func(n_samples
, src
, dst
);
1172 pa_memblock_release(input
->memblock
);
1173 pa_memblock_release(r
->buf4
.memblock
);
1175 r
->buf4
.length
= r
->o_fz
* n_frames
;
1180 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1186 pa_assert(in
->length
);
1187 pa_assert(in
->memblock
);
1188 pa_assert(in
->length
% r
->i_fz
== 0);
1190 buf
= (pa_memchunk
*) in
;
1191 buf
= convert_to_work_format(r
, buf
);
1192 buf
= remap_channels(r
, buf
);
1193 buf
= resample(r
, buf
);
1196 buf
= convert_from_work_format(r
, buf
);
1200 pa_memblock_ref(buf
->memblock
);
1202 pa_memchunk_reset(buf
);
1204 pa_memchunk_reset(out
);
1207 /*** libsamplerate based implementation ***/
1209 #ifdef HAVE_LIBSAMPLERATE
1210 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1216 pa_assert(out_n_frames
);
1218 memset(&data
, 0, sizeof(data
));
1220 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1221 data
.input_frames
= (long int) in_n_frames
;
1223 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1224 data
.output_frames
= (long int) *out_n_frames
;
1226 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1227 data
.end_of_input
= 0;
1229 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1230 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1232 pa_memblock_release(input
->memblock
);
1233 pa_memblock_release(output
->memblock
);
1235 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1238 static void libsamplerate_update_rates(pa_resampler
*r
) {
1241 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1244 static void libsamplerate_reset(pa_resampler
*r
) {
1247 pa_assert_se(src_reset(r
->src
.state
) == 0);
1250 static void libsamplerate_free(pa_resampler
*r
) {
1254 src_delete(r
->src
.state
);
1257 static int libsamplerate_init(pa_resampler
*r
) {
1262 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1265 r
->impl_free
= libsamplerate_free
;
1266 r
->impl_update_rates
= libsamplerate_update_rates
;
1267 r
->impl_resample
= libsamplerate_resample
;
1268 r
->impl_reset
= libsamplerate_reset
;
1274 /*** speex based implementation ***/
1276 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1278 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1283 pa_assert(out_n_frames
);
1285 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1286 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1288 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1290 pa_memblock_release(input
->memblock
);
1291 pa_memblock_release(output
->memblock
);
1293 pa_assert(inf
== in_n_frames
);
1294 *out_n_frames
= outf
;
1297 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1299 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1304 pa_assert(out_n_frames
);
1306 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1307 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1309 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1311 pa_memblock_release(input
->memblock
);
1312 pa_memblock_release(output
->memblock
);
1314 pa_assert(inf
== in_n_frames
);
1315 *out_n_frames
= outf
;
1318 static void speex_update_rates(pa_resampler
*r
) {
1321 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1324 static void speex_reset(pa_resampler
*r
) {
1327 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1330 static void speex_free(pa_resampler
*r
) {
1333 if (!r
->speex
.state
)
1336 speex_resampler_destroy(r
->speex
.state
);
1339 static int speex_init(pa_resampler
*r
) {
1344 r
->impl_free
= speex_free
;
1345 r
->impl_update_rates
= speex_update_rates
;
1346 r
->impl_reset
= speex_reset
;
1348 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1350 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1351 r
->impl_resample
= speex_resample_int
;
1354 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1356 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1357 r
->impl_resample
= speex_resample_float
;
1360 pa_log_info("Choosing speex quality setting %i.", q
);
1362 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1368 /* Trivial implementation */
1370 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1378 pa_assert(out_n_frames
);
1380 fz
= r
->w_sz
* r
->o_ss
.channels
;
1382 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1383 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1385 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1388 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1389 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1391 if (j
>= in_n_frames
)
1394 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1396 memcpy((uint8_t*) dst
+ fz
* o_index
,
1397 (uint8_t*) src
+ fz
* j
, (int) fz
);
1400 pa_memblock_release(input
->memblock
);
1401 pa_memblock_release(output
->memblock
);
1403 *out_n_frames
= o_index
;
1405 r
->trivial
.i_counter
+= in_n_frames
;
1407 /* Normalize counters */
1408 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1409 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1411 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1412 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1416 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1419 r
->trivial
.i_counter
= 0;
1420 r
->trivial
.o_counter
= 0;
1423 static int trivial_init(pa_resampler
*r
) {
1426 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1428 r
->impl_resample
= trivial_resample
;
1429 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1430 r
->impl_reset
= trivial_update_rates_or_reset
;
1435 /* Peak finder implementation */
1437 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1446 pa_assert(out_n_frames
);
1448 fz
= r
->w_sz
* r
->o_ss
.channels
;
1450 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1451 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1453 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1456 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1458 if (j
> r
->peaks
.i_counter
)
1459 j
-= r
->peaks
.i_counter
;
1463 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1465 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1467 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* start
);
1468 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1470 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1472 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1475 n
= (int16_t) (*s
< 0 ? -*s
: *s
);
1477 if (PA_UNLIKELY(n
> r
->peaks
.max_i
[c
]))
1478 r
->peaks
.max_i
[c
] = n
;
1481 if (i
>= in_n_frames
)
1484 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1485 *d
= r
->peaks
.max_i
[c
];
1486 r
->peaks
.max_i
[c
] = 0;
1491 float *s
= (float*) ((uint8_t*) src
+ fz
* start
);
1492 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1494 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1496 for (i
= start
; i
<= j
&& i
< in_n_frames
; i
++)
1497 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1498 float n
= fabsf(*s
);
1500 if (n
> r
->peaks
.max_f
[c
])
1501 r
->peaks
.max_f
[c
] = n
;
1504 if (i
>= in_n_frames
)
1507 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1508 *d
= r
->peaks
.max_f
[c
];
1509 r
->peaks
.max_f
[c
] = 0;
1516 pa_memblock_release(input
->memblock
);
1517 pa_memblock_release(output
->memblock
);
1519 *out_n_frames
= o_index
;
1521 r
->peaks
.i_counter
+= in_n_frames
;
1523 /* Normalize counters */
1524 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1525 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1527 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1528 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1532 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1535 r
->peaks
.i_counter
= 0;
1536 r
->peaks
.o_counter
= 0;
1539 static int peaks_init(pa_resampler
*r
) {
1542 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1543 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1544 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1546 r
->impl_resample
= peaks_resample
;
1547 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1548 r
->impl_reset
= peaks_update_rates_or_reset
;
1553 /*** ffmpeg based implementation ***/
1555 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1556 unsigned used_frames
= 0, c
;
1561 pa_assert(out_n_frames
);
1563 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1566 int16_t *p
, *t
, *k
, *q
, *s
;
1567 int consumed_frames
;
1570 /* Allocate a new block */
1571 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1572 p
= pa_memblock_acquire(b
);
1574 /* Copy the remaining data into it */
1575 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1576 if (r
->ffmpeg
.buf
[c
].memblock
) {
1577 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1579 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1580 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1581 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1584 /* Now append the new data, splitting up channels */
1585 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1586 k
= (int16_t*) ((uint8_t*) p
+ l
);
1587 for (u
= 0; u
< in_n_frames
; u
++) {
1589 t
+= r
->o_ss
.channels
;
1592 pa_memblock_release(input
->memblock
);
1594 /* Calculate the resulting number of frames */
1595 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1597 /* Allocate buffer for the result */
1598 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1599 q
= pa_memblock_acquire(w
);
1602 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1605 (int) in
, (int) *out_n_frames
,
1606 c
>= (unsigned) (r
->o_ss
.channels
-1));
1608 pa_memblock_release(b
);
1610 /* Now store the remaining samples away */
1611 pa_assert(consumed_frames
<= (int) in
);
1612 if (consumed_frames
< (int) in
) {
1613 r
->ffmpeg
.buf
[c
].memblock
= b
;
1614 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1615 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1617 pa_memblock_unref(b
);
1619 /* And place the results in the output buffer */
1620 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1621 for (u
= 0; u
< used_frames
; u
++) {
1624 s
+= r
->o_ss
.channels
;
1626 pa_memblock_release(output
->memblock
);
1627 pa_memblock_release(w
);
1628 pa_memblock_unref(w
);
1631 *out_n_frames
= used_frames
;
1634 static void ffmpeg_free(pa_resampler
*r
) {
1639 if (r
->ffmpeg
.state
)
1640 av_resample_close(r
->ffmpeg
.state
);
1642 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1643 if (r
->ffmpeg
.buf
[c
].memblock
)
1644 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1647 static int ffmpeg_init(pa_resampler
*r
) {
1652 /* We could probably implement different quality levels by
1653 * adjusting the filter parameters here. However, ffmpeg
1654 * internally only uses these hardcoded values, so let's use them
1655 * here for now as well until ffmpeg makes this configurable. */
1657 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1660 r
->impl_free
= ffmpeg_free
;
1661 r
->impl_resample
= ffmpeg_resample
;
1663 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1664 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1669 /*** copy (noop) implementation ***/
1671 static int copy_init(pa_resampler
*r
) {
1674 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);