私はポリフォニック信号ピッチ検出器を実装していたので、プログラムのコーディングを開始しました (RecordData、Convert Data、Zero-padding、Windowing、FFT、Peak 検出)。最初に、取得する必要がある新しいサウンドでテストしたところ、完全に機能しました。
私が抱えている問題は、 Audiorecord クラスを使用して自分の電話で録音するときです。
例: 電話で 2 つまたは 3 つの純音を再生して録音しましたが、Audiorecord クラスで取得した値が正しくありませんでした。携帯電話から間違ったデータを取得すると、適切な分析ができません。
ここに、Record Data(Short) と Convert Data Short から Double への私のコードがあります(このステップが問題だと思います)
これが私のコードです:
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;
}