Using AudioTrack in Android to play a WAV file

Viewed 44142

I'm working with Android, trying to make my AudioTrack application play a Windows .wav file (Tada.wav). Frankly, it shouldn't be this hard, but I'm hearing a lot of strange stuff. The file is saved on my phone's mini SD card and reading the contents doesn't seem to be a problem, but when I play the file (with parameters I'm only PRETTY SURE are right), I get a few seconds of white noise before the sound seems to resolve itself into something that just may be right.

I have successfully recorded and played my own voice back on the phone -- I created a .pcm file according to the directions in this example:

http://emeadev.blogspot.com/2009/09/raw-audio-manipulation-in-android.html

(without the backwards masking)...

Anybody got some suggestions or awareness of an example on the web for playing a .wav file on an Android??

Thanks, R.

7 Answers

Please don't perpetuate terrible parsing code. WAV parsing is trivial to implement http://soundfile.sapp.org/doc/WaveFormat/ and you will thank yourself by being able to parse things such as the sampling rate, bit depth, and number of channels.

Also x86 and ARM (at least by default) are both little endian , so native-endian WAV files should be fine without any shuffling.

Sample wav file:
http://www.mauvecloud.net/sounds/pcm1644m.wav

Sample Code:

public class AudioTrackPlayer {
    Context mContext;
    int minBufferSize;
    AudioTrack at;
    boolean STOPPED;

    public AudioTrackPlayer(Context context) {
        Log.d("------","init");
        mContext = context;
        minBufferSize = AudioTrack.getMinBufferSize(44100,
                AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT);
    }

    public boolean play() {
        Log.d("------","play");
        int i = 0;
        byte[] music = null;
        InputStream is = mContext.getResources().openRawResource(R.raw.pcm1644m);

        at = new AudioTrack(AudioManager.STREAM_MUSIC, 44100,
                AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT,
                minBufferSize, AudioTrack.MODE_STREAM);
        try {
            music = new byte[512];
            at.play();

            while ((i = is.read(music)) != -1)
                at.write(music, 0, i);

        } catch (IOException e) {
            e.printStackTrace();
        }
        at.stop();
        at.release();
        return STOPPED;
    }
}

Just confirm if you have AudioTrack.MODE_STREAM and not AudioTrack.MODE_STATIC in the AudioTrack constructor:

AudioTrack at = new AudioTrack(
  AudioManager.STREAM_MUSIC,
  sampleRate,
  AudioFormat.CHANNEL_IN_STEREO,
  AudioFormat.ENCODING_PCM_16BIT,
  // buffer length in bytes
  outputBufferSize,
  AudioTrack.MODE_STREAM
);
Related