Android 音频开发——AudioTrack播放

Posted VNanyesheshou

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 音频开发——AudioTrack播放相关的知识,希望对你有一定的参考价值。

Android 音频——PCM转WAV
Android 音频开发——AudioRecord录音

 AudioTrack类用来管理、播放单个音频资源,它只能播放PCM数据,其他音频格式(aac、amr、opus、flac等)需要经过解码成PCM才能使用。

运行模式

AudioTrack可以运行两种模式:

  1. 流模式
  2. 静态模式

流模式
 可以将连续的数据流写入AudioTrack,进行播放。播放音频数据块时,这种模式最有用。
如:

  • 声音持续的时间太长,无法容纳在内存中;
  • 由于音频数据的特性(太大的采样率,每个采样的比特数…)而太大而无法容纳在内存中;
  • 在播放先前排队的音频时收到或生成的声音。

静态模式
 当处理很短的音频并且需要以最小延迟播放时,应该选择静态模式。对于经常播放的UI和游戏声音而言,静态模式将是首选方式,并且可能会产生最小的开销。

缓冲区

 当创建AudioTrack时,AudioTrack将初始化其关联的音频缓冲区。在构造期间指定的此缓冲区大小决定了AudioTrack在数据用尽之前可以播放多长时间。
 对于静态模式,此大小是可以从中播放的最大音频数据大小。
 对于流模式,数据将以小于等于此缓冲区大小的块的形式写入音频接收器。

AudioTrack播放

这里主要说一下AudioTrack的流模式使用。
基本步骤

  1. 获取最小缓冲区大小(创建AudioTrack对象所需);
  2. 创建AudioTrack对象;
  3. 调用AudioTrack play方法,开始播放。
  4. 写入音频数据;
  5. 停止播放
  6. 释放对象。

1 获取最小缓冲区大小

int minSize = AudioTrack.getMinBufferSize(sampleRate,
		outChannelConfig, AudioFormat.ENCODING_PCM_16BIT);

sampleRate:采样频率
outChannelConfig:声道配置,CHANNEL_OUT_MONO、CHANNEL_OUT_STEREO。
audioFormat:音频编码,AudioFormat.ENCODING_PCM_16BIT、ENCODING_PCM_8BIT.

2 初始化

AudioTrack构造器已经过时,推荐使用AudioTrack.Builder进行创建AudioTrack对象。

mTrack = new AudioTrack.Builder()
		.setAudioAttributes(new AudioAttributes.Builder()
				.setUsage(AudioAttributes.USAGE_MEDIA)
				.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
				.build())
		.setAudioFormat(new AudioFormat.Builder()
				.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
				.setSampleRate(sampleRate)
				.setChannelMask(outChannelConfig)
				.build())
		.setBufferSizeInBytes(minSize)
		.build();

创建AudioTrack对象,同时设置采样率、声道数、音频格式,缓冲区大小。

3 开始播放

调用play前,可以先向缓冲区写入音频数据。也可以后写。

mTrack.play();

如果不限调用write,或者write数量不足,则调用play处于欠载状态,这种情况下不会播放。只有后续将数据写入,播放才会真正开始播放。

4 写入数据

mTrack.write(audioData.data, 0, size);

将音频数据写入音频接收器以进行播放。
该方法默认情况是阻塞模式,直到所有数据都排入队列进行播放为止,并且将返回完整的传输计数。 但是,如果轨道在进入时停止或暂停,或者另一个线程通过调用停止或暂停来中断写入,或者在写入过程中发生I / O错误,则写入可能会返回较短的传输计数。

  • WRITE_BLOCKING:阻塞模式,写入将被阻塞,直到所有数据都已写入音频接收器为止。
  • WRITE_NON_BLOCKING:非阻塞模式,在排队尽可能多的音频数据以进行播放而不会阻塞,写入将立即返回。

5 停止

调用以下两种方法都可以停止播放,并且都可以恢复播放,停止时机略有不同。
1 停止播放音频数据,调用此方法后,音频将在播放了最后写入的缓冲区后停止播放。

mTrack.stop();

2 暂停音频数据的播放。 未播放的数据将不会被丢弃。 随后调用play将播放此数据。

mTrack.pause();

6 释放内存

释放本地AudioRecord资源。
调用release()之后,将无法再使用该对象,并且应将引用设置为null。

mTrack.release();
mTrack=null;

demo:一边录制WAV,一边播放音频

源代码路径https://github.com/pyzhangfan/audio-sample-app

欢迎大家关注、评论、点赞、打赏。
你们的支持是我坚持的动力。Thank you!

以上是关于Android 音频开发——AudioTrack播放的主要内容,如果未能解决你的问题,请参考以下文章

高通平台开发系列讲解(Android篇)AudioTrack音频流数据传输

使用 Audiotrack 在 Android 中播放 javacv-ffmpeg 解码的音频

Android 自定义音频播放器,用 libPd 或 OpenSL ES 或 AudioTrack 替换 MediaPlayer

Android 音频源码分析——AudioTrack设备选择

Android 音频源码分析——AudioTrack设备选择

Android 音频系统:从 AudioTrack 到 AudioFlinger