SlideShare ist ein Scribd-Unternehmen logo
1 von 8
안드로이드 아나토미 정리



Android Audio System
(PCM데이터 출력준비-
    서비스 서버)




                            박철희
                       1
1.Audio 출력 준비 과정                                                                             안드로이드 아나토미 정리

AudioFlinger.cpp
uint32_t AudioFlinger::MixerThread::prepareTracks_l()
{
   for (size_t i=0 ; i<count ; i++) {
     sp<Track> t = activeTracks[i].promote(); 활성화 트랙을 가져온다.
     Track* const track = t.get();
      audio_track_cblk_t* cblk = track->cblk(); 활성화 트랙의 컨트롤 블록을 얻어온다.
      if (cblk->framesReady() && track->isReady() && !track->isPaused() && !track->isTerminated())
      { 공유 메모리에 할당할 메모리가 남아 있고, track 이 준비되었다면
           mAudioMixer->setBufferProvider(track);  (1)오디오 버퍼 제공자 설정
           mAudioMixer->enable(AudioMixer::MIXING);  (2) 트랙의 믹싱 활성화
           mAudioMixer->setParameter(AudioMixer::TRACK,
            AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer()); (3) 메인 버퍼 설정
           mAudioMixer->setParameter(AudioMixer::RESAMPLE, AudioMixer::SAMPLE_RATE,(void *)(cblk->sampleRate));
           (4)리샘플링 함수 등록
           mixerStatus = MIXER_TRACKS_READY;  (5)오디오 믹서 상태 설정

       }
}
(1) mAudioMixer->setBufferProvider(track);  오디오 버퍼 제공자 설정
   -오디오 믹서는 활성화된 트랙의 PCM 데이터를 믹싱하기 위해 개별 트랙의 PCM 공유 버퍼에서 데이터를 읽어와야 함.

    status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer)               AudioBufferProvider
    {
       mState.tracks[ mActiveTrack ].bufferProvider = buffer;
       return NO_ERROR;                                                                   Trackbase
    }


                                                                                             Track


                                                                                                      2
1.Audio 출력 준비 과정                                                                              안드로이드 아나토미 정리

