免费注册 查看新帖 |

Chinaunix

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

Linux下ALSA声卡编程(1) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-12-29 11:17 |只看该作者 |倒序浏览
一. 介绍
      ALSA 标准是一个先进的linux声音体系。它包含内核驱动集合,API库和工具对Linux声音进行支持。ALSA 包含一系列内核驱动对不同的声卡进行支持,还提供了libasound的API库。用这些进行写程序不需要打开设备等操作,所以编程人员在写程序的时候不会被底层的东西困扰。与此相反OSS/Free 驱动在内核层次调用,需要指定设备名和调用ioctl。为提供向后兼容, ALSA 提供内核模块模仿 OSS/Free 驱动,所以大多数的程序不需要改动。 ALSA 拥有调用插件的能力对新设备提供扩展,包括那些用软件模拟出来的虚拟设备。 ALSA 还提供一组命令行工具包括  mixer, sound file player 和工具控制一些特别的声卡的特别的作用。

二.ALSA 体系:
ALSA API 被主要分为以下几种接口:
l         控制接口:提供灵活的方式管理注册的声卡和对存在的声卡进行查询。
l         PCM接口:提供管理数字音频的捕捉和回放。
l         原始 MIDI 接口: 支持 MIDI (Musical Instrument Digital Interface), 一种标准电子音乐指令集。 这些 API 提供访问声卡上的 MIDI 总线。这些原始借口直接工作在 The  MIDI 事件上,程序员只需要管理协议和时间。
l         记时接口: 为支持声音的同步事件提供访问声卡上的定时器。
l         音序器接口:一个比原始MIDI接口高级的MIDI编程和声音同步高层接口。它可以处理很多的MIDI协议和定时器。
l         混音器接口:控制发送信号和控制声音大小的声卡上的设备。

三.声卡的缓存和数据的传输:
      一块声卡有一个声卡内存用来存储记录的样本。当它被写满时就产生中断。内核驱动就使用DMA将数据传输到内存中。同样地,当在播放时就将内存中的声音样本使用DMA传到声卡的内存中!
      声卡的缓存是环状的,这里只讨论应用程序中的内存结构:ALSA将数据分成连续的片段然后传到按单元片段传输。

四:典型的声音程序结构:
        open interface for capture or playback
        set hardware parameters
        (access mode, data format, channels, rate, etc.)
        while there is data to be processed:
        read PCM data (capture)
        or write PCM data (playback)
        close interface

五.一些例子:
1.显示一些PCM的类型和格式:

#include
#include

int main()
{
       std::cout
#include

int main()
{
       int                               rc;
       snd_pcm_t*                         handle;
       snd_pcm_hw_params_t*      params;
       unsigned int                  val, val2;
       int                               dir;
       snd_pcm_uframes_t             frames;

       if ( (rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0)) (frames)
#include

int main()
{
       long                             loops;
       int                               rc;
       int                                       size;
       snd_pcm_t*                         handle;
       snd_pcm_hw_params_t*      params;
       unsigned int                  val;
       int                               dir;
       snd_pcm_uframes_t             frames;
       char*                                  buffer;

       if ( (rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0))  0) {
              loops--;
              if ( (rc = read(0, buffer, size)) == 0)
              {
                     std::cerr
#include

int main()
{
       long                             loops;
       int                                       rc;
       int                                       size;
       snd_pcm_t*                         handle;
       snd_pcm_hw_params_t*      params;
       unsigned int                  val;
       int                                       dir;
       snd_pcm_uframes_t             frames;
       char*                                  buffer;

       if ( (rc = snd_pcm_open(&handle, "default", SND_PCM_STREAM_CAPTURE, 0))  0)
       {
              loops --;
              rc = snd_pcm_readi(handle, buffer, frames);
              if (rc == -EPIPE)
              {
                     std::cerr

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP