AudioTrack的简单用法

参考 https://github.com/renhui/AudioDemo/blob/master/audiodemo/src/main/java/com/renhui/audiodemo/MainActivity.java

https://blog.csdn.net/ronaldo4511/article/details/89155457

AudioTrack:用于输出音频数据,它有两种数据加载模式

        MODE_STREAM:以流的形式持续把音频数据写到AudioTrack内部的Buffer中

        MODE_STATIC:在play之前只需要把所有数据通过一次write调用传递到AudioTrack中的内部缓冲区

示例代码

import android.Manifest;
import android.annotation.SuppressLint;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class AudioTrackActivity extends AppCompatActivity {

    // 采样率
    // 44100是目前的标准,但是某些设备仍然支持22050,16000,11025
    // 采样频率一般共分为22.05KHz、44.1KHz、48KHz三个等级
    private final static int AUDIO_SAMPLE_RATE = 16000;

    // 音频通道 单声道
    private final static int AUDIO_CHANNEL = AudioFormat.CHANNEL_OUT_MONO;

    // 音频格式:PCM编码
    private final static int AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;

    // 音频格式:PCM编码
    private final static int AUDIO_TRACK_TYPE_STREAM = AudioTrack.MODE_STREAM;

    /**
     * 需要申请的运行时权限
     */
    private String[] permissions = new String[]{
            Manifest.permission.RECORD_AUDIO,
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };
    private static final int MY_PERMISSIONS_REQUEST = 1001;
    private final String pcmFileName = Environment.getExternalStorageDirectory() + "/Download/record.pcm";
    private AudioTrack audioTrack;
    private byte[] audioData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_audio_track);

        ActivityCompat.requestPermissions(this, permissions, MY_PERMISSIONS_REQUEST);

        findViewById(R.id.staticStart).setOnClickListener(v -> staticStart());

        findViewById(R.id.streamStart).setOnClickListener(v -> streamStart());

        findViewById(R.id.stop).setOnClickListener(v -> stop());

    }

    @SuppressLint("StaticFieldLeak")
    private void staticStart(){

        new AsyncTask() {
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    InputStream in = new FileInputStream(new File(pcmFileName));
                    try {
                        ByteArrayOutputStream out = new ByteArrayOutputStream();
                        for (int b; (b = in.read()) != -1; ) {
                            out.write(b);
                        }

                        audioData = out.toByteArray();
                    } finally {
                        in.close();
                    }
                } catch (IOException e) {
                }
                return null;
            }


            @Override
            protected void onPostExecute(Void v) {
                audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, AUDIO_SAMPLE_RATE,
                        AUDIO_CHANNEL, AUDIO_ENCODING, audioData.length, AUDIO_TRACK_TYPE_STREAM);
                audioTrack.write(audioData, 0, audioData.length);
                audioTrack.play();
            }

        }.execute();

    }

    private void stop(){
        if (null != audioTrack) {
            audioTrack.stop();
            audioTrack.release();
            audioTrack = null;
        }
    }

    private void streamStart(){

        final int minBufferSize = AudioTrack.getMinBufferSize(AUDIO_SAMPLE_RATE, AUDIO_CHANNEL, AUDIO_ENCODING);
        audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, AUDIO_SAMPLE_RATE,
                AUDIO_CHANNEL, AUDIO_ENCODING, minBufferSize, AUDIO_TRACK_TYPE_STREAM);
        audioTrack.play();
        File file = new File(pcmFileName);

        new Thread(() -> {

            try {
                FileInputStream fileInputStream = new FileInputStream(file);
                byte[] tempBuffer = new byte[minBufferSize];
                while (fileInputStream.available() > 0) {
                    int readCount = fileInputStream.read(tempBuffer);
                    if (readCount == AudioTrack.ERROR_INVALID_OPERATION ||
                            readCount == AudioTrack.ERROR_BAD_VALUE) {
                        continue;
                    }
                    if (readCount != 0 && readCount != -1) {
                        audioTrack.write(tempBuffer, 0, readCount);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }).start();

    }

}

 

你可能感兴趣的:(android)