1

I'm working on a note recognition software, and, I use a Thread.sleep to ensure a pitch is consistent enough over a period to qualify as a note rather than noise. This seems to be making my app skip frames though, and pretty much breaks the program. How can I avoid this?

package com.example.miguel.guitartab;

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;
import be.tarsos.dsp.pitch.PitchProcessor.PitchEstimationAlgorithm;

import android.content.res.ColorStateList;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity {
    private Song song = new Song();
    private boolean finished = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tarsos_dsp);
        AudioDispatcher dispatcher = AudioDispatcherFactory
                                        .fromDefaultMicrophone(22050,1024,0);



        dispatcher.addAudioProcessor(new PitchProcessor(PitchEstimationAlgorithm.FFT_YIN, 22050, 1024, new PitchDetectionHandler() {

            @Override
            public void handlePitch(final PitchDetectionResult pitchDetectionResult,
                                    AudioEvent audioEvent) {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        final float pitch = pitchDetectionResult.getPitch();
                        TextView text = (TextView) findViewById(R.id.textView1);
                        text.setText("" + pitch);

                        if (pitch>700) {
                            song = new Song();
                            finished = false;
                        } else if (finished){
                            text.setText("Song finished");
                        } else {
                            try{
                                Thread.sleep(80);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            float pitch2 = pitchDetectionResult.getPitch();
                            if (pitch * 0.99 < pitch2 && pitch * 1.01 > pitch2) {
                                if (pitch + 2 > song.notes.get(0) && pitch - 2 < song.notes.get(0)) {
                                    System.out.println("Found pitch: " +song.notes.get(0));
                                    text.setTextColor(0xFF00FF00);
                                    song.notes.remove(0);
                                    if (song.notes.size()==0){
                                        finished = true;
                                        text.setTextColor(0xFFFF0000);
                                    }
                                } else {
                                    if (finished = true){
                                        text.setTextColor(0xFFFF0000);
                                    } else {
                                        text.setTextColor(0xFF00FF00);
                                    }

                                }
                            }
                        }
                    }
                });

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

    }

    @Override
    public void onBackPressed()
    {
        moveTaskToBack(true);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.tarsos_ds, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_tarsos_ds,
                    container, false);
            return rootView;
        }
    }
}
Miguel Boland
  • 131
  • 1
  • 4
  • runOnUiThread + Thread.sleep = you're gonna have a bad time... I mean, if you read that as English, it's already quite obvious your UI thread is going to be unavailable from time to time. You need to have one thread for pitch detection and another to handle UI. – 2Dee Feb 22 '15 at 11:32
  • ah right... how would you pass the text from one thread to another? – Miguel Boland Feb 22 '15 at 12:25

0 Answers0