Decouple OpusProjection* API from static matrices.

Change-Id: I3db285875b6b5548decc436be00096b97be1be3c
Signed-off-by: Jean-Marc Valin <jmvalin@jmvalin.ca>
This commit is contained in:
Andrew Allen 2017-12-05 15:34:43 -08:00 committed by Jean-Marc Valin
parent cae4445fb7
commit 058e8177cb
No known key found for this signature in database
GPG key ID: 5E5DD9A36F9189C8
3 changed files with 69 additions and 33 deletions

View file

@ -83,7 +83,7 @@ extern "C" {
/** Copies the demixing matrix to the supplied pointer location. /** Copies the demixing matrix to the supplied pointer location.
* @param[out] x <tt>unsigned char *</tt>: Returns the demixing matrix to the * @param[out] x <tt>unsigned char *</tt>: Returns the demixing matrix to the
* supplied pointer location. * supplied pointer location.
* @param y <tt>opus_in32</tt>: The size in bytes of the reserved memory at the * @param y <tt>opus_int32</tt>: The size in bytes of the reserved memory at the
* pointer location. * pointer location.
* @hideinitializer * @hideinitializer
*/ */

View file

@ -134,7 +134,7 @@ int opus_projection_decoder_init(OpusProjectionDecoder *st, opus_int32 Fs,
/* Verify supplied matrix size. */ /* Verify supplied matrix size. */
nb_input_streams = streams + coupled_streams; nb_input_streams = streams + coupled_streams;
expected_matrix_size = nb_input_streams * channels * sizeof(opus_int16); expected_matrix_size = nb_input_streams * channels * sizeof(opus_int16);
if (align(expected_matrix_size) != align(demixing_matrix_size)) if (expected_matrix_size != demixing_matrix_size)
{ {
RESTORE_STACK; RESTORE_STACK;
return OPUS_BAD_ARG; return OPUS_BAD_ARG;

View file

@ -138,26 +138,58 @@ opus_int32 opus_projection_ambisonics_encoder_get_size(int channels,
int nb_streams; int nb_streams;
int nb_coupled_streams; int nb_coupled_streams;
int order_plus_one; int order_plus_one;
int matrix_rows; int mixing_matrix_rows, mixing_matrix_cols;
opus_int32 matrix_size; int demixing_matrix_rows, demixing_matrix_cols;
opus_int32 mixing_matrix_size, demixing_matrix_size;
opus_int32 encoder_size; opus_int32 encoder_size;
int ret; int ret;
ret = get_streams_from_channels(channels, mapping_family, &nb_streams, ret = get_streams_from_channels(channels, mapping_family, &nb_streams,
&nb_coupled_streams, &order_plus_one); &nb_coupled_streams, &order_plus_one);
if (ret != OPUS_OK || order_plus_one < 2 || order_plus_one > 4) if (ret != OPUS_OK)
return 0; return 0;
matrix_rows = order_plus_one * order_plus_one + 2; if (order_plus_one == 2)
matrix_size = mapping_matrix_get_size(matrix_rows, matrix_rows); {
if (!matrix_size) mixing_matrix_rows = mapping_matrix_foa_mixing.rows;
mixing_matrix_cols = mapping_matrix_foa_mixing.cols;
demixing_matrix_rows = mapping_matrix_foa_demixing.rows;
demixing_matrix_cols = mapping_matrix_foa_demixing.cols;
}
else if (order_plus_one == 3)
{
mixing_matrix_rows = mapping_matrix_soa_mixing.rows;
mixing_matrix_cols = mapping_matrix_soa_mixing.cols;
demixing_matrix_rows = mapping_matrix_soa_demixing.rows;
demixing_matrix_cols = mapping_matrix_soa_demixing.cols;
}
else if (order_plus_one == 4)
{
mixing_matrix_rows = mapping_matrix_toa_mixing.rows;
mixing_matrix_cols = mapping_matrix_toa_mixing.cols;
demixing_matrix_rows = mapping_matrix_toa_demixing.rows;
demixing_matrix_cols = mapping_matrix_toa_demixing.cols;
}
else
return 0;
mixing_matrix_size =
mapping_matrix_get_size(mixing_matrix_rows, mixing_matrix_cols);
if (!mixing_matrix_size)
return 0;
demixing_matrix_size =
mapping_matrix_get_size(demixing_matrix_rows, demixing_matrix_cols);
if (!demixing_matrix_size)
return 0; return 0;
encoder_size = encoder_size =
opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
if (!encoder_size) if (!encoder_size)
return 0; return 0;
return align(sizeof(OpusProjectionEncoder)) + matrix_size + matrix_size + encoder_size;
return align(sizeof(OpusProjectionEncoder)) +
mixing_matrix_size + demixing_matrix_size + encoder_size;
} }
int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int32 Fs, int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int32 Fs,
@ -168,49 +200,47 @@ int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int3
MappingMatrix *mixing_matrix; MappingMatrix *mixing_matrix;
MappingMatrix *demixing_matrix; MappingMatrix *demixing_matrix;
OpusMSEncoder *ms_encoder; OpusMSEncoder *ms_encoder;
int nb_streams;
int nb_coupled_streams;
int i; int i;
int ret; int ret;
int order_plus_one;
unsigned char mapping[255]; unsigned char mapping[255];
if (get_streams_from_channels(channels, mapping_family,
&nb_streams, &nb_coupled_streams, NULL)
!= OPUS_OK)
return OPUS_BAD_ARG;
if (streams == NULL || coupled_streams == NULL) { if (streams == NULL || coupled_streams == NULL) {
return OPUS_BAD_ARG; return OPUS_BAD_ARG;
} }
*streams = nb_streams;
*coupled_streams = nb_coupled_streams; if (get_streams_from_channels(channels, mapping_family, streams,
coupled_streams, &order_plus_one) != OPUS_OK)
return OPUS_BAD_ARG;
if (mapping_family == 253) if (mapping_family == 253)
{ {
int order_plus_one;
if (get_order_plus_one_from_channels(channels, &order_plus_one) != OPUS_OK)
return OPUS_BAD_ARG;
/* Assign mixing matrix based on available pre-computed matrices. */ /* Assign mixing matrix based on available pre-computed matrices. */
mixing_matrix = get_mixing_matrix(st); mixing_matrix = get_mixing_matrix(st);
if (order_plus_one == 2) if (order_plus_one == 2)
{ {
mapping_matrix_init(mixing_matrix, mapping_matrix_foa_mixing.rows, mapping_matrix_init(mixing_matrix, mapping_matrix_foa_mixing.rows,
mapping_matrix_foa_mixing.cols, mapping_matrix_foa_mixing.gain, mapping_matrix_foa_mixing.cols, mapping_matrix_foa_mixing.gain,
mapping_matrix_foa_mixing_data, 36 * sizeof(opus_int16)); mapping_matrix_foa_mixing_data,
sizeof(mapping_matrix_foa_mixing_data));
} }
else if (order_plus_one == 3) else if (order_plus_one == 3)
{ {
mapping_matrix_init(mixing_matrix, mapping_matrix_soa_mixing.rows, mapping_matrix_init(mixing_matrix, mapping_matrix_soa_mixing.rows,
mapping_matrix_soa_mixing.cols, mapping_matrix_soa_mixing.gain, mapping_matrix_soa_mixing.cols, mapping_matrix_soa_mixing.gain,
mapping_matrix_soa_mixing_data, 121 * sizeof(opus_int16)); mapping_matrix_soa_mixing_data,
sizeof(mapping_matrix_soa_mixing_data));
} }
else if (order_plus_one == 4) else if (order_plus_one == 4)
{ {
mapping_matrix_init(mixing_matrix, mapping_matrix_toa_mixing.rows, mapping_matrix_init(mixing_matrix, mapping_matrix_toa_mixing.rows,
mapping_matrix_toa_mixing.cols, mapping_matrix_toa_mixing.gain, mapping_matrix_toa_mixing.cols, mapping_matrix_toa_mixing.gain,
mapping_matrix_toa_mixing_data, 324 * sizeof(opus_int16)); mapping_matrix_toa_mixing_data,
sizeof(mapping_matrix_toa_mixing_data));
} }
else
return OPUS_BAD_ARG;
st->mixing_matrix_size_in_bytes = mapping_matrix_get_size( st->mixing_matrix_size_in_bytes = mapping_matrix_get_size(
mixing_matrix->rows, mixing_matrix->cols); mixing_matrix->rows, mixing_matrix->cols);
if (!st->mixing_matrix_size_in_bytes) if (!st->mixing_matrix_size_in_bytes)
@ -222,20 +252,26 @@ int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int3
{ {
mapping_matrix_init(demixing_matrix, mapping_matrix_foa_demixing.rows, mapping_matrix_init(demixing_matrix, mapping_matrix_foa_demixing.rows,
mapping_matrix_foa_demixing.cols, mapping_matrix_foa_demixing.gain, mapping_matrix_foa_demixing.cols, mapping_matrix_foa_demixing.gain,
mapping_matrix_foa_demixing_data, 36 * sizeof(opus_int16)); mapping_matrix_foa_demixing_data,
sizeof(mapping_matrix_foa_demixing_data));
} }
else if (order_plus_one == 3) else if (order_plus_one == 3)
{ {
mapping_matrix_init(demixing_matrix, mapping_matrix_soa_demixing.rows, mapping_matrix_init(demixing_matrix, mapping_matrix_soa_demixing.rows,
mapping_matrix_soa_demixing.cols, mapping_matrix_soa_demixing.gain, mapping_matrix_soa_demixing.cols, mapping_matrix_soa_demixing.gain,
mapping_matrix_soa_demixing_data, 121 * sizeof(opus_int16)); mapping_matrix_soa_demixing_data,
sizeof(mapping_matrix_soa_demixing_data));
} }
else if (order_plus_one == 4) else if (order_plus_one == 4)
{ {
mapping_matrix_init(demixing_matrix, mapping_matrix_toa_demixing.rows, mapping_matrix_init(demixing_matrix, mapping_matrix_toa_demixing.rows,
mapping_matrix_toa_demixing.cols, mapping_matrix_toa_demixing.gain, mapping_matrix_toa_demixing.cols, mapping_matrix_toa_demixing.gain,
mapping_matrix_toa_demixing_data, 324 * sizeof(opus_int16)); mapping_matrix_toa_demixing_data,
sizeof(mapping_matrix_toa_demixing_data));
} }
else
return OPUS_BAD_ARG;
st->demixing_matrix_size_in_bytes = mapping_matrix_get_size( st->demixing_matrix_size_in_bytes = mapping_matrix_get_size(
demixing_matrix->rows, demixing_matrix->cols); demixing_matrix->rows, demixing_matrix->cols);
if (!st->demixing_matrix_size_in_bytes) if (!st->demixing_matrix_size_in_bytes)
@ -245,10 +281,10 @@ int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int3
return OPUS_UNIMPLEMENTED; return OPUS_UNIMPLEMENTED;
/* Ensure matrices are large enough for desired coding scheme. */ /* Ensure matrices are large enough for desired coding scheme. */
if (nb_streams + nb_coupled_streams > mixing_matrix->rows || if (*streams + *coupled_streams > mixing_matrix->rows ||
channels > mixing_matrix->cols || channels > mixing_matrix->cols ||
channels > demixing_matrix->rows || channels > demixing_matrix->rows ||
nb_streams + nb_coupled_streams > demixing_matrix->cols) *streams + *coupled_streams > demixing_matrix->cols)
return OPUS_BAD_ARG; return OPUS_BAD_ARG;
/* Set trivial mapping so each input channel pairs with a matrix column. */ /* Set trivial mapping so each input channel pairs with a matrix column. */
@ -257,8 +293,8 @@ int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int3
/* Initialize multistream encoder with provided settings. */ /* Initialize multistream encoder with provided settings. */
ms_encoder = get_multistream_encoder(st); ms_encoder = get_multistream_encoder(st);
ret = opus_multistream_encoder_init(ms_encoder, Fs, channels, nb_streams, ret = opus_multistream_encoder_init(ms_encoder, Fs, channels, *streams,
nb_coupled_streams, mapping, application); *coupled_streams, mapping, application);
return ret; return ret;
} }
@ -385,7 +421,7 @@ int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...)
nb_output_streams = ms_encoder->layout.nb_channels; nb_output_streams = ms_encoder->layout.nb_channels;
external_char = va_arg(ap, unsigned char *); external_char = va_arg(ap, unsigned char *);
external_size = va_arg(ap, opus_uint32); external_size = va_arg(ap, opus_int32);
if (!external_char) if (!external_char)
{ {
goto bad_arg; goto bad_arg;