2012-08-02 9 views
6

Tengo un programa que usa una unidad de audio de reproductor de archivos para reproducir, pausar y detener un archivo de audio. La forma en que lo estoy logrando es inicializando la unidad de audio del reproductor de archivos para reproducir el archivo en la posición cero y luego, cuando el usuario presiona el botón de pausa, detengo el AUGraph, captura la posición actual y luego la uso como posición de inicio cuando el usuario presiona el botón de reproducción. Todo funciona como debería, pero cada 3 o 4 veces que presiono pausa y luego juego, la canción comienza a reproducirse de la mitad a un segundo ANTES del punto donde presioné pausa.En el audio del núcleo IOS, ¿cómo se puede encontrar la posición actual del cabezal de reproducción actual de una unidad de audio de reproductor de archivos?

No puedo entender por qué sucede esto, ¿alguno de ustedes tiene alguna idea? aquí hay una versión simplificada de mi código.

//initialize AUGraph and File player Audio unit 
... 
... 
... 

//Start AUGraph 
... 
... 
... 

// pause playback 
- (void) pauseAUGraph { 

//first stop the AuGrpah 
     result = AUGraphStop (processingGraph); 

// get current play head position   
     AudioTimeStamp ts; 
     UInt32 size = sizeof(ts); 

     result = AudioUnitGetProperty(filePlayerUnit, 
             kAudioUnitProperty_CurrentPlayTime, kAudioUnitScope_Global, 0, &ts, 
             &size); 
     //save our play head position for use later 
     //must add it to itself to take care of multiple presses of the pause button 
     sampleFrameSavedPosition = sampleFrameSavedPosition + ts.mSampleTime; 


     //this stops the file player unit from playing 
     AudioUnitReset(filePlayerUnit, kAudioUnitScope_Global, 0); 
     NSLog (@"AudioUnitReset - stopped file player from playing"); 

    //all done  
} 


// Stop playback 

- (void) stopAUGraph { 
     // lets set the play head to zero, so that when we restart, we restart at the beginning of the file. 

      sampleFrameSavedPosition = 0; 
     //ok now that we saved the current pleayhead position, lets stop the AUGraph 
     result = AUGraphStop (processingGraph); 
} 
+0

¿Qué formato es el archivo de audio? –

+0

son archivos m4a. – Beleg

+0

OK, no soy un experto en compresión de audio, pero los archivos tienden a comprimirse en fragmentos y cuando lo buscas puede ir al fragmento más cercano en lugar de a la posición real. Si encuentro algo más definitivo, publicaré una respuesta. –

Respuesta

0

puede ser debido al redondeo problemas con su código:

Por ejemplo, si cada vez que se pulsa el botón de pausa, el temporizador registraría en un 0,5/4 segundos antes de que su tiempo de pausa real, aún verías un resultado deseado. Pero después de repetir por cuatro veces más, la cantidad de espacio que ha creado es 0.5/4 veces 4, que es la mitad de un segundo que parece estar experimentando.

Por lo tanto, prestaría mucha atención a los tipos de objeto que está utilizando y me aseguraré de que no se redondeen de manera inapropiada. ¡Intente usar un double float para sus tiempos de muestra para tratar de aliviar ese problema!

Espero que esto sea claro y útil. :)

+0

Estoy usando float64 para almacenar audioTimeStamp.mSampletime en sampleFrameSavedPosition, por lo que no debería haber ningún error de redondeo. Me di cuenta de que cuando inicio la copia de seguridad de AuGraph estableciendo ScheduledAudioFileRegion.mStartFrame que ScheduledAudioFileRegion.mStartFrame es un UInt32 y no un float64, dicho esto cuando pruebo mi programa e imprimo los valores de mSampleTime siempre es un entero, así que no debería mater. – Beleg

+0

Luego, en teoría, si todos sus tipos son enteros, ni siquiera debería generar una fracción. ¿Trataste de sacar la posición de la cabeza cada vez y ver si se sumaba? – wayway

1

Puede ser que deba usar conteos de paquetes en lugar de marcas de tiempo, ya que solo desea pausar y reproducir la música, no mostrar la información de tiempo.

Consulte BufferedAudioPlayer para ver un ejemplo del uso de este método.

+0

¿Está sugiriendo usar un rendercallback en lugar de una unidad de audio de reproductor de archivos y contar paquetes en lugar de usar marcas de tiempo? Voy a probar eso esta noche. – Beleg

+0

Sí. Lo utilicé con éxito en más de un proyecto. Audiograph (https://github.com/tkzic/audiograph) es otro ejemplo que tiene el mismo enfoque. Ese proyecto viene con un muy buen manual, también. – Totoro

Cuestiones relacionadas