Android audio system(pcm데이터출력요청-서비스클라이언트)

  • 1,563 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
1,563
On Slideshare
0
From Embeds
0
Number of Embeds
5

Actions

Shares
Downloads
0
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. 안드로이드 아나토미 정리Android Audio System(PCM데이터 출력요청- 서비스 클라이언트) 박철희 1
  • 2. 1.Audio data 전달 안드로이드 아나토미 정리 Audiotrack.java public int write(byte[] audioData,int offsetInBytes, int sizeInBytes) { //audioData:audioData the array that holds the data to play. //the offset expressed in bytes in audioData where the data to play starts. //the number of bytes to read in audioData after the offset. //the number of bytes that were written return native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat); } Android_media_AudioTrack.cpp static jint android_media_AudioTrack_native_write() { if (javaAudioData) { cAudioData = (jbyte *)env->GetPrimitiveArrayCritical(javaAudioData, NULL); ----------------(1) if (cAudioData == NULL) { LOGE("Error retrieving source of audio data to play, cant play"); return 0; // out of memory or no data to load } } jint written = writeToTrack(lpTrack, javaAudioFormat, cAudioData, offsetInBytes, sizeInBytes); ---------(2) } 2
  • 3. 2.Audio data 전달(vm heap -> process heap -> 공유 메모리) 안드로이드 아나토미 정리 (1) cAudioData = (jbyte *)env->GetPrimitiveArrayCritical(javaAudioData, NULL); 가상머신 heap(java영역)에 있는 audio data를 process heap(네이티브 공간)으로 copy한다. Music process Java 계층 Native 계층 Process heap Dalvik VM VM heap Music application copy Audio buffer audiotrack (2) jint written = writeToTrack(lpTrack, javaAudioFormat, cAudioData, offsetInBytes, sizeInBytes); music Process heap에 있는 audiodata를 adiotrack을 위한 공유 메모리에 write한다. (공유 메모리:audio track과 audio flinger가 data를 공유하기 위한 메모리 AudioTrack++ Audioflinger audiob uffer write read android kernel Track[3 32kbyte 1] AudioFlinger::Client (shared memory) 1M Track[0] 3
  • 4. 3. 공유메모리에 audio data copy과정 안드로이드 아나토미 정리 jint writeToTrack(AudioTrack* pTrack, jint audioFormat, jbyte* data, jint offsetInBytes, jint sizeInBytes) { written = pTrack->write(data + offsetInBytes, sizeInBytes); } AudioTrack.cpp ssize_t AudioTrack::write(const void* buffer, size_t userSize) { const int8_t *src = (const int8_t *)buffer;  process heap의 audio buffer를 가리킨다. Buffer audioBuffer; do { status_t err = obtainBuffer(&audioBuffer, -1); 공유 메모리에서 유저 오프셋이 가리키는 곳의 메모리를 할당 받아 audiobuffer에 저장 한다. toWrite = audioBuffer.size; 할당된 버퍼의 크기 memcpy(audioBuffer.i8, src, toWrite); audio buffer의 data를 할당받은 공유메모리에 copy한다. releaseBuffer(&audioBuffer); 오디오 트랙 컨트롤 블록의 유저 변수 값을 재계산 함. } } 4
  • 5. 4.obtainbuffer 안드로이드 아나토미 정리 status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) { uint32_t framesAvail = cblk->framesAvailable(); 공유 메모리에 할당 받을 메모리가 있는지 check한다. if (framesAvail == 0) { while (framesAvail == 0) { 공유 메모리에 할당 받을 메모리가 없을 경우, audio driver에서 data를 출력해서 빈 메모리가 생길때까지 기다린다. } } 남아 있는 메모리가 요구한 메모리보다 적게 남아 있으면 남아 있는 메모리를 넣는다. if (framesReq > framesAvail) { framesReq = framesAvail; } audioBuffer->size = framesReq * cblk->frameSize; audioBuffer->raw = (int8_t *)cblk->buffer(u);  공유 메모리에 buffer를 할당 받고 그 위치를 return한다. audiobuffer User } server userBase serverBase 오디오 컨트롤 블록 5
  • 6. 5.releaseBuffer 안드로이드 아나토미 정리 void AudioTrack::releaseBuffer(Buffer* audioBuffer) { audio_track_cblk_t* cblk = mCblk; cblk->stepUser(audioBuffer->frameCount); } uint32_t audio_track_cblk_t::stepUser(uint32_t frameCount) { uint32_t u = this->user; u += frameCount;  현재 user 변수에 할당 된 frameCount을 더한다. this->user = u; 갱신된 user 값을 설정한다. } User audiobuffer server userBase serverBase 오디오 컨트롤 블록 6