2011-10-31 21 views
10

Descripción


Mi solicitud de registrar el sonido del micrófono del teléfono. Estoy usando las clases estándar de Android (android.media.AudioRecord) para hacer eso. Aplicación tiene 2 botones "Start " y "parada" cuando pulso inicio aplicación del botón de inicio de grabación y cuando pulso parada aplicación deja de grabar y devuélveme memoria intermedia, con los datos de voz en formato .wav. Todo funciona biendetección de voz en la Solicitud Android

Problema


quiero cambiar mi solicitud de esta manera, cuando la aplicación se inicia el trabajo se empiezan a analizar sonido procedente del micrófono, si el usuario mantenga aplicación silencio continuar analizando sonido ingreso del micrófono, si el usuario la aplicación para comenzar a hablar comienza a Grabar sonido proveniente del micrófono y luego el usuario finaliza la conversación, la aplicación deja de grabar y me devuelve el mismo buffer, con datos de voz en formato .wav.

Pregunta


  1. ¿Cómo puedo detectar que inicio de usuario hablar
  2. ¿Cómo puedo detectar que el usuario lo detenga hablar
+1

Creo que tendrá que hacer la mayor parte del trabajo de sonido por su cuenta: Android proporciona algunas funciones limitadas para acceder al micrófono y la grabación, pero nada que haga cálculos pesados ​​o voz a texto. – Noah

+0

@sqrfv gracias por sus comentarios, +1 ¿Alguna otra sugerencia? –

Respuesta

24

