javaandroidaudio-processingpuredatatarsosdsp

Detecting frequency lower than 40 hz using TarsosDSP java android


I am making an Android mobile app, where I have been trying to detect pitch using TarsosDSP. Which has been working great, only if it is greater than 43hz. But I have a requirement to make it work with 40hz. When I play the sound, it doesn't even give results below 43. This is where you can generate a tune online with the desired frequency. here is the code.

void connectsAudioDispatchertoMicrophone() {

  AudioDispatcher dispatcher = AudioDispatcherFactory.fromDefaultMicrophone(22050, 1024, 0);

  PitchDetectionHandler pdh = new PitchDetectionHandler() {
     @Override
     public void handlePitch(final PitchDetectionResult result, AudioEvent e) {
        final float pitchInHz = result.getPitch();
        runOnUiThread(new Runnable() {
           @Override 
           public void run() {
              if (pitchInHz > 1)  
                 Log.d(TAG, "pitchInHz: " + pitchInHz);

           }
        });
     }
  };
  AudioProcessor p = new PitchProcessor(PitchProcessor.PitchEstimationAlgorithm.FFT_YIN,
          22050,
          1024,
          pdh);
  dispatcher.addAudioProcessor(p);

  thread = new Thread(dispatcher, "Audio Dispatcher");
  thread.start();
}

Solution

  • This sounds like a limitation of the FFT that Tarsos uses internally. FFTs split detected sounds into one of several frequency "bins". The center frequency of each bin is a function of:

    For a 22050Hz sample rate, with a 1024 sample wide FFT:

    Fmin = 22050 / 1024 * 2 = 43.066Hz

    (Fmin is the center frequency of the second-lowest "bin". Apparently that is the lowest frequency the algorithm can detect.)

    To lower Fmin, A.) decrease your sample rate, or B.) increase the width of the FFT:

    Fmin = 16000 / 1024 * 2 = 31.25Hz

    Fmin = 22050 / 2048 * 2 = 21.53Hz

    Be sure to stick to powers of 2 for the FFT width, and approved valid settings for the sample rate.