2011-12-14 18 views
47

Estoy diseñando una aplicación para Android y necesito implementar una clase AudioRecord para grabar el sonido del usuario. Después de algunas investigaciones (que no proporcionaron suficiente información) y algunos intentos fallidos, me preguntaba si alguien podría ayudarme publicando un ejemplo (código) sobre cómo capturar sonido de alta calidad usando AudioRecord. Yo realmente lo apreciaría. GraciasEjemplo de Android AudioRecord

Respuesta

74

Aquí le estoy enviando el ejemplo de algunos códigos que registran la buena calidad de sonido usando AudioRecord API.

Nota: Si utiliza en emulador, la calidad del sonido no será muy buena ya que estamos usando una frecuencia de muestreo de 8k que solo es compatible con el emulador. En dispositivo, utilice una frecuencia de muestreo de 44.1k para una mejor calidad.

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); 
    } 
} 

Para más detalles probar este AUDIORECORD BLOG.

Happy Coding !!

+1

¿Puedo preguntar con qué frecuencia los datos se escriben en el OutputStream? Y también, ¿por qué lees en calzoncillos, no ofrece la API leer en bytes? – james

+1

@JamesClark depende del tamaño de su envío al servidor. Si el envío de datos de audio 1024 cortos, es decir, 2048 bytes. luego debe enviar dentro de los 40 ms al servidor. También puede leer en bytes. No tiene mucha importancia. –

+2

Agregando a esto: 44100 es la única frecuencia de muestreo garantizada para ser admitida en todos los dispositivos. http://developer.android.com/reference/android/media/AudioRecord.html –

Cuestiones relacionadas