免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1238 | 回复: 0
打印 上一主题 下一主题

ALSA 0.9.0 HOWTO -- 基本PCM音频 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-06-03 10:46 |只看该作者 |倒序浏览
作者: Matthias Nagorni
译者: Kevin Lei
转载请注明出处:http://kevinlei.cublog.cn
1. 介绍
这个HOWTO计划提供一个简短的介绍,使用ALSA 0.9.0写一个简单的音频应用程序.
Section2解释了PCM音频最基本的函数.如果你删除其中的解释文本,那么最后你会得到一个极小的PCM回放程序. Section3简短地讨论了一些PCM截获函数.
在Section4
你将学习怎么为ALSA音序器写一个简单的客户端.这一章节基于seqdemo.c这个例子,一个可以接收MIDI事件并且表示大多数重要的事件类型的程
序.Section5演示ALSA
MIDI音序器怎样被用于"路由"MIDI事件,从一个输入端口到一些输出端口.这一段基于midiroute.c这个例子.
Section6
使PCM回放和MIDI输入联结起来,并且解释了迷你合成器--miniFMsynth.c.这一章节引入基于回调的音频回放,就像Paul
Davis在linux-audio-dev邮件列表里建议的那样.Section7对基于ALSA音序器队列的MIDI调度提供一个短小的介绍,基于
miniArp.c这个例子.
推荐你也看看doxygen生成的ALSA库函数参考.
编译一个ALSA应用程序:
只要用-lasound参数并且确保你已包含了
#include
2. 基本PCM音频
为ALSA 0.9.0写一个简单的PCM应用程序我们首先需要一个PCM设备的句柄.然后我们必须指定同时可供回放或截获的PCM流的方向.我们同样必须提供一些关于我们想要使用的设置选项的信息,比如缓冲区大小,采样率,PCM数据格式等.所以,首先我们声明:
  
    /* Handle for the PCM device */
    snd_pcm_t *pcm_handle;         
    /* Playback stream */
    snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
    /* This structure contains information about    */
    /* the hardware and can be used to specify the  */      
    /* configuration to be used for the PCM stream. */
    snd_pcm_hw_params_t *hwparams;
  

重要的ALSA PCM设备接口是"plughw"和"hw"接口.
如果你使用"plughw"接口,你不需要很在意声卡硬件.如果你的声卡不支持你指定的采样率或采样格式,你的数据将自动被转换.这同样适用于声道的访问
类型和号码.对于"hw"接口,你必须检查你的硬件是否支持你想要使用的设置选项.
    /* Name of the PCM device, like plughw:0,0          */
    /* The first number is the number of the soundcard, */
    /* the second number is the number of the device.   */
    char *pcm_name;
  
然后我们初始化变量并分配一个hwparams结构:
    /* Init pcm_name. Of course, later you */
    /* will make this configurable ;-)     */
    pcm_name = strdup("plughw:0,0");
  
    /* Allocate the snd_pcm_hw_params_t structure on the stack. */
    snd_pcm_hw_params_alloca(&hwparams);
  
现在我们可以打开PCM设备:
    /* Open PCM. The last parameter of this function is the mode. */
    /* If this is set to 0, the standard mode is used. Possible   */
    /* other values are SND_PCM_NONBLOCK and SND_PCM_ASYNC.       */
    /* If SND_PCM_NONBLOCK is used, read / write access to the    */
    /* PCM device will return immediately. If SND_PCM_ASYNC is    */
    /* specified, SIGIO will be emitted whenever a period has     */
    /* been completely processed by the soundcard.                */
    if (snd_pcm_open(&pcm_handle, pcm_name, stream, 0)
    snd_pcm_hw_params_is_
    snd_pcm_hw_params_get_
  
绝大多数重要的参数的可用性,换句话说,访问类型,缓冲区大小,声道号码,采样格式,采样率,以及周期数目,可以以函数命名的一个集合来检验.
    snd_pcm_hw_params_test_
如果"hw"接口被使用,这些查询函数尤其重要.设置选项空间能以一个函数命名的集合限制在某一设置选项
    snd_pcm_hw_params_set_
  
例如,我们假设声卡可以被设置为16位,Little Endian数据的立体声回放,44100Hz采样率.相应地,我们限制设置选项空间匹配于这个设置选项:
    int rate = 44100; /* Sample rate */
    int exact_rate;   /* Sample rate returned by */
                      /* snd_pcm_hw_params_set_rate_near */
    int dir;          /* exact_rate == rate --> dir = 0 */
                      /* exact_rate  dir = -1 */
                      /* exact_rate > rate  --> dir = 1 */
    int periods = 2;       /* Number of periods */
    snd_pcm_uframes_t periodsize = 8192; /* Periodsize (bytes) */
  
访
问类型指定了哪一个多声道数据储存在缓冲区的方法.对于交错访问,缓冲区里的每一个帧为声道容纳连续的采样数据.对于16位立体声数据,这意味着缓冲区以
字为单位为左右声道交错地容纳采样数据.对于非交错访问,每一个周期为第一个声道容纳所有采样数据接着是第二个声道的采样数据.
  
    /* Set access type. This can be either    */
    /* SND_PCM_ACCESS_RW_INTERLEAVED or       */
    /* SND_PCM_ACCESS_RW_NONINTERLEAVED.      */
    /* There are also access types for MMAPed */
    /* access, but this is beyond the scope   */
    /* of this introduction.                  */
    if (snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)  Using %d Hz instead.\n", rate, exact_rate);
    }
    /* Set number of channels */
    if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2) >2) > 2;
    for(l1 = 0; l1 > 8;
        data[4*l2+2] = (unsigned char)s2;
        data[4*l2+3] = s2 >> 8;
      }
      while ((pcmreturn = snd_pcm_writei(pcm_handle, data, frames)) >>>>>>>>>>>>>>\n");
      }
    }
如果我们想中止回放,我们既可以使用snd_pcm_drop,也可以使用snd_pcm_drain.第一个函数将立即中止回放并丢弃未回放的帧.后一个函数将在回放完所有帧后中止回放.
    /* Stop PCM device and drop pending frames */
    snd_pcm_drop(pcm_handle);
    /* Stop PCM device after pending frames have been played */
    snd_pcm_drain(pcm_handle);
(全文完)
参考链接:
原文
http://www.suse.de/~mana/alsa090_howto.html
Linux音频编程指南
http://www-128.ibm.com/developerworks/cn/linux/l-audio/
A Tutorial on Using the ALSA Audio API
http://www.equalarea.com/paul/alsa-audio.html
The ALSA library API reference
http://www.alsa-project.org/alsa-doc/alsa-lib/
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/70719/showart_724538.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP