2011-12-14 56 views
47

Tôi đang thiết kế một ứng dụng Android và tôi cần triển khai lớp AudioRecord để ghi lại âm thanh của người dùng. Sau khi một số nghiên cứu (không cung cấp đủ thông tin) và một vài lần thất bại, tôi đã tự hỏi liệu có ai có thể giúp tôi bằng cách đăng một ví dụ (mã) về cách ghi lại âm thanh chất lượng cao bằng AudioRecord hay không. Tôi thực sự sẽ đánh giá cao nó. Cảm ơn bạnVí dụ về Android AudioRecord

Trả lời

74

Ở đây tôi đăng cho bạn một số ví dụ về mã ghi lại chất lượng âm thanh tốt bằng cách sử dụng AudioRecord API.

Lưu ý: Nếu bạn sử dụng trong trình mô phỏng, chất lượng âm thanh sẽ không tốt vì chúng tôi đang sử dụng tỷ lệ mẫu 8k chỉ hỗ trợ trong trình mô phỏng. Trong thiết bị sử dụng tỷ lệ mẫu đến 44.1k cho chất lượng tốt hơn.

public class Audio_Record extends Activity { 
    private static final int RECORDER_SAMPLERATE = 8000; 
    private static final int RECORDER_CHANNELS = AudioFormat.CHANNEL_IN_MONO; 
    private static final int RECORDER_AUDIO_ENCODING = AudioFormat.ENCODING_PCM_16BIT; 
    private AudioRecord recorder = null; 
    private Thread recordingThread = null; 
    private boolean isRecording = false; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     setButtonHandlers(); 
     enableButtons(false); 

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

    private void setButtonHandlers() { 
     ((Button) findViewById(R.id.btnStart)).setOnClickListener(btnClick); 
     ((Button) findViewById(R.id.btnStop)).setOnClickListener(btnClick); 
    } 

    private void enableButton(int id, boolean isEnable) { 
     ((Button) findViewById(id)).setEnabled(isEnable); 
    } 

    private void enableButtons(boolean isRecording) { 
     enableButton(R.id.btnStart, !isRecording); 
     enableButton(R.id.btnStop, isRecording); 
    } 

    int BufferElements2Rec = 1024; // want to play 2048 (2K) since 2 bytes we use only 1024 
    int BytesPerElement = 2; // 2 bytes in 16bit format 

    private void startRecording() { 

     recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
       RECORDER_SAMPLERATE, RECORDER_CHANNELS, 
       RECORDER_AUDIO_ENCODING, BufferElements2Rec * BytesPerElement); 

     recorder.startRecording(); 
     isRecording = true; 
     recordingThread = new Thread(new Runnable() { 
      public void run() { 
       writeAudioDataToFile(); 
      } 
     }, "AudioRecorder Thread"); 
     recordingThread.start(); 
    } 

     //convert short to byte 
    private byte[] short2byte(short[] sData) { 
     int shortArrsize = sData.length; 
     byte[] bytes = new byte[shortArrsize * 2]; 
     for (int i = 0; i < shortArrsize; i++) { 
      bytes[i * 2] = (byte) (sData[i] & 0x00FF); 
      bytes[(i * 2) + 1] = (byte) (sData[i] >> 8); 
      sData[i] = 0; 
     } 
     return bytes; 

    } 

    private void writeAudioDataToFile() { 
     // Write the output audio in byte 

     String filePath = "/sdcard/voice8K16bitmono.pcm"; 
     short sData[] = new short[BufferElements2Rec]; 

     FileOutputStream os = null; 
     try { 
      os = new FileOutputStream(filePath); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 

     while (isRecording) { 
      // gets the voice output from microphone to byte format 

      recorder.read(sData, 0, BufferElements2Rec); 
      System.out.println("Short wirting to file" + sData.toString()); 
      try { 
       // // writes the data to file from buffer 
       // // stores the voice buffer 
       byte bData[] = short2byte(sData); 
       os.write(bData, 0, BufferElements2Rec * BytesPerElement); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
     try { 
      os.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    private void stopRecording() { 
     // stops the recording activity 
     if (null != recorder) { 
      isRecording = false; 
      recorder.stop(); 
      recorder.release(); 
      recorder = null; 
      recordingThread = null; 
     } 
    } 

    private View.OnClickListener btnClick = new View.OnClickListener() { 
     public void onClick(View v) { 
      switch (v.getId()) { 
      case R.id.btnStart: { 
       enableButtons(true); 
       startRecording(); 
       break; 
      } 
      case R.id.btnStop: { 
       enableButtons(false); 
       stopRecording(); 
       break; 
      } 
      } 
     } 
    }; 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_BACK) { 
      finish(); 
     } 
     return super.onKeyDown(keyCode, event); 
    } 
} 

Để biết thêm chi tiết, hãy thử điều này AUDIORECORD BLOG.

Mã hóa hạnh phúc !!

+1

Tôi có thể hỏi tần suất dữ liệu được ghi vào đầu ra không? Và cũng là lý do tại sao bạn đọc trong quần short, không phải là api cung cấp để đọc bằng byte? – james

+1

@JamesClark phụ thuộc vào kích thước gửi đến máy chủ của bạn. Nếu bạn gửi dữ liệu âm thanh 1024 quần short, tức là 2048 byte. sau đó bạn phải gửi trong vòng 40ms đến server.you có thể đọc theo byte quá không tạo ra nhiều khác biệt .. –

+2

Thêm vào đây: 44100 là tốc độ mẫu duy nhất được đảm bảo được hỗ trợ trên tất cả các thiết bị. http://developer.android.com/reference/android/media/AudioRecord.html –