sueño salud para monitorear hora gratis eliminar dormir desactivar apple app iphone objective-c audio

salud - eliminar hora de dormir iphone



¿CoreAudio AudioTimeStamp.mHostTime frecuencia de reloj? (2)

Tengo un pequeño problema con AudioTimeStamps en el iPhone. Cuando ejecuto mi aplicación en el simulador, AudioTimeStamp.mHostTime parece estar en nanosegundos (1,000,000,000 de segundo) mientras que cuando se ejecuta en mi dispositivo (iPod Touch 2G), la frecuencia parece ser aproximadamente 6,000,000 de segundo.

Parece que en OS X hay una función (AudioConvertHostTimeToNanos en CoreAudio / CoreAudioTypes.h) para convertir HostTime en y desde nanosegundos, pero esta función no se encuentra en los encabezados del iPhone.

¿Hay alguna manera de averiguar la tasa de mHostTime en tiempo de ejecución? ¿O convertir a segundos, nanosegundos o cualquier otra unidad? ¿Cambiará este valor entre las versiones de software o hardware? (como tiene entre el simulador y mi dispositivo)


Existe el siguiente archivo:

<mach/mach_time.h>

En este archivo encontrará una función llamada mach_absolute_time() . mach_absolute_time() devuelve un número uint64 que no tiene un significado definido. Imagínese que son garrapatas , pero en ninguna parte se define cuánto tiempo dura una garrapata. Sólo se definen cuatro cosas:

  1. mach_absolute_time() devuelve el número de "tics" desde el último arranque.
  2. En cada arranque, el contador de ticks comienza en cero.
  3. El contador de ticks cuenta estrictamente hacia arriba (nunca va hacia atrás).
  4. El contador de ticks solo cuenta los ticks mientras el sistema se está ejecutando.

Como puede ver, el contador de ticks es algo diferente al reloj normal del sistema. En primer lugar, el reloj del sistema no se inicia en cero cuando se inicia el sistema, sino en la mejor aproximación del sistema del "tiempo de reloj de pared" actual. El reloj normal del sistema tampoco funciona estrictamente hacia arriba, por ejemplo, el reloj del sistema puede estar adelantado y el sistema sincroniza regularmente la hora del sistema utilizando NTP (Protocolo de tiempo de red). Si el sistema nota que se adelanta en dos segundos en la próxima sincronización NTP, el reloj del sistema retrocede dos segundos para corregirlo. Esto rompe regularmente el software, porque muchos programadores confían en el hecho de que la hora del sistema nunca salta hacia atrás; pero lo hace y está permitido hacerlo. La última diferencia es que la hora normal del sistema no se detendrá mientras el sistema está durmiendo, pero el contador de tics no aumentará mientras el sistema esté durmiendo. Cuando el sistema vuelve a activarse, solo queda un par de tics adelantados a la hora de dormir.

Entonces, ¿cómo convertir esas garrapatas en un "valor de tiempo" real?

El archivo de arriba también define una estructura llamada mach_timebase_info :

struct mach_timebase_info { uint32_t numer; uint32_t denom; };

Puede obtener los valores correctos para esta estructura utilizando la función mach_timebase_info() , por ejemplo,

kern_return_t kerror; mach_timebase_info_data_t tinfo; kerror = mach_timebase_info(&tinfo); if (kerror != KERN_SUCCESS) { // TODO: handle error }

KERN_SUCCESS (y los posibles códigos de error) se definen en

<mach/kern_return.h>

Sin embargo, es muy poco probable que esta función devuelva un error, y KERN_SUCCESS es igual a cero, por lo que también puede verificar directamente si kerror no es cero.

Una vez que obtuviste la información en tinfo , puedes usarla para calcular un "factor de conversión", en caso de que quieras convertir este número en una unidad de tiempo real:

double hTime2nsFactor = (double)tinfo.numer / tinfo.denom;

Al lanzar el primer número para double , GCC automáticamente lanza el segundo número para double también y el resultado también será double . Sabiendo este factor, que parece ser 1.0 en las máquinas Intel, pero puede ser bastante diferente en las máquinas PPC (y quizás también sea diferente en ARM), es bastante fácil convertir el tiempo de host a nanosegundos y nanosegundos a tiempo de host.

uint64_t systemUptimeNS = (uint64_t)(mach_absolute_time() * hTime2nsFactor);

systemUptimeNS contiene la cantidad de nanosegundos que el sistema estaba ejecutando (no durmiendo) entre el último arranque y ahora. Si divide este tiempo en nanosegundos por este factor, obtendrá el número de tics. Esto puede ser muy útil para la función mach_wait_until() . Supongamos que desea que el subproceso actual se duerma durante 800 nanosegundos. Así es como lo harías:

uint64_t sleepTimeInTicks = (uint64_t)(800 / hTime2nsFactor); mach_wait_until(mach_absolute_time() + sleepTimeInTicks);

Un pequeño consejo: si regularmente necesita convertir los valores de tiempo en tics, es generalmente (depende de la CPU) multiplicarse más rápido que dividir:

double ns2HTimeFactor = 1.0 / hTime2nsFactor;

Ahora puede multiplicar por ns2HTimeFactor lugar de dividir por hTime2nsFactor .

Por supuesto, es una pérdida de tiempo volver a calcular los factores cada vez que los necesite. Esos factores son constantes, nunca cambiarán mientras el sistema esté funcionando. Por lo tanto, puede calcularlos en algún lugar cerca del inicio de la aplicación y mantenerlos hasta que la aplicación se cierre de nuevo.

En Cocoa te recomiendo que escribas una clase estática para todo lo anterior. Puede calcular los factores de conversión para cualquiera de las conversiones en el método de +(void)initialize de la clase. Cocoa garantiza que este método se ejecuta de manera segura antes de que se envíe cualquier mensaje a esta clase, es seguro que solo se ejecuta una vez durante el tiempo de ejecución de la aplicación y se ejecuta de manera segura para la seguridad de subprocesos, por lo que no tiene preocuparse por el bloqueo / sincronización o las operaciones atómicas.


Necesitas usar la estructura mach_timebase_info para resolver esto.

struct mach_timebase_info { uint32_t numer; uint32_t denom; };

Consulte: http://shiftedbits.org/2008/10/01/mach_absolute_time-on-the-iphone/

Lo más fácil de hacer es simplemente usar la clase de ayuda CAHostTimeBase proporcionada por Apple - Desarrollador / Ejemplos / CoreAudio / PublicUtility.

CAHostTimeBase.cpp y CAHostTimeBase.h: hace todo lo que necesita hacer.