Add spek-fft.c

This commit is contained in:
Alexander Kojevnikov 2012-08-05 17:56:06 -07:00
parent 48afd3b4e8
commit 546d61c0a8
4 changed files with 48 additions and 36 deletions

View File

@ -2,6 +2,8 @@ bin_PROGRAMS = spek
spek_SOURCES = \
spek.cc \
spek-fft.c \
spek-fft.h \
spek-window.cc \
spek-window.hh

View File

@ -1,6 +1,6 @@
/* spek-audio.h
*
* Copyright (C) 2010 Alexander Kojevnikov <alexander@kojevnikov.com>
* Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com>
*
* Spek is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by

View File

@ -1,6 +1,6 @@
/* spek-fft.c
*
* Copyright (C) 2010 Alexander Kojevnikov <alexander@kojevnikov.com>
* Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com>
*
* Spek is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,29 +21,31 @@
#include "spek-fft.h"
SpekFftPlan * spek_fft_plan_new (gint n, gint threshold) {
gint bits;
SpekFftPlan *p = g_new0 (SpekFftPlan, 1);
p->input = av_mallocz (sizeof (gfloat) * n);
p->output = av_mallocz (sizeof (gfloat) * (n / 2 + 1));
struct spek_fft_plan * spek_fft_plan_new(int n, int threshold)
{
int bits;
struct spek_fft_plan *p = malloc(sizeof(struct spek_fft_plan));
p->input = av_mallocz(sizeof(float) * n);
p->output = av_mallocz(sizeof(float) * (n / 2 + 1));
p->threshold = threshold;
for (bits = 0; n; n >>= 1, bits++);
for(bits = 0; n; n >>= 1, ++bits);
p->n = 1 << --bits;
p->cx = av_rdft_init (bits, DFT_R2C);
p->cx = av_rdft_init(bits, DFT_R2C);
return p;
}
void spek_fft_execute (SpekFftPlan *p) {
void spek_fft_execute(struct spek_fft_plan *p)
{
int i;
int n = p->n;
av_rdft_calc (p->cx, p->input);
av_rdft_calc(p->cx, p->input);
/* Calculate magnitudes */
// Calculate magnitudes.
p->output[0] = p->input[0] * p->input[0] / (n * n);
p->output[n / 2] = p->input[1] * p->input[1] / (n * n);
for (i = 1; i < n / 2; i++) {
gfloat val;
float val;
val = p->input[i * 2] * p->input[i * 2] + p->input[i * 2 + 1] * p->input[i * 2 + 1];
val /= n * n;
val = 10.0 * log10f (val);
@ -51,9 +53,10 @@ void spek_fft_execute (SpekFftPlan *p) {
}
}
void spek_fft_destroy (SpekFftPlan *p) {
av_rdft_end (p->cx);
av_free (p->input);
av_free (p->output);
g_free (p);
void spek_fft_destroy(struct spek_fft_plan *p)
{
av_rdft_end(p->cx);
av_free(p->input);
av_free(p->output);
free(p);
}

View File

@ -1,6 +1,6 @@
/* spek-fft.h
*
* Copyright (C) 2010 Alexander Kojevnikov <alexander@kojevnikov.com>
* Copyright (C) 2010-2012 Alexander Kojevnikov <alexander@kojevnikov.com>
*
* Spek is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,30 +16,37 @@
* along with Spek. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __SPEK_FFT_H__
#define __SPEK_FFT_H__
#ifndef SPEK_FFT_H__
#define SPEK_FFT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <glib.h>
#include <libavcodec/avfft.h>
typedef struct {
/* Internal data */
struct spek_fft_plan {
// Internal data.
RDFTContext *cx;
gint n;
gint threshold;
int n;
int threshold;
/* Exposed properties */
gfloat *input;
gfloat *output;
} SpekFftPlan;
// Exposed properties.
float *input;
float *output;
};
/* Allocate buffers and create a new FFT plan */
SpekFftPlan * spek_fft_plan_new (gint n, gint threshold);
// Allocate buffers and create a new FFT plan.
struct spek_fft_plan * spek_fft_plan_new(int n, int threshold);
/* Execute the FFT on plan->input */
void spek_fft_execute (SpekFftPlan *p);
// Execute the FFT on plan->input.
void spek_fft_execute(struct spek_fft_plan *p);
/* Destroy the plan and de-allocate buffers */
void spek_fft_destroy (SpekFftPlan *p);
// Destroy the plan and de-allocate buffers.
void spek_fft_delete(struct spek_fft_plan *p);
#ifdef __cplusplus
}
#endif
#endif