usb audio -- 异步方式介绍(1)
Usb audio目前已经有三个版本: 1.0,2.0,3.0 。1.0版本虽然出现的最早,但任然在大多数产品上使用,如TI 的 PCM系列usb audio芯片,基本上都是1.0的版本。 这里有一点需要明确,usb audio的版本并不是对应usb的版本。
同步传输:
usb支持的四种传输机制: 控制传输,中断传输,块传输,同步传输,其中同步传输适用于实时性要求比较高且对数据误差有一定容忍的场合,典型的如音频、视频输出。当然这种实时性是以牺牲数据准确率为代价的,Usb协议里面如何保证同步传输的实时性呢?
1. 无握手机制,即不使用retry 机制,所以在要保证同步传输的质量,高质量的USB线缆是必要的
2. 定义同步传输在所有传输方式里面的带宽优先级为最高
反馈引入:
Usb audio的数据都是通过同步传输到usb device的,虽然usb host能保证如上几点,但同步传输还是会有以下地点问题:
1. 主机受CPU负载影响,无法保证usb 同步数据的发送请求间隔
2. 由于usb host与usb device时钟不可能绝对同步,会导致usb device 端数据buff 出现 over run 或 under run
关于第二点,作以下说明:
比如PC播放一个48K采样率的音频文件,假定usb host按照标准的48K 采样率发送数据包,假定usb device端采样I2S接口播放音频数据,这里按照双通道,16bit数据宽度来计算,I2S理想的时钟应该为(48K * 16 *2)=1536K,但由于usb device I2S控制器的时钟生成机制缺陷,比如只能产生1530K 的时钟,那么就会导致I2S的数据消耗率小于usb host的数据发送率,最终就会出现 usb device buff over run
所以同步传输引入了同步机制来解决device与host数据不同步的问题。当然,如果不考虑各种兼容机制,全部自定义一套传输机制也是可以的,如 :
定义一个中断IN端点: usb device 每隔一定间隔返回自己buff的可用空间
定义一个bulk OUT 端点: usb host 用于发送音频数据
这样usb host根据 中断端点返回的device可用buff空间size,一次发送 size的数据到device即可。
这样也可以解决数据不同步问题,不过前提是usb device驱动,连带播放器应用程序都需要自己动手编写,工作量就大了。
同步方式:
USB协议定义了同步传输的三种同步机制:
1. Asynchronous
2. Synchronous
3. Adaptive
Synchronous模式
Usb device 根据host发送的SOF帧来同步数据的发送。SOF帧是数据的起始帧,对于USB full speed 设备,USB host以 1.00 ms ±0.0005 ms 的间隔发送SOF帧,对于high speed设备,间隔是125 µs ±0.0625 µs 。
这里以full speed设备为例来说明一种Synchronous同步方式。假定usb device的同步OUT端点设定的数据间隔也为1ms(即一个SOF帧传输一次数据),每隔一个SOF ,usb device接收一帧数据后重新启动一次DMA传输,这样usb device端的数据发送率就依据usb host 的SOF来同步。但由于usb host数据发送的不稳定情况和usb device自身发送时钟的不同步问题,任然会导致usb device buff的over 或 under,一般的解决办法是采用resample的方式来保证usb device端的数据已稳定时钟发送: 在over时丢弃某些samples,under时插入某些samples。
Adaptive模式
自适应模式,即device端自动适应host端的数据发送率。如:
1. 虽然host数据发送不稳定,device端主动调整自身数据发送时钟,适应host的数据发送率
2. device通过resample的方式,插入或者丢弃buff内的samples来保证自身数据发送率的稳定性
Asynchronous 模式
以上两种同步方式中原始audio数据总会有损失。而在asynchronous模式下,host会获取device端实际的数据发送率来实时调整自身数据发送率。Device端能依据这一点来保证自身发送buff的稳定性,从而解决数据同步的问题,如,host端发送速率为48K,device反馈实际播放速率为46K,那么主机就会调整自身发送速率为46K。一种典型的Asynchronous同步方式如下图:
以上两种同步方式中原始audio数据总会有损失。而在asynchronous模式下,host会获取device端实际的数据发送率来实时调整自身数据发送率。Device端能依据这一点来保证自身发送buff的稳定性,从而解决数据同步的问题,如,host端发送速率为48K,device反馈实际播放速率为46K,那么主机就会调整自身发送速率为46K。一种典型的Asynchronous同步方式如下图:
Device端有两个同步端点,一个用于音频数据接收,了一个用于反馈实际数据发送率。
相关文章
- Python如何实现异步IO
- python异步编程--回调模型(selectors模块)
- C# 异步工具类 及一点小小的重构经验
- 并发字典ConcurrentDictionary+迭代器--异步
- Gearmand异步处理就安全了吗?不!
- ASP.NET中AJAX的异步加载(Demo演示)
- 并发系列64章(异步编程)第二章
- AsyncHttpClient使用示例:java http异步请求和websocket客户端
- 用手动创建新的script标签的方式,实现JavaScript脚本的异步加载
- Atitit.异步的实现模式attilax大总结
- 【最全最详细】同步、异步、阻塞、非阻塞
- python异步生成器
- 【Kotlin 协程】协程简介 ( 协程概念 | 协程作用 | 创建 Android 工程并进行协程相关配置开发 | 异步任务与协程对比 )
- 【Android 异步操作】Handler 机制 ( Handler 常用用法 | HandlerThread 简介 | HandlerThread 源码注释分析 )
- 【Android 异步操作】AsyncTask 异步任务 ( FutureTask 模拟 AsyncTask 执行过程 | AsyncTask 执行过程回顾 | FutureTask 分析 )
- ios网络学习------1get post异步请求
- ava EE 7 - Injection into Runnable/Callable object ejb entityManager Concurrency ManagedExecutorService 异步调用如何获取context
- .net多线程,线程异步,线程同步,并发问题---1---ShinePans
- Vuejs设计与实现8-异步组件与内建组件