样品code为Android AudioTrack混合 [英] Sample code for Android AudioTrack Mixing

查看:157
本文介绍了样品code为Android AudioTrack混合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在资源两个文件夹的PCM声音文件。我用InputStream和转换成字节组。

然后我处理他们通过标准化和增加music1和音乐2并输出到字节数组输出。最后,将输出数组并把它送入到AudioTrack。

很显然,我没有听到任何东西,什么是错的。

 私人无效mixSound()抛出IOException异常{

    InputStream的IN1 = getResources()openRawResource(R.raw.cheerapp2)。
    InputStream的IN2 = getResources()openRawResource(R.raw.buzzer2)。

     byte []的music1 = NULL;
     music1 =新的字节[in1.available()];
     music1 = convertStreamToByteArray(IN1);
     in1.close();


     byte []的音乐2 = NULL;
     音乐2 =新的字节[in2.available()];
     音乐2 = convertStreamToByteArray(平方英寸);
     in2.close();

     byte []的输出=新的字节[music1.length]

     audioTrack.play();

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

         浮samplef1 = music1 [I] / 128.0f; // 2 ^ 7 = 128
         浮samplef2 =音乐2 [I] / 128.0f;


         浮动混合= samplef1 + samplef2;
         //减少量了一下:
         混合* = 0.8;
         //硬削波
         如果(混合> 1.0F)混合= 1.0F;
         如果(混合< -1.0F)混合= -1.0F;
        字节outputSample =(字节)(混合* 128.0f);
         输出[I] = outputSample;
         audioTrack.write(输出,0,i)的;
      } // for循环


      公共静态的byte [] convertStreamToByteArray(InputStream的是)抛出IOException异常{



    ByteArrayOutputStream BAOS =新ByteArrayOutputStream();
    byte []的BUFF =新的字节[10240]
    INT I = Integer.MAX_VALUE的;
    而((ⅰ= is.​​read(浅黄色,0,buff.length))大于0){
        baos.write(BUFF,0,I);
    }

    返回baos.toByteArray(); //确保关闭的InputStream在调用函数

}
 

解决方案

我想你的code(代入一些我自己的音频文件)。我初始化像这样的AudioTrack实例,希望这是类似你是如何做到的:

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

,并试图运行它。它提出了高音调的噪音,这降低了随着时间的推移。我检查了code和问题是你写的整个输出字节数组audioTrack在循环的每次迭代中你mixSound()方法。

  audioTrack.write(输出,0,I);
 

需要移动在循环外,并改为

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

所以,你混这两个文件一起到输出字节数组,然后写了整个事情一次。

所以,$ C $下工作mixSound方法是这样的:

 私人无效mixSound()抛出IOException异常{
    AudioTrack audioTrack =新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 =新的字节[in1.available()];
    music1 = convertStreamToByteArray(IN1);
    in1.close();


    byte []的音乐2 = NULL;
    音乐2 =新的字节[in2.available()];
    音乐2 = convertStreamToByteArray(平方英寸);
    in2.close();

    byte []的输出=新的字节[music1.length]

    audioTrack.play();

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

        浮samplef1 = music1 [I] / 128.0f; // 2 ^ 7 = 128
        浮samplef2 =音乐2 [I] / 128.0f;


        浮动混合= samplef1 + samplef2;
        //减少量了一下:
        混合* = 0.8;
        //硬削波
        如果(混合> 1.0F)混合= 1.0F;

        如果(混合< -1.0F)混合= -1.0F;

        字节outputSample =(字节)(混合* 128.0f);
        输出[I] = outputSample;

    } // for循环
    audioTrack.write(输出,0,output.length);

}
 

I have two PCM sound file in resource folder. I used inputstream and converted them into bytearray.

Then I processed them by normalized and adding music1 and music2 and output to the byte array output. Finally, put the output array and feed it to the AudioTrack.

Obviously, I don't hear anything and something is wrong.

 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

}

解决方案

I tried your code (substituting in some audio files of my own). I initialised an AudioTrack instance like this, hopefully this is similar to how you did it:

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

And tried running it. It made a high pitched noise, that got lower as time went on. I checked the code and the problem is that you are writing the entire output byte array to the audioTrack on every iteration of the loop in your mixSound() method.

the line

 audioTrack.write(output, 0, i);

needs moved outside the loop and to be changed to

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

So you mix both files together into the output byte array, then write the whole thing at once.

So the code for the working mixSound method looks like this:

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

}

这篇关于样品code为Android AudioTrack混合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