Reputation: 375
I am trying to merge two MP3 files to a single MP3 file. The files are saved in an SD card but it can't be played. First, I converted the MP3 to WAV file stored in /res/raw
folder, and output it on SD card. It also gives ArrayOutOfBoundsException
.
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// MediaPlayer mediaPlayer= MediaPlayer.create(getApplicationContext(),getAssets()+"" )
try {
mixSound();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void mixSound() {
try {
AudioTrack audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT, 44100, AudioTrack.MODE_STREAM);
// Uri url = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.one);
// System.out.println("MainActivity.mixSound() url1"+url.toString());
// File file = new File(url.toString());
// Uri url2 = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.two);
// System.out.println("MainActivity.mixSound() url1"+url2.toString());
// File file2 = new File(url2.toString());
// InputStream in1=new FileInputStream(file);
// InputStream in2=new FileInputStream(file2);
// int rid = getResources().getIdentifier(getPackageName() + ":raw/one.mp3" , null, null);
// get the file as a stream
// InputStream in1 = getResources().openRawResource(rid);
// InputStream in1=new FileInputStream("");
//
// int rid2 = getResources().getIdentifier(getPackageName() + ":raw/two.mp3" , null, null);
// get the file as a stream
// InputStream in2 = getResources().openRawResource(rid2);
//
// InputStream in2=new FileInputStream(getResources().openRawResource(R.raw.one).toString());
InputStream in1 = getApplicationContext().getResources().openRawResource(R.raw.media);
InputStream in2 = getApplicationContext().getResources().openRawResource(R.raw.media1);
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[music2.length];
audioTrack.play();
int j=0;
for(int i=0; i < output.length; i++){
float mixed;
if(j<music1.length){
float samplef1 = music1[j] / 128.0f; // 2^7=128
float samplef2 = music2[i] / 128.0f;
mixed = samplef1 + samplef2;
j++;
}else{
float samplef2 = music2[i] / 128.0f;
mixed = samplef2;
}
float samplef1 = music1[j] / 128.0f; // 2^7=128
float samplef2 = music2[i] / 128.0f;
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);
//convert array of bytes into file
FileOutputStream fileOuputStream = new FileOutputStream(Environment.getExternalStorageDirectory()+"/abc.wav");
fileOuputStream.write(output);
fileOuputStream.close();
System.out.println("MainActivity.mixSound()==>Done");
System.out.println("Done");
}catch(Exception e){
// e.printStackTrace();
System.out.println("MainActivity.mixSound()==>"+e);
}
}
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
}
}
Upvotes: 0
Views: 670
Reputation: 5634
ArrayOutOfBoundException is in code line
for(int i=0; i < output.length; i++)
it should be
for(int i=0; i < output.length-1; i++)
Also as suggested by grattmandu03 below code
if(j<music1.length)
should be
if(j<music1.length-1)
Upvotes: 0
Reputation: 5507
With a length of 166074 the last index to access is (166074 - 1) The arrays starts with element 0. (zero offset)
Upvotes: 1