首先是下面会用到的
OS和用户可以用到的时钟:
clock realtime -> 可以被ntp搞到逆时针转的
clock monotonic -> 只能顺时针转,但可以因ntp而调整转速(速率)
clock monotonic raw ->只能顺时针转 不受ntp影响
以上三个共同点 依赖系统时钟源
ptp clock ->在合理的系统上会和PTP GM运行在相同速率
drifted clock 通常还是会有相对稳定的速率
有小的的drift rate=>去掉drift rate就变成比较精确的时钟
TSC:CPU温度变化剧烈,但TSC来源PLL的REF晶振温度变化不大
unstable clock 时间在很短时间变化,倒退,停止
通常不会被OS选为可靠的系统时钟
ptp clock,用数次sync的时间差除以本地时间差会得到drift rate
结合drifted clock就可以得到相对精确且稳定的时钟(10kHz+)
PTP GM在AES67里可以当做Word Sync, Wall Clock
PTP Slave Clock可以经DPLL锁相到VCO/VCXO,
divide到sample rate可得Media Clock,这种方式得到的是连续时钟,
也可按上面方法得drift rate然后生成timer,
断续的clock不能拿来sample 但依旧可以为sample编号(Media Clock)
这种方式生成的是burst间隔,通常用来按buffer size生成timer
audio file (一大锅米饭)
burst transfer (一大勺=32口米饭)
continuous streaming (一口一口吃)
jitter buffer: https://bit.ly/44O1PVL
借助jitter buffer(碗和大小勺子)把burst transfer变成continuous streaming
声卡上有一个小缓冲区(碗)
声卡的控制器(大小勺子)在晶振的固定频率(continuous)下喂给dac数据(一小勺)
碗快空了就通知主机或者自己再添一大勺饭到碗里(burst)
只向主机要一小勺会生气!! (浪费bus)
会用到的结束
举例子 播MP3文件
通常mp3 decoder通常会耗尽CPU把mp3转回pcm数据并写入声卡
(对,burst,没有速率控制)
但声卡的缓冲区很小且消耗速度是固定的,
decoder必须先暂停然后等待声卡告知自己的缓冲区空出一部分
然后再次写入直到播放完毕
此时MP3的总播放长度与dac时钟速度成比例
短期看播放速率是毛刺状(burst),长期看播放速率固定在dac时钟速率
还可以看到主机的所有时间都和播放无关,
实际上正在使用声卡提供的指示来计算时间.
VAD 就是声卡
使用ptp来的校准 在正确的时间生成定时器中断
~~~~ ~~~~~~~~~~
(burst间隔,1/sample rate * buffer size, 1ms级)
可以看做把声卡晶振的固定频率连接到VAD做时钟(固定的消耗速度)
主机会一次填满缓冲区,定时器提前或延后都不会影响音频数据的完整性
~~~~~~~~~~~~~~
配合接收端jitter buffer把burst数据平滑到continuous,
dac端使用dpll同步到和burst长期速率一致的GM时钟,
burst间隔取决于选择的缓冲区大小,
以32个sample 44.1k为例
只要在和GM同步的timer时间的+-0.7ms内发包,jitter buffer就能维持精确输出.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
VAD最大PTP校正能力是+-1.2x系统时间 外加最短0.125秒生成一次校正,
macOS上的VAD默认使用"clock monotonic"形态的时钟,
可以受ntp影响,但周期长于VAD PTP的校正,且校正量通常远小于jitter容忍范围
除了可能造成解锁外功能可以忽略
如果系统时钟波动过大或者调度器没办法在jitter容忍范围内把RTP包发到接收器
Merging的VAD会在system.log和dmesg里留下痕迹
使用中最大的问题是调度器导致定时器fire过晚,ms级
要提到的还有之所以其他设备的delta很小,
是因为他们的系统会选择ptp做时钟源,
系统时间紧密贴合PTP GM,
macOS没法用PTP做时钟源,所以很难消掉