【问题标题】:Sample code for Android AudioTrack MixingAndroid AudioTrack Mixing 的示例代码
【发布时间】:2013-02-27 07:40:56
【问题描述】:

我在资源文件夹中有两个 PCM 声音文件。我使用了输入流并将它们转换为字节数组。

然后我通过归一化和添加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

}

【问题讨论】:

    标签: android audiotrack


    【解决方案1】:

    我尝试了您的代码(替换为我自己的一些音频文件)。我像这样初始化了一个 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);
    
    }
    

    【讨论】:

    • 在forloop里面我得到一个ArrayIndexOutofBoundsException的错误
    • 如果您的第二个音频文件比第一个短,则可能会发生这种情况。输出数组初始化为第一个音频文件的长度,for 循环遍历输出数组的长度。因此,您最终可能会读到第二个音频文件的末尾。解决方案是在您读取 samplef2 的位置周围添加保护。如果 i > music2.length 您应该将 sample2f 设置为 0(您已到达剪辑的末尾)。
    • 是否可以为单独的 InputStream 保留单独的卷?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-02
    • 1970-01-01
    相关资源
    最近更新 更多