larsba
larsba

Reputation: 51

Making metronome precise for android

I am making a metronome for android. I am able to run the play_tick() function with 1-5ms precision when it is just capturing time, but as soon as I want to play a sound in addition, the system gets inaccurate (by a tenfold at the worst). Do you have any clues on how I can improve this? Sometimes, the system also skips playing ticks completely randomly. Is there any way I can up the priority of the task, or would the scheduler prioritize background running android tasks? I have searched for a while, but could not find any clues.

All help would be appreciated!

I have updated the code a little bit:

public void soundMetronome(){
    MediaPlayer mp = MediaPlayer.create(getApplicationContext(), R.raw.click);
    metronome = new TimerTask() {
            public void run() {
                    handler.post(new Runnable() {
                            public void run() {
                                if(counter<SAMPLE_LENGTH){
                                            store_time[counter] = System.currentTimeMillis();
                                    mp.start(); 
                                    counter++;
                                    Log.d("TIMER", "Timer set off");
                                }
                                else{
                                    stopScan();
                                                                        }
                            }
                   });
            }};


            t.scheduleAtFixedRate(metronome, 0, SAMPLE_INTERVAL_MS); 

        }

However, it is still terribly inaccurate for intervals around 500ms. For the intervals at around 1000ms it is quite stable. The problem is not the timer task itself, but some native android processes seems to interrupt between the time I read the currentTimeMillis() and the PLAYBACK_COMPLETE message from the MediaPlayer.

Is there a way I could call mp.prepare() after mp.start() so the mediaplayer will be prepared to run immediately when the timer function is called?

I am using Galaxy S3 and Android 4.1

thanks

Upvotes: 3

Views: 2171

Answers (1)

Andrei Mankevich
Andrei Mankevich

Reputation: 2273

The lack of precision is caused by garbage collection. Try to get rid of new object creation on each tick. In your code new MediaPlayer is created every time on play_tick, it should be defenitely initialized only once (and btw you are missing MediaPlayer.release call).

Also you can just use Handler.postDelayed instead of TimerTask and Handler.post.

Upvotes: 1

Related Questions