2015-05-19 19 views
5

Tôi đã triển khai tính năng ghi âm trong ứng dụng Android của mình. Ứng dụng của tôi hoạt động tốt trên Linux. nhưng khi tôi chạy cùng một ứng dụng trong mac osx và ghi âm, nó bị treo ứng dụng của tôi.Android - Làm thế nào để chuyển đổi dữ liệu thô của âm thanh sang wav?

 private AudioRecordingThread recordingThread; 

     recordingThread = new AudioRecordingThread(fileName, 
      new AudioRecordingHandler() { 
       @Override 
       public void onFftDataCapture(final byte[] bytes) { 
        runOnUiThread(new Runnable() { 
         public void run() { 
          if (visualizerView != null) { 
           visualizerView.updateVisualizerFFT(bytes); 
          } 
         } 
        }); 
       } 

       @Override 
       public void onRecordSuccess() { 
       } 

       @Override 
       public void onRecordingError() { 
        runOnUiThread(new Runnable() { 
         public void run() { 
          recordStop(); 
          NotificationUtils.showInfoDialog(
            ActivityCropImage.this, 
            "Error in saving"); 
         } 
        }); 
       } 

       @Override 
       public void onRecordSaveError() { 
        runOnUiThread(new Runnable() { 
         public void run() { 
          recordStop(); 
          NotificationUtils.showInfoDialog(
            ActivityCropImage.this, 
            "Error in recording"); 
         } 
        }); 
       } 
      }); 
     PcmAudioHelper.convertRawToWav(WavAudioFormat.mono16Bit(SAMPLING_RATE), file_raw, file_wav); 

Đây là dòng mã mà ứng dụng của tôi gặp sự cố. Tôi đã sử dụng thư viện https://github.com/steelkiwi/AndroidRecording trong dự án của mình.

+0

Bạn giải quyết vấn đề đó. Đối với vấn đề của bạn, tôi đã kiểm tra và nó có thể ghi lại. Tuy nhiên, nếu tôi thay đổi kiểu trực quan như circlerenderer. Nó không hoạt động. Bạn có cùng một vấn đề? – Jame

Trả lời

7
package com.record.util; 

import android.media.AudioFormat; 
import android.media.AudioRecord; 
import android.media.MediaRecorder; 
import android.os.Environment; 
import android.text.format.Time; 
import android.util.Log; 

import java.io.BufferedOutputStream; 
import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 

public class RecordWavMaster { 
    private static final int samplingRates[] = {16000, 11025, 11000, 8000, 6000}; 
    public static int SAMPLE_RATE = 16000; 
    private AudioRecord mRecorder; 
    private File mRecording; 
    private short[] mBuffer; 
    private String audioFilePath; 
    private boolean mIsRecording = false; 
    private String RECORD_WAV_PATH = Environment.getExternalStorageDirectory() + File.separator + "AudioRecord"; 

    /* Initializing AudioRecording MIC */ 
    public RecordWavMaster() { 
     initRecorder(); 
    } 

    /* Get Supported Sample Rate */ 
    public static int getValidSampleRates() { 
     for (int rate : samplingRates) { 
      int bufferSize = AudioRecord.getMinBufferSize(rate, AudioFormat.CHANNEL_CONFIGURATION_DEFAULT, AudioFormat.ENCODING_PCM_16BIT); 
      if (bufferSize > 0) { 
       return rate; 
      } 
     } 
     return SAMPLE_RATE; 
    } 

    /* Start AudioRecording */ 
    public void recordWavStart() { 
     mIsRecording = true; 
     mRecorder.startRecording(); 
     mRecording = getFile("raw"); 
     startBufferedWrite(mRecording); 
    } 

    /* Stop AudioRecording */ 
    public String recordWavStop() { 
     try { 
      mIsRecording = false; 
      mRecorder.stop(); 
      File waveFile = getFile("wav"); 
      rawToWave(mRecording, waveFile); 
      Log.e("path_audioFilePath",audioFilePath); 
      return audioFilePath; 
     } catch (Exception e) { 
      Log.e("Error saving file : ", e.getMessage()); 
     } 
     return null; 
    } 

    /* Release device MIC */ 
    public void releaseRecord() { 
     mRecorder.release(); 
    } 