(2)mAudioMixer->enable(AudioMixer::MIXING);  트랙의 믹싱 활성화
  -해당 트랙을 오디오 믹서의 믹싱처리에 추가 한다.(믹싱 함수를 process__validate 로 설정 함.)

  status_t AudioMixer::enable(int name)
  {
     switch (name) {
        case MIXING: {
          if (mState.tracks[ mActiveTrack ].enabled != 1) {
              mState.tracks[ mActiveTrack ].enabled = 1;
              LOGV("enable(%d)", mActiveTrack);
              invalidateState(1<<mActiveTrack);
          }
       return NO_ERROR;
  }

  void AudioMixer::invalidateState(uint32_t mask)
   {
     if (mask) {
         mState.needsChanged |= mask;
         mState.hook = process__validate;
     }
   }

(3)mAudioMixer->setParameter(AudioMixer::TRACK,AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer());
  audiomixer의 메인 버퍼를 믹서버퍼로 설정 함.

  status_t AudioMixer::setParameter(int target, int name, void *value)
  {
     mState.tracks[ mActiveTrack ].mainBuffer = valueBuf;
     valuebuf가 playbackThread->mixBuffer();를 의미함.
  }

                                                                                                        3
1.Audio 출력 준비 과정                                                                            안드로이드 아나토미 정리

(4)(mAudioMixer->setParameter(AudioMixer::RESAMPLE, AudioMixer::SAMPLE_RATE,(void *)(cblk->sampleRate));
   - 리샘플링 함수 등록
  status_t AudioMixer::setParameter(int target, int name, void *value)
  {
      if (track.setResampler(uint32_t(valueInt), mSampleRate)){
              invalidateState(1<<mActiveTrack);
       }
       return NO_ERROR;
  }

 bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
 {
       if (value!=devSampleRate || resampler) {
        audiohardware에서 설정된 sameplerate(devSampleRate)와 track의 sample rate(value)가 다를 경우
          resampler = AudioResampler::create(
                 format, channelCount, devSampleRate);
 }

 Audioresampler.cpp
 AudioResampler* AudioResampler::create()
 {
  pcm 데이터의 음질에 따라 리샘플링을 처리하는 클래스가 결정 됨.
  switch (quality) {
   case LOW_QUALITY:
       resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate); break;
   case MED_QUALITY:
       resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate); break;
    case HIGH_QUALITY:
       resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate);   break;
    }


                                                                                                  4
1.Audio 출력 준비 과정                                                                             안드로이드 아나토미 정리




                                                                             Audioflinger


                                                                Audiomixer                     Mixerthread


                                                    Buffer
                                                    provider                                   Mixer buffer


                                                   MainBuffer


 AudioTrack++     audiob
                  uffer                                                          resampler

android                           write

                                                                                                      kernel
                      Track[3       32kbyte
                      1]
          AudioFlinger::Client
          (shared memory)                     1M

                       Track[0]




                                                                                                  5
2.PCM 데이터 리샘플링과 믹싱                                                               안드로이드 아나토미 정리


MixerThread::prepareTracks_l() 에서 mixerStatus 가 MIXER_TRACKS_READY 이면
리샘플링과 믹싱 과정을 수행한다.

bool AudioFlinger::MixerThread::threadLoop()
{
  if (LIKELY(mixerStatus == MIXER_TRACKS_READY))
  {
     mAudioMixer->process();
   }

    int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
    mixbuffer에 있는 data를 audio driver에 write한다.
}


void AudioMixer::process()
{
  mState.hook(&mState);
   mState.hook은 process__validate로 설정되어 있음.(invalidateState함수)
}


void AudioMixer::process__validate(state_t* state)
{
  uint32_t en = state->enabledTracks;
  활성화 트랙을 다시 가져온다.
  while (en) {
     n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
  리샘플링 여부 결정


                                                                                     6
2.PCM 데이터 리샘플링과 믹싱                                                                안드로이드 아나토미 정리


    믹싱 함수 결정
    if (resampling) {
       state->hook = process__genericResampling; 리샘플링과 믹싱을 동시에 처리
    }
    Else{
       state->hook = process__genericNoResampling;  믹싱 처리
        if (all16BitsStereoNoResample && !volumeRamp) {
                 if (countActiveTracks == 1) {
                     오디오 트랙이 하나이면 믹싱처리를 하지 않는 아래 함수가 호출 됨.
                     state->hook = process__OneTrack16BitsStereoNoResampling;
                 }
               }
    }

    state->hook(state);  믹싱 함수 호출
    }

void AudioMixer::process__OneTrack16BitsStereoNoResampling()
{
  int32_t* out = t.mainBuffer;  mixerthread의 믹서 버퍼를 out으로 설정한다.

while (numFrames) {

    t.bufferProvider->getNextBuffer(&b); PCM 데이터 공유 버퍼에서 write된 data를 b로 가져온다.

    *out++ = (r<<16) | (l & 0xFFFF);  가져온 data를 믹서 버퍼로 copy한다.
     복사된 데이터는 pcm 데이터 출력 단계에서 소리로 출력 된다.

    t.bufferProvider->releaseBuffer(&b);  오디오 컨트록 블락에서 server 변수의 값을 갱신한다.

}
                                                                                      7
3. PCM 데이터 출력                                                                                안드로이드 아나토미 정리


bool AudioFlinger::MixerThread::threadLoop()
{
  if (LIKELY(mixerStatus == MIXER_TRACKS_READY))
  {
    mAudioMixer->process(); 믹서 버퍼에 PCM 데이터가 복사됨.
   }

      int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);

}


    ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes)
    {
        size_t count = bytes;  write할 data size
        const uint8_t* p = static_cast<const uint8_t*>(buffer);  mixer buffer


       ssize_t written = ::write(mFd, p, count); mFd file descriptor가 가르키는 곳에 mixer buffer의 내용을 write한다.
        mFd는 status = ::open("/dev/msm_pcm_out", O_WRONLY/*O_RDWR*/); 에 대한 file descriptor이다.

         if(msm_route_stream(PCM_PLAY, dec_id, DEV_ID(cur_rx), 1)) {
              LOGE("msm_route_stream failed");
              return 0;
         }
        ioctrl로 PCM_PLAY 를 driver로 전달해서 play됨.




                                                                                                    8

Weitere ähnliche Inhalte

Was ist angesagt?

Android media framework overview
Android media framework overviewAndroid media framework overview
Android media framework overviewJerrin George
 
Android Multimedia Framework
Android Multimedia FrameworkAndroid Multimedia Framework
Android Multimedia FrameworkPicker Weng
 
Android's Multimedia Framework
Android's Multimedia FrameworkAndroid's Multimedia Framework
Android's Multimedia FrameworkOpersys inc.
 
Understanding the Android System Server
Understanding the Android System ServerUnderstanding the Android System Server
Understanding the Android System ServerOpersys inc.
 
Android internals By Rajesh Khetan
Android internals By Rajesh KhetanAndroid internals By Rajesh Khetan
Android internals By Rajesh KhetanRajesh Khetan
 
Android Boot Time Optimization
Android Boot Time OptimizationAndroid Boot Time Optimization
Android Boot Time OptimizationKan-Ru Chen
 
Android for Embedded Linux Developers
Android for Embedded Linux DevelopersAndroid for Embedded Linux Developers
Android for Embedded Linux DevelopersOpersys inc.
 
MediaPlayer Playing Flow
MediaPlayer Playing FlowMediaPlayer Playing Flow
MediaPlayer Playing FlowJavid Hsu
 
Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...Opersys inc.
 
Android booting sequece and setup and debugging
Android booting sequece and setup and debuggingAndroid booting sequece and setup and debugging
Android booting sequece and setup and debuggingUtkarsh Mankad
 

Was ist angesagt? (20)

Embedded Android : System Development - Part III (Audio / Video HAL)
Embedded Android : System Development - Part III (Audio / Video HAL)Embedded Android : System Development - Part III (Audio / Video HAL)
Embedded Android : System Development - Part III (Audio / Video HAL)
 
Android media framework overview
Android media framework overviewAndroid media framework overview
Android media framework overview
 
Android Multimedia Framework
Android Multimedia FrameworkAndroid Multimedia Framework
Android Multimedia Framework
 
Android's Multimedia Framework
Android's Multimedia FrameworkAndroid's Multimedia Framework
Android's Multimedia Framework
 
Understanding the Android System Server
Understanding the Android System ServerUnderstanding the Android System Server
Understanding the Android System Server
 
Android IPC Mechanism
Android IPC MechanismAndroid IPC Mechanism
Android IPC Mechanism
 
Android internals By Rajesh Khetan
Android internals By Rajesh KhetanAndroid internals By Rajesh Khetan
Android internals By Rajesh Khetan
 
Audio Drivers
Audio DriversAudio Drivers
Audio Drivers
 
Android Boot Time Optimization
Android Boot Time OptimizationAndroid Boot Time Optimization
Android Boot Time Optimization
 
GCC compiler
GCC compilerGCC compiler
GCC compiler
 
Android Internals
Android InternalsAndroid Internals
Android Internals
 
Embedded Android : System Development - Part I
Embedded Android : System Development - Part IEmbedded Android : System Development - Part I
Embedded Android : System Development - Part I
 
Low Level View of Android System Architecture
Low Level View of Android System ArchitectureLow Level View of Android System Architecture
Low Level View of Android System Architecture
 
Android for Embedded Linux Developers
Android for Embedded Linux DevelopersAndroid for Embedded Linux Developers
Android for Embedded Linux Developers
 
MediaPlayer Playing Flow
MediaPlayer Playing FlowMediaPlayer Playing Flow
MediaPlayer Playing Flow
 
Android Camera
Android CameraAndroid Camera
Android Camera
 
Embedded Android : System Development - Part IV
Embedded Android : System Development - Part IVEmbedded Android : System Development - Part IV
Embedded Android : System Development - Part IV
 
Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...Using and Customizing the Android Framework / part 4 of Embedded Android Work...
Using and Customizing the Android Framework / part 4 of Embedded Android Work...
 
Android booting sequece and setup and debugging
Android booting sequece and setup and debuggingAndroid booting sequece and setup and debugging
Android booting sequece and setup and debugging
 
Explore Android Internals
Explore Android InternalsExplore Android Internals
Explore Android Internals
 

Ähnlich wie Android audio system(pcm데이터출력준비-서비스서버)

Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)fefe7270
 
Developing game audio with the Web Audio API
Developing game audio with the Web Audio APIDeveloping game audio with the Web Audio API
Developing game audio with the Web Audio APIJae Sung Park
 
사운드처리_텀과제_이정근.pptx
사운드처리_텀과제_이정근.pptx사운드처리_텀과제_이정근.pptx
사운드처리_텀과제_이정근.pptxtangtang1026
 
[SWCON211] LectureCode_13_Matlab Practice.pptx
[SWCON211] LectureCode_13_Matlab Practice.pptx[SWCON211] LectureCode_13_Matlab Practice.pptx
[SWCON211] LectureCode_13_Matlab Practice.pptxoreo329
 
제2회 hello world 오픈세미나 Web Audio API-가능성엿보기
제2회 hello world 오픈세미나 Web Audio API-가능성엿보기제2회 hello world 오픈세미나 Web Audio API-가능성엿보기
제2회 hello world 오픈세미나 Web Audio API-가능성엿보기NAVER D2
 
Android Screen Recorder
Android Screen RecorderAndroid Screen Recorder
Android Screen RecorderSooHwan Ok
 

Ähnlich wie Android audio system(pcm데이터출력준비-서비스서버) (6)

Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)Android audio system(오디오 출력-트랙활성화)
Android audio system(오디오 출력-트랙활성화)
 
Developing game audio with the Web Audio API
Developing game audio with the Web Audio APIDeveloping game audio with the Web Audio API
Developing game audio with the Web Audio API
 
사운드처리_텀과제_이정근.pptx
사운드처리_텀과제_이정근.pptx사운드처리_텀과제_이정근.pptx
사운드처리_텀과제_이정근.pptx
 
[SWCON211] LectureCode_13_Matlab Practice.pptx
[SWCON211] LectureCode_13_Matlab Practice.pptx[SWCON211] LectureCode_13_Matlab Practice.pptx
[SWCON211] LectureCode_13_Matlab Practice.pptx
 
제2회 hello world 오픈세미나 Web Audio API-가능성엿보기
제2회 hello world 오픈세미나 Web Audio API-가능성엿보기제2회 hello world 오픈세미나 Web Audio API-가능성엿보기
제2회 hello world 오픈세미나 Web Audio API-가능성엿보기
 
Android Screen Recorder
Android Screen RecorderAndroid Screen Recorder
Android Screen Recorder
 

Mehr von fefe7270

Surface flingerservice(서피스 출력 요청 jb)
Surface flingerservice(서피스 출력 요청 jb)Surface flingerservice(서피스 출력 요청 jb)
Surface flingerservice(서피스 출력 요청 jb)fefe7270
 
Surface flingerservice(서피스 상태 변경 jb)
Surface flingerservice(서피스 상태 변경 jb)Surface flingerservice(서피스 상태 변경 jb)
Surface flingerservice(서피스 상태 변경 jb)fefe7270
 
Surface flingerservice(서피스 플링거 연결 jb)
Surface flingerservice(서피스 플링거 연결 jb)Surface flingerservice(서피스 플링거 연결 jb)
Surface flingerservice(서피스 플링거 연결 jb)fefe7270
 
Surface flingerservice(서피스플링거서비스초기화 jb)
Surface flingerservice(서피스플링거서비스초기화 jb)Surface flingerservice(서피스플링거서비스초기화 jb)
Surface flingerservice(서피스플링거서비스초기화 jb)fefe7270
 
Surface flingerservice(서피스 플링거 연결 ics)
Surface flingerservice(서피스 플링거 연결 ics)Surface flingerservice(서피스 플링거 연결 ics)
Surface flingerservice(서피스 플링거 연결 ics)fefe7270
 
Surface flingerservice(서피스플링거서비스초기화 ics)
Surface flingerservice(서피스플링거서비스초기화 ics)Surface flingerservice(서피스플링거서비스초기화 ics)
Surface flingerservice(서피스플링거서비스초기화 ics)fefe7270
 
Surface flingerservice(그래픽 공유 버퍼 생성 및 등록)
Surface flingerservice(그래픽 공유 버퍼 생성 및 등록)Surface flingerservice(그래픽 공유 버퍼 생성 및 등록)
Surface flingerservice(그래픽 공유 버퍼 생성 및 등록)fefe7270
 
Surface flingerservice(서피스 상태 변경 및 출력 요청)
Surface flingerservice(서피스 상태 변경 및 출력 요청)Surface flingerservice(서피스 상태 변경 및 출력 요청)
Surface flingerservice(서피스 상태 변경 및 출력 요청)fefe7270
 
Surface flingerservice(서피스 플링거 연결)
Surface flingerservice(서피스 플링거 연결)Surface flingerservice(서피스 플링거 연결)
Surface flingerservice(서피스 플링거 연결)fefe7270
 
Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)fefe7270
 
