2

I successfully could mix two 8 bit files with the code below.(with compiled Musicg 1.4.2.0 jar lib) But when I try to mix two 22050 (sample rate) and 16bit files the resulting file plays faster. Tried everything in the header code or in the mix equation, but still plays faster (maybe twice). Tried to change 128 to 35768( 2^ to 2^15), but I noticed it's related to the amplitude, the length remains the same. So it keeps playing faster. Any suggestion?

    InputStream in1 = getResources().openRawResource(R.raw.myfile);
    InputStream in2 = getResources().openRawResource(R.raw.myfile2);

    Wave w1 = new Wave(in1);
    short[] music1 = w1.getSampleAmplitudes();
    in1.close();

    Wave w2 = new Wave(in2);
    short[] music2 = w2.getSampleAmplitudes();
    in2.close();

    byte[] output = new byte[(music1.length > music2.length) ? music2.length
            : music1.length];

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

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

        float mixed = (samplef1 + samplef2)/2;
        //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


    File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"+"result.wav");
    if (f.exists()) {
        f.delete();
    }

    FileOutputStream fo = new FileOutputStream(f);

    WaveHeader wh = w2.getWaveHeader();
    MyWaveHeader mwh = new MyWaveHeader((short) wh.getAudioFormat(),
            (short) wh.getChannels(), wh.getSampleRate(),
            (short) wh.getBitsPerSample(), output.length);
    mwh.write(fo);

    fo.write(output);
    fo.flush();
    fo.close();

    // MusicPlayer
    MediaPlayer mp = new MediaPlayer();
    // Listeners
    mp.setOnCompletionListener(new OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {
            // TODO Auto-generated method stub

        }
    }); // Important

    mp.reset();

    mp.setDataSource(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"+"birdbellhigh.wav");
    mp.setAudioStreamType(AudioManager.STREAM_MUSIC);

    mp.prepare();
    mp.start();

     AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
     22050, AudioFormat.CHANNEL_OUT_DEFAULT,
     AudioFormat.ENCODING_PCM_16BIT, output.length,
     AudioTrack.MODE_STREAM);
     audioTrack.play();
     audioTrack.write(output, 0, output.length);
Sktsalad
  • 23
  • 4
  • If the two amplitude arrays are short, why use a byte array for the output? – bracco23 Jul 27 '17 at 14:40
  • Looks like your source files have smaller rate (11025), and when you try to handle mixed file as 22050 it plays (twice) faster. – dzikovskyy Jul 27 '17 at 15:01
  • I transformed the byte/short array as bracco23 said and checked the 22050 rate of the files. I added some methods from this post "https://stackoverflow.com/questions/16766248/mix-audio-in-android " and it worked! Thank you guys! – Sktsalad Jul 27 '17 at 20:29
  • you can also have a look at https://stackoverflow.com/questions/39613665/mix-byte-array-android/39634144#39634144 - seems to be quite similar – Martin Frank Jul 28 '17 at 09:59

0 Answers0