Sólo añadir este código a su aplicación y detectará cuando el usuario comience a hablar y cuando se detenga.

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

    // Get the minimum buffer size required for the successful creation of an AudioRecord object. 
    int bufferSizeInBytes = AudioRecord.getMinBufferSize(RECORDER_SAMPLERATE, 
                  RECORDER_CHANNELS, 
                  RECORDER_AUDIO_ENCODING 
                 ); 
    // Initialize Audio Recorder. 
    AudioRecord audioRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 
               RECORDER_SAMPLERATE, 
               RECORDER_CHANNELS, 
               RECORDER_AUDIO_ENCODING, 
               bufferSizeInBytes 
               ); 
    // Start Recording. 
    audioRecorder.startRecording(); 

    int numberOfReadBytes = 0; 
    byte audioBuffer[]  = new byte[bufferSizeInBytes]; 
    boolean recording  = false; 
    float tempFloatBuffer[] = new float[3]; 
    int tempIndex   = 0; 
    int totalReadBytes  = 0; 
    byte totalByteBuffer[] = new byte[60 * 44100 * 2]; 


    // While data come from microphone. 
    while(true) 
    { 
     float totalAbsValue = 0.0f; 
     short sample  = 0; 

     numberOfReadBytes = audioRecorder.read(audioBuffer, 0, bufferSizeInBytes); 

     // Analyze Sound. 
     for(int i=0; i<bufferSizeInBytes; i+=2) 
     { 
      sample = (short)((audioBuffer[i]) | audioBuffer[i + 1] << 8); 
      totalAbsValue += Math.abs(sample)/(numberOfReadBytes/2); 
     } 

     // Analyze temp buffer. 
     tempFloatBuffer[tempIndex%3] = totalAbsValue; 
     float temp     = 0.0f; 
     for(int i=0; i<3; ++i) 
      temp += tempFloatBuffer[i]; 

     if((temp >=0 && temp <= 350) && recording == false) 
     { 
      Log.i("TAG", "1"); 
      tempIndex++; 
      continue; 
     } 

     if(temp > 350 && recording == false) 
     { 
      Log.i("TAG", "2"); 
      recording = true; 
     } 

     if((temp >= 0 && temp <= 350) && recording == true) 
     { 
      Log.i("TAG", "Save audio to file."); 

      // Save audio to file. 
      String filepath = Environment.getExternalStorageDirectory().getPath(); 
      File file = new File(filepath,"AudioRecorder"); 
      if(!file.exists()) 
       file.mkdirs(); 

      String fn = file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".wav"; 

      long totalAudioLen = 0; 
      long totalDataLen = totalAudioLen + 36; 
      long longSampleRate = RECORDER_SAMPLERATE; 
      int channels  = 1; 
      long byteRate  = RECORDER_BPP * RECORDER_SAMPLERATE * channels/8; 
      totalAudioLen  = totalReadBytes; 
      totalDataLen  = totalAudioLen + 36; 
      byte finalBuffer[] = new byte[totalReadBytes + 44]; 

      finalBuffer[0] = 'R'; // RIFF/WAVE header 
      finalBuffer[1] = 'I'; 
      finalBuffer[2] = 'F'; 
      finalBuffer[3] = 'F'; 
      finalBuffer[4] = (byte) (totalDataLen & 0xff); 
      finalBuffer[5] = (byte) ((totalDataLen >> 8) & 0xff); 
      finalBuffer[6] = (byte) ((totalDataLen >> 16) & 0xff); 
      finalBuffer[7] = (byte) ((totalDataLen >> 24) & 0xff); 
      finalBuffer[8] = 'W'; 
      finalBuffer[9] = 'A'; 
      finalBuffer[10] = 'V'; 
      finalBuffer[11] = 'E'; 
      finalBuffer[12] = 'f'; // 'fmt ' chunk 
      finalBuffer[13] = 'm'; 
      finalBuffer[14] = 't'; 
      finalBuffer[15] = ' '; 
      finalBuffer[16] = 16; // 4 bytes: size of 'fmt ' chunk 
      finalBuffer[17] = 0; 
      finalBuffer[18] = 0; 
      finalBuffer[19] = 0; 
      finalBuffer[20] = 1; // format = 1 
      finalBuffer[21] = 0; 
      finalBuffer[22] = (byte) channels; 
      finalBuffer[23] = 0; 
      finalBuffer[24] = (byte) (longSampleRate & 0xff); 
      finalBuffer[25] = (byte) ((longSampleRate >> 8) & 0xff); 
      finalBuffer[26] = (byte) ((longSampleRate >> 16) & 0xff); 
      finalBuffer[27] = (byte) ((longSampleRate >> 24) & 0xff); 
      finalBuffer[28] = (byte) (byteRate & 0xff); 
      finalBuffer[29] = (byte) ((byteRate >> 8) & 0xff); 
      finalBuffer[30] = (byte) ((byteRate >> 16) & 0xff); 
      finalBuffer[31] = (byte) ((byteRate >> 24) & 0xff); 
      finalBuffer[32] = (byte) (2 * 16/8); // block align 
      finalBuffer[33] = 0; 
      finalBuffer[34] = RECORDER_BPP; // bits per sample 
      finalBuffer[35] = 0; 
      finalBuffer[36] = 'd'; 
      finalBuffer[37] = 'a'; 
      finalBuffer[38] = 't'; 
      finalBuffer[39] = 'a'; 
      finalBuffer[40] = (byte) (totalAudioLen & 0xff); 
      finalBuffer[41] = (byte) ((totalAudioLen >> 8) & 0xff); 
      finalBuffer[42] = (byte) ((totalAudioLen >> 16) & 0xff); 
      finalBuffer[43] = (byte) ((totalAudioLen >> 24) & 0xff); 

      for(int i=0; i<totalReadBytes; ++i) 
       finalBuffer[44+i] = totalByteBuffer[i]; 

      FileOutputStream out; 
      try { 
       out = new FileOutputStream(fn); 
       try { 
         out.write(finalBuffer); 
         out.close(); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 

      } catch (FileNotFoundException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 

      //*/ 
      tempIndex++; 
      break; 
     } 

     // -> Recording sound here. 
     Log.i("TAG", "Recording Sound."); 
     for(int i=0; i<numberOfReadBytes; i++) 
      totalByteBuffer[totalReadBytes + i] = audioBuffer[i]; 
     totalReadBytes += numberOfReadBytes; 
     //*/ 

     tempIndex++; 

    } 
} 

Compruebe esto link.

+0

Probé este código pero no funciona para mí. Obtengo la excepción siguiente Ayúdenme a salir de este problema – Dipali

+0

04-06 15: 03: 01.729: E/AndroidRuntime (16174): Causado por: java.lang.IllegalArgumentException: 0Hz no es una frecuencia de muestreo admitida. 04-06 15: 03: 01.729: E/AndroidRuntime (16174): \t en android.media.AudioRecord.audioParamCheck (AudioRecord.java:265) 04-06 15: 03: 01.729: E/AndroidRuntime (16174): \t en android.media.AudioRecord. (AudioRecord.java:223) 04-06 15:03:01.729: E/AndroidRuntime (16174): \t en com.test.recording.RecordingActivity.onCreate (RecordingActivity.java:32) 04-06 15: 03: 01.729: E/AndroidRuntime (16174): \t en android.app .ActivityThread.performLaunchActivity (ActivityThread.java:1615) – Dipali

+0

private static final int RECORDER_SAMPLERATE qué valor debería darle aquí ??? – Dipali

2

es mejor utilizar private static final int RECORDER_SAMPLERAT = 8000; funciona para mí. Creo que ayudará para usted

7

He respondido una pregunta similar antes, un enfoque es utilizar hilos en la grabación y el proceso de análisis de potencia de voz en los bytes grabados, hay un código de muestra para su referencia: http://musicg.googlecode.com/files/musicg_android_demo.zip

+0

puede explicarme o señalarme en algún lugar para entender cómo funciona la detección de audio. Específicamente, ¿el método 'getFrameBytes' en' RecorderThread'? – asloob

1

cuando reemplacé totalAbsValue += Math.abs(sample)/(numberOfReadBytes/2) by totalAbsValue += (float)Math.abs(sample)/((float)numberOfReadBytes/(float)2) entonces funciona bien.