wince下音频驱动架构及数据输出流程

wince7下音频驱动学习(以DM3730为例,主要是数据的输出控制流程)


1、音频硬件连接如下所示:

        McBsp是DM3730上的一个多通道缓冲串行端口,这里音频驱动使用了其中的模块2。音频数据从McBsp2输出,TPS659XX将其解码后输出模拟信号到喇叭。


        在wince下音频驱动有3模式:1.MDD/PDD模式.2.Wavedev2模式.3.UAM模式。我的代码中音频驱动是分为两层的,一层是与硬件无关的驱动tps659xx_wave.dll(WAV层),另一层是与硬件相关的驱动omap_mcbsp.dll(MCP),这两个驱动都是标准的流接口驱动。

2、tps659xx_wave.dll的流接口函数在Wavemain.cpp中,如下所示:


        这几个函数名是微软统一的音频驱动接口,wince系统通过这几个函数来实现音频的各种功能。其中最重要的是WAV_IOControl(),系统调用WAV_IOControl()并通过PMMDRV_MESSAGE_PARAMS结构体的uMsg成员传入各种命令来控制音频驱动,所以驱动中需要实现这些命令各自对应的功能。

对于音频输出的命令主要有(并没有全部列出,在vs2008的help文档可看到全部命令的详解)

WODM_OPEN:请求音频驱动创建一个指定设备的实例

WODM_CLOSE:关闭由WODM_OPEN所创建的指定设备的实例

WODM_PAUSE:暂停音频输出

WODM_RESTART:继续音频输出

WODM_WRITE:向指定设备写入波形数据块

WODM_SETVOLUME:设置音量

WODM_GETPOS:获取当前音频播放位置


以下是加载tps659xx_wave.dll驱动,并发出一次触摸屏声音时所打印的信息。

加载dll时打印的信息

PID:00400002 TID:01F7000EWAV:WIDM_GETNUMDEVS

PID:00400002 TID:01F7000E WAV:WIDM_SETPROP

PID:00400002 TID:01F7000EWAV:WODM_GETNUMDEVS

PID:00400002 TID:01F7000EWAV:WODM_GETEXTDEVCAPS

PID:00400002 TID:01F7000E WAV:WODM_SETPROP

PID:00400002 TID:01F7000EWAV:WODM_SETVOLUME

PID:00400002 TID:01F7000EWAV:+process_MixerMessage()

PID:00400002 TID:01F7000EWAV:MXDM_GETNUMDEVS

PID:00400002 TID:01F7000EWAV:-process_MixerMessage()

点击screen一次打印的信息

PID:00400002 TID:074A3C5A WAV:WODM_OPEN

PID:00400002 TID:074A3C5A WAV:WODM_PAUSE

PID:00400002 TID:074A3C5A WAV:WODM_WRITE

PID:00400002 TID:074A3C5A WAV:WODM_WRITE

PID:00400002 TID:074A3C5A WAV:WODM_WRITE

PID:00400002 TID:074A3C5A WAV:WODM_WRITE

PID:00400002 TID:074A3C5A WAV:WODM_RESTART

PID:00400002 TID:0769001A WAV:WODM_WRITE

PID:00400002 TID:0769001A WAV:WODM_WRITE

PID:00400002 TID:0769001A WAV:WODM_WRITE

PID:00400002 TID:0769001A WAV:WODM_WRITE

PID:00400002 TID:0769001A WAV:WODM_WRITE

PID:00400002 TID:0769001A WAV:WODM_PAUSE

PID:00400002 TID:0769001A WAV: WODM_CLOSE

每次发出一段声音时,流程都与此类似,唯有WODM_WRITE次数不一样(声音数据大小有关)。

3、omap_mcbsp.dll驱动主要是对McBsp模块直接进行初始化和操作,接口函数为:


CopyTransferInfo():在这个函数中会相互交换MCP驱动和WAV驱动的一些接口函数指针,这样这两个驱动就能通过这些函数指针调用对方的接口函数了。

TxCommand():当系统给WAV层传入WODM_RESTART和WODM_PAUSE命令时,WAV层就会调用这个函数,并通过这个函数来调用StartTransmit()和StopTransmit()来开启或者关闭MCP层的DMA音频数据传输。

StartTransmit():用于开启MCP层的第一次DMA数据传输,

ST_TxDMA():与StartTransmit()函数一样,用于开启MCP层的DMA数据传输。不同的是IST_TxDMA()是线程函数,这个线程在MCP_Init()中被创建,它会等待DMA数据传输完成中断,然后开启下一次DMA传输。这就解释了,为什么只要发送一次WODM_RESTART命令(只执行一次StartTransmit()函数),音频数据就能一段一段的被McBsp2发送出去。

4、音频数据的输出传递

        我们知道系统通过WODM_WRITE命令将音频数据一段一段的传输到WAV层,WAV层再将这些音频数据传输到MCP层,MCP层将这些数据通过McBsp2发送给解码器。那么音频数据具体是怎么存储怎么传递的呢?实际上音频数据采用的是先进先出的队列(单链表结构)存储方式,数据由WAV层入队,由MCP层出队。


        在WAV层使用了3个指针来管理这个链表:m_lpWaveHdrHead、m_lpWaveHdrCureent、m_lpWaveHdrTail,分别指向了链表头单元、当前单元、链表尾单元。假设当前系统将data5数据块传输到WAV层,WAV层就会将这个data5插入队尾,此时m_lpWaveHdrTail就会指向这个data5数据块。当MCP层需要获取音频数据时(执行StartTransmit和ST_TxDMA这两个函数时),就会调用WAV层的接口函数(在CopyTransferInfo()函数中获取的)从这个队列的头部获取数据块,然后m_lpWaveHdrHead和m_lpWaveHdrCureent指针会指向队列中的下一个数据块。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值