So playing two audio files simultaneously is definitely an issue so I thought, another way to look at the problem would be to combine two audio files programmatically into one, and play that. That turned out to be simple to implement with WAV files (MP3 and other compressed formats would need to be uncompressed first?). Anyway, here's how I did it:
InputStream is = getResources().openRawResource(R.raw.emokylotheme); // Name of file 1
byte [] bytesTemp2 = fullyReadFileToBytes(new File(
Environment.getExternalStorageDirectory().getAbsolutePath()+
"/Kylo Ren/"+filename+"_morphed.wav")); // Name of file 2
byte [] sample2 = convertInputStreamToByteArray(is);
byte[] temp2 = bytesTemp2.clone();
RandomAccessFile randomAccessFile2 = new RandomAccessFile(new File(
Environment.getExternalStorageDirectory().getAbsolutePath()+
"/Kylo Ren/"+filename+"_morphed.wav"), "rw");
//seek to skip 44 bytes for WAV formats
randomAccessFile2.seek(44);
for (int n = 0; n < bytesTemp2.length; n++)
{
bytesTemp2[n] = (byte) ((temp2[n] + (sample2[n])));
}
randomAccessFile2.write(bytesTemp2);
randomAccessFile2.close();
And here are the support functions:
public byte[] convertInputStreamToByteArray(InputStream inputStream)
{
byte[] bytes= null;
try
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte data[] = new byte[1024];
int count;
while ((count = inputStream.read(data)) != -1)
{
bos.write(data, 0, count);
}
bos.flush();
bos.close();
inputStream.close();
bytes = bos.toByteArray();
}
catch (IOException e)
{
e.printStackTrace();
}
return bytes;
}
byte[] fullyReadFileToBytes(File f) throws IOException {
int size = (int) f.length();
byte bytes[] = new byte[size];
byte tmpBuff[] = new byte[size];
FileInputStream fis= new FileInputStream(f);
try {
int read = fis.read(bytes, 0, size);
if (read < size) {
int remain = size - read;
while (remain > 0) {
read = fis.read(tmpBuff, 0, remain);
System.arraycopy(tmpBuff, 0, bytes, size - remain, read);
remain -= read;
}
}
} catch (IOException e){
throw e;
} finally {
fis.close();
}
return bytes;
}
In essence, what the code does is: It gets the bytes of the two audio files (one is within the app in R.raw and the other is in the external storage directory), sums them up, and writes the new bytes to another file.
The issue with this code is that it generates some amount of background noise. It isn't a lot but I believe the summing up of the bytes at certain points (maybe extremas?) leads to the noise. If someone knows how to fix this, could you edit the answer and let me know.
P.S. this was for an open source voice changer app with dramatic background noise effects called Kylo Ren Voice Changer (https://github.com/advaitsaravade/Kylo-Ren-Voice-Changer)