2015-03-24 8 views
2

Я использую AudioRecord для записи аудио в wav-файлах. Я выполняю операцию read() в цикле вторичного потока, и данные передаются в очередь в другую секунду. поток для записи в файл.AudioRecord иногда пропускает аудиоданные

Вопрос заключается в следующем: Когда я выбираю, чтобы сохранить аудиоданные во внешней SD-карты, аудио содержит некоторые millisc скипов/искажения (только иногда). Другие пользователи имеют эту проблему при сохранении на внутренней карте памяти SD слишком

Это, как я создаю экземпляр объекта AudioRecord:

initBufferSize = assureMinBufferSize(); 
if (minBufferSize == AudioRecord.ERROR_BAD_VALUE) { 
    throw new Exception("" + ErrorCodes.ERROR_CODE_0); 
} 
else if (minBufferSize == AudioRecord.ERROR) { 
    throw new Exception("" + ErrorCodes.ERROR_CODE_0); 
} 

buffer = new byte[initBufferSize]; 
aRecorder = new AudioRecord(mSource, sRate, nChannel, AudioFormat.ENCODING_PCM_16BIT, initBufferSize); 

и это, как я объединить объект AudioRecorder:

private class AudioReaderRunnable implements Runnable { 
    private volatile boolean stopped; 

    @Override 
    public void run() {       
     while (!stopped) { 
      while(mState == State.RECORDING){ 
       read(); 
      } 
     }   

     Log.i(getClass().getName(), "AudioReade thread stopped!"); 
    } 

    private void read(){ 

     if(aRecorder == null) 
      return; 

     // "dirty" patch for some null crash for some users 
     if(buffer == null) 
      buffer = new byte[initBufferSize]; 

     //int x = aRecorder.read(buffer, 0, buffer.length); 
     int x = readFully(buffer, 0, buffer.length); 
     if(x <= 0) 
      return; 

     payloadSize += x; 

     mWavData.arrayCopy(buffer); 

     mWavData.setGain(rGain); 
     mWavData.setBitsPerSamples(bitsPerSample); 
     mWavData.setNrChannels(nChannelsNumber); 

     // send audio to another thread for writing 
     mAudioWritter.add(audioData);    
    } 

    private int readFully(byte[] data, int off, int length) { 
     int read = 0; 
     int result = 0; 
     int requestedSize = length; 

     if(aRecorder == null){ 
      return read; 
     } 

     try {   
      result = aRecorder.read(data, off, requestedSize); 
     } catch (Exception e) { 
      Log.e(getClass().getName(), e.getMessage(), e); 
      if(aRecorder == null) 
       return read; 
     } 

     read = result; 

     while (requestedSize != result && !stopped) { 
      if(aRecorder == null) 
       return read; 

      requestedSize -= result;     
      try { 
       result = aRecorder.read(data, result - 1, requestedSize); 
      } catch (Exception e) { 
       Log.e(getClass().getName(), e.getMessage(), e); 
       if(aRecorder == null) 
        return read; 
      } 
      read += result; 
     } 

     return read; 
    } 

    public void stopThread() { 
     stopped = true; 
    } 
} 
+0

Запись - отличная работа в формате WAV в формате? – cyberlobe

+0

@cyberlobe - да, формат WAV –

+0

У меня есть рабочий код со мной, но код отличается. Хочешь попробовать? – cyberlobe

ответ

1
Try This Code:- 

//This Variable are define in class 

private int recordingcounter; 
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 = 16000;// /44100; //High voice 
                  // recording result 
                  // for use sample 
                  // rate is 44100 
private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_STEREO; 
private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 

private AudioRecord recorder = null; 
private int bufferSize = 0; 
private Thread recordingThread = null; 
private boolean isRecording = false; 


//--------------------- start button click event in add-----------------------------------// 

bufferSize = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, RECORDER_CHANNELS,RECORDER_AUDIO_ENCODING); 

try { 

            startRecording(); 

           } catch (Exception e) { 
            // TODO: handle exception 

            // Toast.makeText(RecordingActivity.this, 
            // e.getMessage(), Toast.LENGTH_SHORT) 
            // .show(); 

           } 







//-------------------- stop button click event in add---------------------------// 

try { 

           stopRecording(); 

          } catch (Exception e) { 
           // TODO: handle exception 
           e.printStackTrace(); 
          } 






//---------this methods are add in your class-----------------------------// 



// --------------------------------------------------------Sound Recording 
    // Code----------------------------------------------------// 

    private String getFilename() { 
     String filepath = Environment.getExternalStorageDirectory().getPath(); 
     File file = new File(filepath, AUDIO_RECORDER_FOLDER); 

     if (!file.exists()) { 
      file.mkdirs(); 
     } 

     return (file.getAbsolutePath() + "/" + "voiceFile" + 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); 
    } 

    @SuppressLint("NewApi") 
    private void startRecording() { 
     recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
       RECORDER_SAMPLERATE, RECORDER_CHANNELS, 
       RECORDER_AUDIO_ENCODING, bufferSize); 

     recorder.startRecording(); 

     // Log.e("Audio session", ""+recorder.getAudioSessionId()); 

     isRecording = true; 

     recordingThread = new Thread(new Runnable() { 

      @Override 
      public void run() { 
       writeAudioDataToFile(); 
      } 
     }, "AudioRecorder Thread"); 

     recordingThread.start(); 
    } 

    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 (AudioRecord.ERROR_INVALID_OPERATION != read) { 
        try { 
         os.write(data); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
      } 

      try { 
       os.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    private void stopRecording() { 
     if (null != recorder) { 
      isRecording = false; 

      recorder.stop(); 
      recorder.release(); 

      // Utility.Log("", "" + recorder.getRecordingState()); 

      // AppLog.logString(""+recorder.getRecordingState()); 

      recorder = null; 
      recordingThread = null; 

     } 

     copyWaveFile(getTempFilename(), getFilename()); 

    } 



    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; 

      // Utility.Log("", "File size: " + totalDataLen); 

      // AppLog.logString("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 & 0xff); 
     header[5] = (byte) ((totalDataLen >> 8) & 0xff); 
     header[6] = (byte) ((totalDataLen >> 16) & 0xff); 
     header[7] = (byte) ((totalDataLen >> 24) & 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 & 0xff); 
     header[25] = (byte) ((longSampleRate >> 8) & 0xff); 
     header[26] = (byte) ((longSampleRate >> 16) & 0xff); 
     header[27] = (byte) ((longSampleRate >> 24) & 0xff); 
     header[28] = (byte) (byteRate & 0xff); 
     header[29] = (byte) ((byteRate >> 8) & 0xff); 
     header[30] = (byte) ((byteRate >> 16) & 0xff); 
     header[31] = (byte) ((byteRate >> 24) & 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 & 0xff); 
     header[41] = (byte) ((totalAudioLen >> 8) & 0xff); 
     header[42] = (byte) ((totalAudioLen >> 16) & 0xff); 
     header[43] = (byte) ((totalAudioLen >> 24) & 0xff); 

     out.write(header, 0, 44); 
    } 

// ---------- и файл манифеста этой строки ------------- //

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 


<uses-permission android:name="android.permission.RECORD_AUDIO" /> 
+0

Спасибо, что разместили это. Я создам другое приложение (только для теста) и интегрирую свой код. Не могли бы вы объяснить, почему вы храните аудиоданные во временном файле и копируете их в другой, когда запись завершена? –

 Смежные вопросы

  • Нет связанных вопросов^_^