4 This file is part of PulseAudio.
6 Copyright 2004-2006 Lennart Poettering
8 PulseAudio is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published
10 by the Free Software Foundation; either version 2 of the License,
11 or (at your option) any later version.
13 PulseAudio is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with PulseAudio; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
30 #if HAVE_LIBSAMPLERATE
31 #include <samplerate.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 "speexwrap.h"
45 #include "ffmpeg/avcodec.h"
47 #include "resampler.h"
49 /* Number of samples of extra space we allow the resamplers to return */
50 #define EXTRA_SAMPLES 128
53 pa_resample_method_t method
;
54 pa_resample_flags_t flags
;
56 pa_sample_spec i_ss
, o_ss
;
57 pa_channel_map i_cm
, o_cm
;
58 size_t i_fz
, o_fz
, w_sz
;
61 pa_memchunk buf1
, buf2
, buf3
, buf4
;
62 unsigned buf1_samples
, buf2_samples
, buf3_samples
, buf4_samples
;
64 pa_sample_format_t work_format
;
66 pa_convert_func_t to_work_format_func
;
67 pa_convert_func_t from_work_format_func
;
69 float map_table
[PA_CHANNELS_MAX
][PA_CHANNELS_MAX
];
70 pa_bool_t map_required
;
72 void (*impl_free
)(pa_resampler
*r
);
73 void (*impl_update_rates
)(pa_resampler
*r
);
74 void (*impl_resample
)(pa_resampler
*r
, const pa_memchunk
*in
, unsigned in_samples
, pa_memchunk
*out
, unsigned *out_samples
);
75 void (*impl_reset
)(pa_resampler
*r
);
77 struct { /* data specific to the trivial resampler */
82 #ifdef HAVE_LIBSAMPLERATE
83 struct { /* data specific to libsamplerate */
88 struct { /* data specific to speex */
89 SpeexResamplerState
* state
;
92 struct { /* data specific to ffmpeg */
93 struct AVResampleContext
*state
;
94 pa_memchunk buf
[PA_CHANNELS_MAX
];
98 static int copy_init(pa_resampler
*r
);
99 static int trivial_init(pa_resampler
*r
);
100 static int speex_init(pa_resampler
*r
);
101 static int ffmpeg_init(pa_resampler
*r
);
102 #ifdef HAVE_LIBSAMPLERATE
103 static int libsamplerate_init(pa_resampler
*r
);
106 static void calc_map_table(pa_resampler
*r
);
108 static int (* const init_table
[])(pa_resampler
*r
) = {
109 #ifdef HAVE_LIBSAMPLERATE
110 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = libsamplerate_init
,
111 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = libsamplerate_init
,
112 [PA_RESAMPLER_SRC_SINC_FASTEST
] = libsamplerate_init
,
113 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = libsamplerate_init
,
114 [PA_RESAMPLER_SRC_LINEAR
] = libsamplerate_init
,
116 [PA_RESAMPLER_SRC_SINC_BEST_QUALITY
] = NULL
,
117 [PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY
] = NULL
,
118 [PA_RESAMPLER_SRC_SINC_FASTEST
] = NULL
,
119 [PA_RESAMPLER_SRC_ZERO_ORDER_HOLD
] = NULL
,
120 [PA_RESAMPLER_SRC_LINEAR
] = NULL
,
122 [PA_RESAMPLER_TRIVIAL
] = trivial_init
,
123 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+0] = speex_init
,
124 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+1] = speex_init
,
125 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+2] = speex_init
,
126 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+3] = speex_init
,
127 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+4] = speex_init
,
128 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+5] = speex_init
,
129 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+6] = speex_init
,
130 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+7] = speex_init
,
131 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+8] = speex_init
,
132 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+9] = speex_init
,
133 [PA_RESAMPLER_SPEEX_FLOAT_BASE
+10] = speex_init
,
134 [PA_RESAMPLER_SPEEX_FIXED_BASE
+0] = speex_init
,
135 [PA_RESAMPLER_SPEEX_FIXED_BASE
+1] = speex_init
,
136 [PA_RESAMPLER_SPEEX_FIXED_BASE
+2] = speex_init
,
137 [PA_RESAMPLER_SPEEX_FIXED_BASE
+3] = speex_init
,
138 [PA_RESAMPLER_SPEEX_FIXED_BASE
+4] = speex_init
,
139 [PA_RESAMPLER_SPEEX_FIXED_BASE
+5] = speex_init
,
140 [PA_RESAMPLER_SPEEX_FIXED_BASE
+6] = speex_init
,
141 [PA_RESAMPLER_SPEEX_FIXED_BASE
+7] = speex_init
,
142 [PA_RESAMPLER_SPEEX_FIXED_BASE
+8] = speex_init
,
143 [PA_RESAMPLER_SPEEX_FIXED_BASE
+9] = speex_init
,
144 [PA_RESAMPLER_SPEEX_FIXED_BASE
+10] = speex_init
,
145 [PA_RESAMPLER_FFMPEG
] = ffmpeg_init
,
146 [PA_RESAMPLER_AUTO
] = NULL
,
147 [PA_RESAMPLER_COPY
] = copy_init
150 static inline size_t sample_size(pa_sample_format_t f
) {
151 pa_sample_spec ss
= {
157 return pa_sample_size(&ss
);
160 pa_resampler
* pa_resampler_new(
162 const pa_sample_spec
*a
,
163 const pa_channel_map
*am
,
164 const pa_sample_spec
*b
,
165 const pa_channel_map
*bm
,
166 pa_resample_method_t method
,
167 pa_resample_flags_t flags
) {
169 pa_resampler
*r
= NULL
;
174 pa_assert(pa_sample_spec_valid(a
));
175 pa_assert(pa_sample_spec_valid(b
));
176 pa_assert(method
>= 0);
177 pa_assert(method
< PA_RESAMPLER_MAX
);
181 if (!(flags
& PA_RESAMPLER_VARIABLE_RATE
) && a
->rate
== b
->rate
) {
182 pa_log_info("Forcing resampler 'copy', because of fixed, identical sample rates.");
183 method
= PA_RESAMPLER_COPY
;
186 if (!pa_resample_method_supported(method
)) {
187 pa_log_warn("Support for resampler '%s' not compiled in, reverting to 'auto'.", pa_resample_method_to_string(method
));
188 method
= PA_RESAMPLER_AUTO
;
191 if (method
== PA_RESAMPLER_FFMPEG
&& (flags
& PA_RESAMPLER_VARIABLE_RATE
)) {
192 pa_log_info("Resampler 'ffmpeg' cannot do variable rate, reverting to resampler 'auto'.");
193 method
= PA_RESAMPLER_AUTO
;
196 if (method
== PA_RESAMPLER_COPY
&& ((flags
& PA_RESAMPLER_VARIABLE_RATE
) || a
->rate
!= b
->rate
)) {
197 pa_log_info("Resampler 'copy' cannot change sampling rate, reverting to resampler 'auto'.");
198 method
= PA_RESAMPLER_AUTO
;
201 if (method
== PA_RESAMPLER_AUTO
)
202 method
= PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
204 r
= pa_xnew(pa_resampler
, 1);
210 r
->impl_update_rates
= NULL
;
211 r
->impl_resample
= NULL
;
212 r
->impl_reset
= NULL
;
214 /* Fill sample specs */
221 pa_channel_map_init_auto(&r
->i_cm
, r
->i_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
);
226 pa_channel_map_init_auto(&r
->o_cm
, r
->o_ss
.channels
, PA_CHANNEL_MAP_DEFAULT
);
228 r
->i_fz
= pa_frame_size(a
);
229 r
->o_fz
= pa_frame_size(b
);
231 pa_memchunk_reset(&r
->buf1
);
232 pa_memchunk_reset(&r
->buf2
);
233 pa_memchunk_reset(&r
->buf3
);
234 pa_memchunk_reset(&r
->buf4
);
236 r
->buf1_samples
= r
->buf2_samples
= r
->buf3_samples
= r
->buf4_samples
= 0;
240 pa_log_info("Using resampler '%s'", pa_resample_method_to_string(method
));
242 if ((method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
) ||
243 (method
== PA_RESAMPLER_FFMPEG
))
244 r
->work_format
= PA_SAMPLE_S16NE
;
245 else if (method
== PA_RESAMPLER_TRIVIAL
|| method
== PA_RESAMPLER_COPY
) {
247 if (r
->map_required
|| a
->format
!= b
->format
) {
249 if (a
->format
== PA_SAMPLE_S32NE
|| a
->format
== PA_SAMPLE_S32RE
||
250 a
->format
== PA_SAMPLE_FLOAT32NE
|| a
->format
== PA_SAMPLE_FLOAT32RE
||
251 b
->format
== PA_SAMPLE_S32NE
|| b
->format
== PA_SAMPLE_S32RE
||
252 b
->format
== PA_SAMPLE_FLOAT32NE
|| b
->format
== PA_SAMPLE_FLOAT32RE
)
253 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
255 r
->work_format
= PA_SAMPLE_S16NE
;
258 r
->work_format
= a
->format
;
261 r
->work_format
= PA_SAMPLE_FLOAT32NE
;
263 pa_log_info("Using %s as working format.", pa_sample_format_to_string(r
->work_format
));
265 r
->w_sz
= sample_size(r
->work_format
);
267 if (r
->i_ss
.format
== r
->work_format
)
268 r
->to_work_format_func
= NULL
;
269 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
270 if (!(r
->to_work_format_func
= pa_get_convert_to_float32ne_function(r
->i_ss
.format
)))
273 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
274 if (!(r
->to_work_format_func
= pa_get_convert_to_s16ne_function(r
->i_ss
.format
)))
278 if (r
->o_ss
.format
== r
->work_format
)
279 r
->from_work_format_func
= NULL
;
280 else if (r
->work_format
== PA_SAMPLE_FLOAT32NE
) {
281 if (!(r
->from_work_format_func
= pa_get_convert_from_float32ne_function(r
->o_ss
.format
)))
284 pa_assert(r
->work_format
== PA_SAMPLE_S16NE
);
285 if (!(r
->from_work_format_func
= pa_get_convert_from_s16ne_function(r
->o_ss
.format
)))
289 /* initialize implementation */
290 if (init_table
[method
](r
) < 0)
302 void pa_resampler_free(pa_resampler
*r
) {
308 if (r
->buf1
.memblock
)
309 pa_memblock_unref(r
->buf1
.memblock
);
310 if (r
->buf2
.memblock
)
311 pa_memblock_unref(r
->buf2
.memblock
);
312 if (r
->buf3
.memblock
)
313 pa_memblock_unref(r
->buf3
.memblock
);
314 if (r
->buf4
.memblock
)
315 pa_memblock_unref(r
->buf4
.memblock
);
320 void pa_resampler_set_input_rate(pa_resampler
*r
, uint32_t rate
) {
324 if (r
->i_ss
.rate
== rate
)
329 r
->impl_update_rates(r
);
332 void pa_resampler_set_output_rate(pa_resampler
*r
, uint32_t rate
) {
336 if (r
->o_ss
.rate
== rate
)
341 r
->impl_update_rates(r
);
344 size_t pa_resampler_request(pa_resampler
*r
, size_t out_length
) {
347 return (((out_length
/ r
->o_fz
)*r
->i_ss
.rate
)/r
->o_ss
.rate
) * r
->i_fz
;
350 size_t pa_resampler_max_block_size(pa_resampler
*r
) {
351 size_t block_size_max
;
357 block_size_max
= pa_mempool_block_size_max(r
->mempool
);
359 /* We deduce the "largest" sample spec we're using during the
362 if (r
->o_ss
.channels
> ss
.channels
)
363 ss
.channels
= r
->o_ss
.channels
;
365 /* We silently assume that the format enum is ordered by size */
366 if (r
->o_ss
.format
> ss
.format
)
367 ss
.format
= r
->o_ss
.format
;
368 if (r
->work_format
> ss
.format
)
369 ss
.format
= r
->work_format
;
371 if (r
->o_ss
.rate
> ss
.rate
)
372 ss
.rate
= r
->o_ss
.rate
;
374 fs
= pa_frame_size(&ss
);
376 return (((block_size_max
/fs
+ EXTRA_SAMPLES
)*r
->i_ss
.rate
)/ss
.rate
)*r
->i_fz
;
379 void pa_resampler_reset(pa_resampler
*r
) {
386 pa_resample_method_t
pa_resampler_get_method(pa_resampler
*r
) {
392 static const char * const resample_methods
[] = {
393 "src-sinc-best-quality",
394 "src-sinc-medium-quality",
396 "src-zero-order-hold",
426 const char *pa_resample_method_to_string(pa_resample_method_t m
) {
428 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
431 return resample_methods
[m
];
434 int pa_resample_method_supported(pa_resample_method_t m
) {
436 if (m
< 0 || m
>= PA_RESAMPLER_MAX
)
439 #ifndef HAVE_LIBSAMPLERATE
440 if (m
<= PA_RESAMPLER_SRC_LINEAR
)
447 pa_resample_method_t
pa_parse_resample_method(const char *string
) {
448 pa_resample_method_t m
;
452 for (m
= 0; m
< PA_RESAMPLER_MAX
; m
++)
453 if (!strcmp(string
, resample_methods
[m
]))
456 if (!strcmp(string
, "speex-fixed"))
457 return PA_RESAMPLER_SPEEX_FIXED_BASE
+ 3;
459 if (!strcmp(string
, "speex-float"))
460 return PA_RESAMPLER_SPEEX_FLOAT_BASE
+ 3;
462 return PA_RESAMPLER_INVALID
;
465 static pa_bool_t
on_left(pa_channel_position_t p
) {
468 p
== PA_CHANNEL_POSITION_FRONT_LEFT
||
469 p
== PA_CHANNEL_POSITION_REAR_LEFT
||
470 p
== PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER
||
471 p
== PA_CHANNEL_POSITION_SIDE_LEFT
||
472 p
== PA_CHANNEL_POSITION_TOP_FRONT_LEFT
||
473 p
== PA_CHANNEL_POSITION_TOP_REAR_LEFT
;
476 static pa_bool_t
on_right(pa_channel_position_t p
) {
479 p
== PA_CHANNEL_POSITION_FRONT_RIGHT
||
480 p
== PA_CHANNEL_POSITION_REAR_RIGHT
||
481 p
== PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER
||
482 p
== PA_CHANNEL_POSITION_SIDE_RIGHT
||
483 p
== PA_CHANNEL_POSITION_TOP_FRONT_RIGHT
||
484 p
== PA_CHANNEL_POSITION_TOP_REAR_RIGHT
;
487 static pa_bool_t
on_center(pa_channel_position_t p
) {
490 p
== PA_CHANNEL_POSITION_FRONT_CENTER
||
491 p
== PA_CHANNEL_POSITION_REAR_CENTER
||
492 p
== PA_CHANNEL_POSITION_TOP_CENTER
||
493 p
== PA_CHANNEL_POSITION_TOP_FRONT_CENTER
||
494 p
== PA_CHANNEL_POSITION_TOP_REAR_CENTER
;
497 static pa_bool_t
on_lfe(pa_channel_position_t p
) {
499 p
== PA_CHANNEL_POSITION_LFE
;
502 static void calc_map_table(pa_resampler
*r
) {
504 pa_bool_t ic_connected
[PA_CHANNELS_MAX
];
511 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
)))))
514 memset(r
->map_table
, 0, sizeof(r
->map_table
));
515 memset(ic_connected
, 0, sizeof(ic_connected
));
516 remix
= (r
->flags
& (PA_RESAMPLER_NO_REMAP
|PA_RESAMPLER_NO_REMIX
)) == 0;
518 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
519 pa_bool_t oc_connected
= FALSE
;
520 pa_channel_position_t b
= r
->o_cm
.map
[oc
];
522 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
523 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
525 if (r
->flags
& PA_RESAMPLER_NO_REMAP
) {
526 /* We shall not do any remapping. Hence, just check by index */
529 r
->map_table
[oc
][ic
] = 1.0;
534 if (r
->flags
& PA_RESAMPLER_NO_REMIX
) {
535 /* We shall not do any remixing. Hence, just check by name */
538 r
->map_table
[oc
][ic
] = 1.0;
545 /* OK, we shall do the full monty: upmixing and
546 * downmixing. Our algorithm is relatively simple, does
547 * not do spacialization, delay elements or apply lowpass
548 * filters for LFE. Patches are always welcome,
549 * though. Oh, and it doesn't do any matrix
550 * decoding. (Which probably wouldn't make any sense
553 * This code is not idempotent: downmixing an upmixed
554 * stereo stream is not identical to the original. The
555 * volume will not match, and the two channels will be a
556 * linear combination of both.
558 * This is losely based on random suggestions found on the
559 * Internet, such as this:
560 * http://www.halfgaar.net/surround-sound-in-linux and the
563 * The algorithm works basically like this:
565 * 1) Connect all channels with matching names.
568 * S:Mono: Copy into all D:channels
569 * D:Mono: Copy in all S:channels
571 * 3) Mix D:Left, D:Right:
572 * D:Left: If not connected, avg all S:Left
573 * D:Right: If not connected, avg all S:Right
576 * If not connected, avg all S:Center
577 * If still not connected, avg all S:Left, S:Right
580 * If not connected, avg all S:*
582 * 6) Make sure S:Left/S:Right is used: S:Left/S:Right: If
583 * not connected, mix into all D:left and all D:right
584 * channels. Gain is 0.1, the current left and right
585 * should be multiplied by 0.9.
587 * 7) Make sure S:Center, S:LFE is used:
589 * S:Center, S:LFE: If not connected, mix into all
590 * D:left, all D:right, all D:center channels, gain is
591 * 0.375. The current (as result of 1..6) factors
592 * should be multiplied by 0.75. (Alt. suggestion: 0.25
595 * S: and D: shall relate to the source resp. destination channels.
597 * Rationale: 1, 2 are probably obvious. For 3: this
598 * copies front to rear if needed. For 4: we try to find
599 * some suitable C source for C, if we don't find any, we
600 * avg L and R. For 5: LFE is mixed from all channels. For
601 * 6: the rear channels should not be dropped entirely,
602 * however have only minimal impact. For 7: movies usually
603 * encode speech on the center channel. Thus we have to
604 * make sure this channel is distributed to L and R if not
605 * available in the output. Also, LFE is used to achieve a
606 * greater dynamic range, and thus we should try to do our
607 * best to pass it to L+R.
610 if (a
== b
|| a
== PA_CHANNEL_POSITION_MONO
|| b
== PA_CHANNEL_POSITION_MONO
) {
611 r
->map_table
[oc
][ic
] = 1.0;
614 ic_connected
[ic
] = TRUE
;
618 if (!oc_connected
&& remix
) {
619 /* OK, we shall remix */
624 /* We are not connected and on the left side, let's
625 * average all left side input channels. */
627 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
628 if (on_left(r
->i_cm
.map
[ic
]))
632 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
633 if (on_left(r
->i_cm
.map
[ic
])) {
634 r
->map_table
[oc
][ic
] = 1.0 / n
;
635 ic_connected
[ic
] = TRUE
;
638 /* We ignore the case where there is no left input
639 * channel. Something is really wrong in this case
642 } else if (on_right(b
)) {
645 /* We are not connected and on the right side, let's
646 * average all right side input channels. */
648 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
649 if (on_right(r
->i_cm
.map
[ic
]))
653 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
654 if (on_right(r
->i_cm
.map
[ic
])) {
655 r
->map_table
[oc
][ic
] = 1.0 / n
;
656 ic_connected
[ic
] = TRUE
;
659 /* We ignore the case where there is no right input
660 * channel. Something is really wrong in this case
663 } else if (on_center(b
)) {
666 /* We are not connected and at the center. Let's
667 * average all center input channels. */
669 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
670 if (on_center(r
->i_cm
.map
[ic
]))
674 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
675 if (on_center(r
->i_cm
.map
[ic
])) {
676 r
->map_table
[oc
][ic
] = 1.0 / n
;
677 ic_connected
[ic
] = TRUE
;
681 /* Hmm, no center channel around, let's synthesize
682 * it by mixing L and R.*/
686 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
687 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
]))
691 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
692 if (on_left(r
->i_cm
.map
[ic
]) || on_right(r
->i_cm
.map
[ic
])) {
693 r
->map_table
[oc
][ic
] = 1.0 / n
;
694 ic_connected
[ic
] = TRUE
;
697 /* We ignore the case where there is not even a
698 * left or right input channel. Something is
699 * really wrong in this case anyway. */
702 } else if (on_lfe(b
)) {
704 /* We are not connected and an LFE. Let's average all
705 * channels for LFE. */
707 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
708 r
->map_table
[oc
][ic
] = 1.0 / r
->i_ss
.channels
;
710 /* Please note that a channel connected to LFE
711 * doesn't really count as connected. */
719 ic_unconnected_left
= 0,
720 ic_unconnected_right
= 0,
721 ic_unconnected_center
= 0,
722 ic_unconnected_lfe
= 0;
724 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
725 pa_channel_position_t a
= r
->i_cm
.map
[ic
];
727 if (ic_connected
[ic
])
731 ic_unconnected_left
++;
732 else if (on_right(a
))
733 ic_unconnected_right
++;
734 else if (on_center(a
))
735 ic_unconnected_center
++;
737 ic_unconnected_lfe
++;
740 if (ic_unconnected_left
> 0) {
742 /* OK, so there are unconnected input channels on the
743 * left. Let's multiply all already connected channels on
744 * the left side by .9 and add in our averaged unconnected
745 * channels multplied by .1 */
747 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
749 if (!on_left(r
->o_cm
.map
[oc
]))
752 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
754 if (ic_connected
[ic
]) {
755 r
->map_table
[oc
][ic
] *= .9;
759 if (on_left(r
->i_cm
.map
[ic
]))
760 r
->map_table
[oc
][ic
] = .1 / ic_unconnected_left
;
765 if (ic_unconnected_right
> 0) {
767 /* OK, so there are unconnected input channels on the
768 * right. Let's multiply all already connected channels on
769 * the right side by .9 and add in our averaged unconnected
770 * channels multplied by .1 */
772 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
774 if (!on_right(r
->o_cm
.map
[oc
]))
777 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
779 if (ic_connected
[ic
]) {
780 r
->map_table
[oc
][ic
] *= .9;
784 if (on_right(r
->i_cm
.map
[ic
]))
785 r
->map_table
[oc
][ic
] = .1 / ic_unconnected_right
;
790 if (ic_unconnected_center
> 0) {
791 pa_bool_t mixed_in
= FALSE
;
793 /* OK, so there are unconnected input channels on the
794 * center. Let's multiply all already connected channels on
795 * the center side by .9 and add in our averaged unconnected
796 * channels multplied by .1 */
798 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
800 if (!on_center(r
->o_cm
.map
[oc
]))
803 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
805 if (ic_connected
[ic
]) {
806 r
->map_table
[oc
][ic
] *= .9;
810 if (on_center(r
->i_cm
.map
[ic
])) {
811 r
->map_table
[oc
][ic
] = .1 / ic_unconnected_center
;
819 /* Hmm, as it appears there was no center channel we
820 could mix our center channel in. In this case, mix
821 it into left and right. Using .375 and 0.75 as
824 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
826 if (!on_left(r
->o_cm
.map
[oc
]) && !on_right(r
->o_cm
.map
[oc
]))
829 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
831 if (ic_connected
[ic
]) {
832 r
->map_table
[oc
][ic
] *= .75;
836 if (on_center(r
->i_cm
.map
[ic
]))
837 r
->map_table
[oc
][ic
] = .375 / ic_unconnected_center
;
843 if (ic_unconnected_lfe
> 0) {
845 /* OK, so there is an unconnected LFE channel. Let's mix
846 * it into all channels, with factor 0.375 */
848 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
850 if (!on_lfe(r
->i_cm
.map
[ic
]))
853 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++)
854 r
->map_table
[oc
][ic
] = 0.375 / ic_unconnected_lfe
;
862 pa_strbuf_printf(s
, " ");
863 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
864 pa_strbuf_printf(s
, " I%02u ", ic
);
865 pa_strbuf_puts(s
, "\n +");
867 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
868 pa_strbuf_printf(s
, "------");
869 pa_strbuf_puts(s
, "\n");
871 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
872 pa_strbuf_printf(s
, "O%02u |", oc
);
874 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++)
875 pa_strbuf_printf(s
, " %1.3f", r
->map_table
[oc
][ic
]);
877 pa_strbuf_puts(s
, "\n");
880 pa_log_debug("Channel matrix:\n%s", t
= pa_strbuf_tostring_free(s
));
884 static pa_memchunk
* convert_to_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
890 pa_assert(input
->memblock
);
892 /* Convert the incoming sample into the work sample format and place them in buf1 */
894 if (!r
->to_work_format_func
|| !input
->length
)
897 n_samples
= (input
->length
/ r
->i_fz
) * r
->i_ss
.channels
;
900 r
->buf1
.length
= r
->w_sz
* n_samples
;
902 if (!r
->buf1
.memblock
|| r
->buf1_samples
< n_samples
) {
903 if (r
->buf1
.memblock
)
904 pa_memblock_unref(r
->buf1
.memblock
);
906 r
->buf1_samples
= n_samples
;
907 r
->buf1
.memblock
= pa_memblock_new(r
->mempool
, r
->buf1
.length
);
910 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
911 dst
= (uint8_t*) pa_memblock_acquire(r
->buf1
.memblock
);
913 r
->to_work_format_func(n_samples
, src
, dst
);
915 pa_memblock_release(input
->memblock
);
916 pa_memblock_release(r
->buf1
.memblock
);
921 static void vectoradd_s16_with_fraction(
922 int16_t *d
, int dstr
,
923 const int16_t *s1
, int sstr1
,
924 const int16_t *s2
, int sstr2
,
926 float s3
, float s4
) {
930 i3
= (int32_t) (s3
* 0x10000);
931 i4
= (int32_t) (s4
* 0x10000);
939 a
= (a
* i3
) / 0x10000;
940 b
= (b
* i4
) / 0x10000;
942 *d
= (int16_t) (a
+ b
);
944 s1
= (const int16_t*) ((const uint8_t*) s1
+ sstr1
);
945 s2
= (const int16_t*) ((const uint8_t*) s2
+ sstr2
);
946 d
= (int16_t*) ((uint8_t*) d
+ dstr
);
951 static pa_memchunk
*remap_channels(pa_resampler
*r
, pa_memchunk
*input
) {
952 unsigned in_n_samples
, out_n_samples
, n_frames
;
959 pa_assert(input
->memblock
);
961 /* Remap channels and place the result int buf2 */
963 if (!r
->map_required
|| !input
->length
)
966 in_n_samples
= input
->length
/ r
->w_sz
;
967 n_frames
= in_n_samples
/ r
->i_ss
.channels
;
968 out_n_samples
= n_frames
* r
->o_ss
.channels
;
971 r
->buf2
.length
= r
->w_sz
* out_n_samples
;
973 if (!r
->buf2
.memblock
|| r
->buf2_samples
< out_n_samples
) {
974 if (r
->buf2
.memblock
)
975 pa_memblock_unref(r
->buf2
.memblock
);
977 r
->buf2_samples
= out_n_samples
;
978 r
->buf2
.memblock
= pa_memblock_new(r
->mempool
, r
->buf2
.length
);
981 src
= ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
982 dst
= pa_memblock_acquire(r
->buf2
.memblock
);
984 memset(dst
, 0, r
->buf2
.length
);
986 o_skip
= r
->w_sz
* r
->o_ss
.channels
;
987 i_skip
= r
->w_sz
* r
->i_ss
.channels
;
989 switch (r
->work_format
) {
990 case PA_SAMPLE_FLOAT32NE
:
992 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
994 static const float one
= 1.0;
996 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
998 if (r
->map_table
[oc
][ic
] <= 0.0)
1002 (float*) dst
+ oc
, o_skip
,
1003 (float*) dst
+ oc
, o_skip
,
1004 (float*) src
+ ic
, i_skip
,
1006 &one
, &r
->map_table
[oc
][ic
]);
1012 case PA_SAMPLE_S16NE
:
1014 for (oc
= 0; oc
< r
->o_ss
.channels
; oc
++) {
1017 for (ic
= 0; ic
< r
->i_ss
.channels
; ic
++) {
1019 if (r
->map_table
[oc
][ic
] <= 0.0)
1022 if (r
->map_table
[oc
][ic
] >= 1.0) {
1023 static const int16_t one
= 1;
1026 (int16_t*) dst
+ oc
, o_skip
,
1027 (int16_t*) dst
+ oc
, o_skip
,
1028 (int16_t*) src
+ ic
, i_skip
,
1034 vectoradd_s16_with_fraction(
1035 (int16_t*) dst
+ oc
, o_skip
,
1036 (int16_t*) dst
+ oc
, o_skip
,
1037 (int16_t*) src
+ ic
, i_skip
,
1039 1.0, r
->map_table
[oc
][ic
]);
1046 pa_assert_not_reached();
1049 pa_memblock_release(input
->memblock
);
1050 pa_memblock_release(r
->buf2
.memblock
);
1052 r
->buf2
.length
= out_n_samples
* r
->w_sz
;
1057 static pa_memchunk
*resample(pa_resampler
*r
, pa_memchunk
*input
) {
1058 unsigned in_n_frames
, in_n_samples
;
1059 unsigned out_n_frames
, out_n_samples
;
1064 /* Resample the data and place the result in buf3 */
1066 if (!r
->impl_resample
|| !input
->length
)
1069 in_n_samples
= input
->length
/ r
->w_sz
;
1070 in_n_frames
= in_n_samples
/ r
->o_ss
.channels
;
1072 out_n_frames
= ((in_n_frames
*r
->o_ss
.rate
)/r
->i_ss
.rate
)+EXTRA_SAMPLES
;
1073 out_n_samples
= out_n_frames
* r
->o_ss
.channels
;
1076 r
->buf3
.length
= r
->w_sz
* out_n_samples
;
1078 if (!r
->buf3
.memblock
|| r
->buf3_samples
< out_n_samples
) {
1079 if (r
->buf3
.memblock
)
1080 pa_memblock_unref(r
->buf3
.memblock
);
1082 r
->buf3_samples
= out_n_samples
;
1083 r
->buf3
.memblock
= pa_memblock_new(r
->mempool
, r
->buf3
.length
);
1086 r
->impl_resample(r
, input
, in_n_frames
, &r
->buf3
, &out_n_frames
);
1087 r
->buf3
.length
= out_n_frames
* r
->w_sz
* r
->o_ss
.channels
;
1092 static pa_memchunk
*convert_from_work_format(pa_resampler
*r
, pa_memchunk
*input
) {
1093 unsigned n_samples
, n_frames
;
1099 /* Convert the data into the correct sample type and place the result in buf4 */
1101 if (!r
->from_work_format_func
|| !input
->length
)
1104 n_samples
= input
->length
/ r
->w_sz
;
1105 n_frames
= n_samples
/ r
->o_ss
.channels
;
1108 r
->buf4
.length
= r
->o_fz
* n_frames
;
1110 if (!r
->buf4
.memblock
|| r
->buf4_samples
< n_samples
) {
1111 if (r
->buf4
.memblock
)
1112 pa_memblock_unref(r
->buf4
.memblock
);
1114 r
->buf4_samples
= n_samples
;
1115 r
->buf4
.memblock
= pa_memblock_new(r
->mempool
, r
->buf4
.length
);
1118 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1119 dst
= pa_memblock_acquire(r
->buf4
.memblock
);
1120 r
->from_work_format_func(n_samples
, src
, dst
);
1121 pa_memblock_release(input
->memblock
);
1122 pa_memblock_release(r
->buf4
.memblock
);
1124 r
->buf4
.length
= r
->o_fz
* n_frames
;
1129 void pa_resampler_run(pa_resampler
*r
, const pa_memchunk
*in
, pa_memchunk
*out
) {
1135 pa_assert(in
->length
);
1136 pa_assert(in
->memblock
);
1137 pa_assert(in
->length
% r
->i_fz
== 0);
1139 buf
= (pa_memchunk
*) in
;
1140 buf
= convert_to_work_format(r
, buf
);
1141 buf
= remap_channels(r
, buf
);
1142 buf
= resample(r
, buf
);
1145 buf
= convert_from_work_format(r
, buf
);
1149 pa_memblock_ref(buf
->memblock
);
1151 pa_memchunk_reset(buf
);
1153 pa_memchunk_reset(out
);
1156 /*** libsamplerate based implementation ***/
1158 #ifdef HAVE_LIBSAMPLERATE
1159 static void libsamplerate_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1165 pa_assert(out_n_frames
);
1167 memset(&data
, 0, sizeof(data
));
1169 data
.data_in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1170 data
.input_frames
= in_n_frames
;
1172 data
.data_out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1173 data
.output_frames
= *out_n_frames
;
1175 data
.src_ratio
= (double) r
->o_ss
.rate
/ r
->i_ss
.rate
;
1176 data
.end_of_input
= 0;
1178 pa_assert_se(src_process(r
->src
.state
, &data
) == 0);
1179 pa_assert((unsigned) data
.input_frames_used
== in_n_frames
);
1181 pa_memblock_release(input
->memblock
);
1182 pa_memblock_release(output
->memblock
);
1184 *out_n_frames
= data
.output_frames_gen
;
1187 static void libsamplerate_update_rates(pa_resampler
*r
) {
1190 pa_assert_se(src_set_ratio(r
->src
.state
, (double) r
->o_ss
.rate
/ r
->i_ss
.rate
) == 0);
1193 static void libsamplerate_reset(pa_resampler
*r
) {
1196 pa_assert_se(src_reset(r
->src
.state
) == 0);
1199 static void libsamplerate_free(pa_resampler
*r
) {
1203 src_delete(r
->src
.state
);
1206 static int libsamplerate_init(pa_resampler
*r
) {
1211 if (!(r
->src
.state
= src_new(r
->method
, r
->o_ss
.channels
, &err
)))
1214 r
->impl_free
= libsamplerate_free
;
1215 r
->impl_update_rates
= libsamplerate_update_rates
;
1216 r
->impl_resample
= libsamplerate_resample
;
1217 r
->impl_reset
= libsamplerate_reset
;
1223 /*** speex based implementation ***/
1225 static void speex_resample_float(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1227 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1232 pa_assert(out_n_frames
);
1234 in
= (float*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1235 out
= (float*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1237 pa_assert_se(paspfl_resampler_process_interleaved_float(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1239 pa_memblock_release(input
->memblock
);
1240 pa_memblock_release(output
->memblock
);
1242 pa_assert(inf
== in_n_frames
);
1243 *out_n_frames
= outf
;
1246 static void speex_resample_int(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1248 uint32_t inf
= in_n_frames
, outf
= *out_n_frames
;
1253 pa_assert(out_n_frames
);
1255 in
= (int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
);
1256 out
= (int16_t*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
);
1258 pa_assert_se(paspfx_resampler_process_interleaved_int(r
->speex
.state
, in
, &inf
, out
, &outf
) == 0);
1260 pa_memblock_release(input
->memblock
);
1261 pa_memblock_release(output
->memblock
);
1263 pa_assert(inf
== in_n_frames
);
1264 *out_n_frames
= outf
;
1267 static void speex_update_rates(pa_resampler
*r
) {
1270 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
)
1271 pa_assert_se(paspfx_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1273 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1274 pa_assert_se(paspfl_resampler_set_rate(r
->speex
.state
, r
->i_ss
.rate
, r
->o_ss
.rate
) == 0);
1278 static void speex_reset(pa_resampler
*r
) {
1281 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
)
1282 pa_assert_se(paspfx_resampler_reset_mem(r
->speex
.state
) == 0);
1284 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1285 pa_assert_se(paspfl_resampler_reset_mem(r
->speex
.state
) == 0);
1289 static void speex_free(pa_resampler
*r
) {
1292 if (!r
->speex
.state
)
1295 if (r
->method
>= PA_RESAMPLER_SPEEX_FIXED_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FIXED_MAX
)
1296 paspfx_resampler_destroy(r
->speex
.state
);
1298 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1299 paspfl_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
) {
1313 q
= r
->method
- PA_RESAMPLER_SPEEX_FIXED_BASE
;
1315 pa_log_info("Choosing speex quality setting %i.", q
);
1317 if (!(r
->speex
.state
= paspfx_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1320 r
->impl_resample
= speex_resample_int
;
1322 pa_assert(r
->method
>= PA_RESAMPLER_SPEEX_FLOAT_BASE
&& r
->method
<= PA_RESAMPLER_SPEEX_FLOAT_MAX
);
1323 q
= r
->method
- PA_RESAMPLER_SPEEX_FLOAT_BASE
;
1325 pa_log_info("Choosing speex quality setting %i.", q
);
1327 if (!(r
->speex
.state
= paspfl_resampler_init(r
->o_ss
.channels
, r
->i_ss
.rate
, r
->o_ss
.rate
, q
, &err
)))
1330 r
->impl_resample
= speex_resample_float
;
1336 /* Trivial implementation */
1338 static void trivial_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1346 pa_assert(out_n_frames
);
1348 fz
= r
->w_sz
* r
->o_ss
.channels
;
1350 src
= (uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
;
1351 dst
= (uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
;
1353 for (o_index
= 0;; o_index
++, r
->trivial
.o_counter
++) {
1356 j
= ((r
->trivial
.o_counter
* r
->i_ss
.rate
) / r
->o_ss
.rate
);
1357 j
= j
> r
->trivial
.i_counter
? j
- r
->trivial
.i_counter
: 0;
1359 if (j
>= in_n_frames
)
1362 pa_assert(o_index
* fz
< pa_memblock_get_length(output
->memblock
));
1364 oil_memcpy((uint8_t*) dst
+ fz
* o_index
,
1365 (uint8_t*) src
+ fz
* j
, fz
);
1368 pa_memblock_release(input
->memblock
);
1369 pa_memblock_release(output
->memblock
);
1371 *out_n_frames
= o_index
;
1373 r
->trivial
.i_counter
+= in_n_frames
;
1375 /* Normalize counters */
1376 while (r
->trivial
.i_counter
>= r
->i_ss
.rate
) {
1377 pa_assert(r
->trivial
.o_counter
>= r
->o_ss
.rate
);
1379 r
->trivial
.i_counter
-= r
->i_ss
.rate
;
1380 r
->trivial
.o_counter
-= r
->o_ss
.rate
;
1384 static void trivial_update_rates_or_reset(pa_resampler
*r
) {
1387 r
->trivial
.i_counter
= 0;
1388 r
->trivial
.o_counter
= 0;
1391 static int trivial_init(pa_resampler
*r
) {
1394 r
->trivial
.o_counter
= r
->trivial
.i_counter
= 0;
1396 r
->impl_resample
= trivial_resample
;
1397 r
->impl_update_rates
= trivial_update_rates_or_reset
;
1398 r
->impl_reset
= trivial_update_rates_or_reset
;
1403 /*** ffmpeg based implementation ***/
1405 static void ffmpeg_resample(pa_resampler
*r
, const pa_memchunk
*input
, unsigned in_n_frames
, pa_memchunk
*output
, unsigned *out_n_frames
) {
1406 unsigned used_frames
= 0, c
;
1411 pa_assert(out_n_frames
);
1413 for (c
= 0; c
< r
->o_ss
.channels
; c
++) {
1416 int16_t *p
, *t
, *k
, *q
, *s
;
1417 int consumed_frames
;
1420 /* Allocate a new block */
1421 b
= pa_memblock_new(r
->mempool
, r
->ffmpeg
.buf
[c
].length
+ in_n_frames
* sizeof(int16_t));
1422 p
= pa_memblock_acquire(b
);
1424 /* Copy the remaining data into it */
1425 l
= r
->ffmpeg
.buf
[c
].length
;
1426 if (r
->ffmpeg
.buf
[c
].memblock
) {
1427 t
= (int16_t*) ((uint8_t*) pa_memblock_acquire(r
->ffmpeg
.buf
[c
].memblock
) + r
->ffmpeg
.buf
[c
].index
);
1429 pa_memblock_release(r
->ffmpeg
.buf
[c
].memblock
);
1430 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1431 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1434 /* Now append the new data, splitting up channels */
1435 t
= ((int16_t*) ((uint8_t*) pa_memblock_acquire(input
->memblock
) + input
->index
)) + c
;
1436 k
= (int16_t*) ((uint8_t*) p
+ l
);
1437 for (u
= 0; u
< in_n_frames
; u
++) {
1439 t
+= r
->o_ss
.channels
;
1442 pa_memblock_release(input
->memblock
);
1444 /* Calculate the resulting number of frames */
1445 in
= in_n_frames
+ l
/ sizeof(int16_t);
1447 /* Allocate buffer for the result */
1448 w
= pa_memblock_new(r
->mempool
, *out_n_frames
* sizeof(int16_t));
1449 q
= pa_memblock_acquire(w
);
1452 used_frames
= av_resample(r
->ffmpeg
.state
,
1456 c
>= (unsigned) r
->o_ss
.channels
-1);
1458 pa_memblock_release(b
);
1460 /* Now store the remaining samples away */
1461 pa_assert(consumed_frames
<= (int) in
);
1462 if (consumed_frames
< (int) in
) {
1463 r
->ffmpeg
.buf
[c
].memblock
= b
;
1464 r
->ffmpeg
.buf
[c
].index
= consumed_frames
* sizeof(int16_t);
1465 r
->ffmpeg
.buf
[c
].length
= (in
- consumed_frames
) * sizeof(int16_t);
1467 pa_memblock_unref(b
);
1469 /* And place the results in the output buffer */
1470 s
= (short*) ((uint8_t*) pa_memblock_acquire(output
->memblock
) + output
->index
) + c
;
1471 for (u
= 0; u
< used_frames
; u
++) {
1474 s
+= r
->o_ss
.channels
;
1476 pa_memblock_release(output
->memblock
);
1477 pa_memblock_release(w
);
1478 pa_memblock_unref(w
);
1481 *out_n_frames
= used_frames
;
1484 static void ffmpeg_free(pa_resampler
*r
) {
1489 if (r
->ffmpeg
.state
)
1490 av_resample_close(r
->ffmpeg
.state
);
1492 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1493 if (r
->ffmpeg
.buf
[c
].memblock
)
1494 pa_memblock_unref(r
->ffmpeg
.buf
[c
].memblock
);
1497 static int ffmpeg_init(pa_resampler
*r
) {
1502 /* We could probably implement different quality levels by
1503 * adjusting the filter parameters here. However, ffmpeg
1504 * internally only uses these hardcoded values, so let's use them
1505 * here for now as well until ffmpeg makes this configurable. */
1507 if (!(r
->ffmpeg
.state
= av_resample_init(r
->o_ss
.rate
, r
->i_ss
.rate
, 16, 10, 0, 0.8)))
1510 r
->impl_free
= ffmpeg_free
;
1511 r
->impl_resample
= ffmpeg_resample
;
1513 for (c
= 0; c
< PA_ELEMENTSOF(r
->ffmpeg
.buf
); c
++)
1514 pa_memchunk_reset(&r
->ffmpeg
.buf
[c
]);
1519 /*** copy (noop) implementation ***/
1521 static int copy_init(pa_resampler
*r
) {
1524 pa_assert(r
->o_ss
.rate
== r
->i_ss
.rate
);