Android音频混合库
AudioMixer所有操作都是线程安全的,无需考虑线程安全问题;AudioMixer释放后会自动释放其他有关资源,无需再对其他相关对象进行释放
// sampleRate: 采样率
// channelCount: 声道数量
// timeLength: 时间长度,单位:微秒(注意:这里不是毫秒),表示一次混合的音频时间
// pcmType: pcm格式类型:PcmType.BIT16、PcmType.BIT8,目前只支持两种
AudioMixer audioMixer = new AudioMixer(sampleRate, channelCount, timeLength, pcmType);
建立线程,在线程循环中执行以下代码:
while(loop) {
// 阻塞方式
ByteBuffer buffer = audioMixer.tickAndWait();
// 非阻塞方式
// ByteBuffer buffer = mixer.tick();
if (null != buffer) {
// buffer里包含了混合后的声音,读取此buffer即可
// ...
// 数据处理后,需要解锁buffer,不执行会导致其输入音频会一直阻塞
audioMixer.unlock();
}
}
AudioMixer可以创建多个输入音轨进行混合,以下为音轨创建示例:
// sampleRate: 采样率
// channelCount: 声道数量
// pcmType: pcm格式类型:PcmType.BIT16、PcmType.BIT8,目前只支持两种
// 请求创建的输入音轨事件长度同AudioMixer本身时间长度;
// 可以创建与AudioMixer本身不同的采样率、声道数量、PcmType进行声音混合
AudioTrack audioTrack = audioMixer.requestTrack(sampleRate, channelCount, pcmType);
// 不再需要用此音轨时,可以删除
audioTrack.delete();
使用ByteBuffer作为数据源,写入数据
// data为ByteBuffer类型,其position和limit要提前设置号
public static void writeByteBufferToTrack(AudioTrack track, ByteBuffer data) {
int size = data.remaining();
int offset = data.position();
int limit = data.limit();
int writeLen = 0;
while (writeLen < size) {
data.position(writeLen + offset);
data.limit(limit);
int len = track.write(data);
if (len < 0) {
// 返回负数,特殊值,需要进行判断
if (len == AudioTrack.WRITE_RESULT_FULL) {
// 已填满
track.flush();
// 等待buffer解锁
track.waitUnlock();
} else {
// 发生错误
break;
}
} else {
writeLen += len;
}
}
}
使用字节数据作为数据源,写入数据
public static void writeBytesToTrack(AudioTrack track, byte[] data, int offset, int size) {
int writeLen = 0;
while (writeLen < size) {
int len = track.write(data, offset + writeLen, size - writeLen);
if (len < 0) {
// 返回负数,特殊值,需要进行判断
if (len == AudioTrack.WRITE_RESULT_FULL) {
// 已填满
track.flush();
// 等待buffer解锁
track.waitUnlock();
} else {
// 发生错误,可以在此判断错误类型
// AudioTrack.WRITE_RESULT_LOCKED
// AudioTrack.WRITE_RESULT_DELETED
break;
}
} else {
writeLen += len;
}
}
}
不再使用AudioMixer时,进行释放
audioMixer.release();
// 如果有线程再循环,需要自己去关闭线程循环,AudioMixer没有管理线程的能力
// loop = false;
更详细使用请查看demo