pcm
核心与声音驱动程序之间的接口以术语
内核对象的叫法来定义。
声音驱动程序通常提供两种主要的接口: CHANNEL以及 MIXER或AC97。
AC97是一个很小的硬件访问(寄存器读/写)
接口,由驱动程序为带AC97编码解码器的硬件来实现。这种情况下,实际的
MIXER接口由pcm
中共享的AC97代码提供。
声音驱动程序通常用一个私有数据结构来描述他们的设备,驱动 程序所支持的播放和录音数据通道各有一个。
对于所有的CHANNEL接口函数,第一个参数是一个不透明的指针。
第二个参数是指向私有的通道数据结构的指针,
channel_init()
是个例外,它的指针指向私有
设备结构(并返回由pcm
以后使用的通道指针)。
对于声音数据传输,pcm
核心与声音驱动
程序是通过一个由struct snd_dbuf
描述的
共享内存区域进行通信的。
struct snd_dbuf
是
pcm
私有的,声音驱动程序通过调用访问者
函数(sndbuf_getxxx()
)来获得感兴趣的值。
共享内存区域的大小等于
sndbuf_getsize()
,并被分割为大小固定,且等于
sndbuf_getblksz()
字节的很多块。
当播放时,常规的传输机制如下(将意思反过来就是录音):
pcm
开始时填充缓冲区,然后以
参数PCMTRIG_START调用声音驱动程序的
xxxchannel_trigger()
。
声音驱动程序接着安排以
sndbuf_getblksz()
字节大小为块,重复将
整个内存区域(sndbuf_getbuf()
,
sndbuf_getsize()
)传输到设备。对于每个
传输块回调pcm
函数
chn_intr()
(这通常在中断时间发生)。
chn_intr()
安排将新数据拷贝到那些
数据已传输到设备(现在空闲)的区域,并对
snd_dbuf
结构进行适当的更新。
调用xxxchannel_init()
来初始化每个播放
和录音通道。这个调用从声音驱动程序的连接例程中发起。(参看
探测和连接一节)。
xxxchannel_setformat()
应当按特定通道,
特定声音格式设置硬件。
xxxchannel_setspeed()
按指定的取样速度
设置通道硬件,并返回返回可能调整过的速度。
xxxchannel_setblocksize()
设置块大小,
这是pcm
与声音驱动程序,以及声音驱动
程序与设备之间的传输单位的大小。传输期间,每次传输这样大小的
数据后,声音驱动程序都应当调用pcm
的
chn_intr()
。
大多数驱动程序只注意这儿的块大小,因为当实际传输开始时应该 使用这个值。
xxxchannel_trigger()
由
pcm
来控制驱动程序中的实际传输操作。
|
如果驱动程序使用ISA DMA,则应当在设备上执行动作前
调用sndbuf_isadma()
,并处理DMA芯片一方的
事情。
xxxchannel_getptr()
返回传输缓冲区中
当前的缓冲。它通常由chn_intr()
调用,而且
这也是为什么pcm
知道它应当往哪儿传送
新数据。
调用xxxchannel_free()
来释放通道资源,
例如当驱动程序卸载时,并且如果通道数据结构是动态分配的,或者
如果不使用sndbuf_alloc()
进行缓冲区分配,
则应当实现这个函数。
xxxmixer_init()
初始化硬件,并告诉
pcm
什么混音器设备可用来播放和录音。
混音器的位定义可以在soundcard.h
中
找到。(SOUND_MASK_XXX
值和
SOUND_MIXER_XXX
移位)。
xxxmixer_set()
为混音器设备设置音量级别
(level)。
xxxmixer_setrecsrc()
设定录音源设备。
本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.
如果对于FreeBSD有问题,请先阅读
文档,如不能解决再联系
<questions@FreeBSD.org>.
关于本文档的问题请发信联系
<doc@FreeBSD.org>.