Wednesday, January 1, 2014

How to: Playback file with PCM samples in android

Note: I have been working on some audio processing related projects at work and thought I could share some code which others find useful. This one is the second in the series. First in the series is here.

As with recording, it makes sense to do audio playback in a separate thread or AsyncTask. Below is the code; should be self-explanatory:

public static final int AUDIO_FORMAT = AudioFormat.ENCODING_PCM_16BIT;
public static final int CHANNEL_IN_CONFIG = AudioFormat.CHANNEL_IN_MONO;
public static final int SAMPLING_RATE = 44100;
public static final int BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLING_RATE, CHANNEL_IN_CONFIG, AUDIO_FORMAT);
public static final String AUDIO_RECORDING_FILE_NAME = "recording.raw";
public static final int CHANNEL_OUT_CONFIG = AudioFormat.CHANNEL_OUT_MONO;


@Override
public void run() {
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
    Log.v(LOGTAG, "Starting playback...");

    AudioTrack audioTrack;
    String filePath = Environment.getExternalStorageDirectory().getPath()
                + "/" + AudioConstants.AUDIO_RECORDING_FILE_NAME;
    File f = new File(filePath);

    try {

        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
                SAMPLING_RATE,
                CHANNEL_OUT_CONFIG,
                AUDIO_FORMAT,
                BUFFER_SIZE, AudioTrack.MODE_STREAM);
        byte[] audioData = new byte[AudioConstants.BUFFER_SIZE];
        AudioTypeBuffer audioTypeBuffer = new AudioTypeBuffer();
        int bytesRead = 0;
        int readSize;
        int fileSize = (int) f.length();

        DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream(f)));

        audioTrack.play();

        while (bytesRead < fileSize && !mStop) {
            readSize = dis.read(audioData, 0, audioData.length);
            if (readSize != -1) {
                // Write the byte array to the track
                audioTrack.write(audioData, 0, readSize);
                bytesRead += readSize;
            }
        }
        dis.close();
        audioTrack.stop();
        audioTrack.release();

        Log.v(LOGTAG, "Playback done...");

        mStop = false;
    } catch (IOException e) {
        Log.e(LOGTAG, "Error playing file ", e);
    } catch (IllegalStateException e) {
        Log.e(LOGTAG, "Audio flinger doesn't like our track", e);
    }   
}

Written with StackEdit.

No comments:

Post a Comment