5

I tried to follow this link:

http://mobilengineering.blogspot.com/2012/06/audio-mix-and-record-in-android.html?showComment=1369622288028#c2333829870074273419

But after mixing audio files, file (mixed.wav) on sdcard can not be played, I do not know why. Can you help me?. Thank you very much ..

This my code:

public class MainActivity extends Activity {

 public static final int FREQUENCY = 44100;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    try {
        mixSound();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

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.media_b);
    InputStream in2 = getResources().openRawResource(R.raw.media_c);

    byte[] arrayMusic1 = null;
    arrayMusic1 = new byte[in1.available()];
    arrayMusic1 = createMusicArray(in1);
    in1.close();

    byte[] arrayMusic2 = null;
    arrayMusic2 = new byte[in2.available()];
    arrayMusic2 = createMusicArray(in2);
    in2.close();


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

    audioTrack.play();

    for (int i = 0; i < output.length; i++) {
        float samplef1 = arrayMusic1[i] / 128.0f; 
        float samplef2 = arrayMusic2[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, output.length);
    convertByteToFile(output);
}

public static byte[] createMusicArray(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

}

public static void convertByteToFile(byte[] fileBytes) throws FileNotFoundException {

    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(Environment.getExternalStorageDirectory().getPath()+"/mixed.wav"));
    try {
        bos.write(fileBytes);
        bos.flush();
        bos.close();    
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

Noe Love
  • 53
  • 1
  • 5

1 Answers1

3

What you're outputting is just the PCM data. A valid WAV file also needs a header:

Offset    Size  Name           Description
------------------------------------------------------------------------
0         4     ChunkID        Contains the letters "RIFF" in ASCII form
                               (0x52494646 big-endian form).
4         4     ChunkSize      36 + SubChunk2Size, or more precisely:
                               4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)
                               This is the size of the rest of the chunk 
                               following this number.  This is the size of the 
                               entire file in bytes minus 8 bytes for the
                               two fields not included in this count:
                               ChunkID and ChunkSize.
8         4     Format         Contains the letters "WAVE"
                               (0x57415645 big-endian form).

12        4     Subchunk1ID    Contains the letters "fmt "
                               (0x666d7420 big-endian form).
16        4     Subchunk1Size  16 for PCM.  This is the size of the
                               rest of the Subchunk which follows this number.
20        2     AudioFormat    PCM = 1 (i.e. Linear quantization)
                               Values other than 1 indicate some 
                               form of compression.
22        2     NumChannels    Mono = 1, Stereo = 2, etc.
24        4     SampleRate     8000, 44100, etc.
28        4     ByteRate       == SampleRate * NumChannels * BitsPerSample/8
32        2     BlockAlign     == NumChannels * BitsPerSample/8
                               The number of bytes for one sample including
                               all channels. I wonder what happens when
                               this number isn't an integer?
34        2     BitsPerSample  8 bits = 8, 16 bits = 16, etc.
          2     ExtraParamSize if PCM, then doesn't exist
          X     ExtraParams    space for extra parameters

36        4     Subchunk2ID    Contains the letters "data"
                               (0x64617461 big-endian form).
40        4     Subchunk2Size  == NumSamples * NumChannels * BitsPerSample/8
                               This is the number of bytes in the data.
                               You can also think of this as the size
                               of the read of the subchunk following this 
                               number.

After this you write the PCM data.

(Reference).

Michael
  • 57,169
  • 9
  • 80
  • 125
  • How to fix it, I do not know how. Can you help me? Thank you very much :) – Noe Love May 27 '13 at 06:32
  • You write all the fields specified in the header. First the string `RIFF`, then a 32-bit value containing `36+size_of_your_audio_data`, then the string `WAVE`, and so on. – Michael May 27 '13 at 06:35
  • Thank you very much. I had mixed success. But mixed.wav file with noise. How to fix it, remove white noise. What do I do with my wav byte array. Can you help me? – Noe Love May 29 '13 at 08:49
  • You should write the PCM data immediately following the header. You could double-check that your PCM data is ok by dumping it to a file without any header and then importing it as raw PCM data in Audacity on your PC. – Michael May 29 '13 at 09:14
  • After I switched to short[] it works very bad :( I do not know where I was wrong. – Noe Love May 31 '13 at 08:52
  • @Michael : Can you provide me the solution of How did you mix two audio files?? I am not able to achieve this..Any help will be greatly appreciated. – Siddharth_Vyas Oct 29 '14 at 10:19
  • @Siddharth_Vyas have you got the solutions for mixing two audio files.Please tell me is it possible and if it is give a way to do it.Any help appreciated.. – Narender Reddy Apr 27 '17 at 07:36
  • @NarenderReddy : Sorry, I was not able to get the solution. – Siddharth_Vyas Apr 28 '17 at 05:23