AudioTrack
AudioTrack类说明:
1 | /** |
构造方法说明
1 | //根据采样率,采样精度,单双声道来得到frame的大小。 |
参数说明
1. AudioTrack.MODE_STREAM的意思:
AudioTrack中有MODE_STATIC和MODE_STREAM两种分类。
STREAM的意思是由用户在应用程序通过write方式把数据一次一次得写到audiotrack中。这个和我们在socket中发送数据一样,应用层从某个地方获取数据,例如通过编解码得到PCM数据,然后write到audiotrack。这种方式的坏处就是总是在JAVA层和Native层交互,效率损失较大。
而STATIC的意思是一开始创建的时候,就把音频数据放到一个固定的buffer,然后直接传给audiotrack,后续就不用一次次得write了。AudioTrack会自己播放这个buffer中的数据。 这种方法对于铃声等内存占用较小,延时要求较高的声音来说很适用。
2. StreamType
这个在构造AudioTrack的第一个参数中使用。这个参数和Android中的AudioManager有关系,涉及到手机上的音频管理策略。 Android将系统的声音分为以下几类常见的(定义在AudioManager):
1 | /** The audio stream for phone calls */ |
常用说明:
- STREAM_ALARM:警告声
- STREAM_MUSCI:音乐声,例如music等
- STREAM_RING:铃声
- STREAM_SYSTEM:系统声音
- STREAM_VOCIE_CALL:电话声音
为什么要分这么多呢?以前在台式机上开发的时候很少知道有这么多的声音类型,不过仔细思考下,发现这样做是有道理的。例如你在听music的时候接到电话,这个时候music播放肯定会停止,此时你只能听到电话,如果你调节音量的话,这个调节肯定只对电话起作用。当电话打完了,再回到music,你肯定不用再调节音量了。
其实系统将这几种声音的数据分开管理,所以,这个参数对AudioTrack来说,它的含义就是告诉系统,我现在想使用的是哪种类型的声音,这样系统就可以对应管理他们了。
AudioRecord
AudioRecord说明
The AudioRecord class manages the audio resources for Java applications to record audio from the audio input hardware of the platform. This is achieved by “pulling” (reading) the data from the AudioRecord object. The application is responsible for polling the AudioRecord object in time using one of the following three methods: read(byte[], int, int)
, read(short[], int, int)
or read(ByteBuffer, int)
. The choice of which method to use will be based on the audio data storage format that is the most convenient for the user of AudioRecord.
Upon creation, an AudioRecord object initializes its associated audio buffer that it will fill with the new audio data. The size of this buffer, specified during the construction, determines how long an AudioRecord can record before “over-running” data that has not been read yet. Data should be read from the audio hardware in chunks of sizes inferior to the total recording buffer size.
audiosource类型
定义在MediaRecorder中
1 | /** Default audio source **/ |
AudioManager
获取系统音量
代码
1 | //初始化AudioManager: |
ps: 游戏过程中只允许调整多媒体音量,而不允许调整通话音量。
1 | setVolumeControlStream(AudioManager.STREAM_MUSIC); |
控制音量
AudioManager提供了设置音量的方法:
1 | public void setStreamVolume(intstreamType,intindex,intflags) |
其中streamType有内置的常量,去文档里面就可以看到。 使用示例:
1 | //音量控制,初始化定义 |
监听按键手动控制音量
1 | AudioManager audio = (AudioManager) getSystemService(Service.AUDIO_SERVICE); |
插入耳机状态仍使用扬声器外放音乐
插入耳机的时候也可以选择使用扬声器播放音乐,来电铃声就是这么用的。但是只能用MediaPlayer,播放音频文件。 使用AudioTrack.write播放是行不通的(有待验证)。按理说AudioRecord、AudioTrack类相对于MediaRecorder mediaPlayer来说,更加接近底层,应该也行得通的。
插入耳机,选择外放的代码如下(兼容性验证):
1 | AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE); |
使用STREAM_VOCIE_CALL播放声音与耳机冲突
使用STREAM_VOCIE_CALL播放声音在某些手机,比如魅蓝等上面会导致声音仍外放,耳机没声音现象. WebRtc使用STREAM_VOCIE_CALL播放声音,导致某些手机声音低,没法使用音量键调节,插入耳机声音仍外放等问题.