getting noise as output instead of mixed sounds

217 Views Asked by At

When I run the following code I have no sound as output instead it gives me noise.

I have two audio files in my resource folder and using 1 inputstream these are converted to bytearray.If I add mp3 then the app closes unfortunately.

    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);
        Log.i(tag,"inside mixSound");
        InputStream in1=getResources().openRawResource(R.raw.cut1);      s
        InputStream in2=getResources().openRawResource(R.raw.cut2);

        byte[] music1 = null;
        music1= new byte[in1.available()]; 
        Log.i(tag,"in1");
        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);

    }

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



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

            return baos.toByteArray(); 
        }

Thank you for help in advance.

1

There are 1 best solutions below

0
On

A few issues here...

  1. If you are working with 16-bit PCM audio (which by your initialization of AudioTrack it appears you are), then you should access your source audio and write to your AudioTrack in shorts (which are 16 bits) rather than bytes (8 bits). If you must read bytes from your source, you'll need to read two of them at a time in your loop and do something like

    short curSample = (myByteArr[i] << 8) | myByteArr[i+1];
    

    and then write the result to your stored buffer. This is assuming you have 16-bit shorts stored in the files you're reading from, which you should. Better to just read those as what they are, though.

  2. Using AudioTrack.MODE_STREAM implies you will write continuously to the buffer while audio is playing. The way you've done it here fills the entire buffer and then writes it to the AudioTrack. If this is a one-off playback, you should probably use AudioTrack.MODE_STATIC.

  3. This is a corner case, but consider what happens if mixed == 1.0f. If you multiply that by 128.0f and truncate to byte, you'll get 128, which is actually beyond the range of a signed byte (because of 0, the range is [-128, 127]).

I believe problem #1 is the source of your noise. You need to keep your 16-bit PCM data intact rather than splitting it up.