Android: necesita grabar entrada de micrófono

¿Hay alguna manera de grabar la entrada de micrófono en Android mientras se está procesando para la reproducción / vista previa en tiempo real? Traté de usar AudioRecord y AudioTrack para hacer esto, pero el problema es que mi dispositivo no puede reproducir el archivo de audio grabado. En realidad, cualquier aplicación de reproductor Android no puede reproducir el archivo de audio grabado.

Por otro lado, el uso de Media.Recorder para grabar genera un buen archivo de audio grabado que cualquier aplicación de jugador puede reproducir. Pero el problema es que no puedo hacer una vista previa / retroiluminación mientras grabo la entrada del micrófono en tiempo real.

¡Cualquier comentario es muy apreciado! ¡Gracias por adelantado!

Para grabar y reproducir audio en tiempo (casi) real, puede iniciar un hilo por separado y usar un AudioRecord y un AudioTrack .

Solo ten cuidado con los comentarios. Si los altavoces están lo suficientemente alto en su dispositivo, la retroalimentación puede ser bastante desagradable bastante rápido.

 /* * Thread to manage live recording/playback of voice input from the device's microphone. */ private class Audio extends Thread { private boolean stopped = false; /** * Give the thread high priority so that it's not canceled unexpectedly, and start it */ private Audio() { android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO); start(); } @Override public void run() { Log.i("Audio", "Running Audio Thread"); AudioRecord recorder = null; AudioTrack track = null; short[][] buffers = new short[256][160]; int ix = 0; /* * Initialize buffer to hold continuously recorded audio data, start recording, and start * playback. */ try { int N = AudioRecord.getMinBufferSize(8000,AudioFormat.CHANNEL_IN_MONO,AudioFormat.ENCODING_PCM_16BIT); recorder = new AudioRecord(AudioSource.MIC, 8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10); track = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, N*10, AudioTrack.MODE_STREAM); recorder.startRecording(); track.play(); /* * Loops until something outside of this thread stops it. * Reads the data from the recorder and writes it to the audio track for playback. */ while(!stopped) { Log.i("Map", "Writing new data to buffer"); short[] buffer = buffers[ix++ % buffers.length]; N = recorder.read(buffer,0,buffer.length); track.write(buffer, 0, buffer.length); } } catch(Throwable x) { Log.w("Audio", "Error reading voice audio", x); } /* * Frees the thread's resources after the loop completes so that it can be run again */ finally { recorder.stop(); recorder.release(); track.stop(); track.release(); } } /** * Called from outside of the thread in order to stop the recording/playback loop */ private void close() { stopped = true; } } 

EDITAR

El audio realmente no está grabando en un archivo. El objeto AudioRecord codifica el audio como datos PCM de 16 bits y lo coloca en un búfer. Luego, el objeto AudioTrack lee los datos de ese búfer y los reproduce a través de los altavoces. No hay ningún archivo en la tarjeta SD al que podrá acceder más tarde.

No puede leer y escribir un archivo desde la tarjeta SD al mismo tiempo para obtener reproducción / vista previa en tiempo real, por lo que debe usar almacenamientos intermedios.

Se requiere el siguiente permiso en manifiesto para que funcione correctamente:

  

Además, 2d buffer array no es necesario. La lógica del código es válida incluso con solo un buffer, como este:

 short[] buffer = new short[160]; while (!stopped) { //Log.i("Map", "Writing new data to buffer"); int n = recorder.read(buffer, 0, buffer.length); track.write(buffer, 0, n); }