summaryrefslogtreecommitdiff
path: root/gst
diff options
context:
space:
mode:
authorBernhard Miller <bernhard.miller@streamunlimited.com>2015-03-30 11:24:46 +0200
committerSebastian Dröge <sebastian@centricular.com>2015-04-01 07:31:37 -0700
commitb2db18cda2e4e7951655cb2a34108a8523b6eca9 (patch)
treed864d4fdbbf3c75036ff1ad1b0ecbbfc0f51ac86 /gst
parent84638199e7cb4c7b3169d6ef120bde045e32a242 (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.h5
-rw-r--r--gst/audioconvert/gstchannelmix.c36
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;