Use the double precision versions of fftw functions so we don't depend on fftwf
This commit is contained in:
parent
4cfa474fb8
commit
0533f015cf
@ -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}
|
||||||
)
|
)
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -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 ]"
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user