Android audio system(audio_hardwareinterace)

4,352 views

Published on

Published in: Technology
1 Comment
4 Likes
Statistics
Notes
No Downloads
Views
Total views
4,352
On SlideShare
0
From Embeds
0
Number of Embeds
188
Actions
Shares
0
Downloads
0
Comments
1
Likes
4
Embeds 0
No embeds

No notes for slide

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

×