2011-08-25 21 views
14

Estoy diseñando una prueba de concepto simple para grabadora multipista.iOS: código de muestra para grabación y reproducción simultánea

punto de partida obvio es jugar de archivo A.caf a los auriculares durante la grabación simultánea de entrada de micrófono en el archivo B.caf

Esta pregunta - Record and play audio Simultaneously - señala que hay tres niveles en los que puedo trabajar :

  • AVFoundation API (+ AVAudioPlayer AVAudioRecorder)
  • audio cola API
  • API Audio Unit (RemoteIO)

¿Cuál es el mejor nivel para trabajar? Obviamente, la respuesta genérica es trabajar al más alto nivel que hace el trabajo, que sería AVFoundation.

Pero estoy aceptando este trabajo de alguien que se dio por vencido debido a problemas de latencia (estaba recibiendo un retraso de 0.3 segundos entre los archivos), ¿entonces quizás necesito trabajar en un nivel inferior para evitar estos problemas?

Además, ¿de qué código fuente está disponible para trampolín? He estado mirando la muestra de SpeakHere (http://developer.apple.com/library/ios/#samplecode/SpeakHere/Introduction/Intro.html). si no puedo encontrar algo más simple, usaré esto.

Pero, ¿alguien puede sugerir algo más simple/más? Preferiría no trabajar con código C++ si puedo evitarlo.

¿Alguien conoce algún código público que utiliza AVFoundation para hacer esto?

EDIT: AVFoundation ejemplo aquí: http://www.iphoneam.com/blog/index.php?title=using-the-iphone-to-record-audio-a-guide&more=1&c=1&tb=1&pb=1

EDITAR (2): Mucho mejor mirando uno aquí: http://www.switchonthecode.com/tutorials/create-a-basic-iphone-audio-player-with-av-foundation-framework

EDITAR (3): How do I record audio on iPhone with AVAudioRecorder?

Respuesta

5

Según lo sugerido por Viraj, aquí está la respuesta.

Sí, puede lograr muy buenos resultados utilizando AVFoundation. En primer lugar, debe prestar atención al hecho de que, tanto para el reproductor como para la grabadora, activarlos es un proceso de dos pasos.

Primero lo preparas.

Entonces juegas.

Por lo tanto, prime todo. Entonces juega todo.

Esto reducirá su latencia a aproximadamente 70 ms. Probé grabando un tic de metrónomo, luego lo reproduje a través de los parlantes mientras sostengo el iPhone en los parlantes y grabo simultáneamente.

La segunda grabación tuvo un eco claro, que me pareció de ~ 70ms. Podría haber analizado la señal en Audacity para obtener una compensación exacta.

Así que con el fin de alinear todo lo que hasta yo sólo performSelector: x withObject: y afterDelay: 70,0 ganchos/1000.0

No pueden estar ocultos, por ejemplo, el retraso puede diferir de un dispositivo a otro. incluso puede diferir dependiendo de la actividad del dispositivo. Incluso es posible que el hilo pueda ser interrumpido/reprogramado entre el inicio del reproductor y el inicio de la grabadora.

Pero funciona, y es mucho más ordenado que jugar con colas de audio/unidades.

+1

¿Cómo lo "preparas"? ¿Puedes explicar a qué te refieres con eso, por favor? –

+3

¿Puede proporcionar el código de muestra de esta funcionalidad? –

+1

Lamentablemente, todavía no hay manera de hacer esto bien (al menos eso puedo encontrar). 70ms es simplemente demasiado fuera de sincronización para mí, y con la variedad de dispositivos diferentes de hoy en día, la diferencia en la desincronización es demasiado grande. En el iPhone 5s, obtengo unos 66ms, pero en el iPhone 6, obtengo unos 40ms. Me di cuenta de que esta publicación es de 2011. ¿Alguna vez encontró una mejor manera de hacerlo? – Sti

6

Para evitar problemas de latencia, que tendrá que trabajar en un nivel más bajo que AVFoundation bien. Consulte este código de ejemplo de Apple: Auriotouch. Utiliza E/S remotas.

+1

En realidad lo conseguí trabajando al instante en el uso de AVFoundation. Solo tienes que asegurarte de que todo esté preparado antes de iniciarlo. Además de eso, debe iniciar la grabadora 70 ms después del reproductor y se alinea muy bien. (esto puede cambiar según el dispositivo). –

+2

Es bueno saberlo. Tal vez deberías responder tu pregunta. – Viraj

1

Tuve este problema y lo resolví en mi proyecto simplemente cambiando el parámetro del AudioSession. Creo que ahora tengo solo 6 ms de latencia, eso es lo suficientemente bueno para mi aplicación.

Compruebe this answer que tiene una buena explicación.

+0

puede proporcionar el código por favor. estoy luchando desde los últimos 4 días. –

+0

Claro, el código que tengo está en Xamarin pero supongo que no es difícil escribirlo en forma rápida u objetiva. Mira el enlace que brindo en la respuesta, hay un ejemplo. Además, asegúrese de preparar su grabadora (yo uso AVAudioRecorder y prepareToRecord) y su reproductor (I crate una instancia de AVPlayer con el nombre de archivo) antes de que comiencen con baja latencia. Además, cuando active AudioSession, asegúrese de configurar la categoría para jugar en AndRecord. En Xamarin se ve así: 'AVAudioSession.SharedInstance(). SetPreferredIOBufferDuration (0.005, error de salida);' – ernewston

+0

Tengo una clase AudioSessionHelper con una función llamada ActivateMyAudioSesion, donde establezco la categoría, establezco el Modo, la preferenceIOBufferDuration y luego Lo hago activo. Llamo a esta función antes de comenzar la primera grabación (no la llames todas las veces, ya que es cara), o puedes hacerlo cuando se inicia la aplicación. ¡Espero eso ayude! – ernewston

Cuestiones relacionadas