3 同步问题
由于USB总线拓扑结构的特殊性,所有数据传输都由主机(PC)发起,在设备插上USB接口并完成初始化、列举等步骤以后,主机会按照设备列举的要求进行流量分配。USB全速模式总线以1 ms为1帧。由于采用Isoch-ronous transfers模式,为测试方便,音频格式采用8 k/s采样率,8位量化。因此单声道每帧数据量为:
MCF52223通过USB D驱动在接收并解出USB数据包里的音频数据后,存入内部开辟的缓存中。ML2308每个声道具有64字节缓存,当缓存满、缓存一半和缓存为空时会分别发送中断信号Full、Mid、Empty给MCF52223,而MCF52223可以根据不同的中断信号对ML2308进行写入新数据工作。
因此,在设备的写入端数据按照PC上的USB的时钟进行传输,而在设备输出端数据按照ML2308的时钟进行操作。ML2308时钟来自板载晶振,这两个时钟不可避免存在一定误差,而且根据测试,不同PC的USB总线时钟也有微小差别。这些差异会造成设备内部缓存的音频数据不断被消耗殆尽,或者不断增加而最终溢出。因此,需要一个易于实现且对资源消耗量较小的方法来同步输入与输出信号。由于这种差异是不确定的,该算法需要一定的自适应能力。
4 自适应软件锁相环设计
之前采用简单的缓存门限控制方法判断是否需要插值,即当缓存高于某门限时,丢弃一个PCM样点。而当低于某一门限时,插入一个PCM样点,由于时钟速度差异的长期固有性,在插入/丢弃一个PCM样点后,缓存数量仍然可能继续减少或增加,从而造成程序无规律的爆发式的插入或丢弃数据操作,产生不可接受的噪音。
因而在算法设计时,重点考虑以下几点。
操作的稳定性:不能有对数据突发性的操作。
操作的分散性:要尽量平均的控制信号,把插入/丢弃产生的失真平均化。
资源消耗量小:要适应嵌入式系统成本低廉、片上存储、运算资源不是很富裕的客观条件。
音频的实时性:声音对实时性要求较高,不能出现停顿、明显延迟等情况。
因此,采用一种插入/丢弃样本间隔平均化的自适应模糊控制算法进行设计。
针对两次插值/丢弃操作之间的样点数进行控制,而非对样点本身,在每次插值/丢弃操作后进行速率匹配判断,修改插值/丢弃间隔。由于通常这种时钟差异在千分之一量级,插入/丢弃操作间隔也在千样点量级,大大减少了频繁的判断操作。算法结构如图3所示。
5 算法实现
由于每台电脑以及每块开发板的时钟都有误差,所以每次连接设备都需要检查两者时钟速率关系,实现该功能的关键代码如下: