Más contenido relacionado
La actualidad más candente (20)
Similar a Android audio system(audio_hardwareinterace) (20)
Android audio system(audio_hardwareinterace)
- 1. 안드로이드의 모든것 분석과 포팅 정리
Android Audio System
(AudioHardware class)
박철희
1/10
- 2. 1.AudioHardware class 위치 및 역활 안드로이드의 모든것 분석과 포팅 정리
Application 역할:
Framework
Device control
(play,stop,routing)
Native
Framework
HAL
Kernel
2/10
- 3. 2.AudioHardware class구조(msm7x30) 안드로이드의 모든것 분석과 포팅 정리
setParameters, getParameters
openOutputStream,
AudioHardwareInterface openOutputSession,
setVoiceVolume , openInputStream
setMode,
setMasterVolume,
openOutputStream,
openOutputSession,
AudioHardwareBase isModeInCall, isInCall
openInputStream
AudioStreamOut AudioHardware AudioStreamIn
AudioStreamOutMSM72xx
AudioStreamInMSM72xx
AudioSessionOutMSM7xxx
setParameters,
setParameters, getParameters,
getParameters, read // read audio buffer in from audio
Write // write audio buffer to driver. driver
Returns number of bytes written
3
- 4. 3.AudioHardware class 초기화 안드로이드의 모든것 분석과 포팅 정리
1)AudioHardware class
AudioFlinger.cpp
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
mAudioHardware(0), mFmEnabled(false), mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1)
{
AudioHardwareInterface* mAudioHardware = AudioHardwareInterface::create();
…
}
AudioHardwareinterface.cpp AudioHardware.cpp(7x30)
AudioHardwareInterface* AudioHardwareInterface::create() AudioHardware::AudioHardware() :
{ {
hw = createAudioHardware(); control =
} msm_mixer_open("/dev/snd/controlC0", 0);
//장착된 device들을 가져와서
device_list 구조체에 넣는다.(소스 참조)
AudioHardware.cpp(7x30)
extern "C" AudioHardwareInterface* createAudioHardware(void) //이 device_list 는 device id를 구할 때
{ 사용된다.
return new AudioHardware(); }
}
4/10
- 5. 3.AudioHardware class 초기화 안드로이드의 모든것 분석과 포팅 정리
2) AudioStreamOutMSM72xx
AudioPolicyManagerBase.cpp
AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)
{
…
mHardwareOutput = mpClientInterface->openOutput(…);
}
AudioFlinger.cpp
int AudioFlinger::openOutput
{
AudioStreamOut *output = mAudioHardware->openOutputStream(*pDevices,…)
}
AudioHardware.cpp(7x30)
AudioStreamOut* AudioHardware::openOutputStream
{
…
AudioStreamOutMSM72xx* out = new AudioStreamOutMSM72xx();
status_t lStatus = out->set(this, devices, format, channels, sampleRate);
}
AudioHardware.cpp(7x30)
status_t AudioHardware::AudioStreamOutMSM72xx::set
{
if (pFormat) *pFormat = lFormat;
if (pChannels) *pChannels = lChannels;
if (pRate) *pRate = lRate;
mDevices = devices;
5/10
- 6. 3.AudioHardware class 초기화 안드로이드의 모든것 분석과 포팅 정리
3) AudioStreamInMSM72xx
AudioPolicyManagerBase.cpp
audio_io_handle_t AudioPolicyManagerBase::getInput(…){
input = mpClientInterface->openInput(&inputDesc->mDevice,…);
}
AudioPolicyService.cpp
audio_io_handle_t AudioPolicyService::openInput(…)
{
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
return af->openInput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, acoustics);
}
int AudioFlinger::openInput(…) status_t AudioHardware::AudioStreamInMSM72xx::set
{ {
… //각 입력되는 format에 맞게
AudioStreamIn *input = mAudioHardware-> mDevices, mFormat, mChannels 등을 설정 함.
openInputStream(*pDevices,…); else if(*pFormat == AUDIO_HW_IN_FORMAT)
} {
..
mDevices = devices;
AudioStreamIn* AudioHardware::openInputStream(…) mFormat = AUDIO_HW_IN_FORMAT;
{ mChannels = *pChannels;
AudioStreamInMSM72xx* in = new AudioStreamInMSM72xx(); …
status_t lStatus = in->set(this, devices, format, channels,
sampleRate, acoustic_flags);
} }
6/10
- 7. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리
1) setVoiceVolume
PhoneWindowManager.java
handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
void handleVolumeKey(int stream, int keycode) {
audioService.adjustStreamVolume(stream,
keycode == KeyEvent.KEYCODE_VOLUME_UP ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER,0);
}
AudioService.java
public void adjustStreamVolume{
sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, STREAM_VOLUME_ALIAS[streamType], SENDMSG_NOOP, 0, 0,
streamState, 0);
}
public void handleMessage(Message msg) {
case MSG_SET_SYSTEM_VOLUME:
setSystemVolume((VolumeStreamState) msg.obj);
break;
}
private void setSystemVolume(VolumeStreamState streamState){
setStreamVolumeIndex(streamState.mStreamType, streamState.mIndex);
}
private void setStreamVolumeIndex(int stream, int index) {
AudioSystem.setStreamVolumeIndex(stream, (index + 5)/10);
}
7/10
- 8. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리
Android_media_AudioSystem.cpp
android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env, jobject thiz, jint stream, jint index)
{
return check_AudioSystem_Command(
AudioSystem::setStreamVolumeIndex(static_cast <AudioSystem::stream_type>(stream), index));
}
AudioSystem.cpp
status_t AudioSystem::setStreamVolumeIndex(stream_type stream, int index)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
return aps->setStreamVolumeIndex(stream, index);
}
AudioPolicyService.cpp
status_t AudioPolicyService::setStreamVolumeIndex()
{
return mpPolicyManager->setStreamVolumeIndex(stream, index);
}
AudioPolicyManagerBase.cpp
status_t AudioPolicyManagerBase::setStreamVolumeIndex(){
status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device());
}
status_t AudioPolicyManagerBase::checkAndSetVolume{
if (stream == AudioSystem::VOICE_CALL ||
stream == AudioSystem::BLUETOOTH_SCO) {
mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
}
8/10
- 9. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리
AudioPolicyService.cpp
status_t AudioPolicyService::setVoiceVolume(float volume, int delayMs)
{
return mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
}
status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand
{
command->mCommand = SET_VOICE_VOLUME;
}
bool AudioPolicyService::AudioCommandThread::threadLoop()
{
case SET_VOICE_VOLUME: {
command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
}
AudioSystem.cpp
status_t AudioSystem::setVoiceVolume(float value)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
return af->setVoiceVolume(value);
}
AudioFlinger.cpp
status_t AudioFlinger::setVoiceVolume(float value)
{
status_t ret = mAudioHardware->setVoiceVolume(value);
}
9/10
- 10. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리
AudioHardware.cpp
status_t AudioHardware::setVoiceVolume(float v)
{
if(msm_set_voice_rx_vol(vol)) {
LOGE("msm_set_voice_rx_vol(%d) failed errno = %d",vol,errno);
return -1;
}
}
Hw.c(vendor/qcom…)
{
int msm_set_voice_rx_vol(int volume)
{
struct snd_ctl_elem_value val;
val.id.numid = NUMID_VOICE_VOL;
val.value.integer.value[0] = DIR_RX;
val.value.integer.value[1] = volume;
return msm_mixer_elem_write(&val);
}
}
static int msm_mixer_elem_write(struct snd_ctl_elem_value *val)
{
rc = ioctl(control->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, val);
}
10/10
- 11. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리
2) setVolume
QwertyKeyListener.java
public boolean onKeyDown{
return super.onKeyDown(view, content, keyCode, event);
}
phoneWindow.java
protected boolean onKeyDown{
audioManager.adjustSuggestedStreamVolume(
keyCode == KeyEvent.KEYCODE_VOLUME_UP
? AudioManager.ADJUST_RAISE
: AudioManager.ADJUST_LOWER,
mVolumeControlStreamType,
AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);}
AudioManager.java
public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {
IAudioService service = getService();
try {
service.adjustSuggestedStreamVolume(direction, suggestedStreamType, flags);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in adjustVolume", e);
}
}
11/10
- 12. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리
AudioService.java
public void adjustSuggestedStreamVolume{
adjustStreamVolume(streamType, direction, flags);
}
public void adjustStreamVolume{
sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME,
STREAM_VOLUME_ALIAS[streamType], SENDMSG_NOOP, 0, 0,
streamState, 0);
AudioService.java
public void handleMessage(Message msg) {
switch (baseMsgWhat) {
case MSG_SET_SYSTEM_VOLUME:
setSystemVolume((VolumeStreamState) msg.obj);
break;
}
AudioFlinger의 setStreamVolume을 호출해서 Volume setting함.
status_t AudioFlinger::PlaybackThread::setStreamVolume(int stream, float value)
{
mStreamTypes[stream].volume = value;
}
AudioFlinger::MixerThread::threadLoop()에서 prepareTracks_l
이 수행 됨.
12/10
- 13. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리
uint32_t AudioFlinger::MixerThread::prepareTracks_l
{
float typeVolume = mStreamTypes[track->type()].volume; setStreamVolume 에서 설정한 volume값을 가져와서
//volume 값 설정
float v = masterVolume * typeVolume;
vl = (uint32_t)(v * cblk->volume[0]) << 12;
vr = (uint32_t)(v * cblk->volume[1]) << 12;
param = AudioMixer::VOLUME;
//AudioMixer.cpp의 setparameter에서 처리 해줌.
mAudioMixer->setParameter(param, AudioMixer::VOLUME0, (void *)left);
mAudioMixer->setParameter(param, AudioMixer::VOLUME1, (void *)right);
mAudioMixer->setParameter(param, AudioMixer::AUXLEVEL, (void *)aux);
…
}
13/10