Use the double precision versions of fftw functions so we don't depend on fftwf

This commit is contained in:
David Sansome 2012-05-27 21:39:53 +01:00
parent 4cfa474fb8
commit 0533f015cf
6 changed files with 49 additions and 49 deletions

View File

@ -25,5 +25,5 @@ target_link_libraries(gstmoodbar
${GLIB_LIBRARIES} ${GLIB_LIBRARIES}
${GSTREAMER_LIBRARIES} ${GSTREAMER_LIBRARIES}
${GSTREAMER_BASE_LIBRARIES} ${GSTREAMER_BASE_LIBRARIES}
${FFTW3_FFTWF_LIBRARY} ${FFTW3_FFTW_LIBRARY}
) )

View File

@ -107,7 +107,7 @@ static GstStateChangeReturn gst_fftwspectrum_change_state (GstElement *element,
GstStateChange transition); GstStateChange transition);
#define OUTPUT_SIZE(conv) (((conv)->size/2+1)*sizeof(fftwf_complex)) #define OUTPUT_SIZE(conv) (((conv)->size/2+1)*sizeof(fftw_complex))
/***************************************************************/ /***************************************************************/
@ -275,11 +275,11 @@ static void
free_fftw_data (GstFFTWSpectrum *conv) free_fftw_data (GstFFTWSpectrum *conv)
{ {
if(conv->fftw_plan != NULL) if(conv->fftw_plan != NULL)
fftwf_destroy_plan (conv->fftw_plan); fftw_destroy_plan (conv->fftw_plan);
if(conv->fftw_in != NULL) if(conv->fftw_in != NULL)
fftwf_free (conv->fftw_in); fftw_free (conv->fftw_in);
if(conv->fftw_out != NULL) if(conv->fftw_out != NULL)
fftwf_free (conv->fftw_out); fftw_free (conv->fftw_out);
conv->fftw_in = NULL; conv->fftw_in = NULL;
conv->fftw_out = NULL; conv->fftw_out = NULL;
@ -294,8 +294,8 @@ alloc_fftw_data (GstFFTWSpectrum *conv)
GST_DEBUG ("Allocating data for size = %d and step = %d", GST_DEBUG ("Allocating data for size = %d and step = %d",
conv->size, conv->step); conv->size, conv->step);
conv->fftw_in = (float *) fftwf_malloc (sizeof(float) * conv->size); conv->fftw_in = (double *) fftw_malloc (sizeof(double) * conv->size);
conv->fftw_out = (float *) fftwf_malloc (OUTPUT_SIZE (conv)); conv->fftw_out = (double *) fftw_malloc (OUTPUT_SIZE (conv));
/* We use the simplest real-to-complex algorithm, which takes n real /* We use the simplest real-to-complex algorithm, which takes n real
* inputs and returns floor(n/2) + 1 complex outputs (the other n/2 * inputs and returns floor(n/2) + 1 complex outputs (the other n/2
@ -306,8 +306,8 @@ alloc_fftw_data (GstFFTWSpectrum *conv)
static GStaticMutex mutex = G_STATIC_MUTEX_INIT; static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
g_static_mutex_lock(&mutex); g_static_mutex_lock(&mutex);
conv->fftw_plan conv->fftw_plan
= fftwf_plan_dft_r2c_1d(conv->size, conv->fftw_in, = fftw_plan_dft_r2c_1d(conv->size, conv->fftw_in,
(fftwf_complex *) conv->fftw_out, (fftw_complex *) conv->fftw_out,
conv->hi_q ? FFTW_MEASURE : FFTW_ESTIMATE); conv->hi_q ? FFTW_MEASURE : FFTW_ESTIMATE);
g_static_mutex_unlock(&mutex); g_static_mutex_unlock(&mutex);
} }
@ -504,7 +504,7 @@ gst_fftwspectrum_change_state (GstElement * element,
alloc_fftw_data (conv); alloc_fftw_data (conv);
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
conv->samples = (gfloat *) g_malloc (sizeof(gfloat)); conv->samples = (gdouble *) g_malloc (sizeof(gdouble));
conv->numsamples = 0; conv->numsamples = 0;
conv->timestamp = 0; conv->timestamp = 0;
conv->offset = 0; conv->offset = 0;
@ -545,13 +545,13 @@ gst_fftwspectrum_change_state (GstElement * element,
static void static void
push_samples (GstFFTWSpectrum *conv, GstBuffer *buf) push_samples (GstFFTWSpectrum *conv, GstBuffer *buf)
{ {
gint newsamples = GST_BUFFER_SIZE (buf) / sizeof (gfloat); gint newsamples = GST_BUFFER_SIZE (buf) / sizeof (gdouble);
gint oldsamples = conv->numsamples; gint oldsamples = conv->numsamples;
conv->numsamples += newsamples; conv->numsamples += newsamples;
conv->samples = g_realloc (conv->samples, conv->numsamples * sizeof (gfloat)); conv->samples = g_realloc (conv->samples, conv->numsamples * sizeof (gdouble));
memcpy (&conv->samples[oldsamples], GST_BUFFER_DATA (buf), memcpy (&conv->samples[oldsamples], GST_BUFFER_DATA (buf),
newsamples * sizeof (gfloat)); newsamples * sizeof (gdouble));
/* GST_LOG ("Added %d samples", newsamples); */ /* GST_LOG ("Added %d samples", newsamples); */
} }
@ -562,12 +562,12 @@ push_samples (GstFFTWSpectrum *conv, GstBuffer *buf)
static void static void
shift_samples (GstFFTWSpectrum *conv, gint toshift) shift_samples (GstFFTWSpectrum *conv, gint toshift)
{ {
gfloat *oldsamples = conv->samples; gdouble *oldsamples = conv->samples;
conv->numsamples -= toshift; conv->numsamples -= toshift;
conv->samples = g_malloc (MAX (conv->numsamples, 1) * sizeof (float)); conv->samples = g_malloc (MAX (conv->numsamples, 1) * sizeof (double));
memcpy (conv->samples, &oldsamples[toshift], memcpy (conv->samples, &oldsamples[toshift],
conv->numsamples * sizeof (gfloat)); conv->numsamples * sizeof (gdouble));
g_free (oldsamples); g_free (oldsamples);
/* Fix the timestamp and offset */ /* Fix the timestamp and offset */
@ -613,8 +613,8 @@ gst_fftwspectrum_chain (GstPad * pad, GstBuffer * buf)
= gst_util_uint64_scale_int (GST_SECOND, conv->step, conv->rate); = gst_util_uint64_scale_int (GST_SECOND, conv->step, conv->rate);
/* Do the Fourier transform */ /* Do the Fourier transform */
memcpy (conv->fftw_in, conv->samples, conv->size * sizeof (float)); memcpy (conv->fftw_in, conv->samples, conv->size * sizeof (double));
fftwf_execute (conv->fftw_plan); fftw_execute (conv->fftw_plan);
{ /* Normalize */ { /* Normalize */
gint i; gint i;
gfloat root = sqrtf (conv->size); gfloat root = sqrtf (conv->size);

View File

@ -41,15 +41,15 @@ struct _GstFFTWSpectrum
gint rate, size, step; gint rate, size, step;
/* Actual queued (incoming) stream */ /* Actual queued (incoming) stream */
gfloat *samples; gdouble *samples;
gint numsamples; gint numsamples;
GstClockTime timestamp; /* Timestamp of the first sample */ GstClockTime timestamp; /* Timestamp of the first sample */
guint64 offset; /* Offset of the first sample */ guint64 offset; /* Offset of the first sample */
/* State data for fftw */ /* State data for fftw */
float *fftw_in; double *fftw_in;
float *fftw_out; double *fftw_out;
fftwf_plan fftw_plan; fftw_plan fftw_plan;
/* Properties */ /* Properties */
gint32 def_size, def_step; gint32 def_size, def_step;

View File

@ -386,9 +386,9 @@ gst_moodbar_change_state (GstElement *element, GstStateChange transition)
calc_barkband_table (mood); calc_barkband_table (mood);
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
mood->r = (gfloat *) g_malloc (FRAME_CHUNK * sizeof(gfloat)); mood->r = (gdouble *) g_malloc (FRAME_CHUNK * sizeof(gdouble));
mood->g = (gfloat *) g_malloc (FRAME_CHUNK * sizeof(gfloat)); mood->g = (gdouble *) g_malloc (FRAME_CHUNK * sizeof(gdouble));
mood->b = (gfloat *) g_malloc (FRAME_CHUNK * sizeof(gfloat)); mood->b = (gdouble *) g_malloc (FRAME_CHUNK * sizeof(gdouble));
mood->numframes = 0; mood->numframes = 0;
break; break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING: case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
@ -438,11 +438,11 @@ allocate_another_frame (GstMoodbar *mood)
if(mood->numframes % FRAME_CHUNK == 0) if(mood->numframes % FRAME_CHUNK == 0)
{ {
guint size = (mood->numframes + FRAME_CHUNK) * sizeof (gfloat); guint size = (mood->numframes + FRAME_CHUNK) * sizeof (gdouble);
mood->r = (gfloat *) g_realloc (mood->r, size); mood->r = (gdouble *) g_realloc (mood->r, size);
mood->g = (gfloat *) g_realloc (mood->g, size); mood->g = (gdouble *) g_realloc (mood->g, size);
mood->b = (gfloat *) g_realloc (mood->b, size); mood->b = (gdouble *) g_realloc (mood->b, size);
if (mood->r == NULL || mood->g == NULL || mood->b == NULL) if (mood->r == NULL || mood->g == NULL || mood->b == NULL)
return FALSE; return FALSE;
@ -461,17 +461,17 @@ gst_moodbar_chain (GstPad *pad, GstBuffer *buf)
{ {
GstMoodbar *mood = GST_MOODBAR (gst_pad_get_parent (pad)); GstMoodbar *mood = GST_MOODBAR (gst_pad_get_parent (pad));
guint i; guint i;
gfloat amplitudes[24], rgb[3] = {0.f, 0.f, 0.f}; gdouble amplitudes[24], rgb[3] = {0.f, 0.f, 0.f};
gfloat *out, real, imag; gdouble *out, real, imag;
guint numfreqs = NUMFREQS (mood); guint numfreqs = NUMFREQS (mood);
if (GST_BUFFER_SIZE (buf) != numfreqs * sizeof (gfloat) * 2) if (GST_BUFFER_SIZE (buf) != numfreqs * sizeof (gdouble) * 2)
{ {
gst_object_unref (mood); gst_object_unref (mood);
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
} }
out = (gfloat *) GST_BUFFER_DATA (buf); out = (gdouble *) GST_BUFFER_DATA (buf);
if (!allocate_another_frame (mood)) if (!allocate_another_frame (mood))
return GST_FLOW_ERROR; return GST_FLOW_ERROR;
@ -512,11 +512,11 @@ gst_moodbar_chain (GstPad *pad, GstBuffer *buf)
* library, normalise.cpp * library, normalise.cpp
*/ */
static void static void
normalize (gfloat *vals, guint numvals) normalize (gdouble *vals, guint numvals)
{ {
gfloat mini, maxi, tu = 0.f, tb = 0.f; gdouble mini, maxi, tu = 0.f, tb = 0.f;
gfloat avgu = 0.f, avgb = 0.f, delta, avg = 0.f; gdouble avgu = 0.f, avgb = 0.f, delta, avg = 0.f;
gfloat avguu = 0.f, avgbb = 0.f; gdouble avguu = 0.f, avgbb = 0.f;
guint i; guint i;
gint t = 0; gint t = 0;
@ -537,7 +537,7 @@ normalize (gfloat *vals, guint numvals)
{ {
if(vals[i] != mini && vals[i] != maxi) if(vals[i] != mini && vals[i] != maxi)
{ {
avg += vals[i] / ((gfloat) numvals); avg += vals[i] / ((gdouble) numvals);
t++; t++;
} }
} }
@ -559,8 +559,8 @@ normalize (gfloat *vals, guint numvals)
} }
} }
avgu /= (gfloat) tu; avgu /= (gdouble) tu;
avgb /= (gfloat) tb; avgb /= (gdouble) tb;
tu = 0.f; tu = 0.f;
tb = 0.f; tb = 0.f;
@ -582,8 +582,8 @@ normalize (gfloat *vals, guint numvals)
} }
} }
avguu /= (gfloat) tu; avguu /= (gdouble) tu;
avgbb /= (gfloat) tb; avgbb /= (gdouble) tb;
mini = MAX (avg + (avgb - avg) * 2.f, avgbb); mini = MAX (avg + (avgb - avg) * 2.f, avgbb);
maxi = MIN (avg + (avgu - avg) * 2.f, avguu); maxi = MIN (avg + (avgu - avg) * 2.f, avguu);
@ -628,7 +628,7 @@ gst_moodbar_finish (GstMoodbar *mood)
GST_BUFFER_OFFSET (buf) = 0; GST_BUFFER_OFFSET (buf) = 0;
data = (guchar *) GST_BUFFER_DATA (buf); data = (guchar *) GST_BUFFER_DATA (buf);
gfloat r, g, b; gdouble r, g, b;
guint i, j, n; guint i, j, n;
guint start, end; guint start, end;
for (line = 0; line < mood->height; ++line) for (line = 0; line < mood->height; ++line)
@ -650,9 +650,9 @@ gst_moodbar_finish (GstMoodbar *mood)
n = end - start; n = end - start;
*(data++) = (guchar) (r / ((gfloat) n)); *(data++) = (guchar) (r / ((gdouble) n));
*(data++) = (guchar) (g / ((gfloat) n)); *(data++) = (guchar) (g / ((gdouble) n));
*(data++) = (guchar) (b / ((gfloat) n)); *(data++) = (guchar) (b / ((gdouble) n));
} }
} }

