2013-12-09 58 views
0

我需要生成2個不同頻率的正弦波音,並在Android上以立體聲模式將它們分別播放到右和左聲道。如何以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」,從而使2個通道的1左無聲音,但都發出聲音

什麼是錯在我的代碼?

+0

什麼是音頻路由到(揚聲器,耳機,USB,...)?如果是揚聲器;你正在測試的設備實際上是否有立體聲揚聲器? – Michael

+0

我使用立體聲耳機! – user3081080

+0

@邁克爾哎,我碰上了這一點,並會爲我的實現是有用的,但我實現之前,我想了解一些基本的概念 1.什麼是用於(如:緩衝器1,緩衝器2,字節緩衝區)緩衝 2.爲什麼是44.1K緩衝區的大小(這是什麼緩衝和採樣率之間的關係) 3.還有什麼地方是緩衝區使用的 謝謝!祝你有愉快的一天! – user1730935

回答

0

我與API 18,Eclipse的開普勒試了一下,在我的三星S4運行,它工作得很好。右聲道無聲,左聲道播放440Hz的正弦波。

我在閱讀代碼時注意到的唯一錯誤是播放的持續時間是它應該是的1/2:行「byteBufferFinal = new byte [buffer1.length * 2];」應該改爲「byteBufferFinal = new byte [byteBuffer1.length * 2];」

可悲的是,這個問題可能只是你的音頻線或揚聲器:音頻插頭可能不會一路插到手機插孔,在兩個揚聲器一個聲道播放。

+0

我在我的Samsung Galaxy Ace上用API 16試過它,並且不起作用(左右聲道發出聲音)。 然後,由於你的回答,我嘗試了API 18,在我的NEXUS 7(帶耳機)上,並且不起作用。你必須運行我的代碼,手機的音量最大,你會意識到兩個聲道的聲音(一個低於另一個聲音)。如果你不這樣做,你會認爲一個頻道聽起來而另一個沒有。 所以,問題不是音頻線或揚聲器:( 我仍然不知道是什麼問題 – user3081080

+0

PD:!我更改線路「byteBufferFinal =新的字節[buffer1.length * 2];」到「 byteBufferFinal = new byte [byteBuffer1.length * 2];「我輸錯了代碼,謝謝!!」 – user3081080

+0

「你必須運行我的代碼,手機的音量最大,你會發現兩個聲道的聲音(**一個低於另一個的聲音**),如果你不這樣做,你會認爲一個聲道發出聲音而另一個聲音不響。「表示你所面對的是**可能不是軟件問題**,而是在音頻輸出**電路**中使用有限的通道隔離。考慮使用* audacity *在一個通道中生成帶有音頻的測試文件,並使用各種播放器應用程序在桌面和手機上播放它。 –

相關問題