版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zxd_Android/article/details/82149989
AudioTrack 可以用来播放PCM数据,上一篇博客我讲了AudioRecord可以录制PCM数据
AudioTrack实例可以在两种模式下运行:静态或流式传输。
在Streaming模式下,应用程序使用write()方法之一将连续的数据流写入AudioTrack。当数据从Java层传输到native层并排队等待回放时,这些是阻塞和返回。在播放音频数据块时,流模式最有用,以下情形适用于流模式:
1、由于播放时间太长,数据量太大以至于内存紧张。
2、由于音频数据的特性(高采样率,每个样本的位数……),因此太大而无法存储在内存中。
3、在播放先前排队的音频时接收或生成。
在处理适合内存的短音并且需要以尽可能小的延迟播放时,应选择静态模式。因此,静态模式将优选用于经常播放的UI和游戏声音,并且可能具有最小的开销
AudioTrack的构造函数目前一共是三个,public AudioTrack (int streamType, int sampleRateInHz,int channelConfig, int audioFormat, int bufferSizeInBytes, int mode, int sessionId) 等带有 streamType的已经在API 26以后废弃
下面是使用 示例
package com.example.mediatest;
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Environment;
import android.util.Log;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* Created by zhangxd on 2018/8/25.
*/
public class AudioTrackManager {
private static final String TAG = AudioTrack.class.getSimpleName();
public static String PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/audio.pcm";
private static AudioTrackManager instance;
private int mSampleRate = 44100;
private int channelCount = 2;
private AudioTrack mAudioTrack;
private int channelConfig = AudioFormat.CHANNEL_IN_STEREO;
private int bufferSize;
private int audioFormatEncode = AudioFormat.ENCODING_PCM_16BIT;
private AudioManager mAudioManager;
private Context mContext;
private AudioFormat mAudioFormat;
private FileInputStream fileInputStream;
private boolean startPlay = false;
public AudioTrackManager() {
}
public static AudioTrackManager getInstance() {
if (instance == null) {
instance = new AudioTrackManager();
}
return instance;
}
public void setContext(Context context) {
this.mContext = context;
init();
}
private void init() {
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
bufferSize = AudioTrack.getMinBufferSize(mSampleRate, channelConfig, audioFormatEncode);
int sessionId = mAudioManager.generateAudioSessionId();
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build();
AudioFormat audioFormat = new AudioFormat.Builder().setSampleRate(mSampleRate)
.setEncoding(audioFormatEncode)
.setChannelMask(channelConfig)
.build();
mAudioTrack = new AudioTrack(audioAttributes, audioFormat, bufferSize * 2, AudioTrack.MODE_STREAM, sessionId);
try {
fileInputStream = new FileInputStream(PATH);
} catch (FileNotFoundException e) {
Log.e(TAG, "init: " + e);
}
}
public void startThread() {
startPlay = true;
new PlayThread().start();
}
public void stopThread() {
startPlay = false;
mAudioTrack.stop();
mAudioTrack.release();
}
class PlayThread extends Thread {
@Override
public void run() {
super.run();
byte[] buffer = new byte[bufferSize];
mAudioTrack.play();
try {
while (fileInputStream.read(buffer) > 0) {
mAudioTrack.write(buffer, 0, buffer.length);
}
} catch (IOException e) {
Log.e(TAG, "IOException " + e);
}
}
}
}