port to new audio API and caps

This commit is contained in:
Wim Taymans 2011-08-19 11:49:44 +02:00
parent 135b41cb5b
commit 90f5b31b4b
18 changed files with 294 additions and 350 deletions

View file

@ -90,52 +90,29 @@ gst_audio_amplify_clipping_method_get_type (void)
{METHOD_NOCLIP, "No clipping", "none"},
{0, NULL, NULL}
};
/* FIXME 0.11: rename to GstAudioAmplifyClippingMethod */
gtype = g_enum_register_static ("GstAudioPanoramaClippingMethod", values);
gtype = g_enum_register_static ("GstAudioAmplifyClippingMethod", values);
}
return gtype;
}
#define ALLOWED_CAPS \
"audio/x-raw-int," \
" depth=(int)8," \
" width=(int)8," \
" endianness=(int)BYTE_ORDER," \
" signed=(bool)TRUE," \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX]; " \
"audio/x-raw-int," \
" depth=(int)16," \
" width=(int)16," \
" endianness=(int)BYTE_ORDER," \
" signed=(bool)TRUE," \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX]; " \
"audio/x-raw-int," \
" depth=(int)32," \
" width=(int)32," \
" endianness=(int)BYTE_ORDER," \
" signed=(bool)TRUE," \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX]; " \
"audio/x-raw-float," \
" width=(int){32,64}," \
" endianness=(int)BYTE_ORDER," \
"audio/x-raw," \
" format=(string) {S8,"GST_AUDIO_NE(S16)","GST_AUDIO_NE(S32)"," \
GST_AUDIO_NE(F32)","GST_AUDIO_NE(F64)"}," \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX]"
G_DEFINE_TYPE (GstAudioAmplify, gst_audio_amplify, GST_TYPE_AUDIO_FILTER);
static gboolean gst_audio_amplify_set_process_function (GstAudioAmplify *
filter, gint clipping, gint format, gint width);
filter, gint clipping, GstAudioFormat format);
static void gst_audio_amplify_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
static void gst_audio_amplify_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_audio_amplify_setup (GstAudioFilter * filter,
GstRingBufferSpec * format);
GstAudioInfo * info);
static GstFlowReturn gst_audio_amplify_transform_ip (GstBaseTransform * base,
GstBuffer * buf);
@ -331,80 +308,76 @@ gst_audio_amplify_init (GstAudioAmplify * filter)
{
filter->amplification = 1.0;
gst_audio_amplify_set_process_function (filter, METHOD_CLIP,
GST_BUFTYPE_LINEAR, 16);
GST_AUDIO_FORMAT_S16);
gst_base_transform_set_in_place (GST_BASE_TRANSFORM (filter), TRUE);
gst_base_transform_set_gap_aware (GST_BASE_TRANSFORM (filter), TRUE);
}
static GstAudioAmplifyProcessFunc
gst_audio_amplify_process_function (gint clipping, gint format, gint width)
gst_audio_amplify_process_function (gint clipping, GstAudioFormat format)
{
static const struct process
{
gint format;
gint width;
GstAudioFormat format;
gint clipping;
GstAudioAmplifyProcessFunc func;
} process[] = {
{
GST_BUFTYPE_FLOAT, 32, METHOD_CLIP,
gst_audio_amplify_transform_gfloat_clip}, {
GST_BUFTYPE_FLOAT, 32, METHOD_WRAP_NEGATIVE,
GST_AUDIO_FORMAT_F32, METHOD_CLIP, gst_audio_amplify_transform_gfloat_clip}, {
GST_AUDIO_FORMAT_F32, METHOD_WRAP_NEGATIVE,
gst_audio_amplify_transform_gfloat_wrap_negative}, {
GST_BUFTYPE_FLOAT, 32, METHOD_WRAP_POSITIVE,
GST_AUDIO_FORMAT_F32, METHOD_WRAP_POSITIVE,
gst_audio_amplify_transform_gfloat_wrap_positive}, {
GST_BUFTYPE_FLOAT, 32, METHOD_NOCLIP,
GST_AUDIO_FORMAT_F32, METHOD_NOCLIP,
gst_audio_amplify_transform_gfloat_noclip}, {
GST_BUFTYPE_FLOAT, 64, METHOD_CLIP,
GST_AUDIO_FORMAT_F64, METHOD_CLIP,
gst_audio_amplify_transform_gdouble_clip}, {
GST_BUFTYPE_FLOAT, 64, METHOD_WRAP_NEGATIVE,
GST_AUDIO_FORMAT_F64, METHOD_WRAP_NEGATIVE,
gst_audio_amplify_transform_gdouble_wrap_negative}, {
GST_BUFTYPE_FLOAT, 64, METHOD_WRAP_POSITIVE,
GST_AUDIO_FORMAT_F64, METHOD_WRAP_POSITIVE,
gst_audio_amplify_transform_gdouble_wrap_positive}, {
GST_BUFTYPE_FLOAT, 64, METHOD_NOCLIP,
GST_AUDIO_FORMAT_F64, METHOD_NOCLIP,
gst_audio_amplify_transform_gdouble_noclip}, {
GST_BUFTYPE_LINEAR, 8, METHOD_CLIP, gst_audio_amplify_transform_gint8_clip}, {
GST_BUFTYPE_LINEAR, 8, METHOD_WRAP_NEGATIVE,
GST_AUDIO_FORMAT_S8, METHOD_CLIP, gst_audio_amplify_transform_gint8_clip}, {
GST_AUDIO_FORMAT_S8, METHOD_WRAP_NEGATIVE,
gst_audio_amplify_transform_gint8_wrap_negative}, {
GST_BUFTYPE_LINEAR, 8, METHOD_WRAP_POSITIVE,
GST_AUDIO_FORMAT_S8, METHOD_WRAP_POSITIVE,
gst_audio_amplify_transform_gint8_wrap_positive}, {
GST_BUFTYPE_LINEAR, 8, METHOD_NOCLIP,
GST_AUDIO_FORMAT_S8, METHOD_NOCLIP,
gst_audio_amplify_transform_gint8_noclip}, {
GST_BUFTYPE_LINEAR, 16, METHOD_CLIP,
gst_audio_amplify_transform_gint16_clip}, {
GST_BUFTYPE_LINEAR, 16, METHOD_WRAP_NEGATIVE,
GST_AUDIO_FORMAT_S16, METHOD_CLIP, gst_audio_amplify_transform_gint16_clip}, {
GST_AUDIO_FORMAT_S16, METHOD_WRAP_NEGATIVE,
gst_audio_amplify_transform_gint16_wrap_negative}, {
GST_BUFTYPE_LINEAR, 16, METHOD_WRAP_POSITIVE,
GST_AUDIO_FORMAT_S16, METHOD_WRAP_POSITIVE,
gst_audio_amplify_transform_gint16_wrap_positive}, {
GST_BUFTYPE_LINEAR, 16, METHOD_NOCLIP,
GST_AUDIO_FORMAT_S16, METHOD_NOCLIP,
gst_audio_amplify_transform_gint16_noclip}, {
GST_BUFTYPE_LINEAR, 32, METHOD_CLIP,
gst_audio_amplify_transform_gint32_clip}, {
GST_BUFTYPE_LINEAR, 32, METHOD_WRAP_NEGATIVE,
GST_AUDIO_FORMAT_S32, METHOD_CLIP, gst_audio_amplify_transform_gint32_clip}, {
GST_AUDIO_FORMAT_S32, METHOD_WRAP_NEGATIVE,
gst_audio_amplify_transform_gint32_wrap_negative}, {
GST_BUFTYPE_LINEAR, 32, METHOD_WRAP_POSITIVE,
GST_AUDIO_FORMAT_S32, METHOD_WRAP_POSITIVE,
gst_audio_amplify_transform_gint32_wrap_positive}, {
GST_BUFTYPE_LINEAR, 32, METHOD_NOCLIP,
GST_AUDIO_FORMAT_S32, METHOD_NOCLIP,
gst_audio_amplify_transform_gint32_noclip}, {
0, 0, 0, NULL}
0, 0, NULL}
};
const struct process *p;
for (p = process; p->func; p++)
if (p->format == format && p->width == width && p->clipping == clipping)
if (p->format == format && p->clipping == clipping)
return p->func;
return NULL;
}
static gboolean
gst_audio_amplify_set_process_function (GstAudioAmplify * filter, gint
clipping_method, gint format, gint width)
clipping_method, GstAudioFormat format)
{
GstAudioAmplifyProcessFunc process;
/* set processing function */
process = gst_audio_amplify_process_function (clipping_method, format, width);
process = gst_audio_amplify_process_function (clipping_method, format);
if (!process) {
GST_DEBUG ("wrong format");
return FALSE;
@ -413,7 +386,6 @@ gst_audio_amplify_set_process_function (GstAudioAmplify * filter, gint
filter->process = process;
filter->clipping_method = clipping_method;
filter->format = format;
filter->width = width;
return TRUE;
}
@ -432,7 +404,7 @@ gst_audio_amplify_set_property (GObject * object, guint prop_id,
break;
case PROP_CLIPPING_METHOD:
gst_audio_amplify_set_process_function (filter, g_value_get_enum (value),
filter->format, filter->width);
filter->format);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -461,12 +433,12 @@ gst_audio_amplify_get_property (GObject * object, guint prop_id,
/* GstAudioFilter vmethod implementations */
static gboolean
gst_audio_amplify_setup (GstAudioFilter * base, GstRingBufferSpec * format)
gst_audio_amplify_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioAmplify *filter = GST_AUDIO_AMPLIFY (base);
return gst_audio_amplify_set_process_function (filter,
filter->clipping_method, format->type, format->width);
filter->clipping_method, GST_AUDIO_INFO_FORMAT (info));
}
/* GstBaseTransform vmethod implementations */
@ -494,7 +466,7 @@ gst_audio_amplify_transform_ip (GstBaseTransform * base, GstBuffer * buf)
return GST_FLOW_OK;
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READWRITE);
num_samples = size / (GST_AUDIO_FILTER (filter)->format.width / 8);
num_samples = size / GST_AUDIO_FILTER_BPS (filter);
filter->process (filter, data, num_samples);