    /* Initializing AudioRecording MIC */ 
    private void initRecorder() { 
     SAMPLE_RATE = getValidSampleRates(); 
     int bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, 
       AudioFormat.ENCODING_PCM_16BIT); 
     mBuffer = new short[bufferSize]; 
     mRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, 
       AudioFormat.ENCODING_PCM_16BIT, bufferSize); 
     new File(RECORD_WAV_PATH).mkdir(); 
    } 

    /* Writing RAW file */ 
    private void startBufferedWrite(final File file) { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       DataOutputStream output = null; 
       try { 
        output = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))); 
        while (mIsRecording) { 
         double sum = 0; 
         int readSize = mRecorder.read(mBuffer, 0, mBuffer.length); 
         for (int i = 0; i < readSize; i++) { 
          output.writeShort(mBuffer[i]); 
          sum += mBuffer[i] * mBuffer[i]; 
         } 
         if (readSize > 0) { 
          final double amplitude = sum/readSize; 
         } 
        } 
       } catch (IOException e) { 
        Log.e("Error writing file : ", e.getMessage()); 
       } finally { 

        if (output != null) { 
         try { 
          output.flush(); 
         } catch (IOException e) { 
          Log.e("Error writing file : ", e.getMessage()); 
         } finally { 
          try { 
           output.close(); 
          } catch (IOException e) { 
           Log.e("Error writing file : ", e.getMessage()); 
          } 
         } 
        } 
       } 
      } 
     }).start(); 
    } 

    /* Converting RAW format To WAV Format*/ 
    private void rawToWave(final File rawFile, final File waveFile) throws IOException { 

     byte[] rawData = new byte[(int) rawFile.length()]; 
     DataInputStream input = null; 
     try { 
      input = new DataInputStream(new FileInputStream(rawFile)); 
      input.read(rawData); 
     } finally { 
      if (input != null) { 
       input.close(); 
      } 
     } 
     DataOutputStream output = null; 
     try { 
      output = new DataOutputStream(new FileOutputStream(waveFile)); 
      // WAVE header 
      writeString(output, "RIFF"); // chunk id 
      writeInt(output, 36 + rawData.length); // chunk size 
      writeString(output, "WAVE"); // format 
      writeString(output, "fmt "); // subchunk 1 id 
      writeInt(output, 16); // subchunk 1 size 
      writeShort(output, (short) 1); // audio format (1 = PCM) 
      writeShort(output, (short) 1); // number of channels 
      writeInt(output, SAMPLE_RATE); // sample rate 
      writeInt(output, SAMPLE_RATE * 2); // byte rate 
      writeShort(output, (short) 2); // block align 
      writeShort(output, (short) 16); // bits per sample 
      writeString(output, "data"); // subchunk 2 id 
      writeInt(output, rawData.length); // subchunk 2 size 
      // Audio data (conversion big endian -> little endian) 
      short[] shorts = new short[rawData.length/2]; 
      ByteBuffer.wrap(rawData).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shorts); 
      ByteBuffer bytes = ByteBuffer.allocate(shorts.length * 2); 
      for (short s : shorts) { 
       bytes.putShort(s); 
      } 
      output.write(bytes.array()); 
     } finally { 
      if (output != null) { 
       output.close(); 
       rawFile.delete(); 
      } 
     } 


    } 

    /* Get file name */ 
    private File getFile(final String suffix) { 
     Time time = new Time(); 
     time.setToNow(); 
     audioFilePath = time.format("%Y%m%d%H%M%S"); 
     return new File(RECORD_WAV_PATH, time.format("%Y%m%d%H%M%S") + "." + suffix); 
    } 

    private void writeInt(final DataOutputStream output, final int value) throws IOException { 
     output.write(value >> 0); 
     output.write(value >> 8); 
     output.write(value >> 16); 
     output.write(value >> 24); 
    } 

    private void writeShort(final DataOutputStream output, final short value) throws IOException { 
     output.write(value >> 0); 
     output.write(value >> 8); 
    } 

    private void writeString(final DataOutputStream output, final String value) throws IOException { 
     for (int i = 0; i < value.length(); i++) { 
      output.write(value.charAt(i)); 
     } 
    } 

    public String getFileName (final String time_suffix) { 
     return (RECORD_WAV_PATH+time_suffix+ "." + "wav"); 
    } 

    public Boolean getRecordingState() { 
     if( mRecorder.getRecordingState() == AudioRecord.RECORDSTATE_STOPPED) { 
     return false; 
     } 
     return true; 
    } 
} 

Sử dụng các điều khoản sau đây trong manifest

<!--Permission record--> 
    <uses-permission android:name="android.permission.RECORD_AUDIO" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
+3

Đây là ví dụ tốt nhất về việc lưu AudioRecord vào một tệp WAV trong toàn bộ SO. Mã này chỉ hoạt động. Xấu hổ rằng nó bị chôn vùi dưới một câu hỏi tồi tệ như vậy. – ktorn

+0

Cảm ơn câu trả lời, tôi đã sử dụng phương thức 'rawToWave' để chỉ nhận xét' .order (ByteOrder.LITTLE_ENDIAN) 'và nó hoạt động hoàn hảo trong trường hợp của tôi. –

Các vấn đề liên quan