i have an app (android) which works with sounds, transforming them (changing pitch or rate and so on) at run time; one of the tranformations consists in playing some sound reversing it. Java Sound class can do that but you cannot use this class in android. So i had to find the way to do that and found a solution which works (as for me!) and perhaps can help others (i have seen on SO that this question is not really answered); yet i have a problem which is exposed in the code below. Is anybody able to explain to me why the "first solution" does not work???
--- CODE (some imports are not used in this method)
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioTrack;
import android.os.Environment;
AudioTrack audioTrack;
FileInputStream is;
void setup(){
orientation(PORTRAIT);
joueenvers();
}
public void joueenvers(){
int minBufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT);
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO,
AudioFormat.ENCODING_PCM_16BIT, minBufferSize, AudioTrack.MODE_STREAM);
audioTrack.play();
byte [] buffer = new byte[2048];
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/clock.wav");//try putting some wave on your sdcard
try {
is = new FileInputStream(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
buffer = convertStreamToByteArray(is, 2048);// this could be done more quickly importing org.apache.commons.io.IOUtils but my method works also...
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//try {
//while((i = inputStream.read(buffer)) != -1)//for reading without inverting uncomment
audioTrack.write(buffer, 0, buffer.length);
//} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
//}
try {
is.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static byte[] convertStreamToByteArray(InputStream is, int size) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[size];
int i = Integer.MAX_VALUE;
while ((i = is.read(buff, 0, buff.length)) > 0)
{
baos.write(buff, 0, i);
}
return reverse(baos.toByteArray());
};
public static byte[] reverse(byte[] array) {
if (array == null)
{
return null;
}
byte[] result = new byte[array.length];
//array.length = 11365644 - that is the exact size from the file choosen
for(int i = 0 ; i < 44 ; i++)// copy header for 44 bytes
{
result[i] = array[i];
}
//copy other bytes inverting the order:: 2 solutions=== HERE IS THE PROBLEM
// first one which seems logical but does not work!!!! i take the first value from array[] and put it a the end of result[]:: only noise, not any error message
/* int o = array.length-1;
for (int l = 44 ; l < array.length ; l++ )//44 is after header
{
byte value1 = array[l];//first value will be array[44];
result[o]= value1;// last value for result will be the first one from the array (array[44])
o--;
if(l<50 && l>=44){
System.out.println("o=======" + o);//returns array.length decrementing it at each loop
}
}*/
//second one which seems only the contrary but works!!! i take the last value from the array and put it at the beginning
int z = array.length;
for (int l= 44; l < array.length; l++ )
{
byte value1 = array[z-l];// 11365600 the first time as asked for: correct, this is the last value from array[]
if(l<50 && l>=44){
System.out.println ("z-l=====" + (z-l));
}
result[l] = value1;// first value from result[] = last value from array[]
}
return result;
};