Stagefright recorder part1
Stagefright recorder part1Stagefright recorder part1
Stagefright recorder part1fefe7270
 
Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)fefe7270
 
C++정리 스마트포인터
C++정리 스마트포인터C++정리 스마트포인터
C++정리 스마트포인터fefe7270
 

Mehr von fefe7270 (13)

Surface flingerservice(서피스 출력 요청 jb)
Surface flingerservice(서피스 출력 요청 jb)Surface flingerservice(서피스 출력 요청 jb)
Surface flingerservice(서피스 출력 요청 jb)
 
Surface flingerservice(서피스 상태 변경 jb)
Surface flingerservice(서피스 상태 변경 jb)Surface flingerservice(서피스 상태 변경 jb)
Surface flingerservice(서피스 상태 변경 jb)
 
Surface flingerservice(서피스 플링거 연결 jb)
Surface flingerservice(서피스 플링거 연결 jb)Surface flingerservice(서피스 플링거 연결 jb)
Surface flingerservice(서피스 플링거 연결 jb)
 
Surface flingerservice(서피스플링거서비스초기화 jb)
Surface flingerservice(서피스플링거서비스초기화 jb)Surface flingerservice(서피스플링거서비스초기화 jb)
Surface flingerservice(서피스플링거서비스초기화 jb)
 
