title: Wav file recorded using AudioRecord sounds speeded up and skips frames when replaying
body: <p>I am using AudioRecord to read microphone data and RandomAccessFile to write it to a wav file. This is the code:  </p>
  
  <pre><code>public class MainActivity extends Activity {
      AudioManager am = null;
      AudioRecord record =null;
      // AudioTrack track =null;
      final int SAMPLE_FREQUENCY = 44100;
      final int SIZE_OF_RECORD_ARRAY = 1024;  // 1024 ORIGINAL
      final int WAV_SAMPLE_MULTIPLICATION_FACTOR = 1;
      int i= 0;
      boolean isPlaying = false;
      private volatile boolean keepThreadRunning;
  //  private RandomAccessFile stateFile, stateFileTemp, savToDisk;
      private RandomAccessFile savToDisk;
      private FileDescriptor fd = new FileDescriptor(); 
      private File delFile, renFile;
      String stateFileLoc = Environment.getExternalStorageDirectory().getPath(); 
      // To keep hederWriter() happy
      private short nChannels = 1;
      private int sRate = SAMPLE_FREQUENCY;
      private short mBitsPersample = 16; // represents 16 bits of one PCM sample
      private int payload;
  
      class MyThread extends Thread{
          private volatile boolean needsToPassThrough;
          // /*
          MyThread(){
              super();
          }
  
          MyThread(boolean newPTV){
              this.needsToPassThrough = newPTV;
          }
          // */
  
          // /*
          @Override
          public void run(){
               short[] lin = new short[SIZE_OF_RECORD_ARRAY];
              // byte[] lin = new byte[SIZE_OF_RECORD_ARRAY];
              int num = 0;
              // /*
              if(needsToPassThrough){
                  record.startRecording();
                  // track.play();
              }
              // */
              while (keepThreadRunning) {
              // while (!isInterrupted()) {
                  // num = record.read(lin, 0, SIZE_OF_RECORD_ARRAY);
                  num = record.read(lin, 0, lin.length);
                  try {
                      // savToDisk.write(lin); // use only this line if lin is a byte array
  
                      // use the for loop block below if lin is an array of short
                      for(i=0;i &lt;lin.length; i++)
                          savToDisk.writeShort(Short.reverseBytes(lin[i]));
  
                      // payload += lin.length; // use this line if lin is an array of byte
                      payload = payload + (lin.length)*2;
                      fd.sync();
                  } catch (IOException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
                  /*
                  catch (SyncFailedException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
                  */
              }
              // /*
              record.stop();
              // track.stop();
              record.release();
              // track.release();
              // */
          }
          // */
  
          // /*
          public void stopThread(){
              keepThreadRunning = false;
          }
          // */
      }
  
      MyThread newThread;
  
      private void init() {
          int min = AudioRecord.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
          // Toast.makeText(getApplicationContext(), Integer.toString(min), Toast.LENGTH_SHORT).show(); // Shows 4096
          record = new AudioRecord(MediaRecorder.AudioSource.VOICE_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_IN_MONO,
                                   AudioFormat.ENCODING_PCM_16BIT, min);
          // int maxJitter = AudioTrack.getMinBufferSize(SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT);
          // track = new AudioTrack(AudioManager.MODE_IN_COMMUNICATION, SAMPLE_FREQUENCY, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, maxJitter, AudioTrack.MODE_STREAM);
          am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
          am.setMode(AudioManager.MODE_IN_COMMUNICATION);
  
          try {
              savToDisk = new RandomAccessFile(stateFileLoc+"/audSampData.wav", "rw");
  
          } catch (FileNotFoundException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
  
          try {
              fd = savToDisk.getFD();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } 
  
      }
  
      private void writeHeader(){
          try {
              savToDisk.setLength(0); // Set file length to 0, to prevent unexpected behavior in case the file already existed
              savToDisk.writeBytes("RIFF");
              savToDisk.writeInt(0); // Final file size not known yet, write 0 
              savToDisk.writeBytes("WAVE");
              savToDisk.writeBytes("fmt ");
              savToDisk.writeInt(Integer.reverseBytes(16)); // Sub-chunk size, 16 for PCM
              savToDisk.writeShort(Short.reverseBytes((short) 1)); // AudioFormat, 1 for PCM
              savToDisk.writeShort(Short.reverseBytes(nChannels));// Number of channels, 1 for mono, 2 for stereo
              savToDisk.writeInt(Integer.reverseBytes(sRate)); // Sample rate
              savToDisk.writeInt(Integer.reverseBytes(sRate*nChannels*mBitsPersample/8)); // Byte rate, SampleRate*NumberOfChannels*mBitsPersample/8
              savToDisk.writeShort(Short.reverseBytes((short)(nChannels*mBitsPersample/8))); // Block align, NumberOfChannels*mBitsPersample/8
              savToDisk.writeShort(Short.reverseBytes(mBitsPersample)); // Bits per sample
              savToDisk.writeBytes("data");
              savToDisk.writeInt(0); // Data chunk size not known yet, write 0
              fd.sync();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
      }
  
      @Override
      protected void onResume(){
          super.onResume();
          // newThread.stopThread();
          Log.d("MYLOG", "onResume() called");
          init();
          writeHeader();
          keepThreadRunning = true;
          // */
  
  
          // newThread = new MyThread(true);
          newThread = new MyThread(isPlaying);
          newThread.start();
  
      }
  
      @Override
      protected void onPause(){
          super.onPause();
          Log.d("MYLOG", "onPause() called");
          newThread.stopThread();
          // android.os.Process.killProcess(android.os.Process.myPid());
          try {
              savToDisk.seek(4);
              savToDisk.writeInt(Integer.reverseBytes(36+payload));
              savToDisk.seek(40);
              savToDisk.writeInt(Integer.reverseBytes(payload));
              savToDisk.close();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
  
      }
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          setVolumeControlStream(AudioManager.MODE_IN_COMMUNICATION);
          payload = 0;
          Log.d("MYLOG","onCreate() called");
      }
  
      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.main, menu);
          return true;
      }
  
      @Override
      protected void onDestroy() {
          super.onDestroy();
          newThread.stopThread();
          // android.os.Process.killProcess(android.os.Process.myPid());
          // killProcess(android.os.Process.myPid());
          // newThread.interrupt();
          // delFile.delete();
           Log.d("MYLOG", "onDestroy() called");
           /*
           try {
              savToDisk.close();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
          */
      }
  
      public void passStop(View view){
          Button playBtn = (Button) findViewById(R.id.button1);  
          // /*
          if(!isPlaying){
              record.startRecording();
              // track.play();
              isPlaying = true;
              playBtn.setText("Pause");
          }
          else{
             record.stop();
             // track.pause();
             isPlaying=false;
             playBtn.setText("Pass through");
          }
          // */
      }
  
  
  
  }  
  </code></pre>
  
  <p>When I play the wav file in an audio player, it sounds speeded up, and also seems to skip frames. What could be the reasons for this? I believe the skipping frames problem is probably due to the fact that I have used <code>writeShort()</code> function to write out each element of the short array that stores the audio sample data separately, but if that is the case please suggest a workaround to it that involves writing data as shorts (and not using the <code>write(byte[])</code> function, because I need to use parts of this code in my main project which involves obtaining audio samples in a short array). Also why is it speeded up?</p>