我一直在实现复音信号音高检测器,所以我开始编写我的程序(记录数据、转换数据、零填充、窗口化、FFT、峰值检测)。起初,我用我已经知道应该获得哪些值的声音对其进行了测试,并且效果很好。
我遇到的问题是使用 Audiorecord 类用我的手机录音时。
例如:我用手机播放和录制了两三个纯音,而我在 Audiorecord 类中得到的值不正确。从我的手机中获取错误的数据并不能让我进行良好的分析。
这是我记录数据(短)并将数据短转换为双倍的代码(这一步是我认为问题所在)
这是我的代码:
void recordAudio() {
mShouldContinue= true;
new Thread(new Runnable() {
@Override
public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO);
// buffer size in short
bufferSize = AudioRecord.getMinBufferSize(sampleRate, channelConfig, audioEncoding); //Consigue el minimo tamaño de buffer para poder analizar
if (bufferSize == AudioRecord.ERROR || bufferSize == AudioRecord.ERROR_BAD_VALUE) {
bufferSize = sampleRate * 2; // si el buffersize obtenido por nuestro getMinBufferSize es apto usaremos el encontrado si no utilizaremos el doble de nuestra frecuencia de sampleo
}
short[] audioBuffer = new short[bufferSize];
if (audioBuffer.length % 2 == 0){ // Aseguramos que nuestro buffer input tenga una tamaño impar para una mejor R.F.
audioBuffer = new short[bufferSize +1];
}
AudioRecord record = new AudioRecord(audioSource, sampleRate, channelConfig, audioEncoding, bufferSize); //Instancia de la clase AudioRecord
if (record.getState() != AudioRecord.STATE_INITIALIZED) { // Si audiorecord no ha sido inicializado displeamos un mensaje advirtiendo.
Log.e(LOG_TAG, "Audio Record can't initialize!");
return;
}
record.startRecording(); //Empezamos a grabar con nuestros parámetros ya definidos.
Log.v(LOG_TAG, "Start recording"); //mensaje informativo
long shortsRead = 0;
while (mShouldContinue) {
int numberOfShort = record.read(audioBuffer, 0, audioBuffer.length); //audiobuffer.length
shortsRead += numberOfShort;
DFT(audioBuffer);
try { // Dormimos el programa durante un segundo
Thread.sleep(1000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
record.stop();
record.release();
Log.v(LOG_TAG, String.format("Recording stopped. Samples read: %d", shortsRead));
}
}).start();
}
Inputsignal 是 audiobuffer 和 N 是长度的转换(内部 DFT 函数):
for(int i = 0; i < N; i++){
doubley[i] = (double)(InputSignal[i])/32768.0;
}