Surface flingerservice(서피스 플링거 연결 ics)
Surface flingerservice(서피스 플링거 연결 ics)Surface flingerservice(서피스 플링거 연결 ics)
Surface flingerservice(서피스 플링거 연결 ics)
 
Surface flingerservice(서피스플링거서비스초기화 ics)
Surface flingerservice(서피스플링거서비스초기화 ics)Surface flingerservice(서피스플링거서비스초기화 ics)
Surface flingerservice(서피스플링거서비스초기화 ics)
 
Surface flingerservice(그래픽 공유 버퍼 생성 및 등록)
Surface flingerservice(그래픽 공유 버퍼 생성 및 등록)Surface flingerservice(그래픽 공유 버퍼 생성 및 등록)
Surface flingerservice(그래픽 공유 버퍼 생성 및 등록)
 
Surface flingerservice(서피스 상태 변경 및 출력 요청)
Surface flingerservice(서피스 상태 변경 및 출력 요청)Surface flingerservice(서피스 상태 변경 및 출력 요청)
Surface flingerservice(서피스 상태 변경 및 출력 요청)
 
Surface flingerservice(서피스 플링거 연결)
Surface flingerservice(서피스 플링거 연결)Surface flingerservice(서피스 플링거 연결)
Surface flingerservice(서피스 플링거 연결)
 
Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)Surface flingerservice(서피스플링거서비스초기화)
Surface flingerservice(서피스플링거서비스초기화)
 
