0

I'm trying to use TarsosDSP library to detect pitch from a .wav file, and the result of frequency is always less than half.

Here is my code.

    public class Main {

public static void main(String[] args){
    try{
        float sampleRate = 44100;
        int audioBufferSize = 2048;
        int bufferOverlap = 0;

        //Create an AudioInputStream from my .wav file
        URL soundURL = Main.class.getResource("/DetectPicthFromWav/329.wav");
        AudioInputStream stream = AudioSystem.getAudioInputStream(soundURL);

        //Convert into TarsosDSP API
        JVMAudioInputStream audioStream = new JVMAudioInputStream(stream);
        AudioDispatcher dispatcher = new AudioDispatcher(audioStream, audioBufferSize, bufferOverlap);
        MyPitchDetector myPitchDetector = new MyPitchDetector();
        dispatcher.addAudioProcessor(new PitchProcessor(PitchEstimationAlgorithm.YIN, sampleRate, audioBufferSize, myPitchDetector));
        dispatcher.run();


    }
    catch(FileNotFoundException fne){fne.printStackTrace();}
    catch(UnsupportedAudioFileException uafe){uafe.printStackTrace();}
    catch(IOException ie){ie.printStackTrace();}
}
}

    class  MyPitchDetector implements PitchDetectionHandler{

//Here the result of pitch is always less than half.
@Override
public void handlePitch(PitchDetectionResult pitchDetectionResult,
        AudioEvent audioEvent) {
    if(pitchDetectionResult.getPitch() != -1){
        double timeStamp = audioEvent.getTimeStamp();
        float pitch = pitchDetectionResult.getPitch();
        float probability = pitchDetectionResult.getProbability();
        double rms = audioEvent.getRMS() * 100;
        String message = String.format("Pitch detected at %.2fs: %.2fHz ( %.2f probability, RMS: %.5f )\n", timeStamp,pitch,probability,rms);
        System.out.println(message);
    }
}
}

The 329.wav file is generated from http://onlinetonegenerator.com/ website with 329Hz. I don't know why the result pitch is always 164.5Hz. Is there any problem in my code?

user7395677
  • 213
  • 1
  • 2
  • 6
  • 1
    This is an octave error, this implementation of YIN Pitch detection causes this problem, I never get time to saw the YIN code in deeper, but some steps from the original paper was forgotten, I did an pitch track AMDF code for Tarsos and you can test him using `PitchEstimationAlgorithm.AMDF` – ederwander Jul 29 '15 at 10:54

2 Answers2

0

Well I don't know what methods you are using, but by looking at how the frequency is exactly halved, it could be a problem of wrong sample rate being set?

Most operations assume an initial sample rate when the signal was sampled, maybe you've passed it as an argument (or its default value is) half that?

A B
  • 189
  • 2
  • 9
0

I just had the same problem with TarsosDSP on Android. For me the answer was that the file from http://onlinetonegenerator.com/ has 32-bit samples instead of 16-bit, which appears to be the default. Relevant code:

AssetFileDescriptor afd = getAssets().openFd("440.wav"); // 440Hz sine wave
InputStream is = afd.createInputStream();
TarsosDSPAudioFormat audioFormat = new TarsosDSPAudioFormat(
  /* sample rate */ 44100,
  /* HERE sample size in bits */ 32,
  /* number of channels */ 1,
  /* signed/unsigned data */ true,
  /* big-endian byte order */ false
);
AudioDispatcher dispatcher = new AudioDispatcher(new UniversalAudioInputStream(is, audioFormat), 2048, 0);
PitchDetectionHandler pdh = ...
AudioProcessor p = new PitchProcessor(PitchProcessor.PitchEstimationAlgorithm.FFT_YIN, 44100, 2048, pdh);
dispatcher.addAudioProcessor(p);
new Thread(dispatcher, "Audio Dispatcher").start();