Quantcast
Channel: Android Mode - Processing 2.x and 3.x Forum
Viewing all articles
Browse latest Browse all 941

about playing audio file (.wav) backwards (reversing)

$
0
0

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;
    };

Viewing all articles
Browse latest Browse all 941

Trending Articles