diff options
author | Bernhard Miller <bernhard.miller@streamunlimited.com> | 2015-03-30 11:24:46 +0200 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2015-04-01 07:31:37 -0700 |
commit | b2db18cda2e4e7951655cb2a34108a8523b6eca9 (patch) | |
tree | d864d4fdbbf3c75036ff1ad1b0ecbbfc0f51ac86 /gst | |
parent | 84638199e7cb4c7b3169d6ef120bde045e32a242 (diff) |
audioconvert: avoid float calculations when mixing integer-formatted channels
The patch calculates a second channel mixing matrix from the current one. The
matrix contains the original values * (2^10) as integers. This matrix is used
when integer-formatted channels are mixed.
On a ARM Cortex-A8, single core, 800MHz this improves performance in a
testcase from 29s to 9s for downmixing 6 channels to stereo.
https://bugzilla.gnome.org/show_bug.cgi?id=747005
Diffstat (limited to 'gst')
-rw-r--r-- | gst/audioconvert/audioconvert.h | 5 | ||||
-rw-r--r-- | gst/audioconvert/gstchannelmix.c | 36 |
2 files changed, 40 insertions, 1 deletions
diff --git a/gst/audioconvert/audioconvert.h b/gst/audioconvert/audioconvert.h index a086cbca8..56080cc55 100644 --- a/gst/audioconvert/audioconvert.h +++ b/gst/audioconvert/audioconvert.h @@ -107,6 +107,11 @@ struct _AudioConvertCtx /* channel conversion matrix, m[in_channels][out_channels]. * If identity matrix, passthrough applies. */ gfloat **matrix; + + /* channel conversion matrix with int values, m[in_channels][out_channels]. + * this is matrix * (2^10) as integers */ + gint **matrix_int; + /* temp storage for channelmix */ gpointer tmp; diff --git a/gst/audioconvert/gstchannelmix.c b/gst/audioconvert/gstchannelmix.c index f5f5e0da6..5df8d1120 100644 --- a/gst/audioconvert/gstchannelmix.c +++ b/gst/audioconvert/gstchannelmix.c @@ -29,6 +29,8 @@ #include "gstchannelmix.h" +#define INT_MATRIX_FACTOR_EXPONENT 10 + /* * Channel matrix functions. */ @@ -48,6 +50,13 @@ gst_channel_mix_unset_matrix (AudioConvertCtx * this) g_free (this->matrix); this->matrix = NULL; + + for (i = 0; i < this->in.channels; i++) + g_free (this->matrix_int[i]); + g_free (this->matrix_int); + + this->matrix_int = NULL; + g_free (this->tmp); this->tmp = NULL; } @@ -590,6 +599,26 @@ gst_channel_mix_fill_matrix (AudioConvertCtx * this) } } +/* only call this after this->matrix is fully set up and normalized */ +static void +gst_channel_mix_setup_matrix_int (AudioConvertCtx * this) +{ + gint i, j; + gfloat tmp; + gfloat factor = (1 << INT_MATRIX_FACTOR_EXPONENT); + + this->matrix_int = g_new0 (gint32 *, this->in.channels); + + for (i = 0; i < this->in.channels; i++) { + this->matrix_int[i] = g_new (gint32, this->out.channels); + + for (j = 0; j < this->out.channels; j++) { + tmp = this->matrix[i][j] * factor; + this->matrix_int[i][j] = (gint)tmp; + } + } +} + /* only call after this->out and this->in are filled in */ void gst_channel_mix_setup_matrix (AudioConvertCtx * this) @@ -618,6 +647,8 @@ gst_channel_mix_setup_matrix (AudioConvertCtx * this) /* setup the matrix' internal values */ gst_channel_mix_fill_matrix (this); + gst_channel_mix_setup_matrix_int(this); + #ifndef GST_DISABLE_GST_DEBUG /* debug */ { @@ -694,9 +725,12 @@ gst_channel_mix_mix_int (AudioConvertCtx * this, /* convert */ res = 0; for (in = 0; in < inchannels; in++) { - res += in_data[n * inchannels + in] * this->matrix[in][out]; + res += in_data[n * inchannels + in] * (gint64)this->matrix_int[in][out]; } + /* remove factor from int matrix */ + res = res >> INT_MATRIX_FACTOR_EXPONENT; + /* clip (shouldn't we use doubles instead as intermediate format?) */ if (res < G_MININT32) res = G_MININT32; |