Android的Audio系统详解
2017年05月06日 10:20:50 zzqhost 阅读数:3318更多
个人分类: Android代码研究
目录
1.4.1 AudioManager和AudioService
1.4.2 RingToneManager和RingTone
3.3.4 AudioPolicyManagerBase的职责
3.3.5 AudioPolicyManagerBase中的主要方法
1 Audio的Framework层功能及用法大全
1.1 多媒体的framework接口预览
类型 | 文件名 | 描述 |
|
多媒体核心 | MediaPlayer.java |
|
|
MediaRecorder.java |
|
| |
应用层控制Extractor,解码 | DecoderCapabilities.java | 用来获得Android平台支持的解码器。 |
|
EncoderCapabilities.java | 用来获得Android平台支持的编码器。 |
| |
MediaCodecInfo.java |
| Android4.1 | |
MediaCodec.java |
| Android4.1 | |
MediaCodecList.java |
| Android4.1 | |
MediaFormat.java |
| Android4.1 | |
MediaExtractor.java |
| Android4.1 | |
Utils | MediaCrypto.java | 为MediaCodec提供支持 | Android4.1 |
MediaCryptoException.java |
| Android4.1 | |
MediaSyncEvent.java |
| Android4.1 | |
Audio核心 | AudioRecord.java |
|
|
AudioTrack.java |
|
| |
AudioSystem.java |
|
| |
AudioFormat.java |
|
| |
声音路由相关 | AudioRoutesInfo.java | 用来设置声音路由,现在用户可以自由设置AudioPolicy中的功能了。 | Android4.1 |
MediaRouter.java |
| Android4.1 | |
Audio辅助及控制 | AsyncPlayer.java | 声音异步加载 |
|
AudioManager.java | 管理音量、铃声 |
| |
AudioService.java | 声音管理服务, AudioManager中调用的是此中的实现 |
| |
RingtoneManager.java |
|
| |
Ringtone.java |
|
| |
ToneGenerator.java |
|
| |
SoundPool.java |
|
| |
MediaActionSound.java |
| Android4.1 | |
Camera | CamcorderProfile.java |
|
|
CameraProfile.java |
|
| |
扫描和Provider | MediaFile.java |
|
|
MediaScannerClient.java |
|
| |
MediaScannerConnection.java |
|
| |
MediaScanner.java |
|
| |
MediaInserter.java |
|
| |
Metadata.java |
|
| |
TimedText.java |
|
| |
MediaMetadataRetriever.java |
|
| |
MiniThumbFile.java |
|
| |
ThumbnailUtils.java |
|
| |
其它 | ExifInterface.java | 用来获得Jpeg图像的Exif信息 |
|
FaceDetector.java | 人脸识别,有没有实现就不知道了,需要再研究。 |
| |
JetPlayer.java |
|
| |
RemoteControlClient.java |
|
| |
AmrInputStream.java |
|
| |
ResampleInputStream.java |
|
|
说明:在frameworks/base/media/java/android/media/ 路径下总共有57个文件:
文件夹: 2个
aidl文件: 10个
html文件: 1个
以上有说明的文件:44个, 相对Android4.0.3增加了11个。
下面是两个文件夹下的具体内容:
VideoEditor | |-- AudioTrack.java |
|-- EffectColor.java | |
|-- Effect.java | |
|-- EffectKenBurns.java | |
|-- ExtractAudioWaveformProgressListener.java | |
|-- MediaArtistNativeHelper.java | |
|-- MediaImageItem.java | |
|-- MediaItem.java | |
|-- MediaProperties.java | |
|-- MediaVideoItem.java | |
|-- OverlayFrame.java | |
|-- Overlay.java | |
|-- TransitionAlpha.java | |
|-- TransitionCrossfade.java | |
|-- TransitionFadeBlack.java | |
|-- Transition.java | |
|-- TransitionSliding.java | |
|-- VideoEditorFactory.java | |
|-- VideoEditorImpl.java | |
|-- VideoEditor.java | |
|-- VideoEditorProfile.java | |
`-- WaveformData.java | |
AudioFx | |-- AcousticEchoCanceler.java |
|-- AudioEffect.java | |
|-- AutomaticGainControl.java | |
|-- BassBoost.java | |
|-- EnvironmentalReverb.java | |
|-- Equalizer.java | |
|-- NoiseSuppressor.java | |
|-- package.html | |
|-- PresetReverb.java | |
|-- Virtualizer.java | |
`-- Visualizer.java |
1.2 Audio相关的文件预览
在整个Framework的Media部分与Audio相关的部分如下:
类型 | 文件名 | 描述 |
|
Audio核心 | AudioRecord.java |
|
|
AudioTrack.java |
|
| |
AudioSystem.java |
|
| |
AudioFormat.java |
|
| |
声音路由相关 | AudioRoutesInfo.java | 用来设置声音路由,现在用户可以自由设置AudioPolicy中的功能了。 | Android4.1 |
MediaRouter.java |
| Android4.1 | |
Audio辅助及控制 | AsyncPlayer.java | 声音异步加载 |
|
AudioManager.java | 管理音量、铃声 |
| |
AudioService.java | 声音管理服务, AudioManager中调用的是此中的实现 |
| |
RingtoneManager.java |
|
| |
Ringtone.java |
|
| |
ToneGenerator.java |
|
| |
SoundPool.java |
|
| |
MediaActionSound.java |
| Android4.1 |
由上图可知:Framework层主要分为两个部分,Audio的核心层和Audio的辅助类。Audio核心层的类包括AudioTrack, AudioRecord, AudioSystem。Audio的辅助类主要有AudioManager,RingToneManager,ToneGenerator和SoundPool。
下面的章节节将分别介绍这些部分。
1.3 Audio核心
1.3.1 AudioTrack
AudioTrack是播放的API接口,具体用法是先new一个实例出来,然后再调用它里边的一个play, write, read等函数, 最后stop, release.
下图是一个建立及销毁的全过程:
1.3.2 AudioRecord
AudioRecord是录音的API,提供接口给用户调用,并且含有大量的native函数,需要JNI调用Native的相关功能。
1.3.3 AudioFormat
AudioFormat中定义了一些变量,这些变量在AudioTrack和AudioRecord中用到。主要有以下内容:
1.3.3.1 Audio data format
/** Invalid audio data format */
public static final int ENCODING_INVALID = 0;
/** Default audio data format */
public static final int ENCODING_DEFAULT = 1;
// These two values must be kept in sync with JNI code for AudioTrack, AudioRecord
/** Audio data format: PCM 16 bit per sample. Guaranteed to be supported by devices. */
public static final int ENCODING_PCM_16BIT = 2;
/** Audio data format: PCM 8 bit per sample. Not guaranteed to be supported by devices. */
public static final int ENCODING_PCM_8BIT = 3;
1.3.3.2 Chanel mask
包括chanel in 和 chanel out的很多掩码定义
1.3.4 AudioSystem
此类包含了一些常量定义,设备定义,native的方法调用接口等。
以下是代码中的说明:
/* These values must be kept in sync with AudioSystem.h */
/*
* If these are modified, please also update Settings.System.VOLUME_SETTINGS
* and attrs.xml and AudioManager.java.
*/
/* The audio stream for phone calls */
1.3.4.1 Audio stream相关
public static final int STREAM_VOICE_CALL = 0;
public static final int STREAM_SYSTEM = 1;
public static final int STREAM_RING = 2;
public static final int STREAM_MUSIC = 3;
public static final int STREAM_ALARM = 4;
public static final int STREAM_NOTIFICATION = 5;
public static final int STREAM_BLUETOOTH_SCO = 6;
public static final int STREAM_SYSTEM_ENFORCED = 7;
public static final int STREAM_DTMF = 8;
public static final int STREAM_TTS = 9;
目前一共10种Type, 从0-9, 并且用以下的函数取得StreameType的Count.
// Expose only the getter method publicly so we can change it in the future
private static final int NUM_STREAM_TYPES = 10;
public static final int getNumStreamTypes() { return NUM_STREAM_TYPES; }
Audio Stream是一个重要的类型,在其它的很多函数中都需要用到它, 如下所示:
public static native boolean isStreamActive(int stream, int inPastMs);
public static native int initStreamVolume(int stream, int indexMin, int indexMax);
public static native int setStreamVolumeIndex(int stream, int index, int device);
public static native int getStreamVolumeIndex(int stream, int device);
public static native int getDevicesForStream(int stream);
1.3.4.2 Microphone是否静音
public static native int muteMicrophone(boolean on);
public static native boolean isMicrophoneMuted();
返回值是 AUDIO_STATUS_OK 或 AUDIO_STATUS_ERROR
1.3.4.3 setPhoneState()
public static native int setPhoneState(int state);
// phone state, match audio_mode???
public static final int PHONE_STATE_OFFCALL = 0;
public static final int PHONE_STATE_RINGING = 1;
public static final int PHONE_STATE_INCALL = 2;
上边的被淘汰了,用下边的定义:
/* modes for setPhoneState, must match AudioSystem.h audio_mode */
public static final int MODE_INVALID = -2;
public static final int MODE_CURRENT = -1;
public static final int MODE_NORMAL = 0;
public static final int MODE_RINGTONE = 1;
public static final int MODE_IN_CALL = 2;
public static final int MODE_IN_COMMUNICATION = 3;
public static final int NUM_MODES = 4;
1.3.4.4 setParameters() 和 getParameters
/*
* Sets a group generic audio configuration parameters. The use of these parameters
* are platform dependent, see libaudio
*
* param keyValuePairs list of parameters key value pairs in the form:
* key1=value1;key2=value2;...
*/
public static native int setParameters(String keyValuePairs);
/*
* Gets a group generic audio configuration parameters. The use of these parameters
* are platform dependent, see libaudio
*
* param keys list of parameters
* return value: list of parameters key value pairs in the form:
* key1=value1;key2=value2;...
*/
public static native String getParameters(String keys);
1.3.4.5 DeviceConnectionState
public static native int setDeviceConnectionState(int device, int state, String device_address);
public static native int getDeviceConnectionState(int device, String device_address);
1.3.4.6 ForceUse
public static native int setForceUse(int usage, int config);
public static native int getForceUse(int usage);
// device categories config for setForceUse, must match AudioSystem::forced_config
public static final int FORCE_NONE = 0;
public static final int FORCE_SPEAKER = 1;
public static final int FORCE_HEADPHONES = 2;
public static final int FORCE_BT_SCO = 3;
public static final int FORCE_BT_A2DP = 4;
public static final int FORCE_WIRED_ACCESSORY = 5;
public static final int FORCE_BT_CAR_DOCK = 6;
public static final int FORCE_BT_DESK_DOCK = 7;
public static final int FORCE_ANALOG_DOCK = 8;
public static final int FORCE_DIGITAL_DOCK = 9;
public static final int FORCE_NO_BT_A2DP = 10;
public static final int FORCE_SYSTEM_ENFORCED = 11;
private static final int NUM_FORCE_CONFIG = 12;
public static final int FORCE_DEFAULT = FORCE_NONE;
// usage for setForceUse, must match AudioSystem::force_use
public static final int FOR_COMMUNICATION = 0;
public static final int FOR_MEDIA = 1;
public static final int FOR_RECORD = 2;
public static final int FOR_DOCK = 3;
public static final int FOR_SYSTEM = 4;
private static final int NUM_FORCE_USE = 5;
1.3.4.7 StreamVolume
public static native int initStreamVolume(int stream, int indexMin, int indexMax);
public static native int setStreamVolumeIndex(int stream, int index, int device);
public static native int getStreamVolumeIndex(int stream, int device);
1.3.4.8 MasterVolume 和 MasterMute
public static native int setMasterVolume(float value);
public static native float getMasterVolume();
public static native int setMasterMute(boolean mute);
public static native boolean getMasterMute();
1.3.4.9 getDevicesForStream()
public static native int getDevicesForStream(int stream);
1.3.4.10 PrimaryOutput
public static native int getPrimaryOutputSamplingRate();
public static native int getPrimaryOutputFrameCount();
1.4 Audio辅助
1.4.1 AudioManager和AudioService
Android中AudioManager主管的是音量及一些铃音等。在代码中的典型用法如下:
// Request the audio focus so that other apps can pause playback.
final AudioManager audioManager = AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.requestAudioFocus(null, AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
得到的AUDIO_SERVICE是AudioManager类型,然后具体的工作再传给AudioService去做。
AudioManager提供的具体方法如下:
1.4.2 RingToneManager和RingTone
RingToneManager类管理所有的RingTone, 其实际是从数据库中查找出都有哪些Ringtone给调用者,然后调用者可以指定创建哪个RongTone, RongToneManager就会new 相应的RingTone类实例。
RingTone分为三种类型:Ringtone, notifaction, alam.
从其存储的位置还可以分为三种: internel ringtone, media ringtone, drmringtone.
RingTone类其实是一个含有StreamType的简单播放器,调用系统的MediaPlayer.
首先尝试用LocalPlayer(类型为MediaPlayer)进行播放设置进来的URI,如果没有LocalPlayer 则用RemotePlayer来进行播放。RemotePlayer是从AudioManager中得来的,即是一个服务中的。
RingTone与Tone音的区别,参见ToneGenerator
1.4.3 ToneGenerator
ToneGenerator的职责是控制简单声音的Tone声发音。 例如电话拨号按键时发出的声音。
ToneGenerator的API也很简单,只是一个构造,然后是StartTone, StopTone.
有一个ToneType的概念。 有很多种Tone类型。
这个ToneGenerator与RingTone不一样, RingTone只是一种概念,其实就是普通的声音文件,比如Mp3, 把它们存到特定的位置,即成为RingTone.这个在扫描的代码中有具体的代码,应该是有三个文件夹的位置。
ToneGenerator有native层的实现,具体的实现均位于Native层。
1.4.4 SoundPool
SoundPool是为了加快那些短小并且需要频繁播放的声音准备的,例如游戏中的一些发音“哈哈哈,嘿嘿嘿”。
从它的表面意思就能看出来,声音池,哈哈!!
什么? 不懂? 那你知道线程池不? 也不知道, 那你就别混了……
1.5 Audio路由
1.5.1 MediaRounter
待研究…
1.6 Audio Framework层总结
待研究…
2 Audio系统的整体结构
Audio从整个结构上来说分为Framework层,JNI 层,Native层,Hal及Driver层。
由上节可知,Framework层主要分为两个部分,Audio的核心层和Audio的辅助类。Audio核心层的类包括AudioTrack, AudioRecord, AudioSystem。Audio的辅助类主要有AudioManager,RingToneManager,ToneGenerator和SoundPool。
其中它们之中具有JNI的有:AudioRecorder, AudioTrack, AudioSystem, ToneGenerator, SoundPool。
再之下就是Native层的AudioPolicy和AudioFlinger了。这些内容将会在Native层的部分进行介绍。
下图是整个系统的框架图:
从Native层开始,它们的对外接口是libmedia中的AudioTrack, AudioRecorder, AudioSyste, 其中AudioSystem依赖于AudioFlinger和AudioPolicy这两个服务中提供的具体功能。如下图所示:
3 Audio系统的Native层
如果按照Android的四层体系架构,Native层(包括)往下是一个完整的体系,Framework层(包括)往上是一个层次,它们分别有它们的对外接口。Framework层的对外接口,请参考第一章,Native层及以下的对外接口就是AudioRecorder, AudioTrack, AudioSyste这三个类。它们之间通过JNI进行联通。
对外接口的三个类:
3.1 Audio框架libmedia
Audio的框架主要是几个对外接口类,及抽象接口定义,比如AudioTrack, AudioSyste, IAudioFlinger,以及AudioPolicyService类的定义。
未完待续…
3.2 AudioFlinger
AudioFlinger是Android中音频的核心,主要负责音频的混音,并把完成的PCM数据送到Hal层的硬件去播放。
未完待续…
3.3 AudioPolicy
3.3.1 代码位置
1. AudioPolicyService位置:
Frameworks/av/services/audioflinger/AudioService.h
Frameworks/av/services/audioflinger/AudioService.cpp
2. AudioPolicy的头文件定义:
hardware/libhardware/include/hardware/audio_policy.h
3. 实现位置
hardware/libhardware_legacy/audio/audio_policy_hal.cpp
hardware/ libhardware_legacy/audio/AudioPolicyManagerBase.cpp
4. 不同的厂商具有不同的实现从以上Android的实现继承下来。
3.3.2 AudioPolicy的结构图
3.3.3 AudioPolicyManagerBase
可以说AudioPolicyManagerBase是AudioPolicy实现的核心,这是Android的一个默认实现,对于每一个平台来说,产生可以从它继承一个子类,进行自己的定制化修改,但是AudioPolicyManagerBase已经完成了完整的逻辑,一般来说厂商的子类不会重载基类AudioPolicyManagerBase中的实现或者只重载一小部分的内容。
3.3.4 AudioPolicyManagerBase的职责
设置电话的状态
设置Stream的音量,并计算音量,设置到AudioFlinger中。
StartOutput
Forceuse
根据电话状和Stream Type和ForceUse选择device
计算音量时,如果是插着耳机的话,为了保护听力,会降低音量。
3.3.5 AudioPolicyManagerBase中的主要方法
virtual status_t setDeviceConnectionState(audio_devices_t device,
AudioSystem::device_connection_state state,
const char *device_address) = 0;
// retrieve a device connection status
virtual AudioSystem::device_connection_state getDeviceConnectionState(audio_devices_t device,
const char *device_address) = 0;
// indicate a change in phone state. Valid phones states are defined by AudioSystem::audio_mode
virtual void setPhoneState(int state) = 0;
// force using a specific device category for the specified usage
virtual void setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config) = 0;
// retrieve current device category forced for a given usage
virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage) = 0;
// set a system property (e.g. camera sound always audible)
virtual void setSystemProperty(const char* property, const char* value) = 0;
// check proper initialization
virtual status_t initCheck() = 0;
//
// Audio routing query functions
//
// request an output appropriate for playback of the supplied stream type and parameters
virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream,
uint32_t samplingRate = 0,
uint32_t format = AudioSystem::FORMAT_DEFAULT,
uint32_t channels = 0,
AudioSystem::output_flags flags = AudioSystem::OUTPUT_FLAG_INDIRECT) = 0;
// indicates to the audio policy manager that the output starts being used by corresponding stream.
virtual status_t startOutput(audio_io_handle_t output,
AudioSystem::stream_type stream,
int session = 0) = 0;
// indicates to the audio policy manager that the output stops being used by corresponding stream.
virtual status_t stopOutput(audio_io_handle_t output,
AudioSystem::stream_type stream,
int session = 0) = 0;
// releases the output.
virtual void releaseOutput(audio_io_handle_t output) = 0;
// request an input appropriate for record from the supplied device with supplied parameters.
virtual audio_io_handle_t getInput(int inputSource,
uint32_t samplingRate = 0,
uint32_t Format = AudioSystem::FORMAT_DEFAULT,
uint32_t channels = 0,
AudioSystem::audio_in_acoustics acoustics = (AudioSystem::audio_in_acoustics)0) = 0;
// indicates to the audio policy manager that the input starts being used.
virtual status_t startInput(audio_io_handle_t input) = 0;
// indicates to the audio policy manager that the input stops being used.
virtual status_t stopInput(audio_io_handle_t input) = 0;
// releases the input.
virtual void releaseInput(audio_io_handle_t input) = 0;
//
// volume control functions
//
// initialises stream volume conversion parameters by specifying volume index range.
virtual void initStreamVolume(AudioSystem::stream_type stream,
int indexMin,
int indexMax) = 0;
// sets the new stream volume at a level corresponding to the supplied index for the
// supplied device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT means
// setting volume for all devices
virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream,
int index,
audio_devices_t device) = 0;
// retrieve current volume index for the specified stream and the
// specified device. By convention, specifying AUDIO_DEVICE_OUT_DEFAULT means
// querying the volume of the active device.
virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream,
int *index,
audio_devices_t device) = 0;
// return the strategy corresponding to a given stream type
virtual uint32_t getStrategyForStream(AudioSystem::stream_type stream) = 0;
// return the enabled output devices for the given stream type
virtual audio_devices_t getDevicesForStream(AudioSystem::stream_type stream) = 0;
// Audio effect management
virtual audio_io_handle_t getOutputForEffect(const effect_descriptor_t *desc) = 0;
virtual status_t registerEffect(const effect_descriptor_t *desc,
audio_io_handle_t io,
uint32_t strategy,
int session,
int id) = 0;
virtual status_t unregisterEffect(int id) = 0;
virtual status_t setEffectEnabled(int id, bool enabled) = 0;
virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const = 0;
virtual bool isStreamActiveRemotely(int stream, uint32_t inPastMs = 0) const = 0;
virtual bool isSourceActive(audio_source_t source) const = 0;
4 Audio系统的Hal层
4.1 代码位置
不同的厂商代码位置不同,但都位于hardware下,以下是intel平台CLV+的代码位置:
hardware/alsa_sound/audio_hw_configurable
其中AudioStreamOutALSA.cpp类是音频输出的实现,如果要dump数据,直接在此类中把数据写到文件中即可, 采用的参数一般来说是, 44100, 16 bit, 双声道。