Stagefright recorder part1
Stagefright recorder part1Stagefright recorder part1
Stagefright recorder part1
 
Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)Camera camcorder framework overview(ginger bread)
Camera camcorder framework overview(ginger bread)
 
C++정리 스마트포인터
C++정리 스마트포인터C++정리 스마트포인터
C++정리 스마트포인터
 

Android audio system(pcm데이터출력준비-서비스서버)

  • 1. 안드로이드 아나토미 정리 Android Audio System (PCM데이터 출력준비- 서비스 서버) 박철희 1
  • 2. 1.Audio 출력 준비 과정 안드로이드 아나토미 정리 AudioFlinger.cpp uint32_t AudioFlinger::MixerThread::prepareTracks_l() { for (size_t i=0 ; i<count ; i++) { sp<Track> t = activeTracks[i].promote(); 활성화 트랙을 가져온다. Track* const track = t.get(); audio_track_cblk_t* cblk = track->cblk(); 활성화 트랙의 컨트롤 블록을 얻어온다. if (cblk->framesReady() && track->isReady() && !track->isPaused() && !track->isTerminated()) { 공유 메모리에 할당할 메모리가 남아 있고, track 이 준비되었다면 mAudioMixer->setBufferProvider(track);  (1)오디오 버퍼 제공자 설정 mAudioMixer->enable(AudioMixer::MIXING);  (2) 트랙의 믹싱 활성화 mAudioMixer->setParameter(AudioMixer::TRACK, AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer()); (3) 메인 버퍼 설정 mAudioMixer->setParameter(AudioMixer::RESAMPLE, AudioMixer::SAMPLE_RATE,(void *)(cblk->sampleRate)); (4)리샘플링 함수 등록 mixerStatus = MIXER_TRACKS_READY;  (5)오디오 믹서 상태 설정 } } (1) mAudioMixer->setBufferProvider(track);  오디오 버퍼 제공자 설정 -오디오 믹서는 활성화된 트랙의 PCM 데이터를 믹싱하기 위해 개별 트랙의 PCM 공유 버퍼에서 데이터를 읽어와야 함. status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer) AudioBufferProvider { mState.tracks[ mActiveTrack ].bufferProvider = buffer; return NO_ERROR; Trackbase } Track 2
  • 3. 1.Audio 출력 준비 과정 안드로이드 아나토미 정리 (2)mAudioMixer->enable(AudioMixer::MIXING);  트랙의 믹싱 활성화 -해당 트랙을 오디오 믹서의 믹싱처리에 추가 한다.(믹싱 함수를 process__validate 로 설정 함.) status_t AudioMixer::enable(int name) { switch (name) { case MIXING: { if (mState.tracks[ mActiveTrack ].enabled != 1) { mState.tracks[ mActiveTrack ].enabled = 1; LOGV("enable(%d)", mActiveTrack); invalidateState(1<<mActiveTrack); } return NO_ERROR; } void AudioMixer::invalidateState(uint32_t mask) { if (mask) { mState.needsChanged |= mask; mState.hook = process__validate; } } (3)mAudioMixer->setParameter(AudioMixer::TRACK,AudioMixer::MAIN_BUFFER, (void *)track->mainBuffer()); audiomixer의 메인 버퍼를 믹서버퍼로 설정 함. status_t AudioMixer::setParameter(int target, int name, void *value) { mState.tracks[ mActiveTrack ].mainBuffer = valueBuf; valuebuf가 playbackThread->mixBuffer();를 의미함. } 3
  • 4. 1.Audio 출력 준비 과정 안드로이드 아나토미 정리 (4)(mAudioMixer->setParameter(AudioMixer::RESAMPLE, AudioMixer::SAMPLE_RATE,(void *)(cblk->sampleRate)); - 리샘플링 함수 등록 status_t AudioMixer::setParameter(int target, int name, void *value) { if (track.setResampler(uint32_t(valueInt), mSampleRate)){ invalidateState(1<<mActiveTrack); } return NO_ERROR; } bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate) { if (value!=devSampleRate || resampler) { audiohardware에서 설정된 sameplerate(devSampleRate)와 track의 sample rate(value)가 다를 경우 resampler = AudioResampler::create( format, channelCount, devSampleRate); } Audioresampler.cpp AudioResampler* AudioResampler::create() { pcm 데이터의 음질에 따라 리샘플링을 처리하는 클래스가 결정 됨. switch (quality) { case LOW_QUALITY: resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate); break; case MED_QUALITY: resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate); break; case HIGH_QUALITY: resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate); break; } 4
  • 5. 1.Audio 출력 준비 과정 안드로이드 아나토미 정리 Audioflinger Audiomixer Mixerthread Buffer provider Mixer buffer MainBuffer AudioTrack++ audiob uffer resampler android write kernel Track[3 32kbyte 1] AudioFlinger::Client (shared memory) 1M Track[0] 5
  • 6. 2.PCM 데이터 리샘플링과 믹싱 안드로이드 아나토미 정리 MixerThread::prepareTracks_l() 에서 mixerStatus 가 MIXER_TRACKS_READY 이면 리샘플링과 믹싱 과정을 수행한다. bool AudioFlinger::MixerThread::threadLoop() { if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) { mAudioMixer->process(); } int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize); mixbuffer에 있는 data를 audio driver에 write한다. } void AudioMixer::process() { mState.hook(&mState);  mState.hook은 process__validate로 설정되어 있음.(invalidateState함수) } void AudioMixer::process__validate(state_t* state) { uint32_t en = state->enabledTracks; 활성화 트랙을 다시 가져온다. while (en) { n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED; 리샘플링 여부 결정 6
  • 7. 2.PCM 데이터 리샘플링과 믹싱 안드로이드 아나토미 정리 믹싱 함수 결정 if (resampling) { state->hook = process__genericResampling; 리샘플링과 믹싱을 동시에 처리 } Else{ state->hook = process__genericNoResampling;  믹싱 처리 if (all16BitsStereoNoResample && !volumeRamp) { if (countActiveTracks == 1) { 오디오 트랙이 하나이면 믹싱처리를 하지 않는 아래 함수가 호출 됨. state->hook = process__OneTrack16BitsStereoNoResampling; } } } state->hook(state);  믹싱 함수 호출 } void AudioMixer::process__OneTrack16BitsStereoNoResampling() { int32_t* out = t.mainBuffer;  mixerthread의 믹서 버퍼를 out으로 설정한다. while (numFrames) { t.bufferProvider->getNextBuffer(&b); PCM 데이터 공유 버퍼에서 write된 data를 b로 가져온다. *out++ = (r<<16) | (l & 0xFFFF);  가져온 data를 믹서 버퍼로 copy한다. 복사된 데이터는 pcm 데이터 출력 단계에서 소리로 출력 된다. t.bufferProvider->releaseBuffer(&b);  오디오 컨트록 블락에서 server 변수의 값을 갱신한다. } 7
  • 8. 3. PCM 데이터 출력 안드로이드 아나토미 정리 bool AudioFlinger::MixerThread::threadLoop() { if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) { mAudioMixer->process(); 믹서 버퍼에 PCM 데이터가 복사됨. } int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize); } ssize_t AudioHardware::AudioStreamOutMSM72xx::write(const void* buffer, size_t bytes) { size_t count = bytes;  write할 data size const uint8_t* p = static_cast<const uint8_t*>(buffer);  mixer buffer ssize_t written = ::write(mFd, p, count); mFd file descriptor가 가르키는 곳에 mixer buffer의 내용을 write한다. mFd는 status = ::open("/dev/msm_pcm_out", O_WRONLY/*O_RDWR*/); 에 대한 file descriptor이다. if(msm_route_stream(PCM_PLAY, dec_id, DEV_ID(cur_rx), 1)) { LOGE("msm_route_stream failed"); return 0; } ioctrl로 PCM_PLAY 를 driver로 전달해서 play됨. 8