Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Android audio system(audio_hardwareinterace)

5,128 views

Published on

Published in: Technology

Android audio system(audio_hardwareinterace)

  1. 1. 안드로이드의 모든것 분석과 포팅 정리Android Audio System(AudioHardware class) 박철희 1/10
  2. 2. 1.AudioHardware class 위치 및 역활 안드로이드의 모든것 분석과 포팅 정리Application 역할:Framework Device control (play,stop,routing)NativeFrameworkHALKernel 2/10
  3. 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 audioWrite // write audio buffer to driver. driverReturns number of bytes written 3
  4. 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. 5. 3.AudioHardware class 초기화 안드로이드의 모든것 분석과 포팅 정리 2) AudioStreamOutMSM72xxAudioPolicyManagerBase.cppAudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface){ … mHardwareOutput = mpClientInterface->openOutput(…);}AudioFlinger.cppint 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. 6. 3.AudioHardware class 초기화 안드로이드의 모든것 분석과 포팅 정리 3) AudioStreamInMSM72xxAudioPolicyManagerBase.cppaudio_io_handle_t AudioPolicyManagerBase::getInput(…){ input = mpClientInterface->openInput(&inputDesc->mDevice,…);}AudioPolicyService.cppaudio_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. 7. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리 1) setVoiceVolumePhoneWindowManager.javahandleVolumeKey(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.javapublic 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. 8. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리Android_media_AudioSystem.cppandroid_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.cppstatus_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.cppstatus_t AudioPolicyService::setStreamVolumeIndex(){ return mpPolicyManager->setStreamVolumeIndex(stream, index);}AudioPolicyManagerBase.cppstatus_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. 9. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리AudioPolicyService.cppstatus_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.cppstatus_t AudioSystem::setVoiceVolume(float value){ const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger(); if (af == 0) return PERMISSION_DENIED; return af->setVoiceVolume(value);}AudioFlinger.cppstatus_t AudioFlinger::setVoiceVolume(float value){ status_t ret = mAudioHardware->setVoiceVolume(value);} 9/10
  10. 10. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리AudioHardware.cppstatus_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. 11. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리 2) setVolumeQwertyKeyListener.javapublic boolean onKeyDown{return super.onKeyDown(view, content, keyCode, event);}phoneWindow.javaprotected boolean onKeyDown{audioManager.adjustSuggestedStreamVolume( keyCode == KeyEvent.KEYCODE_VOLUME_UP ? AudioManager.ADJUST_RAISE : AudioManager.ADJUST_LOWER, mVolumeControlStreamType, AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE);}AudioManager.javapublic 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. 12. 4. AudioHardware class method 분석 안드로이드의 모든것 분석과 포팅 정리AudioService.javapublic 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. 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

×