AudioTrack 基本使用
AudioTrack 是直接播放采集的 PCM 音频流,这里简单看下流程。
AudioTrack mAudioTrack;

//音频流类型
 private static final int mStreamType = AudioManager.STREAM_MUSIC;
 //指定采样率 (MediaRecoder 的采样率通常是 8000Hz AAC 的通常是 44100Hz。 设
 置采样率为 44100,目前为常用的采样率,官方文档表示这个值可以兼容所有的设置)
 private static final int mSampleRateInHz=44100 ;
 //指定捕获音频的声道数目。在 AudioFormat 类中指定用于此的常量
 private static final int mChannelConfig=
 AudioFormat.CHANNEL_CONFIGURATION_MONO; //单声道
 //指定音频量化位数 ,在 AudioFormaat 类中指定了以下各种可能的常量。通常我们选
 择 ENCODING_PCM_16BIT 和 ENCODING_PCM_8BIT PCM 代表的是脉冲编码调制,它实际
 上是原始音频样本。
 //因此可以设置每个样本的分辨率为 16 位或者 8 位,16 位将占用更多的空间和处理能
 力,表示的音频也更加接近真实。
 private static final int mAudioFormat=AudioFormat.ENCODING_PCM_16BIT;
 //指定缓冲区大小。调用 AudioRecord 类的 getMinBufferSize 方法可以获得。
 private int mMinBufferSize;
 //STREAM的意思是由用户在应用程序通过write方式把数据一次一次得写到audiotrack
 中。这个和我们在 socket 中发送数据一样,
 // 应用层从某个地方获取数据,例如通过编解码得到 PCM 数据,然后 write 到
 audiotrack。
 private static int mMode = AudioTrack.MODE_STREAM;
 创建 AudioTrack://根据采样率,采样精度,单双声道来得到 frame 的大小。
 mMinBufferSize = AudioTrack.getMinBufferSize(mSampleRateInHz,mChannelConfig, mAudioFormat);//计算最小缓冲区
 //注意,按照数字音频的知识,这个算出来的是一秒钟 buffer 的大小。
 //创建 AudioTrack
 mAudioTrack = new AudioTrack(mStreamType, mSampleRateInHz,mChannelConfig, mAudioFormat,mMinBufferSize,mMode);
 获取音频文件:
 mDis = new DataInputStream(new FileInputStream(file));
 获取音频数据:
 readCount= mDis.read(tempBuffer);


播放
mAudioTrack.play();
mAudioTrack.write(tempBuffer, 0, readCount);
这里说下,系统声音分很多类型:
 AudioManager.STREAM_MUSIC:用于音乐播放的音频流。
 AudioManager.STREAM_SYSTEM:用于系统声音的音频流。
 AudioManager.STREAM_RING:用于电话铃声的音频流。
 AudioManager.STREAM_VOICE_CALL:用于电话通话的音频流。
 AudioManager.STREAM_ALARM:用于警报的音频流。
 AudioManager.STREAM_NOTIFICATION:用于通知的音频流。
 AudioManager.STREAM_BLUETOOTH_SCO:用于连接到蓝牙电话时的手机音频流。
 AudioManager.STREAM_SYSTEM_ENFORCED:在某些国家实施的系统声音的音频流。
 AudioManager.STREAM_DTMF:DTMF 音调的音频流。
 AudioManager.STREAM_TTS:文本到语音转换(TTS)的音频流。
区分这个的原因是,底层在播放的时候,是有优先级的,同时也有一个就是音量调节会对应
到不同的配置上,需要一个判断参数。
而模式主要有两种,
AudioTrack.MODE_STREAM 和 AudioTrack.MODE_STATIC
使用 AudioTrack.MODE_STREAM 将数据不断地写入缓存里面,这个就是交互比较频繁,一直
要从上层传递下去,效率损失太大。这块的解决方案是,直接调用 C,使用 NDK 开发,完
成音频播放。
这块后续我们会讲一些关于 OpenSL ES 的相关知识。