usb audio--linux usb audio driver简要分析(4)
来源:互联网 发布:知否 书包网 编辑:程序博客网 时间:2024/06/06 18:40
Linux下的usb audio驱动基于ALSA 音频架构,这里只介绍usb audio驱动中的数据流向及反馈的处理,不涉及ALSA架构。
音频文件播放前的调用关系:
PCM的Trigger方法
调用 snd_usb_substream_playback_trigger 设定一些全局指针
PCM的Prepare方法
调用snd_usb_pcm_prepare
1. 调用snd_usb_init_sample_rate,设定usb device采样率等参数
2. 调用start_endpoints,开始USB数据传输
snd_usb_endpoint_start
反馈值的处理:
每次同步传输完成后调用驱动中注册的USB回调函数snd_complete_urb
prepare_outbound_urb -> prepare_playback_urbprepare_playback_urb函数调用snd_usb_endpoint_next_packet_size来计算下一个发送包的大小,该函数实现如下:
int snd_usb_endpoint_next_packet_size(struct snd_usb_endpoint *ep){ unsigned long flags; int ret; if (ep->fill_max) return ep->maxframesize; spin_lock_irqsave(&ep->lock, flags); ep->phase = (ep->phase & 0xffff) + (ep->freqm << ep->datainterval); ret = min(ep->phase >> 16, ep->maxframesize); spin_unlock_irqrestore(&ep->lock, flags); return ret;}
这里 ep->freqm是反馈端点获取的反馈值,以16:16的方式存储,即高16bit存储反馈值的高10bit,低16bit存储反馈值的低14bit,比如,48K反馈值,freqm 高16bit存储48,低16bit为0。Ep->datainterval在这里值为0,因此snd_usb_endpoint_next_packet_size函数实际上返回值就是usb device反馈的播放速率,如device反馈48K,snd_usb_endpoint_next_packet_size返回48,即下一个包大小为48 frames的audio 数据。这里host实际上发送速率就是device实际的播放速率了。当然如果反馈值是44.K 这样的值,snd_usb_endpoint_next_packet_size返回值会将小数部分累加,即返回值是 44.1K,44.2K,44.3K,44.4K等,直到达到45K,重新返回44.1K
反馈值的获取:
snd_usb_handle_sync_urb函数用于获取device的反馈值,主要实现如下:
void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, struct snd_usb_endpoint *sender, const struct urb *urb) { f = le32_to_cpup(urb->transfer_buffer); if (urb->iso_frame_desc[0].actual_length == 3) f &= 0x00ffffff; else f &= 0x0fffffff; if (f == 0) return; if (unlikely(ep->freqshift == INT_MIN)) { shift = 0; while (f < ep->freqn - ep->freqn / 4) { f <<= 1; shift++; } while (f > ep->freqn + ep->freqn / 2) { f >>= 1; shift--; } ep->freqshift = shift; } else if (ep->freqshift >= 0) f <<= ep->freqshift; else f >>= -ep->freqshift; if (likely(f >= ep->freqn - ep->freqn / 8 && f <= ep->freqmax)) { /* * If the frequency looks valid, set it. * This value is referred to in prepare_playback_urb(). */ spin_lock_irqsave(&ep->lock, flags); ep->freqm = f; spin_unlock_irqrestore(&ep->lock, flags); } else { /* * Out of range; maybe the shift value is wrong. * Reset it so that we autodetect again the next time. */ ep->freqshift = INT_MIN; } }
最终的反馈值会存储在 ep->freqm 中,也即上面我们在snd_usb_endpoint_next_packet_size中使用的那个变量。snd_usb_handle_sync_urb主要是对反馈值的范围进行判断(这里的取值范围前面已讲到),然后转换成16:16 的形式存储在ep->freqm中,这里ep->freqshift表示移位偏移,比如usb device 反馈值是10:14的格式,要转换成16:16格式,需要将device的反馈值左移2bit即可,因此ep->freqshift的值就是2。
windowns下的usb audio异步方式驱动
windows下的可以直接使用xmos的驱动(本人使用的驱动链接:http://download.csdn.net/detail/xjq163/9906107),只需将usb固件中PID和VID改成xmos支持的就行。
- usb audio--linux usb audio driver简要分析(4)
- USB Audio Class (UAC) 分析
- usb audio设备驱动
- android usb audio
- usb audio设备驱动
- USB Audio accessory设备
- USB audio调试
- android usb audio
- USB Audio (UAC) 简介
- Linux Audio Device Driver
- Linux Audio Device Driver
- Android下USB Audio注意事项
- 动态加载USB Audio Device
- 动态加载USB Audio Device
- USB audio on Android platform
- USB Audio设计与实现
- USB Audio设计与实现
- NanoPC-T2 支持USB Audio
- Mac使用AndroidStudio导入项目遇到的gradle syns failed的问题
- jquery报错
- 基于caffe的googlenet的多标签检测
- Yii2框架的搭建
- Apache for win x64 安装步骤
- usb audio--linux usb audio driver简要分析(4)
- CSS(进阶)
- jenkins安装和配置
- F
- Debug Assertion Failed!错误 关于m_File.m_hFile != NULL 和m_File.m_hFile != CFile::hFileNull 问题
- HTTP中的一些概念
- MySQL 浮点类型
- 数理逻辑1 -- 命题演算1
- yolo2检测到的物体位置输出