CoreAudio的AudioTimeStamp.mHostTime时钟频率? [英] CoreAudio AudioTimeStamp.mHostTime clock frequency?

查看:1106
本文介绍了CoreAudio的AudioTimeStamp.mHostTime时钟频率?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到一个有点问题与iPhone AudioTimeStamps。当我在模拟器上运行我的应用程序AudioTimeStamp.mHostTime似乎是在纳秒(一秒的1,000,000,000th),而我的设备(iPod触摸2G)的频率似乎是大约一秒钟的第六百万。上运行时

I'm running into a bit of a problem with AudioTimeStamps on the iPhone. When I'm running my application in the simulator the AudioTimeStamp.mHostTime appears to be in nanoseconds (1,000,000,000th of a second) whereas when running on my device (iPod Touch 2G) the frequency appears to be about 6,000,000th of a second.

似乎在OS X有一个功能(AudioConvertHostTimeToNanos在CoreAudio的/ CoreAudioTypes.h)至HostTime转换和从纳秒,但这种功能不在iPhone头

It appears that on OS X there is a function (AudioConvertHostTimeToNanos in CoreAudio/CoreAudioTypes.h) to convert HostTime to and from nanoseconds, but this function is not in the iPhone headers.

有没有办法找出mHostTime在运行时的速度?或转换为秒,纳秒或任何其他单位?将这个值的软件或硬件版本之间的改变? (像它有模拟器和我的设备之间)

Is there any way to find out the rate of mHostTime at runtime? or to convert to seconds, nanoseconds or any other unit? Will this value change between software or hardware versions? (like it has between the simulator and my device)

推荐答案

有存在以下文件:

<mach/mach_time.h>

在这个文件中,你会发现一个名为函数 mach_absolute_time() mach_absolute_time()返回一个没有定义的含义的UINT64号码。试想一下,那些的的,但无处定义一个刻度有多长。只有四件事情定义为:

In this file you'll find a function named mach_absolute_time(). mach_absolute_time() returns an uint64 number that has no defined meaning. Imagine those are ticks, but nowhere is defined how long a single tick is. Only four things are defined:


  1. mach_absolute_time()返回自上次启动蜱的数量。

  2. 在每次启动的时钟计数器从零开始。

  3. 刻度计数器计数严格向上(它永远不会后退。)

  4. 在系统运行时
  5. 刻度计数器只计算蜱。

  1. mach_absolute_time() returns the number of "ticks" since the last boot.
  2. At every boot the tick counter starts at zero.
  3. The tick counter counts strictly upwards (it never goes backwards).
  4. The tick counter only counts ticks while the system is running.

正如你所看到的,刻度计数器是正常的系统时钟有所不同。首先,系统时钟不为零时,在系统引导启动,但​​在系统的最好的目前的挂钟时间近似。正常系统时钟也没有严格运行向上,例如系统时钟可能是时间提前,并且系统经常使用NTP(网络时间协议)同步的系统时间。如果该系统知道它是提前通过在下一NTP同步两秒它变成系统时钟背面由两秒钟纠正它。这打破了定期的软件,因为很多程序员依赖系统时间永远不会跳向后的事实;但它确实并允许它这样做。最后一个区别是,当系统处于睡眠正常的系统时间不会停止,但在系统睡眠刻度计数器不会增加。当系统再次唤醒,这是一对夫妇只蜱提前的时间就睡觉去了。

As you can see, the tick counter is somewhat different to the normal system clock. First of all, the system clock does not start at zero when the system is booted, but at the system's best approximation of the current "wall clock time". The normal system clock also is not running strictly upwards, e.g. the system clock might be ahead of time and the system regularly synchronize the system time using NTP (Network Time Protocol). If the system notices that it is ahead of time by two seconds at the next NTP sync, it turns the system clock back by two seconds to correct it. This regularly breaks software, because many programmers rely on the fact that the system time never jumps backwards; but it does and it is allowed to do so. The last difference is that the normal system time won't stop while the system is sleeping, but the tick counter will not increase while the system is sleeping. When the system wakes up again, it is only a couple of ticks ahead of the time it went to sleep.

