У меня есть звуковой файл (.3gp) и его около ~ 1 мин. Я хотел бы получить частоту этого звукового файла каждые 1/4 секунды. Моя идея состоит в том, чтобы получать образцы в каждые 1/4 секунды из аудиофайла, а с помощью FFT я могу получить значения частоты. Есть какой-либо способ сделать это?Получите частоту аудиофайла через каждые 1/4 секунды в android
Фактически я бы разбил звуковой файл на 1/4sec образцы звуковых файлов (alwyas переписывая превью), затем используя алгоритм FFT и обнаружив частоту, где magintude является самым большим. Но могут быть более простые решения, однако я не знаю, как это сделать.
*** UPDATE 2 - новый код
Я использую этот код до сих пор:
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;
}
Я использую это: http://www.wikijava.org/wiki/The_Fast_Fourier_Transform_in_Java_%28part_1%29
струны гитары кажется правильным, но мой собственный звук не хорошо из-за этого:
Величина двух пиков меняет большую часть времени, и я всегда нахожу самое большое, чтобы получить основную частоту.
Привет, У меня такая же проблема, мне нужно записывать голос в реальном времени и вычислять частоту в каждые 4 мс, как вы это достигли? Любой образец кода с вами? –
Привет, мне не удалось преодолеть проблему, однако мои гитарные звуки были подходящими 9 из 10, но мой голос был, возможно, 7 из 10 .. –