Fix style in gstequalizer, and fix unused warnings from the elusively named irr_cf.h

This commit is contained in:
David Sansome 2010-04-08 21:32:43 +00:00
parent c92d6f1852
commit b6fd4dd3ac
2 changed files with 225 additions and 247 deletions

View File

@ -20,56 +20,56 @@ GST_DEBUG_CATEGORY_STATIC ( gst_equalizer_debug );
/* signals and args */
enum {
LAST_SIGNAL
LAST_SIGNAL
};
enum {
ARG_0,
ARG_ACTIVE,
ARG_PREAMP,
ARG_GAIN
ARG_0,
ARG_ACTIVE,
ARG_PREAMP,
ARG_GAIN
};
static GstElementDetails gst_equalizer_details = {
const_cast<char*>("Equalizer"),
const_cast<char*>("Filter/Effect/Audio"),
const_cast<char*>("Parametric Equalizer"),
const_cast<char*>("Mark Kretschmann <markey@web.de>") };
const_cast<char*>("Equalizer"),
const_cast<char*>("Filter/Effect/Audio"),
const_cast<char*>("Parametric Equalizer"),
const_cast<char*>("Mark Kretschmann <markey@web.de>") };
GstStaticPadTemplate sink_template =
GST_STATIC_PAD_TEMPLATE ( (gchar*) "sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (
"audio/x-raw-int, " \
"rate = (int) [ 1, MAX ], " \
"channels = (int) [ 1, MAX ], " \
"endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
"width = (int) 16, " \
"depth = (int) 16, " \
"signed = (bool) TRUE "
)
);
GST_PAD_SINK,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (
"audio/x-raw-int, " \
"rate = (int) [ 1, MAX ], " \
"channels = (int) [ 1, MAX ], " \
"endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
"width = (int) 16, " \
"depth = (int) 16, " \
"signed = (bool) TRUE "
)
);
GstStaticPadTemplate src_template =
GST_STATIC_PAD_TEMPLATE ( (gchar*) "src",
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (
"audio/x-raw-int, " \
"rate = (int) [ 1, MAX ], " \
"channels = (int) [ 1, MAX ], " \
"endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
"width = (int) 16, " \
"depth = (int) 16, " \
"signed = (bool) TRUE"
)
);
GST_PAD_SRC,
GST_PAD_ALWAYS,
GST_STATIC_CAPS (
"audio/x-raw-int, " \
"rate = (int) [ 1, MAX ], " \
"channels = (int) [ 1, MAX ], " \
"endianness = (int) { LITTLE_ENDIAN, BIG_ENDIAN }, " \
"width = (int) 16, " \
"depth = (int) 16, " \
"signed = (bool) TRUE"
)
);
// static guint gst_equalizer_signals[ LAST_SIGNAL ] = { 0 };
#define _do_init(bla) \
GST_DEBUG_CATEGORY_INIT (gst_equalizer_debug, "equalizer", 0, "equalizer element");
GST_DEBUG_CATEGORY_INIT (gst_equalizer_debug, "equalizer", 0, "equalizer element");
GST_BOILERPLATE_FULL ( GstEqualizer, gst_equalizer, GstBaseTransform, GST_TYPE_BASE_TRANSFORM, _do_init );
@ -80,48 +80,36 @@ static GstFlowReturn gst_equalizer_transform_ip (GstBaseTransform * base, GstBuf
// INIT
/////////////////////////////////////////////////////////////////////////////////////
void
gst_equalizer_base_init ( gpointer g_class )
{
qDebug() << __PRETTY_FUNCTION__;
GstElementClass * gstelement_class = GST_ELEMENT_CLASS ( g_class );
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&src_template));
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&sink_template));
gst_element_class_set_details ( gstelement_class, &gst_equalizer_details );
void gst_equalizer_base_init(gpointer g_class) {
GstElementClass * gstelement_class = GST_ELEMENT_CLASS ( g_class );
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&src_template));
gst_element_class_add_pad_template (gstelement_class,
gst_static_pad_template_get (&sink_template));
gst_element_class_set_details ( gstelement_class, &gst_equalizer_details );
}
void
gst_equalizer_class_init ( GstEqualizerClass * klass )
{
qDebug() << __PRETTY_FUNCTION__;
void gst_equalizer_class_init(GstEqualizerClass* klass) {
GObjectClass* gobject_class;
gobject_class = G_OBJECT_CLASS( klass );
GObjectClass* gobject_class;
gobject_class = G_OBJECT_CLASS( klass );
gobject_class->set_property = gst_equalizer_set_property;
gobject_class->get_property = gst_equalizer_get_property;
gobject_class->set_property = gst_equalizer_set_property;
gobject_class->get_property = gst_equalizer_get_property;
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ACTIVE, g_param_spec_boolean ("active", "active", "active", false, (GParamFlags)G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PREAMP, g_param_spec_int ("preamp", "preamp", "preamp", 0, 100, 0, (GParamFlags)G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_GAIN, g_param_spec_pointer ("gain", "gain", "gain", (GParamFlags)G_PARAM_WRITABLE));
GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ACTIVE, g_param_spec_boolean ("active", "active", "active", false, (GParamFlags)G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PREAMP, g_param_spec_int ("preamp", "preamp", "preamp", 0, 100, 0, (GParamFlags)G_PARAM_READWRITE));
g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_GAIN, g_param_spec_pointer ("gain", "gain", "gain", (GParamFlags)G_PARAM_WRITABLE));
GST_BASE_TRANSFORM_CLASS (klass)->transform_ip =
GST_DEBUG_FUNCPTR (gst_equalizer_transform_ip);
GST_BASE_TRANSFORM_CLASS (klass)->set_caps =
GST_BASE_TRANSFORM_CLASS (klass)->set_caps =
GST_DEBUG_FUNCPTR (gst_equalizer_set_caps);
}
void
gst_equalizer_init ( GstEqualizer* obj, GstEqualizerClass * klass )
{
qDebug() << __PRETTY_FUNCTION__;
// Properties
obj->active = false;
void gst_equalizer_init(GstEqualizer* obj, GstEqualizerClass* klass) {
// Properties
obj->active = false;
}
@ -129,132 +117,131 @@ gst_equalizer_init ( GstEqualizer* obj, GstEqualizerClass * klass )
// PUBLIC METHODS
/////////////////////////////////////////////////////////////////////////////////////
static gboolean
gst_equalizer_set_caps (GstBaseTransform * base, GstCaps * incaps, GstCaps * outcaps)
{
GstEqualizer* obj = GST_EQUALIZER (base);
GstStructure* structure = gst_caps_get_structure (incaps, 0);
static gboolean gst_equalizer_set_caps (GstBaseTransform* base, GstCaps* incaps,
GstCaps* outcaps) {
GstEqualizer* obj = GST_EQUALIZER (base);
GstStructure* structure = gst_caps_get_structure (incaps, 0);
/* Since we're an audio filter, we want to handle raw audio
/* Since we're an audio filter, we want to handle raw audio
* and from that audio type, we need to get the samplerate and
* number of channels. */
gst_structure_get_int (structure, "rate", &obj->samplerate);
gst_structure_get_int (structure, "channels", &obj->channels);
// Load the correct filter table according to the sampling rate
set_filters( obj );
/* Zero the history arrays */
memset(obj->data_history, 0, sizeof(sXYData) * EQ_MAX_BANDS * EQ_CHANNELS);
qDebug() << "Samplerate " << obj->samplerate << ", channels: " << obj->channels;
return TRUE;
gst_structure_get_int (structure, "rate", &obj->samplerate);
gst_structure_get_int (structure, "channels", &obj->channels);
// Load the correct filter table according to the sampling rate
set_filters( obj );
/* Zero the history arrays */
memset(obj->data_history, 0, sizeof(sXYData) * EQ_MAX_BANDS * EQ_CHANNELS);
qDebug() << "Samplerate " << obj->samplerate << ", channels: " << obj->channels;
return TRUE;
}
void
gst_equalizer_set_property ( GObject * object, guint prop_id, const GValue * value,
GParamSpec * pspec )
{
/* it's not null if we got it, but it might not be ours */
g_return_if_fail ( GST_IS_EQUALIZER ( object ) );
void gst_equalizer_set_property(GObject* object, guint prop_id,
const GValue * value, GParamSpec* pspec) {
/* it's not null if we got it, but it might not be ours */
g_return_if_fail ( GST_IS_EQUALIZER ( object ) );
GstEqualizer* obj = GST_EQUALIZER ( object );
std::vector<int>* gains;
GstEqualizer* obj = GST_EQUALIZER ( object );
std::vector<int>* gains;
switch ( prop_id )
{
case ARG_ACTIVE:
obj->active = g_value_get_boolean (value);
break;
switch (prop_id) {
case ARG_ACTIVE:
obj->active = g_value_get_boolean (value);
break;
case ARG_PREAMP:
for ( int chan = 0; chan < EQ_CHANNELS; chan++ )
obj->preamp[chan] = (float)g_value_get_int(value) * 0.01;
break;
case ARG_PREAMP:
for ( int chan = 0; chan < EQ_CHANNELS; chan++ )
obj->preamp[chan] = (float)g_value_get_int(value) * 0.01;
break;
case ARG_GAIN:
gains = (std::vector<int>*) g_value_get_pointer(value);
for ( int band = 0; band < BAND_NUM; band++ )
for ( int chan = 0; chan < EQ_CHANNELS; chan++ )
obj->gain[band][chan] = (float)(*gains)[band] * 0.012 - 0.2;
break;
case ARG_GAIN:
gains = (std::vector<int>*) g_value_get_pointer(value);
for ( int band = 0; band < BAND_NUM; band++ )
for ( int chan = 0; chan < EQ_CHANNELS; chan++ )
obj->gain[band][chan] = (float)(*gains)[band] * 0.012 - 0.2;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID ( object, prop_id, pspec );
break;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID ( object, prop_id, pspec );
break;
}
}
void
gst_equalizer_get_property ( GObject * object, guint prop_id, GValue * value, GParamSpec * pspec )
{
/* it's not null if we got it, but it might not be ours */
g_return_if_fail ( GST_IS_EQUALIZER ( object ) );
void gst_equalizer_get_property(GObject* object, guint prop_id, GValue* value,
GParamSpec* pspec) {
/* it's not null if we got it, but it might not be ours */
g_return_if_fail ( GST_IS_EQUALIZER ( object ) );
GstEqualizer* obj = GST_EQUALIZER ( object );
GstEqualizer* obj = GST_EQUALIZER ( object );
switch ( prop_id )
{
case ARG_ACTIVE:
g_value_set_boolean (value, obj->active);
break;
switch (prop_id) {
case ARG_ACTIVE:
g_value_set_boolean (value, obj->active);
break;
case ARG_PREAMP:
g_value_set_int(value, obj->preamp[0] * 100);
break;
case ARG_PREAMP:
g_value_set_int(value, obj->preamp[0] * 100);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID ( object, prop_id, pspec );
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID ( object, prop_id, pspec );
break;
}
}
void
set_filters( GstEqualizer* obj )
{
switch(obj->samplerate)
{
case 11025:
obj->iir_cf = iir_cf10_11k_11025;
break;
void set_filters(GstEqualizer* obj) {
Q_UNUSED(iir_cforiginal10_44100);
Q_UNUSED(iir_cforiginal10_48000);
Q_UNUSED(iir_cf15_44100);
Q_UNUSED(iir_cf15_48000);
Q_UNUSED(iir_cf25_44100);
Q_UNUSED(iir_cf25_48000);
Q_UNUSED(iir_cf31_44100);
Q_UNUSED(iir_cf31_48000);
case 22050:
obj->iir_cf = iir_cf10_22k_22050;
break;
switch(obj->samplerate) {
case 11025:
obj->iir_cf = iir_cf10_11k_11025;
break;
case 48000:
obj->iir_cf = iir_cf10_48000;
break;
case 22050:
obj->iir_cf = iir_cf10_22k_22050;
break;
default:
obj->iir_cf = iir_cf10_44100;
break;
}
case 48000:
obj->iir_cf = iir_cf10_48000;
break;
default:
obj->iir_cf = iir_cf10_44100;
break;
}
}
static GstFlowReturn
gst_equalizer_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
{
GstEqualizer* obj = GST_EQUALIZER ( base );
static GstFlowReturn gst_equalizer_transform_ip(GstBaseTransform* base,
GstBuffer * outbuf) {
GstEqualizer* obj = GST_EQUALIZER ( base );
if ( !obj->active ) return GST_FLOW_OK;
if ( !obj->active ) return GST_FLOW_OK;
gint16 *data = (gint16*)GST_BUFFER_DATA ( outbuf );
gint length = GST_BUFFER_SIZE( outbuf );
/* Indexes for the history arrays
gint16 *data = (gint16*)GST_BUFFER_DATA ( outbuf );
gint length = GST_BUFFER_SIZE( outbuf );
/* Indexes for the history arrays
* These have to be kept between calls to this function
* hence they are static */
static gint i = 0, j = 2, k = 1;
static gint i = 0, j = 2, k = 1;
gint index, band, channel;
gint halflength;
float out[EQ_CHANNELS], pcm[EQ_CHANNELS];
float tempfloat;
gint index, band, channel;
gint halflength;
float out[EQ_CHANNELS], pcm[EQ_CHANNELS];
float tempfloat;
/**
/**
* IIR filter equation is
* y[n] = 2 * (alpha*(x[n]-x[n-2]) + gamma*y[n-1] - beta*y[n-2])
*
@ -264,77 +251,72 @@ gst_equalizer_transform_ip (GstBaseTransform * base, GstBuffer * outbuf)
* This algorithm cascades two filters to get nice filtering
* at the expense of extra CPU cycles
*/
/* 16bit, 2 bytes per sample, so divide by two the length of
/* 16bit, 2 bytes per sample, so divide by two the length of
* the buffer (length is in bytes)
*/
halflength = (length >> 1);
for (index = 0; index < halflength; index+=2)
{
/* For each channel */
for (channel = 0; channel < obj->channels; channel++)
{
pcm[channel] = data[index+channel];
/* Preamp gain */
pcm[channel] *= obj->preamp[channel];
halflength = (length >> 1);
for (index = 0; index < halflength; index+=2) {
/* For each channel */
for (channel = 0; channel < obj->channels; channel++) {
pcm[channel] = data[index+channel];
/* Preamp gain */
pcm[channel] *= obj->preamp[channel];
out[channel] = 0.;
/* For each band */
for (band = 0; band < BAND_NUM; band++)
{
/* Store Xi(n) */
obj->data_history[band][channel].x[i] = pcm[channel];
/* Calculate and store Yi(n) */
obj->data_history[band][channel].y[i] =
(
/* = alpha * [x(n)-x(n-2)] */
obj->iir_cf[band].alpha * ( obj->data_history[band][channel].x[i]
- obj->data_history[band][channel].x[k])
/* + gamma * y(n-1) */
+ obj->iir_cf[band].gamma * obj->data_history[band][channel].y[j]
/* - beta * y(n-2) */
- obj->iir_cf[band].beta * obj->data_history[band][channel].y[k]
);
/*
out[channel] = 0.;
/* For each band */
for (band = 0; band < BAND_NUM; band++) {
/* Store Xi(n) */
obj->data_history[band][channel].x[i] = pcm[channel];
/* Calculate and store Yi(n) */
obj->data_history[band][channel].y[i] =
(
/* = alpha * [x(n)-x(n-2)] */
obj->iir_cf[band].alpha * ( obj->data_history[band][channel].x[i]
- obj->data_history[band][channel].x[k])
/* + gamma * y(n-1) */
+ obj->iir_cf[band].gamma * obj->data_history[band][channel].y[j]
/* - beta * y(n-2) */
- obj->iir_cf[band].beta * obj->data_history[band][channel].y[k]
);
/*
* The multiplication by 2.0 was 'moved' into the coefficients to save
* CPU cycles here */
/* Apply the gain */
out[channel] += obj->data_history[band][channel].y[i]*obj->gain[band][channel]; // * 2.0;
} /* For each band */
/* Apply the gain */
out[channel] += obj->data_history[band][channel].y[i]*obj->gain[band][channel]; // * 2.0;
} /* For each band */
/* Volume stuff
/* Volume stuff
Scale down original PCM sample and add it to the filters
output. This substitutes the multiplication by 0.25
Go back to use the floating point multiplication before the
conversion to give more dynamic range
*/
out[channel] += pcm[channel]*0.25;
out[channel] += pcm[channel]*0.25;
/* Round and convert to integer and limit the output */
tempfloat = out[channel] < -32768.0 ? -32768.0 : out[channel];
tempfloat = tempfloat > 32767.0 ? 32767.0 : tempfloat;
data[index+channel] = (gint)rintf(tempfloat);
/* Round and convert to integer and limit the output */
tempfloat = out[channel] < -32768.0 ? -32768.0 : out[channel];
tempfloat = tempfloat > 32767.0 ? 32767.0 : tempfloat;
data[index+channel] = (gint)rintf(tempfloat);
} /* For each channel */
} /* For each channel */
i++; j++; k++;
i++; j++; k++;
/* Wrap around the indexes */
if (i == 3) i = 0;
else if (j == 3) j = 0;
else k = 0;
}/* For each pair of samples */
return GST_FLOW_OK;
/* Wrap around the indexes */
if (i == 3) i = 0;
else if (j == 3) j = 0;
else k = 0;
}/* For each pair of samples */
return GST_FLOW_OK;
}
GstEqualizer*
gst_equalizer_new ()
{
GstEqualizer* obj = GST_EQUALIZER ( g_object_new ( GST_TYPE_EQUALIZER, NULL ) );
gst_object_set_name( (GstObject*) obj, "Equalizer" );
GstEqualizer* gst_equalizer_new() {
GstEqualizer* obj = GST_EQUALIZER ( g_object_new ( GST_TYPE_EQUALIZER, NULL ) );
gst_object_set_name( (GstObject*) obj, "Equalizer" );
return obj;
return obj;
}

View File

@ -16,66 +16,62 @@ G_BEGIN_DECLS
#define EQ_CHANNELS 2
#define GST_TYPE_EQUALIZER \
(gst_equalizer_get_type())
(gst_equalizer_get_type())
#define GST_EQUALIZER(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_EQUALIZER,GstEqualizer))
(G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_EQUALIZER,GstEqualizer))
#define GST_EQUALIZER_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_EQUALIZER,GstEqualizerClass))
(G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_EQUALIZER,GstEqualizerClass))
#define GST_IS_EQUALIZER(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_EQUALIZER))
(G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_EQUALIZER))
#define GST_IS_EQUALIZER_CLASS(obj) \
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_EQUALIZER))
(G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_EQUALIZER))
typedef struct _GstEqualizer GstEqualizer;
typedef struct _GstEqualizer GstEqualizer;
typedef struct _GstEqualizerClass GstEqualizerClass;
// Floating point
typedef struct
{
float beta;
float alpha;
float gamma;
typedef struct {
float beta;
float alpha;
float gamma;
} sIIRCoefficients;
/* Coefficient history for the IIR filter */
typedef struct
{
float x[3]; /* x[n], x[n-1], x[n-2] */
float y[3]; /* y[n], y[n-1], y[n-2] */
typedef struct {
float x[3]; /* x[n], x[n-1], x[n-2] */
float y[3]; /* y[n], y[n-1], y[n-2] */
} sXYData;
struct _GstEqualizer
{
// Do not remove
GstBaseTransform element;
struct _GstEqualizer {
// Do not remove
GstBaseTransform element;
GstPad *srcpad;
GstPad *sinkpad;
GstPad *srcpad;
GstPad *sinkpad;
int samplerate;
int channels;
int samplerate;
int channels;
// Properties
bool active;
// Gain for each band
// values should be between -0.2 and 1.0
float gain[EQ_MAX_BANDS][EQ_CHANNELS] __attribute__((aligned));
// Volume gain
// values should be between 0.0 and 1.0
float preamp[EQ_CHANNELS] __attribute__((aligned));
// Properties
bool active;
// Gain for each band
// values should be between -0.2 and 1.0
float gain[EQ_MAX_BANDS][EQ_CHANNELS] __attribute__((aligned));
// Volume gain
// values should be between 0.0 and 1.0
float preamp[EQ_CHANNELS] __attribute__((aligned));
// Coefficients
sIIRCoefficients* iir_cf;
// Coefficients
sIIRCoefficients* iir_cf;
sXYData data_history[EQ_MAX_BANDS][EQ_CHANNELS] __attribute__((aligned));
sXYData data_history[EQ_MAX_BANDS][EQ_CHANNELS] __attribute__((aligned));
};
struct _GstEqualizerClass
{
GstBaseTransformClass parent_class;
struct _GstEqualizerClass {
GstBaseTransformClass parent_class;
/* signals */
/* signals */
};
void gst_equalizer_set_property( GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec );