mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-16 18:05:46 -04:00
dep/cubeb: Update to dc511c6
This commit is contained in:
@ -9,6 +9,9 @@
|
||||
|
||||
#define NOMINMAX
|
||||
|
||||
#include "cubeb_mixer.h"
|
||||
#include "cubeb-internal.h"
|
||||
#include "cubeb_utils.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
@ -16,67 +19,67 @@
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include "cubeb-internal.h"
|
||||
#include "cubeb_mixer.h"
|
||||
#include "cubeb_utils.h"
|
||||
|
||||
#ifndef FF_ARRAY_ELEMS
|
||||
#define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
|
||||
#endif
|
||||
|
||||
#define CHANNELS_MAX 32
|
||||
#define FRONT_LEFT 0
|
||||
#define FRONT_RIGHT 1
|
||||
#define FRONT_CENTER 2
|
||||
#define LOW_FREQUENCY 3
|
||||
#define BACK_LEFT 4
|
||||
#define BACK_RIGHT 5
|
||||
#define FRONT_LEFT_OF_CENTER 6
|
||||
#define FRONT_RIGHT_OF_CENTER 7
|
||||
#define BACK_CENTER 8
|
||||
#define SIDE_LEFT 9
|
||||
#define SIDE_RIGHT 10
|
||||
#define TOP_CENTER 11
|
||||
#define TOP_FRONT_LEFT 12
|
||||
#define TOP_FRONT_CENTER 13
|
||||
#define TOP_FRONT_RIGHT 14
|
||||
#define TOP_BACK_LEFT 15
|
||||
#define TOP_BACK_CENTER 16
|
||||
#define TOP_BACK_RIGHT 17
|
||||
#define NUM_NAMED_CHANNELS 18
|
||||
#define FRONT_LEFT 0
|
||||
#define FRONT_RIGHT 1
|
||||
#define FRONT_CENTER 2
|
||||
#define LOW_FREQUENCY 3
|
||||
#define BACK_LEFT 4
|
||||
#define BACK_RIGHT 5
|
||||
#define FRONT_LEFT_OF_CENTER 6
|
||||
#define FRONT_RIGHT_OF_CENTER 7
|
||||
#define BACK_CENTER 8
|
||||
#define SIDE_LEFT 9
|
||||
#define SIDE_RIGHT 10
|
||||
#define TOP_CENTER 11
|
||||
#define TOP_FRONT_LEFT 12
|
||||
#define TOP_FRONT_CENTER 13
|
||||
#define TOP_FRONT_RIGHT 14
|
||||
#define TOP_BACK_LEFT 15
|
||||
#define TOP_BACK_CENTER 16
|
||||
#define TOP_BACK_RIGHT 17
|
||||
#define NUM_NAMED_CHANNELS 18
|
||||
|
||||
#ifndef M_SQRT1_2
|
||||
#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
|
||||
#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */
|
||||
#endif
|
||||
#ifndef M_SQRT2
|
||||
#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
|
||||
#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */
|
||||
#endif
|
||||
#define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */
|
||||
#define SQRT3_2 1.22474487139158904909 /* sqrt(3/2) */
|
||||
|
||||
#define C30DB M_SQRT2
|
||||
#define C15DB 1.189207115
|
||||
#define C__0DB 1.0
|
||||
#define C_15DB 0.840896415
|
||||
#define C_30DB M_SQRT1_2
|
||||
#define C_45DB 0.594603558
|
||||
#define C_60DB 0.5
|
||||
#define C30DB M_SQRT2
|
||||
#define C15DB 1.189207115
|
||||
#define C__0DB 1.0
|
||||
#define C_15DB 0.840896415
|
||||
#define C_30DB M_SQRT1_2
|
||||
#define C_45DB 0.594603558
|
||||
#define C_60DB 0.5
|
||||
|
||||
static cubeb_channel_layout
|
||||
cubeb_channel_layout_check(cubeb_channel_layout l, uint32_t c)
|
||||
{
|
||||
if (l == CUBEB_LAYOUT_UNDEFINED) {
|
||||
switch (c) {
|
||||
case 1: return CUBEB_LAYOUT_MONO;
|
||||
case 2: return CUBEB_LAYOUT_STEREO;
|
||||
}
|
||||
if (l == CUBEB_LAYOUT_UNDEFINED) {
|
||||
switch (c) {
|
||||
case 1:
|
||||
return CUBEB_LAYOUT_MONO;
|
||||
case 2:
|
||||
return CUBEB_LAYOUT_STEREO;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
unsigned int cubeb_channel_layout_nb_channels(cubeb_channel_layout x)
|
||||
unsigned int
|
||||
cubeb_channel_layout_nb_channels(cubeb_channel_layout x)
|
||||
{
|
||||
#if __GNUC__ || __clang__
|
||||
return __builtin_popcount (x);
|
||||
return __builtin_popcount(x);
|
||||
#else
|
||||
x -= (x >> 1) & 0x55555555;
|
||||
x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
|
||||
@ -87,16 +90,12 @@ unsigned int cubeb_channel_layout_nb_channels(cubeb_channel_layout x)
|
||||
}
|
||||
|
||||
struct MixerContext {
|
||||
MixerContext(cubeb_sample_format f,
|
||||
uint32_t in_channels,
|
||||
cubeb_channel_layout in,
|
||||
uint32_t out_channels,
|
||||
MixerContext(cubeb_sample_format f, uint32_t in_channels,
|
||||
cubeb_channel_layout in, uint32_t out_channels,
|
||||
cubeb_channel_layout out)
|
||||
: _format(f)
|
||||
, _in_ch_layout(cubeb_channel_layout_check(in, in_channels))
|
||||
, _out_ch_layout(cubeb_channel_layout_check(out, out_channels))
|
||||
, _in_ch_count(in_channels)
|
||||
, _out_ch_count(out_channels)
|
||||
: _format(f), _in_ch_layout(cubeb_channel_layout_check(in, in_channels)),
|
||||
_out_ch_layout(cubeb_channel_layout_check(out, out_channels)),
|
||||
_in_ch_count(in_channels), _out_ch_count(out_channels)
|
||||
{
|
||||
if (in_channels != cubeb_channel_layout_nb_channels(in) ||
|
||||
out_channels != cubeb_channel_layout_nb_channels(out)) {
|
||||
@ -159,24 +158,30 @@ struct MixerContext {
|
||||
int init();
|
||||
|
||||
const cubeb_sample_format _format;
|
||||
const cubeb_channel_layout _in_ch_layout; ///< input channel layout
|
||||
const cubeb_channel_layout _out_ch_layout; ///< output channel layout
|
||||
const uint32_t _in_ch_count; ///< input channel count
|
||||
const uint32_t _out_ch_count; ///< output channel count
|
||||
const float _surround_mix_level = C_30DB; ///< surround mixing level
|
||||
const float _center_mix_level = C_30DB; ///< center mixing level
|
||||
const float _lfe_mix_level = 1; ///< LFE mixing level
|
||||
double _matrix[CHANNELS_MAX][CHANNELS_MAX] = {{ 0 }}; ///< floating point rematrixing coefficients
|
||||
float _matrix_flt[CHANNELS_MAX][CHANNELS_MAX] = {{ 0 }}; ///< single precision floating point rematrixing coefficients
|
||||
int32_t _matrix32[CHANNELS_MAX][CHANNELS_MAX] = {{ 0 }}; ///< 17.15 fixed point rematrixing coefficients
|
||||
uint8_t _matrix_ch[CHANNELS_MAX][CHANNELS_MAX+1] = {{ 0 }}; ///< Lists of input channels per output channel that have non zero rematrixing coefficients
|
||||
bool _clipping = false; ///< Set to true if clipping detection is required
|
||||
bool _valid = false; ///< Set to true if context is valid.
|
||||
const cubeb_channel_layout _in_ch_layout; ///< input channel layout
|
||||
const cubeb_channel_layout _out_ch_layout; ///< output channel layout
|
||||
const uint32_t _in_ch_count; ///< input channel count
|
||||
const uint32_t _out_ch_count; ///< output channel count
|
||||
const float _surround_mix_level = C_30DB; ///< surround mixing level
|
||||
const float _center_mix_level = C_30DB; ///< center mixing level
|
||||
const float _lfe_mix_level = 1; ///< LFE mixing level
|
||||
double _matrix[CHANNELS_MAX][CHANNELS_MAX] = {
|
||||
{0}}; ///< floating point rematrixing coefficients
|
||||
float _matrix_flt[CHANNELS_MAX][CHANNELS_MAX] = {
|
||||
{0}}; ///< single precision floating point rematrixing coefficients
|
||||
int32_t _matrix32[CHANNELS_MAX][CHANNELS_MAX] = {
|
||||
{0}}; ///< 17.15 fixed point rematrixing coefficients
|
||||
uint8_t _matrix_ch[CHANNELS_MAX][CHANNELS_MAX + 1] = {
|
||||
{0}}; ///< Lists of input channels per output channel that have non zero
|
||||
///< rematrixing coefficients
|
||||
bool _clipping = false; ///< Set to true if clipping detection is required
|
||||
bool _valid = false; ///< Set to true if context is valid.
|
||||
};
|
||||
|
||||
int MixerContext::auto_matrix()
|
||||
int
|
||||
MixerContext::auto_matrix()
|
||||
{
|
||||
double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS] = { { 0 } };
|
||||
double matrix[NUM_NAMED_CHANNELS][NUM_NAMED_CHANNELS] = {{0}};
|
||||
double maxcoef = 0;
|
||||
float maxval;
|
||||
|
||||
@ -239,8 +244,7 @@ int MixerContext::auto_matrix()
|
||||
matrix[FRONT_LEFT][BACK_CENTER] += _surround_mix_level * M_SQRT1_2;
|
||||
matrix[FRONT_RIGHT][BACK_CENTER] += _surround_mix_level * M_SQRT1_2;
|
||||
} else if (out_ch_layout & CHANNEL_FRONT_CENTER) {
|
||||
matrix[FRONT_CENTER][BACK_CENTER] +=
|
||||
_surround_mix_level * M_SQRT1_2;
|
||||
matrix[FRONT_CENTER][BACK_CENTER] += _surround_mix_level * M_SQRT1_2;
|
||||
}
|
||||
}
|
||||
if (unaccounted & CHANNEL_BACK_LEFT) {
|
||||
@ -321,7 +325,7 @@ int MixerContext::auto_matrix()
|
||||
_matrix[out_i][in_i] = matrix[i][j];
|
||||
} else {
|
||||
_matrix[out_i][in_i] =
|
||||
i == j && (in_ch_layout & out_ch_layout & (1U << i));
|
||||
i == j && (in_ch_layout & out_ch_layout & (1U << i));
|
||||
}
|
||||
sum += fabs(_matrix[out_i][in_i]);
|
||||
in_i++;
|
||||
@ -356,7 +360,8 @@ int MixerContext::auto_matrix()
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MixerContext::init()
|
||||
int
|
||||
MixerContext::init()
|
||||
{
|
||||
int r = auto_matrix();
|
||||
if (r) {
|
||||
@ -398,22 +403,15 @@ int MixerContext::init()
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename TYPE_SAMPLE, typename TYPE_COEFF, typename F>
|
||||
template <typename TYPE_SAMPLE, typename TYPE_COEFF, typename F>
|
||||
void
|
||||
sum2(TYPE_SAMPLE * out,
|
||||
uint32_t stride_out,
|
||||
const TYPE_SAMPLE * in1,
|
||||
const TYPE_SAMPLE * in2,
|
||||
uint32_t stride_in,
|
||||
TYPE_COEFF coeff1,
|
||||
TYPE_COEFF coeff2,
|
||||
F&& operand,
|
||||
uint32_t frames)
|
||||
sum2(TYPE_SAMPLE * out, uint32_t stride_out, const TYPE_SAMPLE * in1,
|
||||
const TYPE_SAMPLE * in2, uint32_t stride_in, TYPE_COEFF coeff1,
|
||||
TYPE_COEFF coeff2, F && operand, uint32_t frames)
|
||||
{
|
||||
static_assert(
|
||||
std::is_same<TYPE_COEFF,
|
||||
typename std::result_of<F(TYPE_COEFF)>::type>::value,
|
||||
"function must return the same type as used by matrix_coeff");
|
||||
std::is_same<TYPE_COEFF, decltype(operand(coeff1))>::value,
|
||||
"function must return the same type as used by coeff1 and coeff2");
|
||||
for (uint32_t i = 0; i < frames; i++) {
|
||||
*out = operand(coeff1 * *in1 + coeff2 * *in2);
|
||||
out += stride_out;
|
||||
@ -422,20 +420,13 @@ sum2(TYPE_SAMPLE * out,
|
||||
}
|
||||
}
|
||||
|
||||
template<typename TYPE_SAMPLE, typename TYPE_COEFF, typename F>
|
||||
template <typename TYPE_SAMPLE, typename TYPE_COEFF, typename F>
|
||||
void
|
||||
copy(TYPE_SAMPLE * out,
|
||||
uint32_t stride_out,
|
||||
const TYPE_SAMPLE * in,
|
||||
uint32_t stride_in,
|
||||
TYPE_COEFF coeff,
|
||||
F&& operand,
|
||||
uint32_t frames)
|
||||
copy(TYPE_SAMPLE * out, uint32_t stride_out, const TYPE_SAMPLE * in,
|
||||
uint32_t stride_in, TYPE_COEFF coeff, F && operand, uint32_t frames)
|
||||
{
|
||||
static_assert(
|
||||
std::is_same<TYPE_COEFF,
|
||||
typename std::result_of<F(TYPE_COEFF)>::type>::value,
|
||||
"function must return the same type as used by matrix_coeff");
|
||||
static_assert(std::is_same<TYPE_COEFF, decltype(operand(coeff))>::value,
|
||||
"function must return the same type as used by coeff");
|
||||
for (uint32_t i = 0; i < frames; i++) {
|
||||
*out = operand(coeff * *in);
|
||||
out += stride_out;
|
||||
@ -444,74 +435,58 @@ copy(TYPE_SAMPLE * out,
|
||||
}
|
||||
|
||||
template <typename TYPE, typename TYPE_COEFF, size_t COLS, typename F>
|
||||
static int rematrix(const MixerContext * s, TYPE * aOut, const TYPE * aIn,
|
||||
const TYPE_COEFF (&matrix_coeff)[COLS][COLS],
|
||||
F&& aF, uint32_t frames)
|
||||
static int
|
||||
rematrix(const MixerContext * s, TYPE * aOut, const TYPE * aIn,
|
||||
const TYPE_COEFF (&matrix_coeff)[COLS][COLS], F && aF, uint32_t frames)
|
||||
{
|
||||
static_assert(
|
||||
std::is_same<TYPE_COEFF,
|
||||
typename std::result_of<F(TYPE_COEFF)>::type>::value,
|
||||
"function must return the same type as used by matrix_coeff");
|
||||
std::is_same<TYPE_COEFF, decltype(aF(matrix_coeff[0][0]))>::value,
|
||||
"function must return the same type as used by matrix_coeff");
|
||||
|
||||
for (uint32_t out_i = 0; out_i < s->_out_ch_count; out_i++) {
|
||||
TYPE* out = aOut + out_i;
|
||||
TYPE * out = aOut + out_i;
|
||||
switch (s->_matrix_ch[out_i][0]) {
|
||||
case 0:
|
||||
for (uint32_t i = 0; i < frames; i++) {
|
||||
out[i * s->_out_ch_count] = 0;
|
||||
case 0:
|
||||
for (uint32_t i = 0; i < frames; i++) {
|
||||
out[i * s->_out_ch_count] = 0;
|
||||
}
|
||||
break;
|
||||
case 1: {
|
||||
int in_i = s->_matrix_ch[out_i][1];
|
||||
copy(out, s->_out_ch_count, aIn + in_i, s->_in_ch_count,
|
||||
matrix_coeff[out_i][in_i], aF, frames);
|
||||
} break;
|
||||
case 2:
|
||||
sum2(out, s->_out_ch_count, aIn + s->_matrix_ch[out_i][1],
|
||||
aIn + s->_matrix_ch[out_i][2], s->_in_ch_count,
|
||||
matrix_coeff[out_i][s->_matrix_ch[out_i][1]],
|
||||
matrix_coeff[out_i][s->_matrix_ch[out_i][2]], aF, frames);
|
||||
break;
|
||||
default:
|
||||
for (uint32_t i = 0; i < frames; i++) {
|
||||
TYPE_COEFF v = 0;
|
||||
for (uint32_t j = 0; j < s->_matrix_ch[out_i][0]; j++) {
|
||||
uint32_t in_i = s->_matrix_ch[out_i][1 + j];
|
||||
v += *(aIn + in_i + i * s->_in_ch_count) * matrix_coeff[out_i][in_i];
|
||||
}
|
||||
break;
|
||||
case 1: {
|
||||
int in_i = s->_matrix_ch[out_i][1];
|
||||
copy(out,
|
||||
s->_out_ch_count,
|
||||
aIn + in_i,
|
||||
s->_in_ch_count,
|
||||
matrix_coeff[out_i][in_i],
|
||||
aF,
|
||||
frames);
|
||||
} break;
|
||||
case 2:
|
||||
sum2(out,
|
||||
s->_out_ch_count,
|
||||
aIn + s->_matrix_ch[out_i][1],
|
||||
aIn + s->_matrix_ch[out_i][2],
|
||||
s->_in_ch_count,
|
||||
matrix_coeff[out_i][s->_matrix_ch[out_i][1]],
|
||||
matrix_coeff[out_i][s->_matrix_ch[out_i][2]],
|
||||
aF,
|
||||
frames);
|
||||
break;
|
||||
default:
|
||||
for (uint32_t i = 0; i < frames; i++) {
|
||||
TYPE_COEFF v = 0;
|
||||
for (uint32_t j = 0; j < s->_matrix_ch[out_i][0]; j++) {
|
||||
uint32_t in_i = s->_matrix_ch[out_i][1 + j];
|
||||
v +=
|
||||
*(aIn + in_i + i * s->_in_ch_count) * matrix_coeff[out_i][in_i];
|
||||
}
|
||||
out[i * s->_out_ch_count] = aF(v);
|
||||
}
|
||||
break;
|
||||
out[i * s->_out_ch_count] = aF(v);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct cubeb_mixer
|
||||
{
|
||||
cubeb_mixer(cubeb_sample_format format,
|
||||
uint32_t in_channels,
|
||||
cubeb_channel_layout in_layout,
|
||||
uint32_t out_channels,
|
||||
struct cubeb_mixer {
|
||||
cubeb_mixer(cubeb_sample_format format, uint32_t in_channels,
|
||||
cubeb_channel_layout in_layout, uint32_t out_channels,
|
||||
cubeb_channel_layout out_layout)
|
||||
: _context(format, in_channels, in_layout, out_channels, out_layout)
|
||||
: _context(format, in_channels, in_layout, out_channels, out_layout)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void copy_and_trunc(size_t frames,
|
||||
const T * input_buffer,
|
||||
template <typename T>
|
||||
void copy_and_trunc(size_t frames, const T * input_buffer,
|
||||
T * output_buffer) const
|
||||
{
|
||||
if (_context._in_ch_count <= _context._out_ch_count) {
|
||||
@ -545,11 +520,8 @@ struct cubeb_mixer
|
||||
}
|
||||
}
|
||||
|
||||
int mix(size_t frames,
|
||||
const void * input_buffer,
|
||||
size_t input_buffer_size,
|
||||
void * output_buffer,
|
||||
size_t output_buffer_size) const
|
||||
int mix(size_t frames, const void * input_buffer, size_t input_buffer_size,
|
||||
void * output_buffer, size_t output_buffer_size) const
|
||||
{
|
||||
if (frames <= 0 || _context._out_ch_count == 0) {
|
||||
return 0;
|
||||
@ -557,7 +529,7 @@ struct cubeb_mixer
|
||||
|
||||
// Check if output buffer is of sufficient size.
|
||||
size_t size_read_needed =
|
||||
frames * _context._in_ch_count * cubeb_sample_size(_context._format);
|
||||
frames * _context._in_ch_count * cubeb_sample_size(_context._format);
|
||||
if (input_buffer_size < size_read_needed) {
|
||||
// We don't have enough data to read!
|
||||
return -1;
|
||||
@ -571,58 +543,46 @@ struct cubeb_mixer
|
||||
// The channel layouts were invalid or unsupported, instead we will simply
|
||||
// either drop the extra channels, or fill with silence the missing ones
|
||||
if (_context._format == CUBEB_SAMPLE_FLOAT32NE) {
|
||||
copy_and_trunc(frames,
|
||||
static_cast<const float*>(input_buffer),
|
||||
static_cast<float*>(output_buffer));
|
||||
copy_and_trunc(frames, static_cast<const float *>(input_buffer),
|
||||
static_cast<float *>(output_buffer));
|
||||
} else {
|
||||
assert(_context._format == CUBEB_SAMPLE_S16NE);
|
||||
copy_and_trunc(frames,
|
||||
static_cast<const int16_t*>(input_buffer),
|
||||
reinterpret_cast<int16_t*>(output_buffer));
|
||||
copy_and_trunc(frames, static_cast<const int16_t *>(input_buffer),
|
||||
reinterpret_cast<int16_t *>(output_buffer));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (_context._format)
|
||||
{
|
||||
case CUBEB_SAMPLE_FLOAT32NE: {
|
||||
auto f = [](float x) { return x; };
|
||||
return rematrix(&_context,
|
||||
static_cast<float*>(output_buffer),
|
||||
static_cast<const float*>(input_buffer),
|
||||
_context._matrix_flt,
|
||||
f,
|
||||
frames);
|
||||
switch (_context._format) {
|
||||
case CUBEB_SAMPLE_FLOAT32NE: {
|
||||
auto f = [](float x) { return x; };
|
||||
return rematrix(&_context, static_cast<float *>(output_buffer),
|
||||
static_cast<const float *>(input_buffer),
|
||||
_context._matrix_flt, f, frames);
|
||||
}
|
||||
case CUBEB_SAMPLE_S16NE:
|
||||
if (_context._clipping) {
|
||||
auto f = [](int x) {
|
||||
int y = (x + 16384) >> 15;
|
||||
// clip the signed integer value into the -32768,32767 range.
|
||||
if ((y + 0x8000U) & ~0xFFFF) {
|
||||
return (y >> 31) ^ 0x7FFF;
|
||||
}
|
||||
return y;
|
||||
};
|
||||
return rematrix(&_context, static_cast<int16_t *>(output_buffer),
|
||||
static_cast<const int16_t *>(input_buffer),
|
||||
_context._matrix32, f, frames);
|
||||
} else {
|
||||
auto f = [](int x) { return (x + 16384) >> 15; };
|
||||
return rematrix(&_context, static_cast<int16_t *>(output_buffer),
|
||||
static_cast<const int16_t *>(input_buffer),
|
||||
_context._matrix32, f, frames);
|
||||
}
|
||||
case CUBEB_SAMPLE_S16NE:
|
||||
if (_context._clipping) {
|
||||
auto f = [](int x) {
|
||||
int y = (x + 16384) >> 15;
|
||||
// clip the signed integer value into the -32768,32767 range.
|
||||
if ((y + 0x8000U) & ~0xFFFF) {
|
||||
return (y >> 31) ^ 0x7FFF;
|
||||
}
|
||||
return y;
|
||||
};
|
||||
return rematrix(&_context,
|
||||
static_cast<int16_t*>(output_buffer),
|
||||
static_cast<const int16_t*>(input_buffer),
|
||||
_context._matrix32,
|
||||
f,
|
||||
frames);
|
||||
} else {
|
||||
auto f = [](int x) { return (x + 16384) >> 15; };
|
||||
return rematrix(&_context,
|
||||
static_cast<int16_t*>(output_buffer),
|
||||
static_cast<const int16_t*>(input_buffer),
|
||||
_context._matrix32,
|
||||
f,
|
||||
frames);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
@ -636,28 +596,26 @@ struct cubeb_mixer
|
||||
MixerContext _context;
|
||||
};
|
||||
|
||||
cubeb_mixer* cubeb_mixer_create(cubeb_sample_format format,
|
||||
uint32_t in_channels,
|
||||
cubeb_channel_layout in_layout,
|
||||
uint32_t out_channels,
|
||||
cubeb_channel_layout out_layout)
|
||||
cubeb_mixer *
|
||||
cubeb_mixer_create(cubeb_sample_format format, uint32_t in_channels,
|
||||
cubeb_channel_layout in_layout, uint32_t out_channels,
|
||||
cubeb_channel_layout out_layout)
|
||||
{
|
||||
return new cubeb_mixer(
|
||||
format, in_channels, in_layout, out_channels, out_layout);
|
||||
return new cubeb_mixer(format, in_channels, in_layout, out_channels,
|
||||
out_layout);
|
||||
}
|
||||
|
||||
void cubeb_mixer_destroy(cubeb_mixer * mixer)
|
||||
void
|
||||
cubeb_mixer_destroy(cubeb_mixer * mixer)
|
||||
{
|
||||
delete mixer;
|
||||
}
|
||||
|
||||
int cubeb_mixer_mix(cubeb_mixer * mixer,
|
||||
size_t frames,
|
||||
const void * input_buffer,
|
||||
size_t input_buffer_size,
|
||||
void * output_buffer,
|
||||
size_t output_buffer_size)
|
||||
int
|
||||
cubeb_mixer_mix(cubeb_mixer * mixer, size_t frames, const void * input_buffer,
|
||||
size_t input_buffer_size, void * output_buffer,
|
||||
size_t output_buffer_size)
|
||||
{
|
||||
return mixer->mix(
|
||||
frames, input_buffer, input_buffer_size, output_buffer, output_buffer_size);
|
||||
return mixer->mix(frames, input_buffer, input_buffer_size, output_buffer,
|
||||
output_buffer_size);
|
||||
}
|
||||
|
Reference in New Issue
Block a user