diff options
Diffstat (limited to 'zh_CN.GB2312/books/arch-handbook/sound/chapter.xml')
-rw-r--r-- | zh_CN.GB2312/books/arch-handbook/sound/chapter.xml | 130 |
1 files changed, 60 insertions, 70 deletions
diff --git a/zh_CN.GB2312/books/arch-handbook/sound/chapter.xml b/zh_CN.GB2312/books/arch-handbook/sound/chapter.xml index c2c97f1803..79125a0a54 100644 --- a/zh_CN.GB2312/books/arch-handbook/sound/chapter.xml +++ b/zh_CN.GB2312/books/arch-handbook/sound/chapter.xml @@ -6,28 +6,20 @@ Original Revision: 1.10 $FreeBSD$ --> - -<chapter id="oss"> - <chapterinfo> +<chapter xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:id="oss"> + <info><title>声音子系统</title> <authorgroup> - <author> - <firstname>Jean-Francois</firstname> - <surname>Dockes</surname> - <contrib>&cnproj.contributed.by;</contrib> - </author> + <author><personname><firstname>Jean-Francois</firstname><surname>Dockes</surname></personname><contrib>&cnproj.contributed.by;</contrib></author> </authorgroup> <authorgroup> - <author> - &author.cn.spellar; - <contrib>&cnproj.translated.by;</contrib> - </author> + <author><personname/><contrib>&cnproj.translated.by;</contrib></author> </authorgroup> - <!-- 23 November 2001 --> - </chapterinfo> + + </info> - <title>声音子系统</title> + - <sect1 id="oss-intro"> + <sect1 xml:id="oss-intro"> <title>简介</title> <indexterm><primary>sound subsystem(声音子系统)</primary></indexterm> @@ -61,10 +53,10 @@ </itemizedlist> <para>对特定声卡的支持是通过硬件特定的驱动程序来实现的,这些驱动程序 - 提供通道和混音器接口,插入到通用<devicename>pcm</devicename>代码中。 + 提供通道和混音器接口,插入到通用<filename>pcm</filename>代码中。 </para> - <para>本章中,术语<devicename>pcm</devicename>将指声音驱动程序的 + <para>本章中,术语<filename>pcm</filename>将指声音驱动程序的 中心,通用部分,这是对比硬件特定的模块而言的。</para> <para>预期的驱动程序编写者当然希望从现有模块开始,并使用那些代码作为 @@ -73,13 +65,13 @@ 一些问题。</para> <para>作为另外的途径,或者说除了从一个可工作的范例开始的办法之外, - 你可以从<ulink url="http://people.FreeBSD.org/~cg/template.c"> - http://people.FreeBSD.org/~cg/template.c</ulink>找到一个注释过的 + 你可以从<link xlink:href="http://people.FreeBSD.org/~cg/template.c"> + http://people.FreeBSD.org/~cg/template.c</link>找到一个注释过的 驱动程序模板。</para> </sect1> - <sect1 id="oss-files"> + <sect1 xml:id="oss-files"> <title>文件</title> <para>除<filename>/usr/src/sys/sys/soundcard.h</filename>中的公共 @@ -93,20 +85,19 @@ </sect1> - <sect1 id="pcm-probe-and-attach"> + <sect1 xml:id="pcm-probe-and-attach"> <title>探测,连接等</title> <para>声音驱动程序使用与任何硬件驱动程序模块相同的方法探测和连接(设备)。 - 你可能希望浏览一下手册中<link linkend="isa-driver">ISA</link>或<link - linkend="pci">PCI</link>章节的内容来获取更多信息。</para> + 你可能希望浏览一下手册中<link linkend="isa-driver">ISA</link>或<link linkend="pci">PCI</link>章节的内容来获取更多信息。</para> <para>然而,声音驱动程序在某些方面又有些不同:</para> <itemizedlist> <listitem> - <para>他们将自己声明为<devicename>pcm</devicename>类设备,带有一个 - 设备私有结构<structname>struct snddev_info</structname>:</para> + <para>他们将自己声明为<filename>pcm</filename>类设备,带有一个 + 设备私有结构<varname remap="structname">struct snddev_info</varname>:</para> <programlisting> static driver_t xxx_driver = { "pcm", @@ -122,13 +113,13 @@ 结构通常在连接例程中分配。其地址通过调用 <function>pcm_register()</function>和 <function>mixer_init()</function>传递给 - <devicename>pcm</devicename>。后面<devicename>pcm</devicename> + <filename>pcm</filename>。后面<filename>pcm</filename> 将此地址作为调用声音驱动程序接口时的参数传递回来。</para> </listitem> <listitem> <para>声音驱动程序的连接例程应当通过调用<function>mixer_init() - </function>向<devicename>pcm</devicename>声明它的MIXER或AC97 + </function>向<filename>pcm</filename>声明它的MIXER或AC97 接口。对于MIXER接口,这会接着引起调用 <link linkend="xxxmixer-init"> <function>xxxmixer_init()</function></link>。</para> @@ -137,9 +128,9 @@ <listitem> <para>声音驱动程序的连接例程通过调用 <function>pcm_register(dev, sc, nplay, nrec)</function> - 向<devicename>pcm</devicename>声明其通用CHANNEL配置,其中 + 向<filename>pcm</filename>声明其通用CHANNEL配置,其中 <varname>sc</varname>是设备数据结构的地址, - 在<devicename>pcm</devicename>以后的调用中将会用到它, + 在<filename>pcm</filename>以后的调用中将会用到它, <varname>nplay</varname>和<varname>nrec</varname>是播放和录音 通道的数目。</para> </listitem> @@ -147,7 +138,7 @@ <listitem> <para>声音驱动程序的连接例程通过调用 <function>pcm_addchan()</function>声明它的每个通道对象。这会在 - <devicename>pcm</devicename>中建立起通道合成,并接着会引起调用 + <filename>pcm</filename>中建立起通道合成,并接着会引起调用 <link linkend="xxxchannel-init"> <function>xxxchannel_init()</function></link> (译注:请参考原文)。</para> @@ -174,7 +165,7 @@ </listitem> </itemizedlist> - <para><devicename>pcm</devicename>驱动程序应当实现 + <para><filename>pcm</filename>驱动程序应当实现 <function>device_suspend</function>, <function>device_resume</function>和 <function>device_shutdown</function>例程,这样电源管理和模块卸载就能 @@ -182,10 +173,10 @@ </sect1> - <sect1 id="oss-interfaces"> + <sect1 xml:id="oss-interfaces"> <title>接口</title> - <para><devicename>pcm</devicename>核心与声音驱动程序之间的接口以术语 + <para><filename>pcm</filename>核心与声音驱动程序之间的接口以术语 <link linkend="kernel-objects">内核对象</link>的叫法来定义。</para> <para>声音驱动程序通常提供两种主要的接口: @@ -194,7 +185,7 @@ <para><emphasis>AC97</emphasis>是一个很小的硬件访问(寄存器读/写) 接口,由驱动程序为带AC97编码解码器的硬件来实现。这种情况下,实际的 - MIXER接口由<devicename>pcm</devicename>中共享的AC97代码提供。 + MIXER接口由<filename>pcm</filename>中共享的AC97代码提供。 </para> <sect2> @@ -211,7 +202,7 @@ <para>第二个参数是指向私有的通道数据结构的指针, <function>channel_init()</function>是个例外,它的指针指向私有 - 设备结构(并返回由<devicename>pcm</devicename>以后使用的通道指针)。 + 设备结构(并返回由<filename>pcm</filename>以后使用的通道指针)。 </para> </sect3> @@ -219,12 +210,12 @@ <sect3> <title>数据传输操作概览</title> - <para>对于声音数据传输,<devicename>pcm</devicename>核心与声音驱动 - 程序是通过一个由<structname>struct snd_dbuf</structname>描述的 + <para>对于声音数据传输,<filename>pcm</filename>核心与声音驱动 + 程序是通过一个由<varname remap="structname">struct snd_dbuf</varname>描述的 共享内存区域进行通信的。</para> - <para><structname>struct snd_dbuf</structname>是 - <devicename>pcm</devicename>私有的,声音驱动程序通过调用访问者 + <para><varname remap="structname">struct snd_dbuf</varname>是 + <filename>pcm</filename>私有的,声音驱动程序通过调用访问者 函数(<function>sndbuf_getxxx()</function>)来获得感兴趣的值。 </para> @@ -237,9 +228,8 @@ <itemizedlist> <listitem> - <para><devicename>pcm</devicename>开始时填充缓冲区,然后以 - 参数PCMTRIG_START调用声音驱动程序的<link - linkend="channel-trigger"> + <para><filename>pcm</filename>开始时填充缓冲区,然后以 + 参数PCMTRIG_START调用声音驱动程序的<link linkend="channel-trigger"> <function>xxxchannel_trigger()</function></link> 。</para> </listitem> @@ -249,7 +239,7 @@ <function>sndbuf_getblksz()</function>字节大小为块,重复将 整个内存区域(<function>sndbuf_getbuf()</function>, <function>sndbuf_getsize()</function>)传输到设备。对于每个 - 传输块回调<devicename>pcm</devicename>函数 + 传输块回调<filename>pcm</filename>函数 <function>chn_intr()</function>(这通常在中断时间发生)。 </para> </listitem> @@ -257,14 +247,14 @@ <listitem> <para><function>chn_intr()</function>安排将新数据拷贝到那些 数据已传输到设备(现在空闲)的区域,并对 - <structname>snd_dbuf</structname>结构进行适当的更新。</para> + <varname remap="structname">snd_dbuf</varname>结构进行适当的更新。</para> </listitem> </itemizedlist> </sect3> - <sect3 id="xxxchannel-init"> + <sect3 xml:id="xxxchannel-init"> <title>channel_init</title> <para>调用<function>xxxchannel_init()</function>来初始化每个播放 @@ -273,27 +263,27 @@ <programlisting> static void * xxxchannel_init(kobj_t obj, void *data, - struct snd_dbuf *b, struct pcm_channel *c, int dir)<co id="co-chinit-params"/> + struct snd_dbuf *b, struct pcm_channel *c, int dir)<co xml:id="co-chinit-params"/> { struct xxx_info *sc = data; struct xxx_chinfo *ch; ... - return ch;<co id="co-chinit-return"/> + return ch;<co xml:id="co-chinit-return"/> }</programlisting> <calloutlist> <callout arearefs="co-chinit-params"> <para><varname>b</varname>为通道 - <structname>struct snd_dbuf</structname>的地址。它应当在 + <varname remap="structname">struct snd_dbuf</varname>的地址。它应当在 函数中通过调用<function>sndbuf_alloc()</function>来初始化。 所用的缓冲区大小通常是设备'典型'传输大小的一个较小的倍数。 </para> <para><varname>c</varname>为 - <devicename>pcm</devicename>通道控制结构的指针。这是个不透明 + <filename>pcm</filename>通道控制结构的指针。这是个不透明 指针。函数应当将它保存到局部通道结构中,在后面调用 - <devicename>pcm</devicename>函数(例如: + <filename>pcm</filename>函数(例如: <function>chn_intr(c)</function>)时会使用它。</para> <para><varname>dir</varname>指示通道方向 @@ -318,7 +308,7 @@ 特定声音格式设置硬件。</para> <programlisting> static int - xxxchannel_setformat(kobj_t obj, void *data, u_int32_t format)<co id="co-chsetformat-params"/> + xxxchannel_setformat(kobj_t obj, void *data, u_int32_t format)<co xml:id="co-chsetformat-params"/> { struct xxx_chinfo *ch = data; ... @@ -355,9 +345,9 @@ <title>channel_setblocksize</title> <para><function>xxxchannel_setblocksize()</function>设置块大小, - 这是<devicename>pcm</devicename>与声音驱动程序,以及声音驱动 + 这是<filename>pcm</filename>与声音驱动程序,以及声音驱动 程序与设备之间的传输单位的大小。传输期间,每次传输这样大小的 - 数据后,声音驱动程序都应当调用<devicename>pcm</devicename>的 + 数据后,声音驱动程序都应当调用<filename>pcm</filename>的 <function>chn_intr()</function>。</para> <para>大多数驱动程序只注意这儿的块大小,因为当实际传输开始时应该 @@ -368,7 +358,7 @@ { struct xxx_chinfo *ch = data; ... - return blocksize;<co id="co-chsetblocksize-return"/> + return blocksize;<co xml:id="co-chsetblocksize-return"/> }</programlisting> <calloutlist> @@ -382,15 +372,15 @@ </sect3> - <sect3 id="channel-trigger"> + <sect3 xml:id="channel-trigger"> <title>channel_trigger</title> <para><function>xxxchannel_trigger()</function>由 - <devicename>pcm</devicename>来控制驱动程序中的实际传输操作。 + <filename>pcm</filename>来控制驱动程序中的实际传输操作。 </para> <programlisting> static int - xxxchannel_trigger(kobj_t obj, void *data, int go)<co id="co-chtrigger-params"/> + xxxchannel_trigger(kobj_t obj, void *data, int go)<co xml:id="co-chtrigger-params"/> { struct xxx_chinfo *ch = data; ... @@ -440,7 +430,7 @@ <para><function>xxxchannel_getptr()</function>返回传输缓冲区中 当前的缓冲。它通常由<function>chn_intr()</function>调用,而且 - 这也是为什么<devicename>pcm</devicename>知道它应当往哪儿传送 + 这也是为什么<filename>pcm</filename>知道它应当往哪儿传送 新数据。</para> </sect3> @@ -461,14 +451,14 @@ <programlisting> struct pcmchan_caps * xxxchannel_getcaps(kobj_t obj, void *data) { - return &xxx_caps;<co id="co-chgetcaps-return"/> + return &xxx_caps;<co xml:id="co-chgetcaps-return"/> }</programlisting> <calloutlist> <callout arearefs="co-chgetcaps-return"> <para>这个例程返回指向(通常静态定义的) - <structname>pcmchan_caps</structname>结构的指针(在 + <varname remap="structname">pcmchan_caps</varname>结构的指针(在 <filename>sound/pcm/channel.h</filename>中定义)。这个结构 保存着最小和最大采样频率和被接受的声音格式。任何声音驱动 程序都可以作为一个范例。</para> @@ -494,11 +484,11 @@ <sect2> <title>MIXER接口</title> - <sect3 id="xxxmixer-init"> + <sect3 xml:id="xxxmixer-init"> <title>mixer_init</title> <para><function>xxxmixer_init()</function>初始化硬件,并告诉 - <devicename>pcm</devicename>什么混音器设备可用来播放和录音。 + <filename>pcm</filename>什么混音器设备可用来播放和录音。 </para> <programlisting> static int @@ -509,7 +499,7 @@ [初始化硬件] - [为播放混音器设置v中适当的位]<co id="co-mxini-sd"/> + [为播放混音器设置v中适当的位]<co xml:id="co-mxini-sd"/> mix_setdevs(m, v); [为录音混音器设置v中适当的位] mix_setrecdevs(m, v) @@ -522,7 +512,7 @@ <para>设置一个整数值中的位,并调用 <function>mix_setdevs()</function>和 <function>mix_setrecdevs()</function>来告诉 - <devicename>pcm</devicename>存在什么设备。</para> + <filename>pcm</filename>存在什么设备。</para> </callout> </calloutlist> @@ -540,11 +530,11 @@ <programlisting> static int xxxmixer_set(struct snd_mixer *m, unsigned dev, - unsigned left, unsigned right)<co id="co-mxset-params"/> + unsigned left, unsigned right)<co xml:id="co-mxset-params"/> { struct sc_info *sc = mix_getdevinfo(m); [设置音量级别(level)] - return left | (right << 8);<co id="co-mxset-return"/> + return left | (right << 8);<co xml:id="co-mxset-return"/> }</programlisting> <calloutlist> @@ -568,14 +558,14 @@ </para> <programlisting> static int - xxxmixer_setrecsrc(struct snd_mixer *m, u_int32_t src)<co id="co-mxsr-params"/> + xxxmixer_setrecsrc(struct snd_mixer *m, u_int32_t src)<co xml:id="co-mxsr-params"/> { struct xxx_info *sc = mix_getdevinfo(m); [查看src中的非零位, 设置硬件] [更新src反映实际动作] - return src;<co id="co-mxsr-return"/> + return src;<co xml:id="co-mxsr-return"/> }</programlisting> <calloutlist> @@ -624,7 +614,7 @@ </itemizedlist> <para>The <emphasis>AC97</emphasis>接口由 - <devicename>pcm</devicename>中的AC97代码来执行高层操作。参看 + <filename>pcm</filename>中的AC97代码来执行高层操作。参看 <filename>sound/pci/maestro3.c</filename>或 <filename>sound/pci/</filename>下很多其他内容作为范例。</para> |