0

I have been implementing a Polyphonic signal pitch detector so I started to code my Program doing (RecordData, Convert Data, Zero-padding, Windowing, FFT, Peak detection). At first I tested it with sounds I already new which values I should get, and it worked perfectly.

The problem I have is when recording with my Phone using the Audiorecord class.

For example: I played and recorded two or three pure tones with my phone and the values I get with the Audiorecord class were not correct. Getting wrong data from my phone does not let me do a good analysis.

Here is my code to Record Data(Short) and Convert Data Short to Double (This step is where i think its the problem)

Here is my code:

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();
}

Convertion where Inputsignal is audiobuffer and N it's length (Inside DFT Function):

for(int i = 0; i < N; i++){
    doubley[i] = (double)(InputSignal[i])/32768.0;

}
John Doe
  • 1
  • 2

1 Answers1

1

An FFT magnitude peak detector is not a reliable musical pitch (frequency/note) estimator. It will often find harmonic frequencies instead for some timbres.

Instead, look up some pitch detection/estimation methods (weighted autocorrelation, AMDF, HPS, cepstral, decision, CDNN, etc.), and try one of those, instead of (mis)using a spectral frequency estimator.

hotpaw2
  • 70,107
  • 14
  • 90
  • 153
  • I do sub harmonic summing to find the fundamental frequency (sum Each harmonic peak divided by 1, 2 ,3) so the F0 will always be predominant even though it could not be present at first, and it is very effective when you have the right data. My problem is when converting my short data to double, any suggestions?. – John Doe May 16 '17 at 18:40