View file

@ -48,8 +48,7 @@ struct _GstAudioAmplify
/* < private > */
GstAudioAmplifyProcessFunc process;
gint clipping_method;
gint format;
gint width;
GstAudioFormat format;
};
struct _GstAudioAmplifyClass

View file

@ -107,7 +107,7 @@ static void gst_audio_cheb_band_get_property (GObject * object,
static void gst_audio_cheb_band_finalize (GObject * object);
static gboolean gst_audio_cheb_band_setup (GstAudioFilter * filter,
GstRingBufferSpec * format);
GstAudioInfo * info);
enum
{
@ -211,6 +211,7 @@ generate_biquad_coefficients (GstAudioChebBand * filter,
{
gint np = filter->poles / 2;
gdouble ripple = filter->ripple;
gint rate = GST_AUDIO_FILTER_RATE (filter);
/* pole location in s-plane */
gdouble rp, ip;
@ -333,12 +334,8 @@ generate_biquad_coefficients (GstAudioChebBand * filter,
{
gdouble a, b, d;
gdouble alpha, beta;
gdouble w0 =
2.0 * G_PI * (filter->lower_frequency /
GST_AUDIO_FILTER (filter)->format.rate);
gdouble w1 =
2.0 * G_PI * (filter->upper_frequency /
GST_AUDIO_FILTER (filter)->format.rate);
gdouble w0 = 2.0 * G_PI * (filter->lower_frequency / rate);
gdouble w1 = 2.0 * G_PI * (filter->upper_frequency / rate);
if (filter->mode == MODE_BAND_PASS) {
a = cos ((w1 + w0) / 2.0) / cos ((w1 - w0) / 2.0);
@ -391,7 +388,9 @@ generate_biquad_coefficients (GstAudioChebBand * filter,
static void
generate_coefficients (GstAudioChebBand * filter)
{
if (GST_AUDIO_FILTER (filter)->format.rate == 0) {
gint rate = GST_AUDIO_FILTER_RATE (filter);
if (rate == 0) {
gdouble *a = g_new0 (gdouble, 1);
a[0] = 1.0;
@ -412,8 +411,8 @@ generate_coefficients (GstAudioChebBand * filter)
return;
}
if (filter->upper_frequency > GST_AUDIO_FILTER (filter)->format.rate / 2) {
filter->upper_frequency = GST_AUDIO_FILTER (filter)->format.rate / 2;
if (filter->upper_frequency > rate / 2) {
filter->upper_frequency = rate / 2;
GST_LOG_OBJECT (filter, "clipped upper frequency to nyquist frequency");
}
@ -492,12 +491,8 @@ generate_coefficients (GstAudioChebBand * filter)
} else {
/* gain is H(wc), wc = center frequency */
gdouble w1 =
2.0 * G_PI * (filter->lower_frequency /
GST_AUDIO_FILTER (filter)->format.rate);
gdouble w2 =
2.0 * G_PI * (filter->upper_frequency /
GST_AUDIO_FILTER (filter)->format.rate);
gdouble w1 = 2.0 * G_PI * (filter->lower_frequency / rate);
gdouble w2 = 2.0 * G_PI * (filter->upper_frequency / rate);
gdouble w0 = (w2 + w1) / 2.0;
gdouble zr = cos (w0), zi = sin (w0);
gdouble gain =
@ -524,12 +519,8 @@ generate_coefficients (GstAudioChebBand * filter)
20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b,
np + 1, 1.0, 0.0)));
{
gdouble w1 =
2.0 * G_PI * (filter->lower_frequency /
GST_AUDIO_FILTER (filter)->format.rate);
gdouble w2 =
2.0 * G_PI * (filter->upper_frequency /
GST_AUDIO_FILTER (filter)->format.rate);
gdouble w1 = 2.0 * G_PI * (filter->lower_frequency / rate);
gdouble w2 = 2.0 * G_PI * (filter->upper_frequency / rate);
gdouble w0 = (w2 + w1) / 2.0;
gdouble zr, zi;
@ -552,8 +543,7 @@ generate_coefficients (GstAudioChebBand * filter)
}
GST_LOG_OBJECT (filter, "%.2f dB gain @ %dHz",
20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b,
np + 1, -1.0, 0.0)),
GST_AUDIO_FILTER (filter)->format.rate / 2);
np + 1, -1.0, 0.0)), rate / 2);
}
}
@ -651,11 +641,11 @@ gst_audio_cheb_band_get_property (GObject * object, guint prop_id,
/* GstAudioFilter vmethod implementations */
static gboolean
gst_audio_cheb_band_setup (GstAudioFilter * base, GstRingBufferSpec * format)
gst_audio_cheb_band_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioChebBand *filter = GST_AUDIO_CHEB_BAND (base);
generate_coefficients (filter);
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, info);
}

View file

