2013-12-09 1 views
0

다른 주파수로 2 개의 사인파를 생성하고 안드로이드에서 스테레오 모드로 좌우 채널에 따로 따로 재생해야합니다.왼쪽 및 오른쪽 채널에서 두 개의 사인파를 16 비트 형식으로 개별적으로 재생하는 방법은 무엇입니까?

int sample; 
double sampleRate; 
double duration;  
double time; 
double f1; 
double f2; 
double amplitude1; 
double amplitude2; 
double sineWave1; 
double sineWave2; 
float[] buffer1; 
float[] buffer2; 
byte[] byteBuffer1; 
byte[] byteBuffer2; 
byte[] byteBufferFinal; 
int bufferIndex;  
short x; 
short y;  
AudioTrack audioTrack; 

@Override 
public void onCreate(Bundle savedInstanceState){ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    sampleRate = 44100.0; 
    duration = 20.0; 
    f1 = 440.0; 
    amplitude1= 1; 
    f2 = 444.0; 
    amplitude2 = 0; 

    buffer1 = new float[(int)(duration*sampleRate)]; 
    buffer2 = new float[(int)(duration*sampleRate)]; 

    for(sample = 0; sample < buffer1.length; sample ++){ 
     time = sample/sampleRate; 
     buffer1[sample] = (float)(amplitude1*Math.sin(2*Math.PI*f1*time)); 
     buffer2[sample] = (float)(amplitude2*Math.sin(2*Math.PI*f2*time)); 
    } 

    byteBuffer1 = new byte[buffer1.length*2]; //two bytes per audio frame, 16 bits 

    for(int i = 0, bufferIndex=0; i < byteBuffer1.length; i++){ 
     x = (short) (buffer1[bufferIndex++]*32767.0); // [2^16 - 1]/2 = 32767.0 
     byteBuffer1[i] = (byte) x; // low byte 
     byteBuffer1[++i] = (byte) (x >>> 8); // high byte   
    } 


    byteBuffer2 = new byte[buffer2.length*2]; 

    for(int j = 0, bufferIndex=0; j < byteBuffer2.length; j++){ 
     y = (short) (buffer2[bufferIndex++]*32767.0); 
     byteBuffer2[j] = (byte) y;   // low byte 
     byteBuffer2[++j] = (byte) (y >>> 8); // high byte 

    } 

    byteBufferFinal = new byte[byteBuffer1.length*2]; 
    //LL RR LL RR LL RR 
    for(int k = 0, index = 0; index < byteBufferFinal.length - 4; k=k+2){ 
     byteBufferFinal[index] = byteBuffer1[k]; // LEFT {0,1/4,5/8,9/12,13;...} 
     byteBufferFinal[index+1] = byteBuffer1[k+1]; 
     index = index + 2; 
     byteBufferFinal[index] = byteBuffer2[k]; // RIGHT {2,3/6,7/10,11;...} 
     byteBufferFinal[index+1] = byteBuffer2[k+1]; 
     index = index + 2; 
    } 

    audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 
      (int) sampleRate,AudioFormat.CHANNEL_OUT_STEREO, 
      AudioFormat.ENCODING_PCM_16BIT,byteBufferFinal.length, 
      AudioTrack.MODE_STATIC); 

    audioTrack.write(byteBufferFinal, 0, byteBufferFinal.length); 
    audioTrack.play(); 
    } 

출력 버퍼 (byteBufferFinal)를 16 비트 형식을 갖는다 :

내 코드 LL RR LL RR LL RR LL

내 코드 (각 문자가 1 바이트 임) 왼쪽 및 오른쪽 채널에서 사운드의 분배를 잘 수행하지 못합니다. 한 채널 진폭을 "1"로 남겨두고 다른 채널은 "0"으로 두 채널 중 하나가 소리없이 나왔지만 소리가 나지 않습니다.

내 코드에 무슨 문제가 있습니까?

+0

(라우드 스피커, 헤드폰, USB 등)로 라우팅되는 오디오는 무엇입니까? 라우드 스피커라면. 테스트중인 기기에 실제로 스테레오 스피커가 있습니까? – Michael

+0

스테레오 헤드폰을 사용합니다! – user3081080

+0

@Michael 안녕하세요, 저는 이것에 대해 찬성했고 구현에 유용 할 것입니다.하지만 구현하기 전에 기본 개념을 이해하고 싶습니다. 1. 사용 된 버퍼는 무엇입니까 (예 : buffer1, buffer2, byteBuffer) 왜 버퍼의 크기는 44.1k입니다 (버퍼와 샘플 속도의 관계는 무엇입니까?) 3. 다른 버퍼는 어디에 사용합니까 고마워요! 즐거운 하루 되세요! – user1730935

답변

0

내 삼성 S4에서 실행되는 API 18, Eclipse Kepler로 시도했지만 정상적으로 작동했습니다. 오른쪽 채널은 조용했고 왼쪽 채널은 440Hz 사인파를 재생했습니다.

코드를 읽는 동안 내가 알아챈 유일한 버그는 재생되는 지속 시간이 1/2이되어야한다는 것입니다. "byteBufferFinal = new byte [buffer1.length * 2];" 그 대신에 "byteBufferFinal = new byte [byteBuffer1.length * 2];"

슬프게도 문제는 오디오 케이블 또는 스피커 일 수 있습니다. 오디오 플러그가 전화 잭에 완전히 연결되어 있지 않아서 하나의 채널이 두 스피커에서 재생 될 수 있습니다.

+0

내 삼성 Galaxy Ace에서 API 16을 사용해 보았는데 작동하지 않습니다 (왼쪽 및 오른쪽 채널에서 소리가납니다). 그렇다면 귀하의 답변으로 인해 NEXUS 7 (헤드폰 사용)에서 API 18로 시도했지만 작동하지 않습니다. 휴대 전화의 최대 음량으로 내 코드를 실행해야하며 두 채널이 모두 소리가 나는 것을 알게됩니다 (다른 하나보다 낮은 소리). 당신이하지 않으면, 당신은 하나의 채널 소리와 다른 소리하지 않을 것이라고 생각합니다. 문제는 오디오 케이블이나 스피커가 아닙니다. ( 여전히 문제가 무엇인지 모르겠습니다! – user3081080

+0

PD : "byteBufferFinal = new byte [buffer1.length * 2];"행을 " "코드를 전송할 때 틀 렸습니다. 감사합니다. – user3081080

+0

"휴대 전화의 최대 음량으로 코드를 실행해야하고 두 채널 모두 소리가 나게됩니다. (** 다른 하나보다 낮은 소리 **) 당신이하지 않으면, 당신은 하나의 채널이 소리를 내고 다른 하나는 소리가 나지 않을 것이라고 생각할 것입니다. "당신이 직면하고있는 것이 ** 아마도 소프트웨어 문제가 아님 **, ** audacity *를 사용하여 하나의 채널에서만 오디오가있는 테스트 파일을 생성하고 다양한 플레이어 응용 프로그램을 사용하여 데스크톱과 휴대 전화에서 모두 재생하는 것을 고려하십시오. –

관련 문제