Question

I'm building, inside my existing app, a player using the AudioTrack class,in MODE_STATIC, because i want to implement the timestretch and the loop points features. The code is ok for start() and stop(), but when paused, if i try to resume, calling play() again, the status bar remain fixed and no audio is played.

Now, from the docs :

Public void pause ()Pauses the playback of the audio data. Data that has not been played >back will not be discarded. Subsequent calls to play() will play this data back. See >flush() to discard this data.

It seems so easy to understand but there is something that escapes me. Can some one help me?

Is it necessary to create boolean variables like start, play, pause, stopAudio etc? If yes, where is the utility of the methods inherited from the AudioTrack class?

In MODE_STREAM i have realized the project, using the above boolean variables., but i need the MODE_STATIC.

This is the code, thanks:

Button playpause, stop;
SeekBar posBar;
int sliderval=0;
int headerOffset = 0x2C;
File file =new File(Environment.getExternalStorageDirectory(), "raw.pcm");
int fileSize = (int) file.length();
int dataSize = fileSize-headerOffset ;
byte[] dataArray = new byte[dataSize];
int posValue;
int dataBytesRead = initializeTrack();
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, 
        AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, dataBytesRead , AudioTrack.MODE_STATIC);

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    playpause= (Button)(findViewById(R.id.playpause));
    stop= (Button)(findViewById(R.id.stop));

    posBar=(SeekBar)findViewById(R.id.posBar);

    // create a listener for the slider bar;
    OnSeekBarChangeListener listener = new OnSeekBarChangeListener() {
      public void onStopTrackingTouch(SeekBar seekBar) { }
      public void onStartTrackingTouch(SeekBar seekBar) { }
      public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (fromUser) { sliderval = progress;}
       }
    };

    // set the listener on the slider
    posBar.setOnSeekBarChangeListener(listener); }


public void toggleButtonSound(View button)
{
    switch (button.getId())
    {
        case R.id.playpause:
            play();
            break;

        case R.id.stop:
            stop();

            break;
    }

}

    private void stop() {
        if(audioTrack.getState()==AudioTrack.PLAYSTATE_PLAYING ||
                audioTrack.getState()==AudioTrack.PLAYSTATE_PAUSED || audioTrack.getState()==AudioTrack.PLAYSTATE_STOPPED)
         { audioTrack.stop();
        resetPlayer();}

}


    Context context;
    private double actualPos=0;

    public void pause() {}

    public void play()
    {   


        if (audioTrack.getPlayState()==AudioTrack.PLAYSTATE_PLAYING) 
        {   //Log.i("", "Play pressed in state "+audioTrack.getPlayState());
            audioTrack.pause();
            }
        else if (audioTrack.getPlayState()==AudioTrack.PLAYSTATE_PAUSED)
        {   //Log.i("", "Play pressed in state "+audioTrack.getPlayState());
            audioTrack.play(); 
        }
     else if (audioTrack.getPlayState()==AudioTrack.PLAYSTATE_STOPPED)
     {      //Log.i("", "Play pressed in state "+audioTrack.getPlayState());
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, dataSize, AudioTrack.MODE_STATIC);
        audioTrack.write(dataArray, 0, dataBytesRead);
        audioTrack.play();

        }
        posBar.setMax((int) (dataBytesRead/2));     // Set the Maximum range of the

            audioTrack.setNotificationMarkerPosition((int) (dataSize/2));
            audioTrack.setPositionNotificationPeriod(1000);
            audioTrack.setPlaybackPositionUpdateListener(new OnPlaybackPositionUpdateListener() {
          @Override
          public void onPeriodicNotification(AudioTrack track) { 
              posBar.setProgress(audioTrack.getPlaybackHeadPosition());
              Log.i("", " " + audioTrack.getPlaybackHeadPosition() + " " + dataBytesRead/2);
          }
            @Override
          public void onMarkerReached(AudioTrack track) {
                Log.i("", " End reached ");

                audioTrack.pause();
                audioTrack.flush();
                audioTrack.release();
                posBar.setProgress(0);
                resetPlayer();}
       });
    }



        private int initializeTrack() {
            InputStream is;
            BufferedInputStream bis;
            DataInputStream dis;
            int temp = 0;
            try {
                is = new FileInputStream(file);
                bis = new BufferedInputStream(is);
                dis = new DataInputStream(bis);
                temp = dis.read(dataArray, 0, dataSize);
                dis.close();
                bis.close();
                is.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            return temp;
        }

        public void resetPlayer() {
            audioTrack.flush();
            audioTrack.release();
            posBar.setProgress(0);
            sliderval=0;
            }
Was it helpful?

Solution

You see, you did implement AudioTrack so that even when its paused the contents of file still uploads to AudioTrack:

I don't know how it manage it but in my case I also pause data uploading to AT. Like:

            while (byteOffset < fileLengh) {
                if(isPaused)
                    continue;
                ret = in.read(byteData, 0, byteCount);
                if (ret != -1) { // Write the byte array to the track
                    audioTrack.write(byteData, 0, ret);
                    byteOffset += ret;
                } else
                    break;
            }

So then I unpause the AT the file uploading while cycle resumes too. I guess that's it. Also I have to mention that even when AT is playing the following:

if (audioTrack.getPlayState()==AudioTrack.PLAYSTATE_PLAYING)

and

if (audioTrack.getPlayState()==AudioTrack.PLAYSTATE_PAUSED)

doesn't work for me and getPlayState() always returns 1 (AudioTrack.PLAYSTATE_STOPPED) for me, no matter if its playing or has been paused.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top