1

I have the following functions:

void playSound(){
    final AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
            sampleRate, AudioFormat.CHANNEL_OUT_MONO,
            AudioFormat.ENCODING_PCM_16BIT, generatedSnd.length,
            AudioTrack.MODE_STATIC);
    audioTrack.write(generatedSnd, 0, generatedSnd.length);
    audioTrack.play();
}

Button Click:

public void btnTx_click(View view){
    textView.setText("CLICKED1");

    int rem;

    while(dataToSend != 0){
        rem = dataToSend % 2;
        if(rem==0)
            genTone(0.0);
        else
            genTone(1.0);
        dataToSend /= 2; 
        counter++;
    }

    // Use a new tread as this can take a while
    final Thread thread = new Thread(new Runnable() {
        public void run() {
            // genTone();       // this line is left here for my recor donly
            handler.post(new Runnable() {

                public void run() {
                    playSound();
                }
            });
        }
    });
    thread.start();
}  

The while loop in the btnTx_click() function prepares the generatedSnd array used in the playSound() function. When a button is pressed, this program loads audio samples into the generatedSnd array and then plays them using an AudioTrack. The loading and playing are done in a thread.

How do I know when this thread ends? Does it end after the playing of AudioTrack ends? Or does it end immediately after public void run() exits? Is it possible to check exactly when the thread ends, and if yes, where in MainActivity.java should such a check be included?

What I want to do is, once the AudioTrack completes playing of generatedSnd, I want to load a new set of values in generatedSnd and start playing this new tone. In effect, I want to play Tone 1, followed by Tone 2, followed by Tone 3,.... and so on.

user13267
  • 6,871
  • 28
  • 80
  • 138

1 Answers1

2

The call to audioTrack.play() does not block. It will begin playback and the run() method of the Thread will return, likely before playback is over. The actual playback of audio is happening in yet another thread internally created, not the one it was called from.

You have AudioTrack.setPlaybackPositionUpdateListener() available to receive a callback when playback reaches a point set with AudioTrack.setNotificationMarkerPosition() which will solve your problem.

Steve M
  • 9,296
  • 11
  • 49
  • 98
  • What did you mean by another thread created internally? Isn't `thread` declared in `btnTx_click()` the one playing the AudioTrack? – user13267 Dec 22 '14 at 11:47
  • The playback is happening in a different thread in the native layer. Try calling play() on the UI thread you will see that playback happens without blocking the UI. – Steve M Dec 22 '14 at 12:26
  • Well, write() blocks until all the bytes are written, so you may need to put that in another thread. – Steve M Dec 22 '14 at 22:22
  • Although in static mode, it's only copying the entire contents to the buffer, so it should be pretty fast for small files. – Steve M Dec 23 '14 at 03:30
  • I think I might not need a new thread for this, as I will not be reading files, I will be calculating the tone values I want to generate (mainly sinusoids) and the tones will not be too long (however, might still be about 10 seconds or slightly more) – user13267 Dec 23 '14 at 03:33