那么,你如何转换这些蜱成一个真正的时间价值?

So how do you convert those ticks into a real "time value"?

以上的文件还定义了一个名为结构 mach_timebase_info

The file of above also defines a structure named mach_timebase_info:

struct mach_timebase_info {
        uint32_t        numer;
        uint32_t        denom;
};

您可以使用功能得到正确的值这个结构mach_timebase_info(),例如

kern_return_t kerror;
mach_timebase_info_data_t tinfo;

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

KERN_SUCCESS (以及可能的错误codeS)在

KERN_SUCCESS (and possible error codes) are defined in

<mach/kern_return.h>

这是不太可能,此函数返回一个错误,虽然和 KERN_SUCCESS 等于零,所以你也可以直接检查 kerror 不是零。

It is very unlikely for this function to return an error, though, and KERN_SUCCESS is equal to zero, thus you can also directly check for kerror not being zero.

一旦你得到了信息到 TINFO ,你可以用它来计算出一个转换系数,如果你想这个数字转换成一个真正的时间单位:

Once you got the info into tinfo, you can use it to calculate a "conversion factor", in case you want to convert this number into a real time unit:

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

通过浇注第一号双击,GCC自动转换的第二号双击以及和结果也将是双击。知道了这个因素,这似乎是1.0的Intel的机器,但它可以对PPC机器完全不同的(也许它是在ARM以及不同),它是pretty易主时间转换为纳秒纳秒举办时间。

By casting the first number to double, GCC automatically casts the second number to double as well and the result will also be double. Knowing this factor, which seems to be 1.0 on Intel machines, but it can be quite different on PPC machines (and maybe it's different on ARM as well), it is pretty easy to convert host time to nanoseconds and nanoseconds to host time.

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

systemUptimeNS包含的最后一个引导和现在之间的系统运行纳秒(不睡觉)的数量。如果通过这个因素鸿沟纳秒任何时候,你会得到蜱的数量。这可以为功能mach_wait_until非常有用的()。假设你想在当前线程睡眠800纳秒。这里是你如何做到这一点:

systemUptimeNS contains the number of nanoseconds the system was running (not sleeping) between the last boot and now. If you divide any time in nanoseconds by this factor, you get the number of ticks. This can be very useful for the function mach_wait_until(). Assume you want the current thread to sleep for 800 nanoseconds. Here's how you'd do it:

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

小提示:如果您经常需要将时间值转换成蜱,它通常是(取决于CPU)速度繁殖,而不是划分:

A little tip: If you regularly need to convert time values to ticks, it is usually (depends on CPU) faster to multiply than to divide:

double ns2HTimeFactor = 1.0 / hTime2nsFactor;

现在,你可以通过 ns2HTimeFactor 繁衍,而不是由 hTime2nsFactor 分裂。

Now you can multiply by ns2HTimeFactor instead of dividing by hTime2nsFactor.

当然,这是时间重新计算的因素每次需要他们在浪费时间。这些因素是恒定的,在系统运行的同时,他们将不会改变。因此,你可以计算出某个它们的应用程序的起点附近,让他们到周围的应用程序再次退出。

Of course it is a waste of time to re-calculate the factors each time you need them. Those factors are constant, they will never change while the system is running. Thus you can calculate them somewhere near the start of the application and keep them around till the application quits again.

在可可,我建议你自己写高于一切静态类。你可以计算出转换系数在 +(无效)初始化类的方法要么转换。可可保证这种方法是肯定的自动执行之前的任何消息不断发送到这个类,它是在应用程序运行时请务必仅执行一次,这是肯定的一个线程安全的方式执行的,所以你不必担心锁定/同步或原子操作。

In Cocoa I'd recommend to write yourself a static class for everything above. You can calculate the conversion factors for either conversion in the +(void)initialize method of the class. Cocoa guarantees that this method is for sure automatically executed before any message is ever sent to this class, it is for sure only executed once during application run time and it is for sure executed in a thread-safe manner, so you don't have to worry about locking/synchronizing or atomic operations.

这篇关于CoreAudio的AudioTimeStamp.mHostTime时钟频率?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