Análisis espectral utilizando FFT, derivación de frecuencia fundamental

Necesito realizar un análisis espectral de un archivo wav simple. Las cosas que ya hice:

Leer el archivo en la matriz de bytes:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead = 0;

while ((bytesRead = audioStream.read(buffer)) != -1) {
    baos.write(buffer, 0, bytesRead);
}

fileByteArray = baos.toByteArray();

Luego lo transformo a los valores reales (dobles). Tengo valores de muestra almacenados en matriz doble [].

¿Cómo puedo hacer FFT de esas muestras + estimar la frecuencia fundamental?

Usando la biblioteca JTranforms intenté algo como esto:

DoubleFFT_1D fft = new DoubleFFT_1D(reader.getSpectrum().getYvalues().length);
double[] x = reader.getSpectrum().getYvalues();
double[] frequencyArray = new double[x.lenght/2];
double[] amplitudeArray = new double[x.lenght/2];
fft.realForward(x);
int i=0;
for (int j = 0; j < x.length-2; j += 2) {
    i++;
    this.frequencyArray[i] = i;
    this.amplitudeArray[i] = Math.sqrt(Math.pow(doub[j],2) + Math.pow(doub[j + 1],2));
}

¿Es correcto?

Todas las sugerencias son apreciadas;)

Respuesta 1

Debe usar la autocorrelación que se puede calcular de manera eficiente con FFT:

DoubleFFT_1D fft = new DoubleFFT_1D(reader.getSpectrum().getYvalues().length);
DoubleFFT_1D ifft = new DoubleFFT_1D(reader.getSpectrum().getYvalues().length);

fft.realForward(x);
for (int i = 0; i < x.length/2; i++) {
    x[2*i] = Math.sqrt(Math.pow(x[2*i],2) + Math.pow(x[2*i+1],2));
    x[2*i+1] = 0;
}
ifft.realInverse(x);
for (int i = 1; i < x.length; i++)
    x[i] /= x[0];
x[0] = 1.0;

Este código le brinda una lista de valores para los cuales:

x[i]: corelación con i turnos

Entonces, por ejemplo, si tiene un valor alto (cercano a 1) para x[n], eso significa que tiene un período de señal fundamental que es: n*(1000/sampleRateHz)msecs. Esto es equivalente a una frecuencia de:sampleRateHz/(1000*n)

Respuesta: 2

Estoy completando datos de mi base de datos en mi JTable. Después de agregar nuevos datos y presionar el botón Actualizar, quiero eliminar la fila existente que se muestra en la tabla antes de recuperar los nuevos datos. Cómo puedo ...

Recibo el siguiente error al usar TomEE y JPA: GRAVE: AGENTE JAVA NO INSTALADO. El proveedor de persistencia JPA solicitó la instalación de un ClassFileTransformer que requiere un JavaAgent. Ver ...

Tengo un JPanel con componentes agregados con ubicaciones absolutas (es decir, "pos x y"), y el diseño es efectivamente dos columnas de campos de texto. Lo que me gustaría lograr sería que Tab cambiara el enfoque ...

Estoy tratando de analizar la siguiente URL: http://kavim-t.co.il/include/getXMLStations.asp?parent=55_%20_2 Código: // usando jdom SAX parser SAXBuilder builder = new SAXBuilder (); URL url = nueva URL ("http: // kavim-t ....