2. 1.AudiopolicyManager 위치 및 역활 안드로이드의 모든것 분석과 포팅 정리
Application 역할:
Framework
1.입출력 디바이스 관리
2.오디오 볼륨 제어 및 관리
Native
Framework 3.오디오 정책 관리
HAL
Kernel
2/10
3. 2.입출력 디바이스 관리 안드로이드의 모든것 분석과 포팅 정리
AudioPolicyManagerbase의 생성자에서 초기 입출력 device 지정
AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)
{
Audiosysystem.h
//출력이 가능한 device enum audio_devices {
mAvailableOutputDevices = AudioSystem::DEVICE_OUT_EARPIECE; // output devices
mAvailableOutputDevices |= AudioSystem::DEVICE_OUT_SPEAKER; DEVICE_OUT_EARPIECE = 0x1,
DEVICE_OUT_SPEAKER = 0x2,
//입력이 가능한 device DEVICE_OUT_WIRED_HEADSET = 0x4,
mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC; DEVICE_OUT_WIRED_HEADPHONE = 0x8,
…
// input devices
outputDesc->mDevice = AudioSystem::DEVICE_OUT_SPEAKER; DEVICE_IN_COMMUNICATION = 0x10000,
mHardwareOutput = mpClientInterface->openOutput DEVICE_IN_AMBIENT = 0x20000,
(&outputDesc->mDevice, DEVICE_IN_BUILTIN_MIC = 0x40000,
&outputDesc->mSamplingRate, DEVICE_IN_BLUETOOTH_SCO_HEADSET =
&outputDesc->mFormat, 0x80000,
&outputDesc->mChannels, …
&outputDesc->mLatency,
outputDesc->mFlags);
mHardwareOutput 는 playbackthread의 id
//playbackthread가 DEVICE_OUT_SPEAKER 로 설정됨을 gOutput에 저장.
setOutputDevice(mHardwareOutput, , defaultDevice, true);
아래와 같은 함수들에서 현재 output stream의
}
정보를 구할 때 gOutputs 가 사용된다.
getOutputSamplingRate
AudioSystem의 gOutput의 정보를 갱신 함.
getOutputFrameCount
getOutputLatency
3/10
4. 2.입출력 디바이스 관리 안드로이드의 모든것 분석과 포팅 정리
setDeviceConnectionState 에 의해 입출력 device 변경
status_t AudioPolicyManagerBase::setDeviceConnectionState
{
// handle output devices
if (AudioSystem::isOutputDevice(device)){
case AudioSystem::DEVICE_STATE_AVAILABLE:
mAvailableOutputDevices |= device;
case AudioSystem::DEVICE_STATE_UNAVAILABLE:
mAvailableOutputDevices &= ~device;
// request routing change if necessary
uint32_t newDevice = getNewDevice(mHardwareOutput, false);
setOutputDevice(mHardwareOutput, newDevice);
}
// handle input devices
if (AudioSystem::isInputDevice(device)) {
…
mAvailableInputDevices |= device;
mpClientInterface->setParameters(activeInput, param.toString());
}
4/10
5. 2.입출력 디바이스 관리 안드로이드의 모든것 분석과 포팅 정리
setForceUse();정해진 device만을 사용
startOutput(),stopOutput();play시에 Strategy에 맞는 device 선택 및 해제
startInput(),stopInput(); record시에 Strategy에 맞는 device 선택 및 해제
void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
{
.. AudioSystem::FOR_MEDI FORCE_SPEAK
case AudioSystem::FOR_MEDIA: A ER
mForceUse[usage] = config;
}
status_t AudioPolicyManagerBase::startOutput
{
//getNewDevice로 설정할 device를 가져와서 set함.
setOutputDevice(output, getNewDevice(output));
}
status_t AudioPolicyManagerBase::stopOutput
{
//현재 play시킨 device와 playbackthred의 output이 일치 하지 않을 경우
//playbackthread의 device로 다시 set해줌.
if (output != mHardwareOutput) {
setOutputDevice(mHardwareOutput, getNewDevice(mHardwareOutput), true);
}
}
5/10
6. 3. 오디오 볼륨 제어 및 관리 안드로이드의 모든것 분석과 포팅 정리
각 stream별 volume setting(MIN,MAX)
AudioService.java
private int[] MAX_STREAM_VOLUME = new int[] {
6, // STREAM_VOICE_CALL
7, // STREAM_SYSTEM
7, // STREAM_RING
15, // STREAM_MUSIC
7, // STREAM_ALARM
7, // STREAM_NOTIFICATION
15, // STREAM_BLUETOOTH_SCO
15, // STREAM_FM
15, // STREAM_DTMF
15, // STREAM_TTS
7, // STREAM_SYSTEM_ENFORCED
};
VolumeStreamState의 생성자에서 각 stream에 대한 volume level 설정
public class VolumeStreamState {
private VolumeStreamState(String settingName, int streamType) {
mIndexMax = MAX_STREAM_VOLUME[streamType];
AudioSystem.initStreamVolume(streamType, 0, mIndexMax);
}
각 stream에 대한 min,max value 설정
void AudioPolicyManagerBase::initStreamVolume{
mStreams[stream].mIndexMin = indexMin;
mStreams[stream].mIndexMax = indexMax;
}
6/10
7. 3. 오디오 볼륨 제어 및 관리 안드로이드의 모든것 분석과 포팅 정리
Volume 조절
AudioService.java
public void handleMessage(Message msg) {
switch (baseMsgWhat) {
case MSG_SET_SYSTEM_VOLUME:
setSystemVolume((VolumeStreamState) msg.obj);
break;
}
private void setSystemVolume(VolumeStreamState streamState) {
// Adjust volume
setStreamVolumeIndex(streamState.mStreamType, streamState.mIndex);
//setting에 sound value 값을 반영 하기 위해 MSG_PERSIST_VOLUME 날려 줌.
sendMsg(mAudioHandler, MSG_PERSIST_VOLUME, streamState.mStreamType,
SENDMSG_REPLACE, 1, 1, streamState, PERSIST_DELAY);
}
private void setStreamVolumeIndex(int stream, int index) {
AudioSystem.setStreamVolumeIndex(stream, (index + 5)/10);
}
status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
{
status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device());
}
7/10
8. 3. 오디오 볼륨 제어 및 관리 안드로이드의 모든것 분석과 포팅 정리
status_t AudioPolicyManagerBase::checkAndSetVolume((int stream, int index..)
{
//정수로 들어온 volume value를 float형으로 바꿔준다.
float volume = computeVolume(stream, index, output, device);
mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
}
AudioFlinger의 mStreamTypes 변수에 volume set해줌.
status_t AudioFlinger::PlaybackThread::setStreamVolume(int stream, float value)
{
mStreamTypes[stream].volume = value;
}
Play시에 이 구조체에 있는 volume값으로 play됨.
8/10