|
解码器的抖动会导致音频输出信号出现非谐波失真, 而这非谐波失真是人耳所难以接受的, 所以设计电路时要尽可能的把抖动率降低.
对于一个16位20KHz的信号而言, 121pS 的抖动等于LSB也就是最低有效位的变化, 咱们以这个数字的三分之一作为设计目标, 也就是不大于40pS才不会造成信号显着的恶化.对于一个24位20KHz的信号就更为严峻了, 不过目前市面上最优秀的解码芯片能做到的只是20位精度左右, 以这个精度来说, 抖动率要求是2.5pS以下.业余条件下咱们可以使用有一定质量的声卡和免费或有试用期的测试软件进行测试. 声卡的ADC部分对抖动比较不敏感, 对比DAC解码部分来说会好了许多, 对一般的解码器测试是足够了.
一般优质的高性能解码器的抖动率是100pS左右, 可以使用测试软件如ARTA来测试, 不过ARTA的抖动测试信号调制峰值是-123dB左右, 只能测试到10pS以上的jitter, 如果要测试更低的抖动率就不行了.于是俺编写了一个函数由STM32F405单片机来生成这个更高精度的抖动率测试信号:
生成一个大约是-3分贝幅度的测试信号, 这个正弦波频率是采样率的整倍分数, 44.1K的四分之一采样率 = 11025Hz, 再以192分之一的采样率(229.6875Hz)来调制这个信号, 调制幅度是24位中最小的一个位, 这样调制幅度的变化就会低于-160dB而被底噪淹没了, 也不会造成观察FFT频谱时误判了. 这里用了 0xBFFFFE, 0xBFFFFE, 0x400001,0x400001 重复24次, 然后每192个周期一次 0xC00000, 0xC00000, 0xC00000, 0xC00000. 最后不停的循环这2组数据. 这样一个最低有效值位数的轻微调制会导致几乎所有的24位数据发生0和1的翻转变化,也就是说可以诱发产生极致恶化的抖动以便于观察了.
每个周期刚好是四个采样点, 每个采样点都固定在同一个相位和幅度, 因为加入了229.6875Hz方波的调制, 所以在11,025Hz 的左右2边每间隔229.6875Hz会产生一个抖动峰值, 这样就可以轻易从FFT频谱观察到和计算抖动的幅度了. (倘若采样点不是整倍数, 每个周期的采样点的相位和幅度都会不断的变化, 这样的话所产生的抖动峰值就不断的移动而不是固定的, 看起来像噪音一样, 也就无法直接观察到了)
测试频谱时设置了MI软件的FFT窗口为 Kaiser7 以降低频谱泄漏, 和四百万个采样点数来提高解析度.从频谱图找出基频11025Hz以外近端的最高峰值之后就可以用下面的公式来计算出抖动率了:
信号幅度 [db] = 20 log ( 1 / ( 2 x 3.1416 x 信号频率 ** x jitter [pico-second] ) )
峰值dB = 20 log ( 1 / (69272 x jitter) )
-103.2dB = 100pS 抖动率
-109.2dB = 50pS 抖动率
-123.2dB = 10pS 抖动率
-143.2dB = 1pS 抖动率
下面这个是ARTA测试软件生成的24位44.1K抖动测试音频文件的开头部分
00000000 52 49 46 46 48 40 F2 00-57 41 56 45 66 6D 74 20 RIFFH@..WAVEfmt
00000010 28 00 00 00 FE FF 02 00-44 AC 00 00 98 09 04 00 (.......D.......
00000020 06 00 18 00 16 00 18 00-00 00 00 00 01 00 00 00 ................
00000030 00 00 10 00 80 00 00 AA-00 38 9B 71 66 61 63 74 .........8.qfact
00000040 04 00 00 00 00 00 00 00-64 61 74 61 00 40 F2 00 ........data.@..
00000050 80 00 C0 80 00 C0 80 FF-BF 80 FF BF 80 00 40 80 ..............@.
00000060 00 40 80 00 40 80 00 40-80 FF BF 80 FF BF 80 FF .@..@..@........
00000070 BF 80 FF BF 80 00 40 80-00 40 80 00 40 80 00 40 ......@..@..@..@
00000080 80 FF BF 80 FF BF 80 FF-BF 80 FF BF 80 00 40 80 ..............@.
00000090 00 40 80 00 40 80 00 40-80 FF BF 80 FF BF 80 FF .@..@..@........
000000A0 BF 80 FF BF 80 00 40 80-00 40 80 00 40 80 00 40 ......@..@..@..@
000000B0 80 FF BF 80 FF BF 80 FF-BF 80 FF BF 80 00 40 80 ..............@.
000000C0 00 40 80 00 40 80 00 40-80 FF BF 80 FF BF 80 FF .@..@..@........
000000D0 BF 80 FF BF 80 00 40 80-00 40 80 00 40 80 00 40 ......@..@..@..@
000000E0 80 FF BF 80 FF BF 80 FF-BF 80 FF BF 80 00 40 80 ..............@.
000000F0 00 40 80 00 40 80 00 40-80 FF BF 80 FF BF 80 FF .@..@..@........
我们可以看出来测试数据是循环 0xBFFF80 0xBFFF80 0xBFFF80 0xBFFF80 0x400080 0x400080 0x400080 0x400080, 然后每隔192个采样就加入调制信号 0xC00080 0xC00080 来代替一组 0xBFFF80 0xBFFF80,每一个数据的最后都是 80, 不会变化, 也就是说虽然数据是24位的, 然而却调制到最后精度只有16位而已.
以下是使用ARTA测试软件生成的音频测试文件写入SD卡后再由播放器来播放, 音频输出接到EMU-1212m声卡的输入以MI软件测试所得到的结果. 播放器的解码器是ES9018, 主基准时钟是5元一枚的廉价贴片晶振.
可以看出来基频11025Hz的左右2边间隔229.6875Hz就会产生一个小峰值, 所有的小峰值都基本是一样的幅度, -123dB左右(10pS) 没有任何突出的一个, 这意味着这是调制信号本身的幅度, 被测的解码器所产生的抖动率低于调制信号都被掩埋瞅不见了.
这是生成更高精度测试信号的源代码:
switch(SignalType)
{
case jitter: /* 生成 11025Hz 信号, 幅度 -3dB, 调制信号 229.6875Hz */
while(dest < PCM_BlockSize/4)
{
for( count=0; count<48; count++ ) //48 * 4 个周期每声道
{
for( count0=0; count0<4; count0++ ) //下半个周期2个采样点, 225度和315度, 左右声道就是4个采样点
{
buff[dest++] = 0xFE00BFFF; //字节大端次序 2301
}
for( count0=0; count0<4; count0++ ) //上半个周期2个采样点, 45度和135度, 左右声道就是4个采样点
{
buff[dest++] = 0x01004000; //字节大端次序 2301
}
}
buff[dest-384] = 0x0000C000; //每192个周期加入调制信号=229.6875Hz, 左右声道就双倍地址
buff[dest-383] = 0x0000C000;
}
break;
以下是直接由播放器单片机STM32F405生成更高精度测试信号以I2S送到ES9018. 主基准时钟是5元一枚的廉价贴片晶振, 音频输出接到EMU-1212m声卡的输入以MI软件测试所得到的结果.
可以看出来基频11025Hz的左右2边有许多高低不一的小峰值, 最高幅度在-140dB 以下, 可以算出抖动率是低于2pS (也许是声卡的极限). 以一枚5元的贴片晶振为时基而得到如此优秀的效果, ES9018 确实是有效的解决了抖动的问题.以下顺便提供2张硬件默认和软件优化设置ES9018的频谱图:
软件优化后的高次谐波和高频干扰降低了许多.
|
|