View File

@ -43,7 +43,7 @@ struct _GstMoodbar
guint *barkband_table; guint *barkband_table;
/* Queued moodbar data */ /* Queued moodbar data */
gfloat *r, *g, *b; gdouble *r, *g, *b;
guint numframes; guint numframes;
/* Property */ /* Property */

View File

@ -22,7 +22,7 @@
"rate = (int) [ 1, MAX ], " \ "rate = (int) [ 1, MAX ], " \
"channels = (int) 1, " \ "channels = (int) 1, " \
"endianness = (int) BYTE_ORDER, " \ "endianness = (int) BYTE_ORDER, " \
"width = (int) 32, " \ "width = (int) 64, " \
"signed = (boolean) true" "signed = (boolean) true"
/* audio/x-spectrum-complex-float is an array of complex floats. A /* audio/x-spectrum-complex-float is an array of complex floats. A
@ -44,7 +44,7 @@
#define SPECTRUM_FREQ_CAPS "audio/x-spectrum-complex-float, " \ #define SPECTRUM_FREQ_CAPS "audio/x-spectrum-complex-float, " \
"rate = (int) [ 1, MAX ], " \ "rate = (int) [ 1, MAX ], " \
"endianness = (int) BYTE_ORDER, " \ "endianness = (int) BYTE_ORDER, " \
"width = (int) 32, " \ "width = (int) 64, " \
"size = (int) [ 1, MAX ], " \ "size = (int) [ 1, MAX ], " \
"step = (int) [ 1, MAX ]" "step = (int) [ 1, MAX ]"