Android AudioTrack Mixing的示例代码

时间:2013-02-27 07:40:57

标签: android audiotrack

我在资源文件夹中有两个PCM声音文件。我使用inputstream并将它们转换为bytearray。

然后我通过规范化处理它们并添加music1和music2并输出到字节数组输出。最后,输出数组并将其提供给AudioTrack。

显然,我没有听到任何声音,也没有出现问题。

 private void mixSound() throws IOException {

    InputStream in1=getResources().openRawResource(R.raw.cheerapp2);      
    InputStream in2=getResources().openRawResource(R.raw.buzzer2);

     byte[] music1 = null;
     music1= new byte[in1.available()]; 
     music1=convertStreamToByteArray(in1);
     in1.close();


     byte[] music2 = null;
     music2= new byte[in2.available()]; 
     music2=convertStreamToByteArray(in2);
     in2.close();

     byte[] output = new byte[music1.length];

     audioTrack.play();

     for(int i=0; i < output.length; i++){

         float samplef1 = music1[i] / 128.0f;      //     2^7=128
         float samplef2 = music2[i] / 128.0f;


         float mixed = samplef1 + samplef2;
         // reduce the volume a bit:
         mixed *= 0.8;
         // hard clipping
         if (mixed > 1.0f) mixed = 1.0f;
         if (mixed < -1.0f) mixed = -1.0f;
        byte outputSample = (byte)(mixed * 128.0f);
         output[i] = outputSample;
         audioTrack.write(output, 0, i);
      }   //for loop


      public static byte[] convertStreamToByteArray(InputStream is) throws IOException {



    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buff = new byte[10240];
    int i = Integer.MAX_VALUE;
    while ((i = is.read(buff, 0, buff.length)) > 0) {
        baos.write(buff, 0, i);
    }

    return baos.toByteArray(); // be sure to close InputStream in calling function

}

1 个答案:

答案 0 :(得分:9)

我尝试了你的代码(替换了我自己的一些音频文件)。我初始化了一个像这样的AudioTrack实例,希望这与你的做法类似:

AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, 44100, AudioTrack.MODE_STREAM);

尝试运行它。它发出了高亢的噪音,随着时间的推移逐渐降低。我检查了代码,问题是你在mixSound()方法的循环的每次迭代中都将整个输出字节数组写入audioTrack。

 audioTrack.write(output, 0, i);

需要移出循环并更改为

 audioTrack.write(output, 0, output.length);

因此,您将两个文件混合到输出字节数组中,然后立即写入整个文件。

因此,使用mixSound方法的代码如下所示:

private void mixSound() throws IOException {
    AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, 44100, AudioTrack.MODE_STREAM);

    InputStream in1=getResources().openRawResource(R.raw.track1);      
    InputStream in2=getResources().openRawResource(R.raw.track2);

    byte[] music1 = null;
    music1= new byte[in1.available()]; 
    music1=convertStreamToByteArray(in1);
    in1.close();


    byte[] music2 = null;
    music2= new byte[in2.available()]; 
    music2=convertStreamToByteArray(in2);
    in2.close();

    byte[] output = new byte[music1.length];

    audioTrack.play();

    for(int i=0; i < output.length; i++){

        float samplef1 = music1[i] / 128.0f;      //     2^7=128
        float samplef2 = music2[i] / 128.0f;


        float mixed = samplef1 + samplef2;
        // reduce the volume a bit:
        mixed *= 0.8;
        // hard clipping
        if (mixed > 1.0f) mixed = 1.0f;

        if (mixed < -1.0f) mixed = -1.0f;

        byte outputSample = (byte)(mixed * 128.0f);
        output[i] = outputSample;

    }   //for loop
    audioTrack.write(output, 0, output.length);

}