2 This file is part of PulseAudio.
4 Copyright 2004-2006 Lennart Poettering
6 PulseAudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
11 PulseAudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with PulseAudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
28 #if HAVE_LIBSAMPLERATE
29 #include <samplerate.h>
32 #include <speex/speex_resampler.h>
34 #include <liboil/liboilfuncs.h>
35 #include <liboil/liboil.h>
37 #include <pulse/xmalloc.h>
38 #include <pulsecore/sconv.h>
39 #include <pulsecore/log.h>
40 #include <pulsecore/macro.h>
41 #include <pulsecore/strbuf.h>
43 #include "ffmpeg/avcodec.h"
45 #include "resampler.h"
47 /* Number of samples of extra space we allow the resamplers to return */
48 #define EXTRA_FRAMES 128
51 pa_resample_method_t method
;
52 pa_resample_flags_t flags
;
54 pa_sample_spec i_ss
, o_ss
;
55 pa_channel_map i_cm
, o_cm
;
56 size_t i_fz
, o_fz
, w_sz
;
59 pa_memchunk buf1
, buf2
, buf3
, buf4
;
60 unsigned buf1_samples
, buf2_samples
, buf3_samples
, buf4_samples
;
62 pa_sample_format_t work_format
;
64 pa_convert_func_t to_work_format_func
;
65 pa_convert_func_t from_work_format_func
;
67 float map_table
[PA_CHANNELS_MAX
][PA_CHANNELS_MAX
];
68 pa_bool_t map_required
;
70 void (*impl_free
)(pa_resampler
*r
);
71 void (*impl_update_rates
)(pa_resampler
*r
);
72 void (*impl_resample
)(pa_resampler
*r
, const pa_memchunk
*in
, unsigned in_samples
, pa_memchunk
*out
, unsigned *out_samples
);
73 void (*impl_reset
)(pa_resampler
*r
);
75 struct { /* data specific to the trivial resampler */
80 struct { /* data specific to the peak finder pseudo resampler */
84 float max_f
[PA_CHANNELS_MAX
];
85 int16_t max_i
[PA_CHANNELS_MAX
];
89 #ifdef HAVE_LIBSAMPLERATE
90 struct { /* data specific to libsamplerate */
95 struct { /* data specific to speex */
96 SpeexResamplerState
* state
;
99 struct { /* data specific to ffmpeg */
100 struct AVResampleContext
*state
;
101 pa_memchunk buf
[PA_CHANNELS_MAX
];
105 static int copy_init(pa_resampler
*r
);
106 static int trivial_init(pa_resampler
*r
);
107 static int speex_init(pa_resampler
*r
);
108 static int ffmpeg_init(pa_resampler
*r
);
109 static int peaks_init(pa_resampler
*r
);
110 #ifdef HAVE_LIBSAMPLERATE
111 static int libsamplerate_init(pa_resampler
*r
);
114 static void calc_map_table(pa_resampler
*r
);
116 static int (* const init_table
[])(pa_resampler
*r
) = {
117 #ifdef HAVE_LIBSAMPLERATE
118 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = libsamplerate_init
,
119 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = libsamplerate_init
,
120 [PA_RESAMPLER_SRC_SINC_FASTEST
] = libsamplerate_init
,
121 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = libsamplerate_init
,
122 [PA_RESAMPLER_SRC_LINEAR
] = libsamplerate_init
,
124 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = NULL
,
125 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = NULL
,
126 [PA_RESAMPLER_SRC_SINC_FASTEST
] = NULL
,
127 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = NULL
,
128 [PA_RESAMPLER_SRC_LINEAR
] = NULL
,
130 [PA_RESAMPLER_TRIVIAL
] = trivial_init
,
131 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+0] = speex_init
,
132 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+1] = speex_init
,
133 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+2] = speex_init
,
134 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+3] = speex_init
,
135 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+4] = speex_init
,
136 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+5] = speex_init
,
137 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+6] = speex_init
,
138 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+7] = speex_init
,
139 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+8] = speex_init
,
140 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+9] = speex_init
,
141 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+10] = speex_init
,
142 [PA_RESAMPLER_SPEEX_FIXED_BASE
+0] = speex_init
,
143 [PA_RESAMPLER_SPEEX_FIXED_BASE
+1] = speex_init
,
144 [PA_RESAMPLER_SPEEX_FIXED_BASE
+2] = speex_init
,
145 [PA_RESAMPLER_SPEEX_FIXED_BASE
+3] = speex_init
,
146 [PA_RESAMPLER_SPEEX_FIXED_BASE
+4] = speex_init
,
147 [PA_RESAMPLER_SPEEX_FIXED_BASE
+5] = speex_init
,
148 [PA_RESAMPLER_SPEEX_FIXED_BASE
+6] = speex_init
,
149 [PA_RESAMPLER_SPEEX_FIXED_BASE
+7] = speex_init
,
150 [PA_RESAMPLER_SPEEX_FIXED_BASE
+8] = speex_init
,
151 [PA_RESAMPLER_SPEEX_FIXED_BASE
+9] = speex_init
,
152 [PA_RESAMPLER_SPEEX_FIXED_BASE
+10] = speex_init
,
153 [PA_RESAMPLER_FFMPEG
] = ffmpeg_init
,
154 [PA_RESAMPLER_AUTO
] = NULL
,
155 [PA_RESAMPLER_COPY
] = copy_init
,
156 [PA_RESAMPLER_PEAKS
] = peaks_init
,
159 static inline size_t sample_size(pa_sample_format_t f
) {
160 pa_sample_spec ss
= {
166 return pa_sample_size(&ss
);
169 pa_resampler
* pa_resampler_new(
171 const pa_sample_spec
*a
,
172 const pa_channel_map
*am
,
173 const pa_sample_spec
*b
,
174 const pa_channel_map
*bm
,
175 pa_resample_method_t method
,
176 pa_resample_flags_t flags
) {
178 pa_resampler
*r
= NULL
;
183 pa_assert(pa_sample_spec_valid(a
));
184 pa_assert(pa_sample_spec_valid(b
));
185 pa_assert(method
>= 0);
186 pa_assert(method
< PA_RESAMPLER_MAX
);
190 if (!(flags
& PA_RESAMPLER_VARIABLE_RATE
) && a
->rate
== b
->rate
) {
191 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
192 method
= PA_RESAMPLER_COPY
;
195 if (!pa_resample_method_supported(method
)) {
196 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method
));
197 method
= PA_RESAMPLER_AUTO
;
200 if (method
== PA_RESAMPLER_FFMPEG
&& (flags
& PA_RESAMPLER_VARIABLE_RATE
)) {
201 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
202 method
= PA_RESAMPLER_AUTO
;
205 if (method
== PA_RESAMPLER_COPY
&& ((flags
& PA_RESAMPLER_VARIABLE_RATE
) || a
->rate
!= b
->rate
)) {
206 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
207 method
= PA_RESAMPLER_AUTO
;
210 if (method
== PA_RESAMPLER_AUTO
)
211 method
= PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
213 r
= pa_xnew(pa_resampler
, 1);
219 r
->impl_update_rates
= NULL
;
220 r
->impl_resample
= NULL
;
221 r
->impl_reset
= NULL
;
223 /* Fill sample specs */
229 else if (!pa_channel_map_init_auto(&r
->i_cm
, r
->i_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
234 else if (!pa_channel_map_init_auto(&r
->o_cm
, r
->o_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
))
237 r
->i_fz
= pa_frame_size(a
);
238 r
->o_fz
= pa_frame_size(b
);
240 pa_memchunk_reset(&r
->buf1
);
241 pa_memchunk_reset(&r
->buf2
);
242 pa_memchunk_reset(&r
->buf3
);
243 pa_memchunk_reset(&r
->buf4
);
245 r
->buf1_samples
= r
->buf2_samples
= r
->buf3_samples
= r
->buf4_samples
= 0;
249 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method
));
251 if ((method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) ||
252 (method
== PA_RESAMPLER_FFMPEG
))
253 r
->work_format
= PA_SAMPLE_S16NE
;
254 else if (method
== PA_RESAMPLER_TRIVIAL
|| method
== PA_RESAMPLER_COPY
|| method
== PA_RESAMPLER_PEAKS
) {
256 if (r
->map_required
|| a
->format
!= b
->format
|| method
== PA_RESAMPLER_PEAKS
) {
258 if (a
->format
== PA_SAMPLE_S32NE
|| a
->format
== PA_SAMPLE_S32RE
||
259 a
->format
== PA_SAMPLE_FLOAT32NE
|| a
->format
== PA_SAMPLE_FLOAT32RE
||
260 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
261 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
)
262 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
264 r
->work_format
= PA_SAMPLE_S16NE
;
267 r
->work_format
= a
->format
;
270 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
272 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
274 r
->w_sz
= sample_size(r
->work_format
);
276 if (r
->i_ss
.format
== r
->work_format
)
277 r
->to_work_format_func
= NULL
;
278 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
279 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
282 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
283 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
287 if (r
->o_ss
.format
== r
->work_format
)
288 r
->from_work_format_func
= NULL
;
289 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
290 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
293 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
294 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
298 /* initialize implementation */
299 if (init_table
[method
](r
) < 0)
311 void pa_resampler_free(pa_resampler
*r
) {
317 if (r
->buf1
.memblock
)
318 pa_memblock_unref(r
->buf1
.memblock
);
319 if (r
->buf2
.memblock
)
320 pa_memblock_unref(r
->buf2
.memblock
);
321 if (r
->buf3
.memblock
)
322 pa_memblock_unref(r
->buf3
.memblock
);
323 if (r
->buf4
.memblock
)
324 pa_memblock_unref(r
->buf4
.memblock
);
329 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
333 if (r
->i_ss
.rate
== rate
)
338 r
->impl_update_rates(r
);
341 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
345 if (r
->o_ss
.rate
== rate
)
350 r
->impl_update_rates(r
);
353 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
356 return (((out_length
/ r
->o_fz
)*r
->i_ss
.rate
)/r
->o_ss
.rate
) * r
->i_fz
;
359 size_t pa_resampler_result(pa_resampler
*r
, size_t in_length
) {
362 return (((in_length
/ r
->i_fz
)*r
->o_ss
.rate
)/r
->i_ss
.rate
) * r
->o_fz
;
365 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
366 size_t block_size_max
;
372 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
374 /* We deduce the "largest" sample spec we're using during the
376 ss
.channels
= (uint8_t) (PA_MAX(r
->i_ss
.channels
, r
->o_ss
.channels
));
378 /* We silently assume that the format enum is ordered by size */
379 ss
.format
= PA_MAX(r
->i_ss
.format
, r
->o_ss
.format
);
380 ss
.format
= PA_MAX(ss
.format
, r
->work_format
);
382 ss
.rate
= PA_MAX(r
->i_ss
.rate
, r
->o_ss
.rate
);
384 fs
= pa_frame_size(&ss
);
386 return (((block_size_max
/fs
- EXTRA_FRAMES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
389 void pa_resampler_reset(pa_resampler
*r
) {
396 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
402 static const char * const resample_methods
[] = {
403 "src-sinc-best-quality",
404 "src-sinc-medium-quality",
406 "src-zero-order-hold",
437 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
439 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
442 return resample_methods
[m
];
445 int pa_resample_method_supported(pa_resample_method_t m
) {
447 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
450 #ifndef HAVE_LIBSAMPLERATE
451 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
458 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
459 pa_resample_method_t m
;
463 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
464 if (!strcmp(string
, resample_methods
[m
]))
467 if (!strcmp(string
, "speex-fixed"))
468 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
470 if (!strcmp(string
, "speex-float"))
471 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
473 return PA_RESAMPLER_INVALID
;
476 static pa_bool_t
on_left(pa_channel_position_t p
) {
479 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
480 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
481 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
482 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
483 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
484 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
487 static pa_bool_t
on_right(pa_channel_position_t p
) {
490 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
491 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
492 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
493 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
494 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
495 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
498 static pa_bool_t
on_center(pa_channel_position_t p
) {
501 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
502 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
503 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
504 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
505 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
508 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
510 p
== PA_CHANNEL_POSITION_LFE
;
513 static void calc_map_table(pa_resampler
*r
) {
515 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
522 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
)))))
525 memset(r
->map_table
, 0, sizeof(r
->map_table
));
526 memset(ic_connected
, 0, sizeof(ic_connected
));
527 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
529 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
530 pa_bool_t oc_connected
= FALSE
;
531 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
533 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
534 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
536 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
537 /* We shall not do any remapping. Hence, just check by index */
540 r
->map_table
[oc
][ic
] = 1.0;
545 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
546 /* We shall not do any remixing. Hence, just check by name */
549 r
->map_table
[oc
][ic
] = 1.0;
556 /* OK, we shall do the full monty: upmixing and
557 * downmixing. Our algorithm is relatively simple, does
558 * not do spacialization, delay elements or apply lowpass
559 * filters for LFE. Patches are always welcome,
560 * though. Oh, and it doesn't do any matrix
561 * decoding. (Which probably wouldn't make any sense
564 * This code is not idempotent: downmixing an upmixed
565 * stereo stream is not identical to the original. The
566 * volume will not match, and the two channels will be a
567 * linear combination of both.
569 * This is losely based on random suggestions found on the
570 * Internet, such as this:
571 * http://www.halfgaar.net/surround-sound-in-linux and the
574 * The algorithm works basically like this:
576 * 1) Connect all channels with matching names.
579 * S:Mono: Copy into all D:channels
580 * D:Mono: Copy in all S:channels
582 * 3) Mix D:Left, D:Right:
583 * D:Left: If not connected, avg all S:Left
584 * D:Right: If not connected, avg all S:Right
587 * If not connected, avg all S:Center
588 * If still not connected, avg all S:Left, S:Right
591 * If not connected, avg all S:*
593 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
594 * not connected, mix into all D:left and all D:right
595 * channels. Gain is 0.1, the current left and right
596 * should be multiplied by 0.9.
598 * 7) Make sure S:Center, S:LFE is used:
600 * S:Center, S:LFE: If not connected, mix into all
601 * D:left, all D:right, all D:center channels, gain is
602 * 0.375. The current (as result of 1..6) factors
603 * should be multiplied by 0.75. (Alt. suggestion: 0.25
606 * S: and D: shall relate to the source resp. destination channels.
608 * Rationale: 1, 2 are probably obvious. For 3: this
609 * copies front to rear if needed. For 4: we try to find
610 * some suitable C source for C, if we don't find any, we
611 * avg L and R. For 5: LFE is mixed from all channels. For
612 * 6: the rear channels should not be dropped entirely,
613 * however have only minimal impact. For 7: movies usually
614 * encode speech on the center channel. Thus we have to
615 * make sure this channel is distributed to L and R if not
616 * available in the output. Also, LFE is used to achieve a
617 * greater dynamic range, and thus we should try to do our
618 * best to pass it to L+R.
621 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
622 r
->map_table
[oc
][ic
] = 1.0;
625 ic_connected
[ic
] = TRUE
;
629 if (!oc_connected
&& remix
) {
630 /* OK, we shall remix */
635 /* We are not connected and on the left side, let's
636 * average all left side input channels. */
638 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
639 if (on_left(r
->i_cm
.map
[ic
]))
643 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
644 if (on_left(r
->i_cm
.map
[ic
])) {
645 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
646 ic_connected
[ic
] = TRUE
;
649 /* We ignore the case where there is no left input
650 * channel. Something is really wrong in this case
653 } else if (on_right(b
)) {
656 /* We are not connected and on the right side, let's
657 * average all right side input channels. */
659 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
660 if (on_right(r
->i_cm
.map
[ic
]))
664 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
665 if (on_right(r
->i_cm
.map
[ic
])) {
666 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
667 ic_connected
[ic
] = TRUE
;
670 /* We ignore the case where there is no right input
671 * channel. Something is really wrong in this case
674 } else if (on_center(b
)) {
677 /* We are not connected and at the center. Let's
678 * average all center input channels. */
680 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
681 if (on_center(r
->i_cm
.map
[ic
]))
685 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
686 if (on_center(r
->i_cm
.map
[ic
])) {
687 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
688 ic_connected
[ic
] = TRUE
;
692 /* Hmm, no center channel around, let's synthesize
693 * it by mixing L and R.*/
697 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
698 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
702 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
703 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
704 r
->map_table
[oc
][ic
] = 1.0f
/ (float) n
;
705 ic_connected
[ic
] = TRUE
;
708 /* We ignore the case where there is not even a
709 * left or right input channel. Something is
710 * really wrong in this case anyway. */
713 } else if (on_lfe(b
)) {
715 /* We are not connected and an LFE. Let's average all
716 * channels for LFE. */
718 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
720 if (!(r
->flags
& PA_RESAMPLER_NO_LFE
))
721 r
->map_table
[oc
][ic
] = 1.0f
/ (float) r
->i_ss
.channels
;
723 r
->map_table
[oc
][ic
] = 0;
725 /* Please note that a channel connected to LFE
726 * doesn't really count as connected. */
734 ic_unconnected_left
= 0,
735 ic_unconnected_right
= 0,
736 ic_unconnected_center
= 0,
737 ic_unconnected_lfe
= 0;
739 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
740 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
742 if (ic_connected
[ic
])
746 ic_unconnected_left
++;
747 else if (on_right(a
))
748 ic_unconnected_right
++;
749 else if (on_center(a
))
750 ic_unconnected_center
++;
752 ic_unconnected_lfe
++;
755 if (ic_unconnected_left
> 0) {
757 /* OK, so there are unconnected input channels on the
758 * left. Let's multiply all already connected channels on
759 * the left side by .9 and add in our averaged unconnected
760 * channels multplied by .1 */
762 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
764 if (!on_left(r
->o_cm
.map
[oc
]))
767 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
769 if (ic_connected
[ic
]) {
770 r
->map_table
[oc
][ic
] *= .9f
;
774 if (on_left(r
->i_cm
.map
[ic
]))
775 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_left
;
780 if (ic_unconnected_right
> 0) {
782 /* OK, so there are unconnected input channels on the
783 * right. Let's multiply all already connected channels on
784 * the right side by .9 and add in our averaged unconnected
785 * channels multplied by .1 */
787 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
789 if (!on_right(r
->o_cm
.map
[oc
]))
792 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
794 if (ic_connected
[ic
]) {
795 r
->map_table
[oc
][ic
] *= .9f
;
799 if (on_right(r
->i_cm
.map
[ic
]))
800 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_right
;
805 if (ic_unconnected_center
> 0) {
806 pa_bool_t mixed_in
= FALSE
;
808 /* OK, so there are unconnected input channels on the
809 * center. Let's multiply all already connected channels on
810 * the center side by .9 and add in our averaged unconnected
811 * channels multplied by .1 */
813 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
815 if (!on_center(r
->o_cm
.map
[oc
]))
818 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
820 if (ic_connected
[ic
]) {
821 r
->map_table
[oc
][ic
] *= .9f
;
825 if (on_center(r
->i_cm
.map
[ic
])) {
826 r
->map_table
[oc
][ic
] = .1f
/ (float) ic_unconnected_center
;
834 /* Hmm, as it appears there was no center channel we
835 could mix our center channel in. In this case, mix
836 it into left and right. Using .375 and 0.75 as
839 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
841 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
844 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
846 if (ic_connected
[ic
]) {
847 r
->map_table
[oc
][ic
] *= .75f
;
851 if (on_center(r
->i_cm
.map
[ic
]))
852 r
->map_table
[oc
][ic
] = .375f
/ (float) ic_unconnected_center
;
858 if (ic_unconnected_lfe
> 0 && !(r
->flags
& PA_RESAMPLER_NO_LFE
)) {
860 /* OK, so there is an unconnected LFE channel. Let's mix
861 * it into all channels, with factor 0.375 */
863 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
865 if (!on_lfe(r
->i_cm
.map
[ic
]))
868 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
869 r
->map_table
[oc
][ic
] = 0.375f
/ (float) ic_unconnected_lfe
;
877 pa_strbuf_printf(s
, " ");
878 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
879 pa_strbuf_printf(s
, " I%02u ", ic
);
880 pa_strbuf_puts(s
, "\n +");
882 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
883 pa_strbuf_printf(s
, "------");
884 pa_strbuf_puts(s
, "\n");
886 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
887 pa_strbuf_printf(s
, "O%02u |", oc
);
889 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
890 pa_strbuf_printf(s
, " %1.3f", r
->map_table
[oc
][ic
]);
892 pa_strbuf_puts(s
, "\n");
895 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
899 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
905 pa_assert(input
->memblock
);
907 /* Convert the incoming sample into the work sample format and place them in buf1 */
909 if (!r
->to_work_format_func
|| !input
->length
)
912 n_samples
= (unsigned) ((input
->length
/ r
->i_fz
) * r
->i_ss
.channels
);
915 r
->buf1
.length
= r
->w_sz
* n_samples
;
917 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
918 if (r
->buf1
.memblock
)
919 pa_memblock_unref(r
->buf1
.memblock
);
921 r
->buf1_samples
= n_samples
;
922 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
925 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
926 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
928 r
->to_work_format_func(n_samples
, src
, dst
);
930 pa_memblock_release(input
->memblock
);
931 pa_memblock_release(r
->buf1
.memblock
);
936 static void vectoradd_s16_with_fraction(
937 int16_t *d
, int dstr
,
938 const int16_t *s1
, int sstr1
,
939 const int16_t *s2
, int sstr2
,
941 float s3
, float s4
) {
945 i3
= (int32_t) (s3
* 0x10000);
946 i4
= (int32_t) (s4
* 0x10000);
954 a
= (a
* i3
) / 0x10000;
955 b
= (b
* i4
) / 0x10000;
957 *d
= (int16_t) (a
+ b
);
959 s1
= (const int16_t*) ((const uint8_t*) s1
+ sstr1
);
960 s2
= (const int16_t*) ((const uint8_t*) s2
+ sstr2
);
961 d
= (int16_t*) ((uint8_t*) d
+ dstr
);
966 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
967 unsigned in_n_samples
, out_n_samples
, n_frames
;
974 pa_assert(input
->memblock
);
976 /* Remap channels and place the result int buf2 */
978 if (!r
->map_required
|| !input
->length
)
981 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
982 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
983 out_n_samples
= n_frames
* r
->o_ss
.channels
;
986 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
988 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
989 if (r
->buf2
.memblock
)
990 pa_memblock_unref(r
->buf2
.memblock
);
992 r
->buf2_samples
= out_n_samples
;
993 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
996 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
997 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
999 memset(dst
, 0, r
->buf2
.length
);
1001 o_skip
= (int) (r
->w_sz
* r
->o_ss
.channels
);
1002 i_skip
= (int) (r
->w_sz
* r
->i_ss
.channels
);
1004 switch (r
->work_format
) {
1005 case PA_SAMPLE_FLOAT32NE
:
1007 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1009 static const float one
= 1.0;
1011 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1013 if (r
->map_table
[oc
][ic
] <= 0.0)
1017 (float*) dst
+ oc
, o_skip
,
1018 (float*) dst
+ oc
, o_skip
,
1019 (float*) src
+ ic
, i_skip
,
1021 &one
, &r
->map_table
[oc
][ic
]);
1027 case PA_SAMPLE_S16NE
:
1029 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1032 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1034 if (r
->map_table
[oc
][ic
] <= 0.0)
1037 if (r
->map_table
[oc
][ic
] >= 1.0) {
1038 static const int16_t one
= 1;
1041 (int16_t*) dst
+ oc
, o_skip
,
1042 (int16_t*) dst
+ oc
, o_skip
,
1043 (int16_t*) src
+ ic
, i_skip
,
1049 vectoradd_s16_with_fraction(
1050 (int16_t*) dst
+ oc
, o_skip
,
1051 (int16_t*) dst
+ oc
, o_skip
,
1052 (int16_t*) src
+ ic
, i_skip
,
1054 1.0f
, r
->map_table
[oc
][ic
]);
1061 pa_assert_not_reached();
1064 pa_memblock_release(input
->memblock
);
1065 pa_memblock_release(r
->buf2
.memblock
);
1067 r
->buf2
.length
= out_n_samples
* r
->w_sz
;
1072 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1073 unsigned in_n_frames
, in_n_samples
;
1074 unsigned out_n_frames
, out_n_samples
;
1079 /* Resample the data and place the result in buf3 */
1081 if (!r
->impl_resample
|| !input
->length
)
1084 in_n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1085 in_n_frames
= (unsigned) (in_n_samples
/ r
->o_ss
.channels
);
1087 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_FRAMES
;
1088 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1091 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1093 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1094 if (r
->buf3
.memblock
)
1095 pa_memblock_unref(r
->buf3
.memblock
);
1097 r
->buf3_samples
= out_n_samples
;
1098 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1101 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1102 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1107 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1108 unsigned n_samples
, n_frames
;
1114 /* Convert the data into the correct sample type and place the result in buf4 */
1116 if (!r
->from_work_format_func
|| !input
->length
)
1119 n_samples
= (unsigned) (input
->length
/ r
->w_sz
);
1120 n_frames
= n_samples
/ r
->o_ss
.channels
;
1123 r
->buf4
.length
= r
->o_fz
* n_frames
;
1125 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1126 if (r
->buf4
.memblock
)
1127 pa_memblock_unref(r
->buf4
.memblock
);
1129 r
->buf4_samples
= n_samples
;
1130 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1133 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1134 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1135 r
->from_work_format_func(n_samples
, src
, dst
);
1136 pa_memblock_release(input
->memblock
);
1137 pa_memblock_release(r
->buf4
.memblock
);
1139 r
->buf4
.length
= r
->o_fz
* n_frames
;
1144 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1150 pa_assert(in
->length
);
1151 pa_assert(in
->memblock
);
1152 pa_assert(in
->length
% r
->i_fz
== 0);
1154 buf
= (pa_memchunk
*) in
;
1155 buf
= convert_to_work_format(r
, buf
);
1156 buf
= remap_channels(r
, buf
);
1157 buf
= resample(r
, buf
);
1160 buf
= convert_from_work_format(r
, buf
);
1164 pa_memblock_ref(buf
->memblock
);
1166 pa_memchunk_reset(buf
);
1168 pa_memchunk_reset(out
);
1171 /*** libsamplerate based implementation ***/
1173 #ifdef HAVE_LIBSAMPLERATE
1174 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1180 pa_assert(out_n_frames
);
1182 memset(&data
, 0, sizeof(data
));
1184 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1185 data
.input_frames
= (long int) in_n_frames
;
1187 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1188 data
.output_frames
= (long int) *out_n_frames
;
1190 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1191 data
.end_of_input
= 0;
1193 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1194 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1196 pa_memblock_release(input
->memblock
);
1197 pa_memblock_release(output
->memblock
);
1199 *out_n_frames
= (unsigned) data
.output_frames_gen
;
1202 static void libsamplerate_update_rates(pa_resampler
*r
) {
1205 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1208 static void libsamplerate_reset(pa_resampler
*r
) {
1211 pa_assert_se(src_reset(r
->src
.state
) == 0);
1214 static void libsamplerate_free(pa_resampler
*r
) {
1218 src_delete(r
->src
.state
);
1221 static int libsamplerate_init(pa_resampler
*r
) {
1226 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1229 r
->impl_free
= libsamplerate_free
;
1230 r
->impl_update_rates
= libsamplerate_update_rates
;
1231 r
->impl_resample
= libsamplerate_resample
;
1232 r
->impl_reset
= libsamplerate_reset
;
1238 /*** speex based implementation ***/
1240 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1242 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1247 pa_assert(out_n_frames
);
1249 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1250 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1252 pa_assert_se(speex_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1254 pa_memblock_release(input
->memblock
);
1255 pa_memblock_release(output
->memblock
);
1257 pa_assert(inf
== in_n_frames
);
1258 *out_n_frames
= outf
;
1261 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1263 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1268 pa_assert(out_n_frames
);
1270 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1271 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1273 pa_assert_se(speex_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1275 pa_memblock_release(input
->memblock
);
1276 pa_memblock_release(output
->memblock
);
1278 pa_assert(inf
== in_n_frames
);
1279 *out_n_frames
= outf
;
1282 static void speex_update_rates(pa_resampler
*r
) {
1285 pa_assert_se(speex_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1288 static void speex_reset(pa_resampler
*r
) {
1291 pa_assert_se(speex_resampler_reset_mem(r
->speex
.state
) == 0);
1294 static void speex_free(pa_resampler
*r
) {
1297 if (!r
->speex
.state
)
1300 speex_resampler_destroy(r
->speex
.state
);
1303 static int speex_init(pa_resampler
*r
) {
1308 r
->impl_free
= speex_free
;
1309 r
->impl_update_rates
= speex_update_rates
;
1310 r
->impl_reset
= speex_reset
;
1312 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) {
1314 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1315 r
->impl_resample
= speex_resample_int
;
1318 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1320 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1321 r
->impl_resample
= speex_resample_float
;
1324 pa_log_info("Choosing speex quality setting %i.", q
);
1326 if (!(r
->speex
.state
= speex_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1332 /* Trivial implementation */
1334 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1342 pa_assert(out_n_frames
);
1344 fz
= r
->w_sz
* r
->o_ss
.channels
;
1346 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1347 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1349 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1352 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1353 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1355 if (j
>= in_n_frames
)
1358 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1360 oil_memcpy((uint8_t*) dst
+ fz
* o_index
,
1361 (uint8_t*) src
+ fz
* j
, (int) fz
);
1364 pa_memblock_release(input
->memblock
);
1365 pa_memblock_release(output
->memblock
);
1367 *out_n_frames
= o_index
;
1369 r
->trivial
.i_counter
+= in_n_frames
;
1371 /* Normalize counters */
1372 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1373 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1375 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1376 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1380 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1383 r
->trivial
.i_counter
= 0;
1384 r
->trivial
.o_counter
= 0;
1387 static int trivial_init(pa_resampler
*r
) {
1390 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1392 r
->impl_resample
= trivial_resample
;
1393 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1394 r
->impl_reset
= trivial_update_rates_or_reset
;
1399 /* Peak finder implementation */
1401 static void peaks_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1410 pa_assert(out_n_frames
);
1412 fz
= r
->w_sz
* r
->o_ss
.channels
;
1414 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1415 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1417 for (o_index
= 0;; o_index
++, r
->peaks
.o_counter
++) {
1420 j
= ((r
->peaks
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1421 j
= j
> r
->peaks
.i_counter
? j
- r
->peaks
.i_counter
: 0;
1423 if (j
>= in_n_frames
)
1426 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1428 if (r
->work_format
== PA_SAMPLE_S16NE
) {
1430 int16_t *s
= (int16_t*) ((uint8_t*) src
+ fz
* j
);
1431 int16_t *d
= (int16_t*) ((uint8_t*) dst
+ fz
* o_index
);
1433 for (i
= start
; i
<= j
; i
++)
1434 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1437 n
= (int16_t) (*s
< 0 ? -*s
: *s
);
1439 if (n
> r
->peaks
.max_i
[c
])
1440 r
->peaks
.max_i
[c
] = n
;
1443 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1444 *d
= r
->peaks
.max_i
[c
];
1445 r
->peaks
.max_i
[c
] = 0;
1449 float *s
= (float*) ((uint8_t*) src
+ fz
* j
);
1450 float *d
= (float*) ((uint8_t*) dst
+ fz
* o_index
);
1452 pa_assert(r
->work_format
== PA_SAMPLE_FLOAT32NE
);
1454 for (i
= start
; i
<= j
; i
++)
1455 for (c
= 0; c
< r
->o_ss
.channels
; c
++, s
++) {
1456 float n
= fabsf(*s
);
1458 if (n
> r
->peaks
.max_f
[c
])
1459 r
->peaks
.max_f
[c
] = n
;
1462 for (c
= 0; c
< r
->o_ss
.channels
; c
++, d
++) {
1463 *d
= r
->peaks
.max_f
[c
];
1464 r
->peaks
.max_f
[c
] = 0;
1471 pa_memblock_release(input
->memblock
);
1472 pa_memblock_release(output
->memblock
);
1474 *out_n_frames
= o_index
;
1476 r
->peaks
.i_counter
+= in_n_frames
;
1478 /* Normalize counters */
1479 while (r
->peaks
.i_counter
>= r
->i_ss
.rate
) {
1480 pa_assert(r
->peaks
.o_counter
>= r
->o_ss
.rate
);
1482 r
->peaks
.i_counter
-= r
->i_ss
.rate
;
1483 r
->peaks
.o_counter
-= r
->o_ss
.rate
;
1487 static void peaks_update_rates_or_reset(pa_resampler
*r
) {
1490 r
->peaks
.i_counter
= 0;
1491 r
->peaks
.o_counter
= 0;
1494 static int peaks_init(pa_resampler
*r
) {
1497 r
->peaks
.o_counter
= r
->peaks
.i_counter
= 0;
1498 memset(r
->peaks
.max_i
, 0, sizeof(r
->peaks
.max_i
));
1499 memset(r
->peaks
.max_f
, 0, sizeof(r
->peaks
.max_f
));
1501 r
->impl_resample
= peaks_resample
;
1502 r
->impl_update_rates
= peaks_update_rates_or_reset
;
1503 r
->impl_reset
= peaks_update_rates_or_reset
;
1508 /*** ffmpeg based implementation ***/
1510 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1511 unsigned used_frames
= 0, c
;
1516 pa_assert(out_n_frames
);
1518 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1521 int16_t *p
, *t
, *k
, *q
, *s
;
1522 int consumed_frames
;
1525 /* Allocate a new block */
1526 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1527 p
= pa_memblock_acquire(b
);
1529 /* Copy the remaining data into it */
1530 l
= (unsigned) r
->ffmpeg
.buf
[c
].length
;
1531 if (r
->ffmpeg
.buf
[c
].memblock
) {
1532 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1534 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1535 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1536 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1539 /* Now append the new data, splitting up channels */
1540 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1541 k
= (int16_t*) ((uint8_t*) p
+ l
);
1542 for (u
= 0; u
< in_n_frames
; u
++) {
1544 t
+= r
->o_ss
.channels
;
1547 pa_memblock_release(input
->memblock
);
1549 /* Calculate the resulting number of frames */
1550 in
= (unsigned) in_n_frames
+ l
/ (unsigned) sizeof(int16_t);
1552 /* Allocate buffer for the result */
1553 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1554 q
= pa_memblock_acquire(w
);
1557 used_frames
= (unsigned) av_resample(r
->ffmpeg
.state
,
1560 (int) in
, (int) *out_n_frames
,
1561 c
>= (unsigned) (r
->o_ss
.channels
-1));
1563 pa_memblock_release(b
);
1565 /* Now store the remaining samples away */
1566 pa_assert(consumed_frames
<= (int) in
);
1567 if (consumed_frames
< (int) in
) {
1568 r
->ffmpeg
.buf
[c
].memblock
= b
;
1569 r
->ffmpeg
.buf
[c
].index
= (size_t) consumed_frames
* sizeof(int16_t);
1570 r
->ffmpeg
.buf
[c
].length
= (size_t) (in
- (unsigned) consumed_frames
) * sizeof(int16_t);
1572 pa_memblock_unref(b
);
1574 /* And place the results in the output buffer */
1575 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1576 for (u
= 0; u
< used_frames
; u
++) {
1579 s
+= r
->o_ss
.channels
;
1581 pa_memblock_release(output
->memblock
);
1582 pa_memblock_release(w
);
1583 pa_memblock_unref(w
);
1586 *out_n_frames
= used_frames
;
1589 static void ffmpeg_free(pa_resampler
*r
) {
1594 if (r
->ffmpeg
.state
)
1595 av_resample_close(r
->ffmpeg
.state
);
1597 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1598 if (r
->ffmpeg
.buf
[c
].memblock
)
1599 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1602 static int ffmpeg_init(pa_resampler
*r
) {
1607 /* We could probably implement different quality levels by
1608 * adjusting the filter parameters here. However, ffmpeg
1609 * internally only uses these hardcoded values, so let's use them
1610 * here for now as well until ffmpeg makes this configurable. */
1612 if (!(r
->ffmpeg
.state
= av_resample_init((int) r
->o_ss
.rate
, (int) r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1615 r
->impl_free
= ffmpeg_free
;
1616 r
->impl_resample
= ffmpeg_resample
;
1618 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1619 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1624 /*** copy (noop) implementation ***/
1626 static int copy_init(pa_resampler
*r
) {
1629 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);