java - ejemplo - ¿Cómo obtener la frecuencia del resultado fft?
private jlabel (1)
Los datos complejos están intercalados, con componentes reales en índices pares y componentes imaginarios en índices impares, es decir, los componentes reales están en el índice 2*i
, los componentes imaginarios están en el índice 2*i+1
.
Para obtener la magnitud del espectro en el índice i, desea:
re = fft[2*i];
im = fft[2*i+1];
magnitude[i] = sqrt(re*re+im*im);
Luego puede trazar la magnitud [i] para i = 0 a N / 2 para obtener el espectro de potencia. Dependiendo de la naturaleza de su entrada de audio, debería ver uno o más picos en el espectro.
Para obtener la frecuencia aproximada de cualquier pico dado, puede convertir el índice del pico de la siguiente manera:
freq = i * Fs / N;
dónde:
freq = frequency in Hz
i = index of peak
Fs = sample rate (e.g. 44100 Hz or whatever you are using)
N = size of FFT (e.g. 1024 in your case)
Nota: si no ha aplicado previamente una función de ventana adecuada a los datos de entrada de dominio de tiempo, obtendrá una cierta cantidad de fuga espectral y el espectro de potencia se verá "manchado".
Para ampliar más esto, aquí hay un pseudocódigo para un ejemplo completo donde tomamos datos de audio e identificamos la frecuencia del pico más grande:
N = 1024 // size of FFT and sample window
Fs = 44100 // sample rate = 44.1 kHz
data[N] // input PCM data buffer
fft[N * 2] // FFT complex buffer (interleaved real/imag)
magnitude[N / 2] // power spectrum
capture audio in data[] buffer
apply window function to data[]
// copy real input data to complex FFT buffer
for i = 0 to N - 1
fft[2*i] = data[i]
fft[2*i+1] = 0
perform in-place complex-to-complex FFT on fft[] buffer
// calculate power spectrum (magnitude) values from fft[]
for i = 0 to N / 2 - 1
re = fft[2*i]
im = fft[2*i+1]
magnitude[i] = sqrt(re*re+im*im)
// find largest peak in power spectrum
max_magnitude = -INF
max_index = -1
for i = 0 to N / 2 - 1
if magnitude[i] > max_magnitude
max_magnitude = magnitude[i]
max_index = i
// convert index of largest peak to frequency
freq = max_index * Fs / N
He grabado una matriz [1024] de datos de mi micrófono en mi teléfono Android, pasé a través de un DFT 1D hacia adelante de los datos reales (estableciendo 1024 bits más a 0). Guardé la matriz en un archivo de texto y lo repetí 8 veces.
Regresé 16384 resultados. Abrí el archivo de texto en Excel e hice un gráfico para ver cómo se veía (x = índice de la matriz, y = tamaño del número devuelto). Hay algunos picos masivos (tanto positivos como negativos) en magnitud alrededor de 110, 232, y los picos pequeños continúan de esa manera hasta alrededor de 1817 y 1941, donde los picos se vuelven grandes de nuevo, luego vuelven a caer.
Mi problema es que cada vez que busco ayuda sobre el tema, menciono obtener los números reales e imaginarios, solo tengo una matriz 1D, que obtuve del método que utilicé de la clase de Piotr Wendykier:
DoubleFFT_1D.realForwardFull(audioDataArray); // from the library JTransforms.
Mi pregunta es: ¿Qué debo hacer con estos datos para devolver una frecuencia? El sonido grabado era yo tocando una ''A'' en la cuerda inferior (5º traste) de mi guitarra (a aproximadamente 440Hz).