How to play two sine wave on left and right channel separately with 16-bit format?

北慕城南 提交于 2019-12-23 04:23:15

问题


I need to generate 2 sine wave tones with different frequency and play them separately into right and left channel in stereo mode on Android.

This is my code:

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();
   }

The output buffer(byteBufferFinal) has the 16-bit format: LL RR LL RR LL RR LL (where each character is 1 byte)

My code doesn't do well the distribution of the sound in the left and right channel. I prove it leaving one amplitude in "1" and the other in "0", so that 1 of the 2 channels left without sound, BUT both emit sound

What's wrong in my code?


回答1:


I tried it with API 18, Eclipse Kepler, running on my Samsung S4 and it worked fine. The right channel was silent and the left channel played a 440Hz sine wave.

The only bug I noticed while reading the code is that the played duration is 1/2 of what it should be: the line "byteBufferFinal = new byte[buffer1.length*2];" should instead be "byteBufferFinal = new byte[byteBuffer1.length*2];"

Sadly, the problem might just be your audio cable or speakers: the audio plug might not be plugged all the way into the phone jack, making one channel play in both speakers.



来源:https://stackoverflow.com/questions/20461243/how-to-play-two-sine-wave-on-left-and-right-channel-separately-with-16-bit-forma

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!