2011-02-22 2 views
0

마이크의 오디오를 실시간 처리하는 안드로이드 용 응용 프로그램을 만들고 있습니다. 샘플링 및 재생이 효과적으로 작동하지만 첫 번째 오디오 효과 인 왜곡을 구현하는 데 어려움을 겪고 있습니다. 오디오는 단락의 버퍼로 제공되므로, 이들 중 하나가 수신 될 때마다 값을 서명 된 단락의 전체 크기로 매핑하려고 시도하고 본질적으로 특정 레벨 이상인 경우이 값을 잘라냅니다. 이 오디오는 분명히 왜곡되어 있지만 바람직한 방식은 아닙니다. 이 작업을 수행하기 위해 코드를 포함했습니다. 누구든지 여기에서 오류를 볼 수 있습니까?자바 오디오 효과 - Android의 왜곡 알고리즘

public void onMarkerReached(AudioRecord recorder) { 
      // TODO Auto-generated method stub 
      short max = maxValue(buffers[ix]); 
      short multiplier; 

      if(max!=0) 
       multiplier = (short) (0x7fff/max); 
      else 
       multiplier = 0x7fff; 
      double distLvl =.8; 
      short distLvlSho = 31000; 
      short max2 =100; 
     for(int i=0;i<buffers[ix].length;i++){ 
      buffers[ix][i]=(short) (buffers[ix][i]*multiplier); 
      if(buffers[ix][i]>distLvlSho) 
       buffers[ix][i]=distLvlSho; 
      else if(buffers[ix][i]<-distLvlSho) 
       buffers[ix][i]=(short)-distLvlSho; 
      buffers[ix][i]=(short) (buffers[ix][i]/multiplier); 
     } 

버퍼들 어레이는 팬티의 2 차원 배열이며, 처리 [IX]를 여기에서, 어레이 내의 어레이 중 하나에서 수행 될 버퍼링한다.

답변

0

2 개의 짧은 정수를 곱하면 결과에 긴 정수가 필요하거나 결과가 오버플로 될 수 있습니다.

1000 * 1000 = 1000000으로, 16 비트 정수로는 너무 큽니다.

전에 스케일링 연산 (나누기 또는 오른쪽 시프트)을 수행해야합니다. 곱하기 결과를 저장하기 위해 짧은 값으로 변환합니다. 같은 뭔가 :

result_short = (short)((short_op_1 * short_op_2) >> 16); 
+0

이 언급해야는 시작 부분에 사용되는 maxValue를 기능 때문에 승수 짧은 기껏에 배열의 값 짧은의 한계 값을 곱해야한다, 내가 함께 일하고 있어요 배열의 최대 발견 , 32767 개최 할 수 있습니다. –

2

는 지금까지 내가 당신이 무엇을 얻을 결국 보는 바와 같이 비율 clipThr/최대 (입력) = distLvlSho /에서 0x7FFF을 다음과 클립 임계 값과 소스의 단지 클리핑입니다. 대부분의 입력은 기본적으로 변경되지 않습니다.

당신은 실제로 당신이 전체 신호에 어떤 종류의 비선형 함수를 적용한다 (더하기 결국 근처 샘플 최대 클리핑 아날로그 포화을 시뮬레이션)이 나열되어 왜곡을

몇 가지 간단한 모델을 신호를 왜곡하고 싶었다면 책 : http://books.google.it/books?id=h90HIV0uwVsC&printsec=frontcover#v=onepage&q&f=false

가장 단순한 것은 simmetrical soft clipping (118 페이지 참조)입니다. 다음은 그 소프트 클립 함수로 수정 ​​된 메서드입니다. 왜곡 된 사운드에 대한 요구 사항을 충족시키는 지 확인하십시오 (입력시 약간의 사인 곡선을 만들고 출력을 플로팅하기 위해 Excel을 사용하여 테스트했습니다)

동일한 장에서 간단한 튜브 모델링과 퍼지 필터 모델링을 찾으십시오 (성능에 문제가있는 경우 해당 모델을 근사치로 나타낼 수있는 몇 가지 지수가 있습니다).

public void onMarkerReachedSoftClip(short[] buffer) { 
    double th=1.0/3.0; 
    double multiplier = 1.0/0x7fff; // normalize input to double -1,1 
    double out = 0.0; 
    for(int i=0;i<buffer.length;i++){ 
     double in = multiplier*(double)buffer[i]; 
     double absIn = java.lang.Math.abs(in); 
     if(absIn<th){ 
      out=(buffer[i]*2*multiplier); 
     } 
     else if(absIn<2*th){ 
      if(in>0)out= (3-(2-in*3)*(2-in*3))/3; 
      else if(in<0)out=-(3-(2-absIn*3)*(2-absIn*3))/3; 
     } 
     else if(absIn>=2*th){ 
      if(in>0)out=1; 
      else if(in<0)out=-1; 
     } 
     buffer[i] = (short)(out/multiplier); 
    } 
} 
+0

+1 좋은 답변! –

관련 문제