Tengo un archivo de sonido (.3gp) y es aproximadamente ~ 1 min. Me gustaría obtener la frecuencia de este archivo de sonido cada 1/4 segundos. Mi idea es recibir muestras cada 1/4 segundos del archivo de audio y usar FFT I podría obtener los valores de frecuencia. ¿Hay alguna manera de hacer esto?Obtenga la frecuencia de un archivo de audio cada 1/4 segundos en android
En realidad, dividiría el archivo de sonido en archivos de sonido de samples de 1/4sec (siempre sobrescribiendo el anterior), luego usaría el algoritmo FFT y detectaría la frecuencia donde la magintude es la más grande. Pero podría haber soluciones más fáciles, pero tampoco tengo ni idea de cómo hacer esto.
*** ACTUALIZACIÓN 2 - nuevo código
utilizo este código hasta ahora:
public class RecordAudio extends AsyncTask<Void, double[], Void> {
@Override
protected Void doInBackground(Void... arg0) {
try {
int bufferSize = AudioRecord.getMinBufferSize(frequency,
AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
//int bufferSize = AudioRecord.getMinBufferSize(frequency,
// channelConfiguration, audioEncoding);
AudioRecord audioRecord = new AudioRecord(
MediaRecorder.AudioSource.MIC, frequency,
channelConfiguration, audioEncoding, bufferSize);
short[] buffer = new short[blockSize];
//double[] toTransform = new double[blockSize];
audioRecord.startRecording();
// started = true; hopes this should true before calling
// following while loop
while (started) {
sampling++;
double[] re = new double[blockSize];
double[] im = new double[blockSize];
double[] newArray = new double[blockSize*2];
double[] magns = new double[blockSize];
double MaxMagn=0;
double pitch = 0;
int bufferReadResult = audioRecord.read(buffer, 0,
blockSize);
for (int i = 0; i < blockSize && i < bufferReadResult; i++) {
re[i] = (double) buffer[i]/32768.0; // signed 16bit
im[i] = 0;
}
newArray = FFTbase.fft(re, im,true);
for (int i = 0; i < newArray.length; i+=2) {
re[i/2]=newArray[i];
im[i/2]=newArray[i+1];
magns[i/2] = Math.sqrt(re[i/2]*re[i/2]+im[i/2]*im[i/2]);
}
// I only need the first half
for (int i = 0; i < (magns.length)/2; i++) {
if (magns[i]>MaxMagn)
{
MaxMagn = magns[i];
pitch=i;
}
}
if (sampling > 50) {
Log.i("pitch and magnitude", "" + MaxMagn + " " + pitch*15.625f);
sampling=0;
MaxMagn=0;pitch=0;
}
}
audioRecord.stop();
} catch (Throwable t) {
t.printStackTrace();
Log.e("AudioRecord", "Recording Failed");
}
return null;
}
utilizo este: http://www.wikijava.org/wiki/The_Fast_Fourier_Transform_in_Java_%28part_1%29
cuerdas de la guitarra parecen correctas, pero mi propio sonido no es buena debido a esto:
La magnitud de los dos picos cambia la mayor parte del tiempo y siempre encuentro el más grande para obtener la frecuencia fundamental.
Hola, tengo el mismo problema, necesito grabar la voz en tiempo real y calcular la frecuencia en cada 4ms, ¿cómo lo lograste? ¿Algún código de muestra con usted? –
Hola, no tuve éxito para superar el problema; sin embargo, mis sonidos de guitarra fueron apropiados 9 de 10, pero mi voz fue tal vez 7 de 10 .. –