@ -102,7 +102,7 @@ static void gst_audio_cheb_limit_get_property (GObject * object,
static void gst_audio_cheb_limit_finalize (GObject * object);
static gboolean gst_audio_cheb_limit_setup (GstAudioFilter * filter,
GstRingBufferSpec * format);
GstAudioInfo * info);
enum
{
@ -318,7 +318,7 @@ generate_biquad_coefficients (GstAudioChebLimit * filter,
{
gdouble k, d;
gdouble omega =
2.0 * G_PI * (filter->cutoff / GST_AUDIO_FILTER (filter)->format.rate);
2.0 * G_PI * (filter->cutoff / GST_AUDIO_FILTER_RATE (filter));
if (filter->mode == MODE_LOW_PASS)
k = sin ((1.0 - omega) / 2.0) / sin ((1.0 + omega) / 2.0);
@ -342,7 +342,7 @@ generate_biquad_coefficients (GstAudioChebLimit * filter,
static void
generate_coefficients (GstAudioChebLimit * filter)
{
if (GST_AUDIO_FILTER (filter)->format.rate == 0) {
if (GST_AUDIO_FILTER_RATE (filter) == 0) {
gdouble *a = g_new0 (gdouble, 1);
a[0] = 1.0;
@ -353,7 +353,7 @@ generate_coefficients (GstAudioChebLimit * filter)
return;
}
if (filter->cutoff >= GST_AUDIO_FILTER (filter)->format.rate / 2.0) {
if (filter->cutoff >= GST_AUDIO_FILTER_RATE (filter) / 2.0) {
gdouble *a = g_new0 (gdouble, 1);
a[0] = (filter->mode == MODE_LOW_PASS) ? 1.0 : 0.0;
@ -450,8 +450,7 @@ generate_coefficients (GstAudioChebLimit * filter)
#ifndef GST_DISABLE_GST_DEBUG
{
gdouble wc =
2.0 * G_PI * (filter->cutoff /
GST_AUDIO_FILTER (filter)->format.rate);
2.0 * G_PI * (filter->cutoff / GST_AUDIO_FILTER_RATE (filter));
gdouble zr = cos (wc), zi = sin (wc);
GST_LOG_OBJECT (filter, "%.2f dB gain @ %d Hz",
@ -462,8 +461,7 @@ generate_coefficients (GstAudioChebLimit * filter)
GST_LOG_OBJECT (filter, "%.2f dB gain @ %d Hz",
20.0 * log10 (gst_audio_fx_base_iir_filter_calculate_gain (a, np + 1, b,
np + 1, -1.0, 0.0)),
GST_AUDIO_FILTER (filter)->format.rate / 2);
np + 1, -1.0, 0.0)), GST_AUDIO_FILTER_RATE (filter) / 2);
}
}
@ -552,11 +550,11 @@ gst_audio_cheb_limit_get_property (GObject * object, guint prop_id,
/* GstAudioFilter vmethod implementations */
static gboolean
gst_audio_cheb_limit_setup (GstAudioFilter * base, GstRingBufferSpec * format)
gst_audio_cheb_limit_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioChebLimit *filter = GST_AUDIO_CHEB_LIMIT (base);
generate_coefficients (filter);
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, info);
}

View file

@ -70,17 +70,9 @@ enum
};
#define ALLOWED_CAPS \
"audio/x-raw-int," \
" depth=(int)16," \
" width=(int)16," \
" endianness=(int)BYTE_ORDER," \
" signed=(bool)TRUE," \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX]; " \
"audio/x-raw-float," \
" width=(int)32," \
" endianness=(int)BYTE_ORDER," \
" rate=(int)[1,MAX]," \
"audio/x-raw," \
" format=(string) {"GST_AUDIO_NE(S16)","GST_AUDIO_NE(F32)"}," \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX]"
G_DEFINE_TYPE (GstAudioDynamic, gst_audio_dynamic, GST_TYPE_AUDIO_FILTER);
@ -91,7 +83,7 @@ static void gst_audio_dynamic_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_audio_dynamic_setup (GstAudioFilter * filter,
GstRingBufferSpec * format);
GstAudioInfo * info);
static GstFlowReturn gst_audio_dynamic_transform_ip (GstBaseTransform * base,
GstBuffer * buf);
@ -196,7 +188,7 @@ gst_audio_dynamic_set_process_function (GstAudioDynamic * filter)
func_index = (filter->mode == MODE_COMPRESSOR) ? 0 : 4;
func_index += (filter->characteristics == CHARACTERISTICS_HARD_KNEE) ? 0 : 2;
func_index +=
(GST_AUDIO_FILTER (filter)->format.type == GST_BUFTYPE_FLOAT) ? 1 : 0;
(GST_AUDIO_FILTER_FORMAT (filter) == GST_AUDIO_FORMAT_F32) ? 1 : 0;
if (func_index >= 0 && func_index < 8) {
filter->process = process_functions[func_index];
@ -331,7 +323,7 @@ gst_audio_dynamic_get_property (GObject * object, guint prop_id,
/* GstAudioFilter vmethod implementations */
static gboolean
gst_audio_dynamic_setup (GstAudioFilter * base, GstRingBufferSpec * format)
gst_audio_dynamic_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioDynamic *filter = GST_AUDIO_DYNAMIC (base);
gboolean ret = TRUE;
@ -580,6 +572,7 @@ gst_audio_dynamic_transform_soft_knee_expander_int (GstAudioDynamic * filter,
gdouble zero_p, zero_n;
gdouble a_p, b_p, c_p;
gdouble a_n, b_n, c_n;
gdouble r2;
/* Nothing to do for us here if threshold equals 0.0
* or ratio equals 1.0 */
@ -609,11 +602,12 @@ gst_audio_dynamic_transform_soft_knee_expander_int (GstAudioDynamic * filter,
* b = (1 + r^2) / 2
* c = t * (1.0 - b - a*t)
* f(x) = ax^2 + bx + c */
a_p = (1.0 - filter->ratio * filter->ratio) / (4.0 * thr_p);
b_p = (1.0 + filter->ratio * filter->ratio) / 2.0;
r2 = filter->ratio * filter->ratio;
a_p = (1.0 - r2) / (4.0 * thr_p);
b_p = (1.0 + r2) / 2.0;
c_p = thr_p * (1.0 - b_p - a_p * thr_p);
a_n = (1.0 - filter->ratio * filter->ratio) / (4.0 * thr_n);
b_n = (1.0 + filter->ratio * filter->ratio) / 2.0;
a_n = (1.0 - r2) / (4.0 * thr_n);
b_n = (1.0 + r2) / 2.0;
c_n = thr_n * (1.0 - b_n - a_n * thr_n);
for (; num_samples; num_samples--) {
@ -639,6 +633,7 @@ gst_audio_dynamic_transform_soft_knee_expander_float (GstAudioDynamic * filter,
gdouble zero;
gdouble a_p, b_p, c_p;
gdouble a_n, b_n, c_n;
gdouble r2;
/* Nothing to do for us here if threshold equals 0.0
* or ratio equals 1.0 */
@ -664,11 +659,12 @@ gst_audio_dynamic_transform_soft_knee_expander_float (GstAudioDynamic * filter,
* b = (1 + r^2) / 2
* c = t * (1.0 - b - a*t)
* f(x) = ax^2 + bx + c */
a_p = (1.0 - filter->ratio * filter->ratio) / (4.0 * threshold);
b_p = (1.0 + filter->ratio * filter->ratio) / 2.0;
r2 = filter->ratio * filter->ratio;
a_p = (1.0 - r2) / (4.0 * threshold);
b_p = (1.0 + r2) / 2.0;
c_p = threshold * (1.0 - b_p - a_p * threshold);
a_n = (1.0 - filter->ratio * filter->ratio) / (-4.0 * threshold);
b_n = (1.0 + filter->ratio * filter->ratio) / 2.0;
a_n = (1.0 - r2) / (-4.0 * threshold);
b_n = (1.0 + r2) / 2.0;
c_n = -threshold * (1.0 - b_n + a_n * threshold);
for (; num_samples; num_samples--) {
@ -710,7 +706,7 @@ gst_audio_dynamic_transform_ip (GstBaseTransform * base, GstBuffer * buf)
return GST_FLOW_OK;
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READWRITE);
num_samples = size / (GST_AUDIO_FILTER (filter)->format.width / 8);
num_samples = size / GST_AUDIO_FILTER_BPS (filter);
filter->process (filter, data, num_samples);

View file

@ -67,10 +67,9 @@ enum
};
#define ALLOWED_CAPS \
"audio/x-raw-float," \
" width=(int) { 32, 64 }, " \
" endianness=(int)BYTE_ORDER," \
" rate=(int)[1,MAX]," \
"audio/x-raw," \
" format=(string) {"GST_AUDIO_NE(F32)","GST_AUDIO_NE(F64)"}, " \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX]"
#define gst_audio_echo_parent_class parent_class
@ -83,7 +82,7 @@ static void gst_audio_echo_get_property (GObject * object, guint prop_id,
static void gst_audio_echo_finalize (GObject * object);
static gboolean gst_audio_echo_setup (GstAudioFilter * self,
GstRingBufferSpec * format);
GstAudioInfo * info);
static gboolean gst_audio_echo_stop (GstBaseTransform * base);
static GstFlowReturn gst_audio_echo_transform_ip (GstBaseTransform * base,
GstBuffer * buf);
@ -272,19 +271,24 @@ gst_audio_echo_get_property (GObject * object, guint prop_id,
/* GstAudioFilter vmethod implementations */
static gboolean
gst_audio_echo_setup (GstAudioFilter * base, GstRingBufferSpec * format)
gst_audio_echo_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioEcho *self = GST_AUDIO_ECHO (base);
gboolean ret = TRUE;
if (format->type == GST_BUFTYPE_FLOAT && format->width == 32)
self->process = (GstAudioEchoProcessFunc)
gst_audio_echo_transform_float;
else if (format->type == GST_BUFTYPE_FLOAT && format->width == 64)
self->process = (GstAudioEchoProcessFunc)
gst_audio_echo_transform_double;
else
ret = FALSE;
switch (GST_AUDIO_INFO_FORMAT (info)) {
case GST_AUDIO_FORMAT_F32:
self->process = (GstAudioEchoProcessFunc)
gst_audio_echo_transform_float;
break;
case GST_AUDIO_FORMAT_F64:
self->process = (GstAudioEchoProcessFunc)
gst_audio_echo_transform_double;
break;
default:
ret = FALSE;
break;
}
g_free (self->buffer);
self->buffer = NULL;
@ -315,8 +319,8 @@ gst_audio_echo_transform_##name (GstAudioEcho * self, \
type * data, guint num_samples) \
{ \
type *buffer = (type *) self->buffer; \
guint channels = GST_AUDIO_FILTER (self)->format.channels; \
guint rate = GST_AUDIO_FILTER (self)->format.rate; \
guint channels = GST_AUDIO_FILTER_CHANNELS (self); \
guint rate = GST_AUDIO_FILTER_RATE (self); \
guint i, j; \
guint echo_index = self->buffer_size_frames - self->delay_frames; \
gdouble echo_off = ((((gdouble) self->delay) * rate) / GST_SECOND) - self->delay_frames; \
@ -369,18 +373,17 @@ gst_audio_echo_transform_ip (GstBaseTransform * base, GstBuffer * buf)
gst_object_sync_values (G_OBJECT (self), stream_time);
if (self->buffer == NULL) {
guint width, rate, channels;
guint bpf, rate;
width = GST_AUDIO_FILTER (self)->format.width / 8;
rate = GST_AUDIO_FILTER (self)->format.rate;
channels = GST_AUDIO_FILTER (self)->format.channels;
bpf = GST_AUDIO_FILTER_BPS (self);
rate = GST_AUDIO_FILTER_RATE (self);
self->delay_frames =
MAX (gst_util_uint64_scale (self->delay, rate, GST_SECOND), 1);
self->buffer_size_frames =
MAX (gst_util_uint64_scale (self->max_delay, rate, GST_SECOND), 1);
self->buffer_size = self->buffer_size_frames * width * channels;
self->buffer_size = self->buffer_size_frames * bpf;
self->buffer = g_try_malloc0 (self->buffer_size);
self->buffer_pos = 0;
@ -391,7 +394,7 @@ gst_audio_echo_transform_ip (GstBaseTransform * base, GstBuffer * buf)
}
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READWRITE);
num_samples = size / (GST_AUDIO_FILTER (self)->format.width / 8);
num_samples = size / GST_AUDIO_FILTER_BPS (self);
self->process (self, data, num_samples);

View file

@ -86,7 +86,7 @@ static void gst_audio_fir_filter_get_property (GObject * object, guint prop_id,
static void gst_audio_fir_filter_finalize (GObject * object);
static gboolean gst_audio_fir_filter_setup (GstAudioFilter * base,
GstRingBufferSpec * format);
GstAudioInfo * info);
static void
@ -183,17 +183,17 @@ gst_audio_fir_filter_init (GstAudioFIRFilter * self)
/* get notified of caps and plug in the correct process function */
static gboolean
gst_audio_fir_filter_setup (GstAudioFilter * base, GstRingBufferSpec * format)
gst_audio_fir_filter_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioFIRFilter *self = GST_AUDIO_FIR_FILTER (base);
gint new_rate = GST_AUDIO_INFO_RATE (info);
if (self->rate != format->rate) {
if (GST_AUDIO_FILTER_RATE (self) != new_rate) {
g_signal_emit (G_OBJECT (self),
gst_audio_fir_filter_signals[SIGNAL_RATE_CHANGED], 0, format->rate);
self->rate = format->rate;
gst_audio_fir_filter_signals[SIGNAL_RATE_CHANGED], 0, new_rate);
}
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, info);
}
static void

View file

@ -56,7 +56,6 @@ struct _GstAudioFIRFilter {
/* < private > */
GMutex *lock;
gint rate;
};
struct _GstAudioFIRFilterClass {

View file

@ -32,21 +32,15 @@
#include <gst/audio/gstaudiofilter.h>
#include <gst/controller/gstcontroller.h>
/* FIXME: Remove this once we depend on gst-plugins-base 0.10.26 */
#ifndef GST_AUDIO_FILTER_CAST
#define GST_AUDIO_FILTER_CAST(obj) ((GstAudioFilter *) (obj))
#endif
#include "audiofxbasefirfilter.h"
#define GST_CAT_DEFAULT gst_audio_fx_base_fir_filter_debug
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define ALLOWED_CAPS \
"audio/x-raw-float, " \
" width = (int) { 32, 64 }, " \
" endianness = (int) BYTE_ORDER, " \
" rate = (int) [ 1, MAX ], " \
"audio/x-raw, " \
" format=(string){"GST_AUDIO_NE(F32)","GST_AUDIO_NE(F64)"}, " \
" rate = (int) [ 1, MAX ], " \
" channels = (int) [ 1, MAX ]"
/* Switch from time-domain to FFT convolution for kernels >= this */
@ -76,7 +70,7 @@ static gboolean gst_audio_fx_base_fir_filter_transform_size (GstBaseTransform *
base, GstPadDirection direction, GstCaps * caps, gsize size,
GstCaps * othercaps, gsize * othersize);
static gboolean gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base,
GstRingBufferSpec * format);
GstAudioInfo * info);
static gboolean gst_audio_fx_base_fir_filter_query (GstPad * pad,
GstQuery * query);
@ -99,7 +93,7 @@ static const GstQueryType *gst_audio_fx_base_fir_filter_query_type (GstPad *
static guint \
process_##width (GstAudioFXBaseFIRFilter * self, const g##ctype * src, g##ctype * dst, guint input_samples) \
{ \
gint channels = GST_AUDIO_FILTER_CAST (self)->format.channels; \
gint channels = GST_AUDIO_FILTER_CHANNELS (self); \
TIME_DOMAIN_CONVOLUTION_BODY (channels); \
}
@ -238,7 +232,7 @@ static guint \
process_fft_##width (GstAudioFXBaseFIRFilter * self, const g##ctype * src, \
g##ctype * dst, guint input_samples) \
{ \
gint channels = GST_AUDIO_FILTER_CAST (self)->format.channels; \
gint channels = GST_AUDIO_FILTER_CHANNELS (self); \
FFT_CONVOLUTION_BODY (channels); \
}
@ -416,38 +410,46 @@ static void
/* Must be called with base transform lock! */
static void
gst_audio_fx_base_fir_filter_select_process_function (GstAudioFXBaseFIRFilter *
self, gint width, gint channels)
self, GstAudioFormat format, gint channels)
{
if (width == 32 && self->fft && !self->low_latency) {
if (channels == 1)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_1_32;
else if (channels == 2)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_2_32;
else
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_32;
} else if (width == 64 && self->fft && !self->low_latency) {
if (channels == 1)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_1_64;
else if (channels == 2)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_2_64;
else
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_64;
} else if (width == 32) {
if (channels == 1)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_1_32;
else if (channels == 2)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_2_32;
else
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_32;
} else if (width == 64) {
if (channels == 1)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_1_64;
else if (channels == 2)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_2_64;
else
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_64;
} else {
self->process = NULL;
switch (format) {
case GST_AUDIO_FORMAT_F32:
if (self->fft && !self->low_latency) {
if (channels == 1)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_1_32;
else if (channels == 2)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_2_32;
else
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_32;
} else {
if (channels == 1)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_1_32;
else if (channels == 2)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_2_32;
else
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_32;
}
break;
case GST_AUDIO_FORMAT_F64:
if (self->fft && !self->low_latency) {
if (channels == 1)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_1_64;
else if (channels == 2)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_2_64;
else
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_fft_64;
} else {
if (channels == 1)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_1_64;
else if (channels == 2)
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_2_64;
else
self->process = (GstAudioFXBaseFIRFilterProcessFunc) process_64;
}
break;
default:
self->process = NULL;
break;
}
}
@ -500,8 +502,7 @@ gst_audio_fx_base_fir_filter_set_property (GObject * object, guint prop_id,
self->low_latency = low_latency;
gst_audio_fx_base_fir_filter_calculate_frequency_response (self);
gst_audio_fx_base_fir_filter_select_process_function (self,
GST_AUDIO_FILTER_CAST (self)->format.width,
GST_AUDIO_FILTER_CAST (self)->format.channels);
GST_AUDIO_FILTER_FORMAT (self), GST_AUDIO_FILTER_CHANNELS (self));
}
GST_BASE_TRANSFORM_UNLOCK (self);
break;
@ -625,9 +626,9 @@ gst_audio_fx_base_fir_filter_push_residue (GstAudioFXBaseFIRFilter * self)
{
GstBuffer *outbuf;
GstFlowReturn res;
gint rate = GST_AUDIO_FILTER_CAST (self)->format.rate;
gint channels = GST_AUDIO_FILTER_CAST (self)->format.channels;
gint width = GST_AUDIO_FILTER_CAST (self)->format.width / 8;
gint rate = GST_AUDIO_FILTER_RATE (self);
gint channels = GST_AUDIO_FILTER_CHANNELS (self);
gint bps = GST_AUDIO_FILTER_BPS (self);
gint outsize, outsamples;
guint8 *in, *out, *data;
gsize size;
@ -648,7 +649,7 @@ gst_audio_fx_base_fir_filter_push_residue (GstAudioFXBaseFIRFilter * self)
self->buffer = NULL;
return;
}
outsize = outsamples * channels * width;
outsize = outsamples * channels * bps;
if (!self->fft || self->low_latency) {
gint64 diffsize, diffsamples;
@ -659,7 +660,7 @@ gst_audio_fx_base_fir_filter_push_residue (GstAudioFXBaseFIRFilter * self)
diffsamples =
((gint64) self->latency) - ((gint64) self->buffer_fill) / channels;
if (diffsamples > 0) {
diffsize = diffsamples * channels * width;
diffsize = diffsamples * channels * bps;
in = g_new0 (guint8, diffsize);
out = g_new0 (guint8, diffsize);
self->nsamples_out += self->process (self, in, out, diffsamples);
@ -684,15 +685,15 @@ gst_audio_fx_base_fir_filter_push_residue (GstAudioFXBaseFIRFilter * self)
while (gensamples < outsamples) {
guint step_insamples = self->block_length - self->buffer_fill;
guint8 *zeroes = g_new0 (guint8, step_insamples * channels * width);
guint8 *out = g_new (guint8, self->block_length * channels * width);
guint8 *zeroes = g_new0 (guint8, step_insamples * channels * bps);
guint8 *out = g_new (guint8, self->block_length * channels * bps);
guint step_gensamples;
step_gensamples = self->process (self, zeroes, out, step_insamples);
g_free (zeroes);
memcpy (data + gensamples * width, out, MIN (step_gensamples,
outsamples - gensamples) * width);
memcpy (data + gensamples * bps, out, MIN (step_gensamples,
outsamples - gensamples) * bps);
gensamples += MIN (step_gensamples, outsamples - gensamples);
g_free (out);
@ -742,8 +743,7 @@ gst_audio_fx_base_fir_filter_push_residue (GstAudioFXBaseFIRFilter * self)
/* get notified of caps and plug in the correct process function */
static gboolean
gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base,
GstRingBufferSpec * format)
gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
@ -759,8 +759,8 @@ gst_audio_fx_base_fir_filter_setup (GstAudioFilter * base,
self->nsamples_in = 0;
}
gst_audio_fx_base_fir_filter_select_process_function (self, format->width,
format->channels);
gst_audio_fx_base_fir_filter_select_process_function (self,
GST_AUDIO_INFO_FORMAT (info), GST_AUDIO_INFO_CHANNELS (info));
return (self->process != NULL);
}
@ -774,27 +774,23 @@ gst_audio_fx_base_fir_filter_transform_size (GstBaseTransform * base,
{
GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
guint blocklen;
GstStructure *s;
gint width, channels;
GstAudioInfo info;
gint bpf;
if (!self->fft || self->low_latency || direction == GST_PAD_SRC) {
*othersize = size;
return TRUE;
}
s = gst_caps_get_structure (caps, 0);
if (!gst_structure_get_int (s, "width", &width) ||
!gst_structure_get_int (s, "channels", &channels))
if (!gst_audio_info_from_caps (&info, caps))
return FALSE;
width /= 8;
size /= width * channels;
bpf = GST_AUDIO_INFO_BPF (&info);
size /= bpf;
blocklen = self->block_length - self->kernel_length + 1;
*othersize = ((size + blocklen - 1) / blocklen) * blocklen;
*othersize *= width * channels;
*othersize *= bpf;
return TRUE;
}
@ -805,9 +801,9 @@ gst_audio_fx_base_fir_filter_transform (GstBaseTransform * base,
{
GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (base);
GstClockTime timestamp, expected_timestamp;
gint channels = GST_AUDIO_FILTER_CAST (self)->format.channels;
gint rate = GST_AUDIO_FILTER_CAST (self)->format.rate;
gint width = GST_AUDIO_FILTER_CAST (self)->format.width / 8;
gint channels = GST_AUDIO_FILTER_CHANNELS (self);
gint rate = GST_AUDIO_FILTER_RATE (self);
gint bps = GST_AUDIO_FILTER_BPS (self);
guint8 *indata, *outdata;
gsize insize, outsize;
guint input_samples;
@ -867,8 +863,8 @@ gst_audio_fx_base_fir_filter_transform (GstBaseTransform * base,
indata = gst_buffer_map (inbuf, &insize, NULL, GST_MAP_READ);
outdata = gst_buffer_map (outbuf, &outsize, NULL, GST_MAP_WRITE);
input_samples = (insize / width) / channels;
output_samples = (outsize / width) / channels;
input_samples = (insize / bps) / channels;
output_samples = (outsize / bps) / channels;
self->nsamples_in += input_samples;
@ -892,8 +888,8 @@ gst_audio_fx_base_fir_filter_transform (GstBaseTransform * base,
diff = generated_samples - diff;
generated_samples = tmp;
}
gst_buffer_resize (outbuf, diff * width * channels,
generated_samples * width * channels);
gst_buffer_resize (outbuf, diff * bps * channels,
generated_samples * bps * channels);
output_offset = self->nsamples_out - self->latency - generated_samples;
GST_BUFFER_TIMESTAMP (outbuf) =
@ -963,7 +959,7 @@ gst_audio_fx_base_fir_filter_query (GstPad * pad, GstQuery * query)
gboolean live;
guint64 latency;
GstPad *peer;
gint rate = GST_AUDIO_FILTER (self)->format.rate;
gint rate = GST_AUDIO_FILTER_RATE (self);
if (rate == 0) {
res = FALSE;
@ -1081,8 +1077,7 @@ gst_audio_fx_base_fir_filter_set_kernel (GstAudioFXBaseFIRFilter * self,
gst_audio_fx_base_fir_filter_calculate_frequency_response (self);
gst_audio_fx_base_fir_filter_select_process_function (self,
GST_AUDIO_FILTER_CAST (self)->format.width,
GST_AUDIO_FILTER_CAST (self)->format.channels);
GST_AUDIO_FILTER_FORMAT (self), GST_AUDIO_FILTER_CHANNELS (self));
if (latency_changed) {
self->latency = latency;

View file

@ -36,10 +36,9 @@
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
#define ALLOWED_CAPS \
"audio/x-raw-float," \
" width = (int) { 32, 64 }, " \
" endianness = (int) BYTE_ORDER," \
" rate = (int) [ 1, MAX ]," \
"audio/x-raw," \
" format=(string){"GST_AUDIO_NE(F32)","GST_AUDIO_NE(F64)"}," \
" rate = (int) [ 1, MAX ]," \
" channels = (int) [ 1, MAX ]"
#define gst_audio_fx_base_iir_filter_parent_class parent_class
@ -47,7 +46,7 @@ G_DEFINE_TYPE (GstAudioFXBaseIIRFilter,
gst_audio_fx_base_iir_filter, GST_TYPE_AUDIO_FILTER);
static gboolean gst_audio_fx_base_iir_filter_setup (GstAudioFilter * filter,
GstRingBufferSpec * format);
GstAudioInfo * info);
static GstFlowReturn
gst_audio_fx_base_iir_filter_transform_ip (GstBaseTransform * base,
GstBuffer * buf);
@ -237,48 +236,50 @@ gst_audio_fx_base_iir_filter_set_coefficients (GstAudioFXBaseIIRFilter * filter,
/* GstAudioFilter vmethod implementations */
static gboolean
gst_audio_fx_base_iir_filter_setup (GstAudioFilter * base,
GstRingBufferSpec * format)
gst_audio_fx_base_iir_filter_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (base);
gboolean ret = TRUE;
gint channels;
if (format->width == 32)
filter->process = (GstAudioFXBaseIIRFilterProcessFunc)
process_32;
else if (format->width == 64)
filter->process = (GstAudioFXBaseIIRFilterProcessFunc)
process_64;
else
ret = FALSE;
switch (GST_AUDIO_INFO_FORMAT (info)) {
case GST_AUDIO_FORMAT_F32:
filter->process = (GstAudioFXBaseIIRFilterProcessFunc)
process_32;
break;
case GST_AUDIO_FORMAT_F64:
filter->process = (GstAudioFXBaseIIRFilterProcessFunc)
process_64;
break;
default:
ret = FALSE;
break;
}
if (format->channels != filter->nchannels) {
channels = GST_AUDIO_INFO_CHANNELS (info);
if (channels != filter->nchannels) {
guint i;
GstAudioFXBaseIIRFilterChannelCtx *ctx;
if (filter->channels) {
for (i = 0; i < filter->nchannels; i++) {
ctx = &filter->channels[i];
g_free (ctx->x);
g_free (ctx->y);
}
g_free (filter->channels);
filter->channels = NULL;
}
filter->nchannels = format->channels;
filter->channels =
g_new0 (GstAudioFXBaseIIRFilterChannelCtx, filter->nchannels);
filter->channels = g_new0 (GstAudioFXBaseIIRFilterChannelCtx, channels);
for (i = 0; i < filter->nchannels; i++) {
ctx = &filter->channels[i];
ctx->x = g_new0 (gdouble, filter->na);
ctx->y = g_new0 (gdouble, filter->nb);
}
filter->nchannels = channels;
}
return ret;
@ -327,7 +328,7 @@ static void \
process_##width (GstAudioFXBaseIIRFilter * filter, \
g##ctype * data, guint num_samples) \
{ \
gint i, j, channels = GST_AUDIO_FILTER (filter)->format.channels; \
gint i, j, channels = filter->nchannels; \
gdouble val; \
\
for (i = 0; i < num_samples / channels; i++) { \
@ -370,7 +371,7 @@ gst_audio_fx_base_iir_filter_transform_ip (GstBaseTransform * base,
g_return_val_if_fail (filter->a != NULL, GST_FLOW_ERROR);
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READWRITE);
num_samples = size / (GST_AUDIO_FILTER (filter)->format.width / 8);
num_samples = size / GST_AUDIO_FILTER_BPS (filter);
filter->process (filter, data, num_samples);
@ -384,7 +385,7 @@ static gboolean
gst_audio_fx_base_iir_filter_stop (GstBaseTransform * base)
{
GstAudioFXBaseIIRFilter *filter = GST_AUDIO_FX_BASE_IIR_FILTER (base);
guint channels = GST_AUDIO_FILTER (filter)->format.channels;
guint channels = filter->nchannels;
GstAudioFXBaseIIRFilterChannelCtx *ctx;
guint i;
@ -399,6 +400,7 @@ gst_audio_fx_base_iir_filter_stop (GstBaseTransform * base)
g_free (filter->channels);
}
filter->channels = NULL;
filter->nchannels = 0;
return TRUE;
}

View file

@ -82,7 +82,7 @@ static void gst_audio_iir_filter_get_property (GObject * object, guint prop_id,
static void gst_audio_iir_filter_finalize (GObject * object);
static gboolean gst_audio_iir_filter_setup (GstAudioFilter * base,
GstRingBufferSpec * format);
GstAudioInfo * info);
static void
gst_audio_iir_filter_class_init (GstAudioIIRFilterClass * klass)
@ -200,17 +200,17 @@ gst_audio_iir_filter_init (GstAudioIIRFilter * self)
/* get notified of caps and plug in the correct process function */
static gboolean
gst_audio_iir_filter_setup (GstAudioFilter * base, GstRingBufferSpec * format)
gst_audio_iir_filter_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioIIRFilter *self = GST_AUDIO_IIR_FILTER (base);
gint new_rate = GST_AUDIO_INFO_RATE (info);
if (self->rate != format->rate) {
if (GST_AUDIO_FILTER_RATE (self) != new_rate) {
g_signal_emit (G_OBJECT (self),
gst_audio_iir_filter_signals[SIGNAL_RATE_CHANGED], 0, format->rate);
self->rate = format->rate;
gst_audio_iir_filter_signals[SIGNAL_RATE_CHANGED], 0, new_rate);
}
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, info);
}
static void

View file

@ -55,7 +55,6 @@ struct _GstAudioIIRFilter {
/* < private > */
GMutex *lock;
gint rate;
};
struct _GstAudioIIRFilterClass {

View file

@ -65,18 +65,10 @@ enum
};
#define ALLOWED_CAPS \
"audio/x-raw-int," \
" depth=(int)16," \
" width=(int)16," \
" endianness=(int)BYTE_ORDER," \
" signed=(bool)TRUE," \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX]; " \
"audio/x-raw-float," \
" width=(int)32," \
" endianness=(int)BYTE_ORDER," \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX]"
"audio/x-raw," \
" format=(string) {"GST_AUDIO_NE(S16)","GST_AUDIO_NE(F32)"}," \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX] "
G_DEFINE_TYPE (GstAudioInvert, gst_audio_invert, GST_TYPE_AUDIO_FILTER);
@ -86,7 +78,7 @@ static void gst_audio_invert_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_audio_invert_setup (GstAudioFilter * filter,
GstRingBufferSpec * format);
GstAudioInfo * info);
static GstFlowReturn gst_audio_invert_transform_ip (GstBaseTransform * base,
GstBuffer * buf);
@ -180,20 +172,24 @@ gst_audio_invert_get_property (GObject * object, guint prop_id,
/* GstAudioFilter vmethod implementations */
static gboolean
gst_audio_invert_setup (GstAudioFilter * base, GstRingBufferSpec * format)
gst_audio_invert_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioInvert *filter = GST_AUDIO_INVERT (base);
gboolean ret = TRUE;
if (format->type == GST_BUFTYPE_FLOAT && format->width == 32)
filter->process = (GstAudioInvertProcessFunc)
gst_audio_invert_transform_float;
else if (format->type == GST_BUFTYPE_LINEAR && format->width == 16)
filter->process = (GstAudioInvertProcessFunc)
gst_audio_invert_transform_int;
else
ret = FALSE;
switch (GST_AUDIO_INFO_FORMAT (info)) {
case GST_AUDIO_FORMAT_S16:
filter->process = (GstAudioInvertProcessFunc)
gst_audio_invert_transform_int;
break;
case GST_AUDIO_FORMAT_F32:
filter->process = (GstAudioInvertProcessFunc)
gst_audio_invert_transform_float;
break;
default:
ret = FALSE;
break;
}
return ret;
}
@ -250,7 +246,7 @@ gst_audio_invert_transform_ip (GstBaseTransform * base, GstBuffer * buf)
return GST_FLOW_OK;
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READWRITE);
num_samples = size / (GST_AUDIO_FILTER (filter)->format.width / 8);
num_samples = size / GST_AUDIO_FILTER_BPS (filter);
filter->process (filter, data, num_samples);

View file

@ -72,17 +72,9 @@ enum
};
#define ALLOWED_CAPS \
"audio/x-raw-int," \
" depth=(int)16," \
" width=(int)16," \
" endianness=(int)BYTE_ORDER," \
" signed=(bool)TRUE," \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX]; " \
"audio/x-raw-float," \
" width=(int)32," \
" endianness=(int)BYTE_ORDER," \
" rate=(int)[1,MAX]," \
"audio/x-raw," \
" format=(string){"GST_AUDIO_NE(S16)","GST_AUDIO_NE(F32)"}," \
" rate=(int)[1,MAX]," \
" channels=(int)[1,MAX]"
G_DEFINE_TYPE (GstAudioKaraoke, gst_audio_karaoke, GST_TYPE_AUDIO_FILTER);
@ -93,7 +85,7 @@ static void gst_audio_karaoke_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
static gboolean gst_audio_karaoke_setup (GstAudioFilter * filter,
GstRingBufferSpec * format);
GstAudioInfo * info);
static GstFlowReturn gst_audio_karaoke_transform_ip (GstBaseTransform * base,
GstBuffer * buf);
@ -168,10 +160,12 @@ gst_audio_karaoke_init (GstAudioKaraoke * filter)
}
static void
update_filter (GstAudioKaraoke * filter, gint rate)
update_filter (GstAudioKaraoke * filter)
{
gfloat A, B, C;
gint rate;
rate = GST_AUDIO_FILTER_RATE (filter);
if (rate == 0)
return;
@ -203,11 +197,11 @@ gst_audio_karaoke_set_property (GObject * object, guint prop_id,
break;
case PROP_FILTER_BAND:
filter->filter_band = g_value_get_float (value);
update_filter (filter, filter->rate);
update_filter (filter);
break;
case PROP_FILTER_WIDTH:
filter->filter_width = g_value_get_float (value);
update_filter (filter, filter->rate);
update_filter (filter);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -245,24 +239,25 @@ gst_audio_karaoke_get_property (GObject * object, guint prop_id,
/* GstAudioFilter vmethod implementations */
static gboolean
gst_audio_karaoke_setup (GstAudioFilter * base, GstRingBufferSpec * format)
gst_audio_karaoke_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioKaraoke *filter = GST_AUDIO_KARAOKE (base);
gboolean ret = TRUE;
filter->channels = format->channels;
filter->rate = format->rate;
if (format->type == GST_BUFTYPE_FLOAT && format->width == 32)
filter->process = (GstAudioKaraokeProcessFunc)
gst_audio_karaoke_transform_float;
else if (format->type == GST_BUFTYPE_LINEAR && format->width == 16)
filter->process = (GstAudioKaraokeProcessFunc)
gst_audio_karaoke_transform_int;
else
ret = FALSE;
update_filter (filter, format->rate);
switch (GST_AUDIO_INFO_FORMAT (info)) {
case GST_AUDIO_FORMAT_S16:
filter->process = (GstAudioKaraokeProcessFunc)
gst_audio_karaoke_transform_int;
break;
case GST_AUDIO_FORMAT_F32:
filter->process = (GstAudioKaraokeProcessFunc)
gst_audio_karaoke_transform_float;
break;
default:
ret = FALSE;
break;
}
update_filter (filter);
return ret;
}
@ -276,7 +271,7 @@ gst_audio_karaoke_transform_int (GstAudioKaraoke * filter,
gdouble y;
gint level;
channels = filter->channels;
channels = GST_AUDIO_FILTER_CHANNELS (filter);
level = filter->level * 256;
for (i = 0; i < num_samples; i += channels) {
@ -309,7 +304,7 @@ gst_audio_karaoke_transform_float (GstAudioKaraoke * filter,
gdouble l, r, o;
gdouble y;
channels = filter->channels;
channels = GST_AUDIO_FILTER_CHANNELS (filter);
for (i = 0; i < num_samples; i += channels) {
/* get left and right inputs */
@ -353,7 +348,7 @@ gst_audio_karaoke_transform_ip (GstBaseTransform * base, GstBuffer * buf)
return GST_FLOW_OK;
data = gst_buffer_map (buf, &size, NULL, GST_MAP_READWRITE);
num_samples = size / (GST_AUDIO_FILTER (filter)->format.width / 8);
num_samples = size / GST_AUDIO_FILTER_BPS (filter);
filter->process (filter, data, num_samples);

View file

@ -42,9 +42,6 @@ struct _GstAudioKaraoke
{
GstAudioFilter audiofilter;
gint channels;
gint rate;
/* properties */
gfloat level;
gfloat mono_level;

View file

@ -149,8 +149,7 @@ static void gst_audio_wsincband_get_property (GObject * object, guint prop_id,
static void gst_audio_wsincband_finalize (GObject * object);
static gboolean gst_audio_wsincband_setup (GstAudioFilter * base,
GstRingBufferSpec * format);
GstAudioInfo * info);
#define POW2(x) (x)*(x)
@ -228,26 +227,27 @@ gst_audio_wsincband_build_kernel (GstAudioWSincBand * self)
gdouble *kernel_lp, *kernel_hp;
gdouble w;
gdouble *kernel;
gint rate, channels;
len = self->kernel_length;
if (GST_AUDIO_FILTER (self)->format.rate == 0) {
rate = GST_AUDIO_FILTER_RATE (self);
channels = GST_AUDIO_FILTER_CHANNELS (self);
if (rate == 0) {
GST_DEBUG ("rate not set yet");
return;
}
if (GST_AUDIO_FILTER (self)->format.channels == 0) {
if (channels == 0) {
GST_DEBUG ("channels not set yet");
return;
}
/* Clamp frequencies */
self->lower_frequency =
CLAMP (self->lower_frequency, 0.0,
GST_AUDIO_FILTER (self)->format.rate / 2);
self->upper_frequency =
CLAMP (self->upper_frequency, 0.0,
GST_AUDIO_FILTER (self)->format.rate / 2);
self->lower_frequency = CLAMP (self->lower_frequency, 0.0, rate / 2);
self->upper_frequency = CLAMP (self->upper_frequency, 0.0, rate / 2);
if (self->lower_frequency > self->upper_frequency) {
gint tmp = self->lower_frequency;
@ -262,7 +262,7 @@ gst_audio_wsincband_build_kernel (GstAudioWSincBand * self)
(self->mode == MODE_BAND_PASS) ? "band-pass" : "band-reject");
/* fill the lp kernel */
w = 2 * G_PI * (self->lower_frequency / GST_AUDIO_FILTER (self)->format.rate);
w = 2 * G_PI * (self->lower_frequency / rate);
kernel_lp = g_new (gdouble, len);
for (i = 0; i < len; ++i) {
if (i == (len - 1) / 2.0)
@ -299,7 +299,7 @@ gst_audio_wsincband_build_kernel (GstAudioWSincBand * self)
kernel_lp[i] /= sum;
/* fill the hp kernel */
w = 2 * G_PI * (self->upper_frequency / GST_AUDIO_FILTER (self)->format.rate);
w = 2 * G_PI * (self->upper_frequency / rate);
kernel_hp = g_new (gdouble, len);
for (i = 0; i < len; ++i) {
if (i == (len - 1) / 2.0)
@ -371,13 +371,13 @@ gst_audio_wsincband_build_kernel (GstAudioWSincBand * self)
/* get notified of caps and plug in the correct process function */
static gboolean
gst_audio_wsincband_setup (GstAudioFilter * base, GstRingBufferSpec * format)
gst_audio_wsincband_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioWSincBand *self = GST_AUDIO_WSINC_BAND (base);
gst_audio_wsincband_build_kernel (self);
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, info);
}
static void

View file

@ -1,5 +1,5 @@
/* -*- c-basic-offset: 2 -*-
*
*
* GStreamer
* Copyright (C) 1999-2001 Erik Walthinsen <omega@cse.ogi.edu>
* 2006 Dreamlab Technologies Ltd. <mathis.hofer@dreamlab.net>
@ -19,8 +19,8 @@
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
*
*
*
* this windowed sinc filter is taken from the freely downloadable DSP book,
* "The Scientist and Engineer's Guide to Digital Signal Processing",
* chapter 16

View file

@ -148,7 +148,7 @@ static void gst_audio_wsinclimit_get_property (GObject * object, guint prop_id,
static void gst_audio_wsinclimit_finalize (GObject * object);
static gboolean gst_audio_wsinclimit_setup (GstAudioFilter * base,
GstRingBufferSpec * format);
GstAudioInfo * info);
#define POW2(x) (x)*(x)
@ -221,22 +221,25 @@ gst_audio_wsinclimit_build_kernel (GstAudioWSincLimit * self)
gint len = 0;
gdouble w;
gdouble *kernel = NULL;
gint rate, channels;
len = self->kernel_length;
if (GST_AUDIO_FILTER (self)->format.rate == 0) {
rate = GST_AUDIO_FILTER_RATE (self);
channels = GST_AUDIO_FILTER_CHANNELS (self);
if (rate == 0) {
GST_DEBUG ("rate not set yet");
return;
}
if (GST_AUDIO_FILTER (self)->format.channels == 0) {
if (channels == 0) {
GST_DEBUG ("channels not set yet");
return;
}
/* Clamp cutoff frequency between 0 and the nyquist frequency */
self->cutoff =
CLAMP (self->cutoff, 0.0, GST_AUDIO_FILTER (self)->format.rate / 2);
self->cutoff = CLAMP (self->cutoff, 0.0, rate / 2);
GST_DEBUG ("gst_audio_wsinclimit_: initializing filter kernel of length %d "
"with cutoff %.2lf Hz "
@ -245,7 +248,7 @@ gst_audio_wsinclimit_build_kernel (GstAudioWSincLimit * self)
(self->mode == MODE_LOW_PASS) ? "low-pass" : "high-pass");
/* fill the kernel */
w = 2 * G_PI * (self->cutoff / GST_AUDIO_FILTER (self)->format.rate);
w = 2 * G_PI * (self->cutoff / rate);
kernel = g_new (gdouble, len);
@ -303,13 +306,13 @@ gst_audio_wsinclimit_build_kernel (GstAudioWSincLimit * self)
/* get notified of caps and plug in the correct process function */
static gboolean
gst_audio_wsinclimit_setup (GstAudioFilter * base, GstRingBufferSpec * format)
gst_audio_wsinclimit_setup (GstAudioFilter * base, GstAudioInfo * info)
{
GstAudioWSincLimit *self = GST_AUDIO_WSINC_LIMIT (base);
gst_audio_wsinclimit_build_kernel (self);
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, format);
return GST_AUDIO_FILTER_CLASS (parent_class)->setup (base, info);
}
static void