title: reading raw data from a wav file on android
body: <p>So this code records audio into a wav file that is stored in the emulated storage. How can I then take this wav file and get an array of the raw audio data?</p>
  
  <p>The code would go down in the buttonDecode section where it says:
  //read raw data from wav file</p>
  
  <pre><code>package com.example.wesle.noisemachine;
  
  import android.content.Intent;
  import android.media.AudioFormat;
  import android.media.AudioManager;
  import android.media.AudioRecord;
  import android.net.Uri;
  import android.support.v7.app.AppCompatActivity;
  import android.os.Bundle;
  import android.view.View;
  import android.widget.Button;
  import android.media.MediaPlayer;
  import android.media.MediaRecorder;
  import android.os.Environment;
  import android.widget.Toast;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.IOException;
  import java.io.*;
  
  public class ReceiveScreen extends AppCompatActivity {
  
      private Button buttonStart, buttonStop, buttonDecode, buttonPlay;
      private String filePath;
  
      private static final int RECORDER_BPP = 16;
      private static final String AUDIO_RECORDER_FILE_EXT_WAV = ".wav";
      private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
      private static final String AUDIO_RECORDER_TEMP_FILE = "record_temp.raw";
      private static final int RECORDER_SAMPLERATE = 44100;
      private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO;
      private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
      short[] audioData;
  
      private AudioRecord recorder = null;
      private int bufferSize = 0;
      private Thread recordingThread = null;
      private boolean isRecording = false;
      Complex[] fftTempArray;
      Complex[] fftArray;
      int[] bufferData;
      int bytesRecorded;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_receive_screen);
  
  
          //final MediaPlayer wavRecording = MediaPlayer.create(this, "/storage/emulated/0");
          buttonStart = (Button) findViewById(R.id.buttonStart);
          buttonStop = (Button) findViewById(R.id.buttonStop);
          buttonPlay = (Button) findViewById(R.id.buttonPlay);
          buttonDecode = (Button) findViewById(R.id.buttonDecode);
          buttonStop.setEnabled(false);
          buttonDecode.setEnabled(false);
          buttonPlay.setEnabled(false);
          //outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.3gp";
          //System.out.println(outputFile);
  
          bufferSize = AudioRecord.getMinBufferSize
                  (RECORDER_SAMPLERATE,RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING)*3;
          audioData = new short [bufferSize];
  
  
          buttonStart.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  buttonStart.setEnabled(false);
                  buttonDecode.setEnabled(false);
                  buttonPlay.setEnabled(false);
                  recorder = new AudioRecord(MediaRecorder.AudioSource.MIC,
                          RECORDER_SAMPLERATE,
                          RECORDER_CHANNELS,
                          RECORDER_AUDIO_ENCODING,
                          bufferSize);
                  int i = recorder.getState();
                  if (i==1)
                      recorder.startRecording();
  
                  isRecording = true;
  
                  recordingThread = new Thread(new Runnable() {
                      @Override
                      public void run() {
                          writeAudioDataToFile();
                      }
                  }, "AudioRecorder Thread");
  
                  recordingThread.start();
  
                  buttonStop.setEnabled(true);
  
                  Toast.makeText(getApplicationContext(), "Recording started", Toast.LENGTH_LONG).show();
  
              }
          });
  
          buttonStop.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  buttonStop.setEnabled(false);
                  if (null != recorder){
                      isRecording = false;
  
                      int i = recorder.getState();
                      if (i==1)
                          recorder.stop();
                      recorder.release();
  
                      recorder = null;
                      recordingThread = null;
                  }
                  filePath = getFilename();
                  copyWaveFile(getTempFilename(),filePath);
                  deleteTempFile();
  
                  Toast.makeText(getApplicationContext(), "Recording Completed", Toast.LENGTH_LONG).show();
                  buttonStart.setEnabled(true);
                  buttonPlay.setEnabled(true);
                  buttonDecode.setEnabled(true);
              }
          });
  
          buttonPlay.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  buttonStart.setEnabled(false);
                  buttonDecode.setEnabled(false);
                  buttonPlay.setEnabled(false);
                  Toast.makeText(getApplicationContext(), "Recording Playing", Toast.LENGTH_LONG).show();
  
                  //play code
                  File wavfile = new File(filePath);
                  Uri myUri1 = Uri.fromFile(wavfile);
                  final MediaPlayer mPlayer = new MediaPlayer();
                  mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
  
                  try {
                      mPlayer.setDataSource(getApplicationContext(), myUri1);
                  } catch (IllegalArgumentException e) {
                      Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
                  } catch (SecurityException e) {
                      Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
                  } catch (IllegalStateException e) {
                      Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
                  } catch (IOException e) {
                      e.printStackTrace();
                  }
  
                  try {
                      mPlayer.prepare();
                  } catch (IllegalStateException e) {
                      Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
                  } catch (IOException e) {
                      Toast.makeText(getApplicationContext(), "You might not set the URI correctly!", Toast.LENGTH_LONG).show();
                  }
  
                  mPlayer.start();
  
                  buttonStart.setEnabled(true);
                  buttonDecode.setEnabled(true);
                  buttonPlay.setEnabled(true);
              }
          });
  
          buttonDecode.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  buttonStart.setEnabled(false);
                  buttonDecode.setEnabled(false);
                  buttonPlay.setEnabled(false);
  
                  //read raw data from wav file
  
                  buttonStart.setEnabled(true);
                  buttonDecode.setEnabled(true);
                  buttonPlay.setEnabled(true);
              }
          });
  
          //Code for the back button
          Button backbuttonR = (Button) findViewById(R.id.backbuttonR);
          backbuttonR.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View view) {
                  startActivity(new Intent(ReceiveScreen.this, MainActivity.class));
              }
          });
  
      }
  
      private String getFilename(){
          String filepath = Environment.getExternalStorageDirectory().getPath();
          File file = new File(filepath,AUDIO_RECORDER_FOLDER);
          System.out.println(file.getAbsolutePath() + "/" + System.currentTimeMillis() + AUDIO_RECORDER_FILE_EXT_WAV);
          if (!file.exists()) {
              file.mkdirs();
          }
  
          return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + AUDIO_RECORDER_FILE_EXT_WAV);
      }
  
      private String getTempFilename() {
          String filepath = Environment.getExternalStorageDirectory().getPath();
          File file = new File(filepath,AUDIO_RECORDER_FOLDER);
  
          if (!file.exists()) {
              file.mkdirs();
          }
  
          File tempFile = new File(filepath,AUDIO_RECORDER_TEMP_FILE);
  
          if (tempFile.exists())
              tempFile.delete();
  
          return (file.getAbsolutePath() + "/" + AUDIO_RECORDER_TEMP_FILE);
      }
  
      private void writeAudioDataToFile() {
          byte data[] = new byte[bufferSize];
          String filename = getTempFilename();
          FileOutputStream os = null;
  
          try {
              os = new FileOutputStream(filename);
          } catch (FileNotFoundException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
  
          int read = 0;
          if (null != os) {
              while(isRecording) {
                  read = recorder.read(data, 0, bufferSize);
                  if (read &gt; 0){
                  }
  
                  if (AudioRecord.ERROR_INVALID_OPERATION != read) {
                      try {
                          os.write(data);
                      } catch (IOException e) {
                          e.printStackTrace();
                      }
                  }
              }
  
              try {
                  os.close();
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }
  
      private void deleteTempFile() {
          File file = new File(getTempFilename());
          file.delete();
      }
  
      private void copyWaveFile(String inFilename,String outFilename){
          FileInputStream in = null;
          FileOutputStream out = null;
          long totalAudioLen = 0;
          long totalDataLen = totalAudioLen + 36;
          long longSampleRate = RECORDER_SAMPLERATE;
          int channels = 2;
          long byteRate = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8;
  
          byte[] data = new byte[bufferSize];
  
          try {
              in = new FileInputStream(inFilename);
              out = new FileOutputStream(outFilename);
              totalAudioLen = in.getChannel().size();
              totalDataLen = totalAudioLen + 36;
  
              System.out.println("File size: " + totalDataLen);
  
              WriteWaveFileHeader(out, totalAudioLen, totalDataLen,
                      longSampleRate, channels, byteRate);
  
              while(in.read(data) != -1) {
                  out.write(data);
              }
  
              in.close();
              out.close();
          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  
      private void WriteWaveFileHeader(
              FileOutputStream out, long totalAudioLen,
              long totalDataLen, long longSampleRate, int channels,
              long byteRate) throws IOException
      {
          byte[] header = new byte[44];
  
          header[0] = 'R';  // RIFF/WAVE header
          header[1] = 'I';
          header[2] = 'F';
          header[3] = 'F';
          header[4] = (byte) (totalDataLen &amp; 0xff);
          header[5] = (byte) ((totalDataLen &gt;&gt; 8) &amp; 0xff);
          header[6] = (byte) ((totalDataLen &gt;&gt; 16) &amp; 0xff);
          header[7] = (byte) ((totalDataLen &gt;&gt; 24) &amp; 0xff);
          header[8] = 'W';
          header[9] = 'A';
          header[10] = 'V';
          header[11] = 'E';
          header[12] = 'f';  // 'fmt ' chunk
          header[13] = 'm';
          header[14] = 't';
          header[15] = ' ';
          header[16] = 16;  // 4 bytes: size of 'fmt ' chunk
          header[17] = 0;
          header[18] = 0;
          header[19] = 0;
          header[20] = 1;  // format = 1
          header[21] = 0;
          header[22] = (byte) channels;
          header[23] = 0;
          header[24] = (byte) (longSampleRate &amp; 0xff);
          header[25] = (byte) ((longSampleRate &gt;&gt; 8) &amp; 0xff);
          header[26] = (byte) ((longSampleRate &gt;&gt; 16) &amp; 0xff);
          header[27] = (byte) ((longSampleRate &gt;&gt; 24) &amp; 0xff);
          header[28] = (byte) (byteRate &amp; 0xff);
          header[29] = (byte) ((byteRate &gt;&gt; 8) &amp; 0xff);
          header[30] = (byte) ((byteRate &gt;&gt; 16) &amp; 0xff);
          header[31] = (byte) ((byteRate &gt;&gt; 24) &amp; 0xff);
          header[32] = (byte) (2 * 16 / 8);  // block align
          header[33] = 0;
          header[34] = RECORDER_BPP;  // bits per sample
          header[35] = 0;
          header[36] = 'd';
          header[37] = 'a';
          header[38] = 't';
          header[39] = 'a';
          header[40] = (byte) (totalAudioLen &amp; 0xff);
          header[41] = (byte) ((totalAudioLen &gt;&gt; 8) &amp; 0xff);
          header[42] = (byte) ((totalAudioLen &gt;&gt; 16) &amp; 0xff);
          header[43] = (byte) ((totalAudioLen &gt;&gt; 24) &amp; 0xff);
  
          out.write(header, 0, 44);
      }
  
      /*public class SoundPoolPlayer {
          private SoundPool mShortPlayer= null;
          private HashMap mSounds = new HashMap();
  
          public SoundPoolPlayer(Context pContext)
          {
              // setup Soundpool
              this.mShortPlayer = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);
  
  
              mSounds.put(R.raw.&lt;sound_1_name&gt;, this.mShortPlayer.load(pContext, R.raw.&lt;sound_1_name&gt;, 1));
              mSounds.put(R.raw.&lt;sound_2_name&gt;, this.mShortPlayer.load(pContext, R.raw.&lt;sound_2_name&gt;, 1));
          }
  
          public void playShortResource(int piResource) {
              int iSoundId = (Integer) mSounds.get(piResource);
              this.mShortPlayer.play(iSoundId, 0.99f, 0.99f, 0, 0, 1);
          }
  
          // Cleanup
          public void release() {
              // Cleanup
              this.mShortPlayer.release();
              this.mShortPlayer = null;
          }
      }*/
  
      public static final class Complex {
          // The number stored is x+I*y.
          final private double x, y;
          // I don't want to allow anyone to access these numbers so I've labeled
          // them private.
  
          /** Construct a point from real and imaginary parts. */
          public Complex(double real_part, double imaginary_part) {
              x=real_part;
              y=imaginary_part;
          }
  
          /** Construct a real number. */
          public Complex(double real_part) {
              x=real_part;
              y=0;
          }
  
          // A static constructor.
  
          /** Construct a complex number from the given polar coordinates. */
          public static Complex fromPolar(double r, double theta) {
              return new Complex(r*Math.cos(theta), r*Math.sin(theta));
          }
  
          // Basic operations on Complex numbers.
  
          /** Return the real part. */
          public double re(){
              return x;
          }
  
          /** Return the imaginary part. */
          public double im(){
              return y;
          }
  
          /** Return the complex conjugate */
          public Complex conj() {
              return new Complex(x,-y);
          }
  
          /** Return the square of the absolute value. */
          public double absSquared() {
              return x*x+y*y;
          }
  
          /** Return the absolute value. */
          public double abs() {
              // The java.lang.Math package contains many useful mathematical functions,
              // including the square root function.
              return Math.sqrt(absSquared());
          }
  
          // ARITHMETIC
  
          /** Add a complex number to this one.
           *
           * @param z The complex number to be added.
           * @return A new complex number which is the sum.
           */
          public Complex add(Complex z) {
              return new Complex(x+z.x, y+z.y);
          }
  
          /** Subtract a complex number from this one.
           *
           * @param z The complex number to be subtracted.
           * @return A new complex number which is the sum.
           */
          public Complex minus(Complex z) {
              return new Complex(x-z.x, y-z.y);
          }
  
          /** Negate this complex number.
           *
           * @return The negation.
           */
          public Complex neg() {
              return new Complex(-x, -y);
          }
  
          /** Compute the product of two complex numbers
           *
           * @param z The complex number to be multiplied.
           * @return A new complex number which is the product.
           */
          public Complex mult(Complex z) {
              return new Complex(x*z.x-y*z.y, x*z.y+z.x*y);
          }
  
          /** Divide this complex number by a real number.
           *
           * @param q The number to divide by.
           * @return A new complex number representing the quotient.
           */
          public Complex div(double q) {
              return new Complex(x/q,y/q);
          }
  
          /** Return the multiplicative inverse. */
          public Complex inv() {
              // find the square of the absolute value of this complex number.
              double abs_squared=absSquared();
              return new Complex(x/abs_squared, -y/abs_squared);
          }
  
          /** Compute the quotient of two complex numbers.
           *
           * @param z The complex number to divide this one by.
           * @return A new complex number which is the quotient.
           */
          public Complex div(Complex z) {
              return mult(z.inv());
          }
  
          /** Return the complex exponential of this complex number. */
          public Complex exp() {
              return new Complex(Math.exp(x)*Math.cos(y),Math.exp(x)*Math.sin(y));
          }
  
  
          // FUNCTIONS WHICH KEEP JAVA HAPPY:
  
          /** Returns this point as a string.
           * The main purpose of this function is for printing the string out,
           * so we return a string in a (fairly) human readable format.
           */
          // The _optional_ override directive "@Override" below just says we are
          // overriding a function defined in a parent class. In this case, the
          // parent is java.lang.Object. All classes in Java have the Object class
          // as a superclass.
          @Override
          public String toString() {
              // Comments:
              // 1) "" represents the empty string.
              // 2) If you add something to a string, it converts the thing you
              // are adding to a string, and then concatentates it with the string.
  
              // We do some voodoo to make sure the number is displayed reasonably.
              if (y==0) {
                  return ""+x;
              }
              if (y&gt;0) {
                  return ""+x+"+"+y+"*I";
              }
              // otherwise y&lt;0.
              return ""+x+"-"+(-y)+"*I";
          }
  
          /** Return true if the object is a complex number which is equal to this complex number. */
          @Override
          public boolean equals(Object obj) {
              // Return false if the object is null
              if (obj == null) {
                  return false;
              }
              // Return false if the object is not a Complex number
              if (!(obj instanceof Complex)) {
                  return false;
              }
  
              // Now the object must be a Complex number, so we can convert it to a
              // Complex number.
              Complex other = (Complex) obj;
  
              // If the x-coordinates are not equal, then return false.
              if (x != other.x) {
                  return false;
              }
              // If the y-coordinates are not equal, then return false.
              if (y != other.y) {
                  return false;
              }
              // Both parts are equal, so return true.
              return true;
          }
  
          // Remark: In Java, we should really override the hashcode function
          // whenever we override the equals function. But, I don't want to
          // get into this for a light introduction to programming in java.
          // Hash codes are necessary for various of Java's collections. See HashSet for instance.
          // The following was generated by Netbeans.
          @Override
          public int hashCode() {
              int hash = 3;
              hash = 83 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) &gt;&gt;&gt; 32));
              hash = 83 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) &gt;&gt;&gt; 32));
              return hash;
          }
      }
  }
  </code></pre>