JorenSix / TarsosDSP

A Real-Time Audio Processing Framework in Java
http://0110.be/tag/TarsosDSP
GNU General Public License v3.0
1.97k stars 472 forks source link

PitchProcessor does not stop handlePitch even after stopping dispatcher #178

Closed apatait closed 4 years ago

apatait commented 4 years ago

I am using the TarsosDSP library for pitch detection. I have set it up as follows.

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

PitchDetectionHandler pdh = new PitchDetectionHandler() {
        @Override
        public void handlePitch(PitchDetectionResult result,AudioEvent e) {
                final float pitchInHz = result.getPitch();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                           // Code to handle the pitch detection
                          Log("Raw detected pitch = " + pitchInHz);
                    }
                });                        
        }
};
AudioProcessor m_pitchProcessor = new PitchProcessor(PitchEstimationAlgorithm.FFT_YIN, 22050, 1024, pdh);
m_dispatcher.addAudioProcessor(m_pitchProcessor);
new Thread(m_dispatcher,"Audio Dispatcher").start();

The pitch detection works great (thank you for an awesome library). However, when I want to stop the dispatcher, it does not stop, and it seems to be running forever. My clean-up code is as follows:

    public void Stop() {
            m_dispatcher.stop();
            m_dispatcher.removeAudioProcessor(m_pitchProcessor);
        }

Even after the above code (Stop()) is called, I continuously keep seeing the prints in the log such as

Raw detected pitch = 4364.935 Hz
Raw detected pitch = -1.0 Hz

etc.

from the line

Log("Raw detected pitch = " + pitchInHz);

What am I doing wrong?

UPDATE: I debugged the problem further. m_dispatcher.stop() calls the correct function in the TarsosDSP library as follows (verified via logs in the function):

    /**
     * Stops dispatching audio data.
     */
    public void stop() {
        stopped = true;
        for (final AudioProcessor processor : audioProcessors) {
            processor.processingFinished();
        }
        try {
            audioInputStream.close();
        } catch (IOException e) {
            LOG.log(Level.SEVERE, "Closing audio stream error.", e);
        }
    }

But the value of variable "stopped" is only true until this function runs (very strange). The run() function of the dispatcher keeps executing despite the function having the main runloop condition as follows:

while (bytesRead != 0 && !stopped) {

The value of "stopped" in this runloop remains false, which is very confusing.

I may be doing something stupid, but I cannot figure it out. Any help would be greatly appreciated.

apatait commented 4 years ago

Never mind... It was a stupid mistake in the calling class on my part. I was creating two instances of dispatcher. Sorry about it.