/* extract log scaled, mel-shaped, frequency bins */ float * recur_extract_log_freq_bins(RecurAudioBinner *ab, float *data){ /* XXX assumes ab->value_size is 2 */ const float *windowed_data = recur_apply_window(ab, data, data); gst_fft_f32_fft(ab->fft, windowed_data, ab->freq_data ); return recur_bin_complex(ab, ab->freq_data); }
void FFTFrame::doFFT(const float* data) { gst_fft_f32_fft(m_fft, data, m_complexData); // Scale the frequency domain data to match vecLib's scale factor // on the Mac. FIXME: if we change the definition of FFTFrame to // eliminate this scale factor then this code will need to change. // Also, if this loop turns out to be hot then we should use SSE // or other intrinsics to accelerate it. float scaleFactor = 2; float* imagData = m_imagData.data(); float* realData = m_realData.data(); for (unsigned i = 0; i < unpackedFFTDataSize(m_FFTSize); ++i) { imagData[i] = m_complexData[i].i * scaleFactor; realData[i] = m_complexData[i].r * scaleFactor; } }
static void gst_spectrum_run_fft (GstSpectrum * spectrum, GstSpectrumChannel * cd, guint input_pos) { guint i; guint bands = spectrum->bands; guint nfft = 2 * bands - 2; gint threshold = spectrum->threshold; gfloat *input = cd->input; gfloat *input_tmp = cd->input_tmp; gfloat *spect_magnitude = cd->spect_magnitude; gfloat *spect_phase = cd->spect_phase; GstFFTF32Complex *freqdata = cd->freqdata; GstFFTF32 *fft_ctx = cd->fft_ctx; for (i = 0; i < nfft; i++) input_tmp[i] = input[(input_pos + i) % nfft]; gst_fft_f32_window (fft_ctx, input_tmp, GST_FFT_WINDOW_HAMMING); gst_fft_f32_fft (fft_ctx, input_tmp, freqdata); if (spectrum->message_magnitude) { gdouble val; /* Calculate magnitude in db */ for (i = 0; i < bands; i++) { val = freqdata[i].r * freqdata[i].r; val += freqdata[i].i * freqdata[i].i; val /= nfft * nfft; val = 10.0 * log10 (val); if (val < threshold) val = threshold; spect_magnitude[i] += val; } } if (spectrum->message_phase) { /* Calculate phase */ for (i = 0; i < bands; i++) spect_phase[i] += atan2 (freqdata[i].i, freqdata[i].r); } }
static void bp_vis_pcm_handoff (GstElement *sink, GstBuffer *buffer, GstPad *pad, gpointer userdata) { BansheePlayer *player = (BansheePlayer*)userdata; GstStructure *structure; gint channels, wanted_size; gfloat *data; BansheePlayerVisDataCallback vis_data_cb; g_return_if_fail (IS_BANSHEE_PLAYER (player)); vis_data_cb = player->vis_data_cb; if (vis_data_cb == NULL) { return; } if (player->vis_thawing) { // Flush our buffers out. gst_adapter_clear (player->vis_buffer); memset (player->vis_fft_sample_buffer, 0, sizeof(gfloat) * SLICE_SIZE); player->vis_thawing = FALSE; } structure = gst_caps_get_structure (gst_buffer_get_caps (buffer), 0); gst_structure_get_int (structure, "channels", &channels); wanted_size = channels * SLICE_SIZE * sizeof (gfloat); gst_adapter_push (player->vis_buffer, gst_buffer_copy (buffer)); while ((data = (gfloat *)gst_adapter_peek (player->vis_buffer, wanted_size)) != NULL) { gfloat *deinterlaced = g_malloc (wanted_size); gfloat *specbuf = g_new (gfloat, SLICE_SIZE * 2); gint i, j; memcpy (specbuf, player->vis_fft_sample_buffer, SLICE_SIZE * sizeof(gfloat)); for (i = 0; i < SLICE_SIZE; i++) { gfloat avg = 0.0f; for (j = 0; j < channels; j++) { gfloat sample = data[i * channels + j]; deinterlaced[j * SLICE_SIZE + i] = sample; avg += sample; } avg /= channels; specbuf[i + SLICE_SIZE] = avg; } memcpy (player->vis_fft_sample_buffer, &specbuf[SLICE_SIZE], SLICE_SIZE * sizeof(gfloat)); gst_fft_f32_window (player->vis_fft, specbuf, GST_FFT_WINDOW_HAMMING); gst_fft_f32_fft (player->vis_fft, specbuf, player->vis_fft_buffer); for (i = 0; i < SLICE_SIZE; i++) { gfloat val; GstFFTF32Complex cplx = player->vis_fft_buffer[i]; val = cplx.r * cplx.r + cplx.i * cplx.i; val /= SLICE_SIZE * SLICE_SIZE; val = 10.0f * log10f(val); val = (val + 60.0f) / 60.0f; if (val < 0.0f) val = 0.0f; specbuf[i] = val; } vis_data_cb (player, channels, SLICE_SIZE, deinterlaced, SLICE_SIZE, specbuf); g_free (deinterlaced); g_free (specbuf); gst_adapter_flush (player->vis_buffer, wanted_size); } }