2

I am using the audiodispatcher from the TarsosDSPlibrary.

The pitchdetection is used to detect sounds from the mic. Once detected, it switches to the next activity (which is a Maths quiz). After completing the quiz on the next activity, it returns to this activity and starts the process all over again.

What is bugging me is that my APP is working 90% of the time when using the pitchdetection function. However, sometimes it doesn't work and throws an error as follows:

E/AudioRecord: start() status -38

and the app no longers switches to the next activity.

package com.humanfactorsandappliedcognitionlab.research.mathsapp;

import android.content.Context;
import android.content.DialogInterface;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.IBinder;
import android.speech.tts.TextToSpeech;
import android.speech.tts.UtteranceProgressListener;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;

import java.util.HashMap;
import java.util.Locale;
import java.util.concurrent.RunnableFuture;

import be.tarsos.dsp.AudioDispatcher;
import be.tarsos.dsp.AudioEvent;
import be.tarsos.dsp.io.android.AudioDispatcherFactory;
import be.tarsos.dsp.pitch.PitchDetectionHandler;
import be.tarsos.dsp.pitch.PitchDetectionResult;
import be.tarsos.dsp.pitch.PitchProcessor;

public class MainActivity extends AppCompatActivity implements TextToSpeech.OnInitListener {

MediaPlayer notifySound;
MediaPlayer endSound;

AudioDispatcher dispatcherMAIN;
PitchProcessor pitchProcessorMAIN;
public boolean isListening = false;

TextToSpeech tts;

private int sensitivity = 100;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    notifySound = MediaPlayer.create(this, R.raw.samsung);
    endSound = MediaPlayer.create(this, R.raw.ding);

    OPTION = dbHandler.getOPTION();

    tts = new TextToSpeech(this, this);
    tts.setOnUtteranceProgressListener(new UtteranceProgressListener() {
        @Override
        public void onStart(String utteranceId) {
            runOnUiThread(new Runnable() {
                @Override
                public void run(){

                }
            });
        }

        @Override
        public void onDone(String utteranceId) {
            runOnUiThread(new Runnable() {
                @Override
                public void run(){

                    startListenToTalk();
                }
            });
        }

        @Override
        public void onError(String utteranceId) {

        }
    });

}

private void speakOut() {
    Log.e("TTS", "SPEAKING...");
    String text = "Please  Say  Continue  to  Proceed  ";
    HashMap<String, String> map = new HashMap<String, String>();
    map.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, "");
    tts.speak(text, TextToSpeech.QUEUE_FLUSH, map);
}

private void startListenToTalk() {
    dispatcherMAIN = AudioDispatcherFactory.fromDefaultMicrophone(22050, 1024, 0);
    pitchProcessorMAIN = new PitchProcessor(PitchProcessor.PitchEstimationAlgorithm.FFT_YIN, 22050, 1024, new PitchDetectionHandler() {
        @Override
        public void handlePitch(PitchDetectionResult pitchDetectionResult,
                                AudioEvent audioEvent) {

            final float pitchInHz = pitchDetectionResult.getPitch();

            runOnUiThread(new Runnable() {
                @Override
                public void run() {

                    ImageButton buttonOK = (ImageButton) findViewById(R.id.buttonOK);
                    TextView textINPUT = (TextView)findViewById(R.id.textINPUT);
                    if (pitchInHz > sensitivity) {
                        Log.e("pitch : ", pitchInHz + "");
                        if (isListening) {
                            try {
                                dispatcherMAIN.stop();
                                Intent gotoMaths = new Intent(MainActivity.this, MathsActivity.class);
                                startActivity(gotoMaths);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            });
        }
    });

    dispatcherMAIN.addAudioProcessor(pitchProcessorMAIN);
    new Thread(dispatcherMAIN, "Audio Dispatcher").start();
    isListening = true;
}

@Override
protected void onPause() {
    super.onPause();

    if (notifySound != null) {
        notifySound.release();
    }

    if (endSound != null) {
        endSound.release();
    }

    if (isListening) {
        try {
            dispatcherMAIN.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
        isListening = false;
    }

    finish();
}

@Override
public void onStop(){
    super.onStop();

    if (tts != null) {
        tts.shutdown();
    }
}

@Override
public void onInit(int status) {
    if (status == TextToSpeech.SUCCESS) {
        int result = tts.setLanguage(Locale.US);
        if (result == TextToSpeech.LANG_MISSING_DATA
                || result == TextToSpeech.LANG_NOT_SUPPORTED) {
            Log.e("TTS", "This Language is not supported");
        } else {
                if(OPTION == "3") {
                    speakOut();
                }
        }
    } else {
        Log.e("TTS", "Initilization Failed!");
    }
}
Alvin Lee
  • 21
  • 2
  • Please consider only including relevant code :) it's difficult to skim through and find relevant code seeing it for the first time – jhhoff02 May 22 '17 at 14:16
  • Done. Removed irrelevant code. – Alvin Lee May 25 '17 at 19:10
  • I am having the same issue. It appears that TarsosDSP fails to release() their AudioRecord when you tell it to stop. So when you leave the activity and enter without restarting your app, you don't have access to the microphone. I am still trying to find a solution. – Sub 6 Resources Jul 29 '17 at 22:51
  • Have you considered using AudioRecord instance yourself in your code and then pass that onto tardosDSP dispatcher? Then each time you need to release, you can call AudioRecord release() method in your code; and recapture the mic stream on the next usage. – Sushovan Mandal Dec 01 '17 at 08:27

0 Answers0