제임스딘딘의
Tech & Life

수행 프로젝트 이력/참여자주도형 정보공유 시스템 [2011.12~2012.02]

이번 과제 컨셉을 구현하기 위한 자료조사 (1)

제임스-딘딘 2011. 11. 25. 02:08

1. 안드로이드에서 PC로 음성을 실시간 전송?
 - 폰의 마이크로부터 음성 데이터를 얻음
 - 음성 데이터를 오디오코덱으로 인코딩
 - 서버와 소켓통신.(UDP) 방화벽이 있을 경우 어떻게 통신하는지 예외 처리 
 - 압축한 데이터를 패킷(RTP)으로 나누어 보낸다
 - 받은 패킷을 디코딩/재생
 - 소실 될 수 있는 데이터에 대해 Jitter 보정을


2. 안드로이드 SDK의 AudioRecord를 사용하여 일정 시간마다 PCM데이터를 획득하는 방법

:: 단서 ::
 - "AudioRecordInstance.read()라는 함수로 PCM데이터를 획득 할 수 있다. "
 - * 그런데, while문 돌려서 계속해서 read를 호출하니 일정한 FrameSize 만큼 계속 획득이 되긴 하나,
      획득하는 시간이 일정하지 않다.
 - 8Khz 샘플링 레이트로 프레임사이즈를 160으로 잡았을때
   8000/160 = 50 이므로 1초에 50번을 획득해야 되니, read() 함수는 20ms마다 호출이 되어야된다.
   그러나 실질적으로 20 ms인 주기를 정확히 맞추기가 힘들다!

   로그를 중간 중간 삽입해 보니 어떤건 1ms마다 호출할때도 존재하고
   또 다른건 120ms 마다 호출할 때도 있고 너무 들쭉날쭉이 심하다

 - (왜?)

 - 리스너가 있다. 리스너를 통해서 실행 -> 계속적인 콜백 효과 -> 역시 들쭉 거림 -> while문 보다는 변동폭이 작다 but 들쭉거린다 문제
 
- 그나마 가장 효율이 높았던 건 while 문으로 돌리면서
  과거 실행시간 vs 현재 실행시간 비교 sleep을 주는 정도로 트릭을 쓴게 3ms 차이 내외로 왔다갔다함
 
:: 결론 :: 
 - 아직 답을 찾는중.
.
.


3. AudioRecord, AudioTrack dalay를 줄이면서 실시간으로 처리하는 방법
 - (폰 - 폰)의 통화 기능을 구현 
 - 폰1(녹음,재생) <--- 전송 ----> 폰2(녹음,재생)

 - AudioRecord, AudioTrack, DatagramSocket  => 사용

:: 문제 ::
- AudioRecord로 녹음시, read()함수를 반복적으로 사용할경우, 빠르게 동작하지 않는다!

:: 문제원인 추측 ::
- (하드웨어를 직접접근해서 그런지...?) 
========================================

byte[] recordBuffer = new byte[1024*5]; 


while(true){

   int offset=0;

   int readSize=1024;

   while(true){

       readByte = audioRecord.read(recordBuffer, offset, readSize);    

       offset+=readByte;     

     

       if(offset+1024>recordBuffer.length) readSize = recordBuffer.length-offset;

       if(readByte<=0 || readSize<=0) break;    

      } 


   try {Thread.sleep(200);} 

   catch (InterruptedException e){ e.printStackTrace(); } 

 } 
=========================================
 
 :: 0.2초에 1024*5byte씩 딱딱 뽑아내고 싶은데 중간중간에 제대로 read를 못하게 됩니다

=>OnRecordPositionUpdateListener를 사용하게 되면 이문제는 해결할수 있나요? 아니면 어떤방법이 있을까요? ::