Use the AudioTrack component to play audio files in Pcm raw format

First, audio playback

1.1 MediaPlayer

In general, in Android development, when playing audio, you will consider using MediaPlayer for playback, such as MP3, AAC files

The process of using MediaPlayer is generally

  • Build instance

    MediaPlayer mediaPlayer = new MediaPlayer()

  • Setting the play path

    MediaPlayer mediaPlayer.setDataSource(path)

  • To prepare

    MediaPlayer prepare()

  • Start playing

    MediaPlayer.start()

  • Stop playing

    MediaPlayer.stop()

Of course, MediaPlayer is quite powerful. In addition to the above basic functions, there are also functions such as pause, jump, and setting some state callbacks

Because of this, MediaPlayer is convenient for playing audio in general development, but not if you want to play Pcm audio files

So what do you do? In fact, Android provides a component that plays Pcm audio files, called AudioTrack. AudioTrack is a component that plays Pcm audio files, compared to MediaPlayer

1.2 AudioTrack

In the previous chapter, I recorded an audio file in Pcm format by using AudioRecord, but I was anxious about the player to play it, so I didn’t know whether the Pcm recorded was normal, so I could verify whether the Pcm recorded was normal by AudioTrack

The usage process of AudioTrack is similar to that of AudioRecord

  • Starting a child thread
  • Build instance
  • Start playing
  • Loop to read and write file dataAudioTrack
  • Stop the playback to release resources

The following section describes the playing process of AudioTrack in detail

2. AudioTrack Playback process

2.1 Enabling subthreads

Like AudioRecord’s recording process, AudioTrack’s playback process also needs to be executed in child threads

private static class PlayThread extends Thread {
    public PlayThread(a){}}Copy the code

2.2 Set parameters

private static class PlayThread extends Thread {
    /** * PCM playback component */
    private AudioTrack audioTrack;
    /** * File input */
    private FileInputStream fis;
    private final String path;
    /** * Audio stream format (usually music) */
    private final int streamType;
    /**
     * 采样率
     */
    private final int sampleRateInHz;
    /** * Channel Settings */
    private final int channelConfig;
    /** * Encoding format */
    private final int audioFormat;
    /** * Play mode (generally use stream mode) */
    private final int mod;
    /**
     * 音频缓存大小
     */
    private int bufferSizeInBytes;
    /** * Whether to stop playing */
    private boolean isStopPlay = false;
    /** * constructor (passing in the necessary arguments) */
    public PlayThread(String path,
                      int streamType,
                      int sampleRateInHz,
                      int channelConfig,
                      int audioFormat,
                      int mod
    ) {
        this.path = path;
        this.streamType = streamType;
        this.sampleRateInHz = sampleRateInHz;
        this.channelConfig = channelConfig;
        this.audioFormat = audioFormat;
        this.mod = mod; }}Copy the code

The following parameters are required to build AudioTrack

  • streamType

    In Android audio management, there are many audio stream types. Generally, you can use audiomanager.stream_music

  • sampleRateInHz

    Sampling rate, generally used 44100

  • channelConfig

    Sound channel Settings, mono CHANNEL_OUT_MONO, dual channel CHANNEL_OUT_STEREO, note that different from the channelConfig of AudioRecord, one is in, the other is out, indicating input and output respectively

  • audioFormat

    As with AudioRecord, ENCODING_PCM_8BIT and ENCODING_PCM_16BIT can also be selected

  • mod

    This parameter indicates the usage type of AudioTrack, usually audioTrack. MODE_STREAM

  • bufferSizeInBytes

    This parameter is the same as that of AudioRecord, which indicates the size of the buffer and is used when writing to AudioTrack

2.3 the initialization

Override Thread’s run method

# run()

@Override
public void run(a) {
    super.run();
    initIo();
    initAudioTrack();
    play();
}
Copy the code

The run method calls three methods, which are

  • initIo()

    Initializes the read file IO stream

  • initAudioTrack()

    Initialize the AudioTrack component

  • play()

    Let’s actually play

# initIo()

/** * Initialize IO */
private void initIo(a) {
    if (TextUtils.isEmpty(path)) {
        return;
    }
    try {
        fis = new FileInputStream(path);
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        fis = null; }}Copy the code

# initAudioTrack()

/** * Initialize the PCM playback component */
private void initAudioTrack(a) {
    bufferSizeInBytes = AudioTrack.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
    audioTrack = new AudioTrack(streamType, sampleRateInHz, channelConfig, audioFormat, bufferSizeInBytes, mod);
}
Copy the code

2.4 play

Once you’ve entered the play() method, it’s time to actually play # play()

/** * Start playing */
private void play(a) {
    if (audioTrack == null || fis == null) {
        return;
    }
    byte[] data = new byte[bufferSizeInBytes];
    audioTrack.play();
    for(; ;) {if (isStopPlay) {
            release();
            break;
        }
        int readSize = -1;
        try {
            readSize = fis.read(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (readSize <= 0) {
            isStopPlay = true;
            continue;
        }
        audioTrack.write(data, 0, readSize); }}Copy the code

Similar to AudioRecord, AudioTrack also uses for(;;). An infinite loop is built with the isStopPlay flag to control the call to the release() method and the exit of the loop

In contrast to AudioRecord, data is read from an AudioRecord and then written to a file, while AudioTrack is read from a file and then written to an AudioTrack

Resources are released at the end of manual or file reading

# release()

/** * Release resources */
private void release(a) {
    if(audioTrack ! =null) {
        audioTrack.stop();
        audioTrack.release();
        audioTrack = null;
    }
    if(fis ! =null) {
        try {
            fis.close();
        } catch(IOException e) { e.printStackTrace(); }}}Copy the code

During execution, you can hear the program playing Pcm

Third, making

Related classes are available on GitHub

PcmPlayer.java

PcmActivity.java