背景介绍
通常游戏帧率的微小浮动并不太会影响用户体验,人的视觉感受能力比较低。一般仅需要使用简单的休眠来控制帧率就满足需求。
但在音频播放时,这对定时器迎来巨大的挑战。人的耳朵能感受到的音乐质量通常很高,微小的频率震荡都可能引起不适。曲有误,周郎顾。说的就是这种情况。
更苛刻的是声卡接口的特殊性,对于以60帧采样的音频流,每一块长度为 1 / 60秒。如果播放频率大于60帧,那么由于播放过快,导致块之间形成空隙,听起来会有颤音。如果播放过慢,那么播放缓冲区将随着时间逐渐填满,并逐渐与原始音轨发生滞后差异,造成音画不同步,当缓冲区满,会发生一次强烈的断层。
基本思路
在定时器设计中,完全达到帧间隔保持一致是十分困难的,这完全取决于系统提供的关于时间的接口精度。
这些接口统共两类
第一类,计时器,记录两个时间点的间隔。
第二类,睡眠器,休眠一段时间。
使用这两类时间接口就可以以统计学方式,让一个线程以帧每秒的单位度量,平稳的保持到一个期望的频率。当总任务量小于运算效能时,这在理论上总是成立的。
第一个元件,2幂长度环形队列帧率统计
我们使用定长环形队列来存储每帧时间间隔,取平均值作为统计频率。通常以2的幂作为环形队列长度有很大优势,能使用位移运算提高速度,而64作为渲染频率60帧最接近的长度是首选。首先我们在设置期望频率时将全长缓存变为期望间隔。平均值结算发生在插入新值的地方,仅出队和入队一次加法和一次减法。
组件:c语言2幂采样平均帧率统计_登高思危-少言勿躁的博客-优快云博客
第二个元件,生成回调的定时循环
我们将回调前的时间点距离上次定时器重置时间记为wt。将回调后的时间点距离上次重置,与上一帧做差,得出当前帧的业务耗时间隔ht,使用帧率统计反馈的统计帧率记为R,期望帧率记为P,则我们使用期望频率平方为基准的反比例函数得出修正帧率为
X=(P x P) / R
修正频率间隔即为xt = 1 / X
本帧休眠间隔即为st=ht - xt
期望频率P为常数,所以这是一个反比例函数。采用这种方式负反馈。在统计帧率越接近期望帧率时修正幅度越小&