zoukankan      html  css  js  c++  java
  • ALSA概述--高级linux声音驱动基本介绍和应用

      基本介绍:

      ALSA是Advanced Linux Sound Architecture,高级Linux声音架构的简称,它在Linux操作系统上提供了音频和MIDI(Musical Instrument Digital Interface,音乐设备数字化接口)的支持。在2.6系列内核中,ALSA已经成为默认的声音子系统,用来替换2.4系列内核中的OSS(Open Sound System,开放声音系统)。 [1] 
      ALSA的主要特性包括:高效地支持从消费类入门级声卡到专业级音频设备所有类型的音频接口,完全模块化的设计, 支持对称多处理(SMP)和线程安全,对OSS的向后兼容,以及提供了用户空间的alsa-lib库来简化应用程序的开发。

       应用:

      下面的这个例子就是调用系统的音频并进行回放的过程。

     1 #include <sys/types.h>
     2 #include <sys/ioctl.h>
     3 #include <stdlib.h>
     4 #include <stdio.h>
     5 #include <linux/soundcard.h>
     6 #define LENGTH 3    /* 存储秒数 */
     7 #define RATE 16000   /* 采样频率 */
     8 #define SIZE 16     /* 量化位数 */
     9 #define CHANNELS 1  /* 声道数目 */
    10 /* 用于保存数字音频数据的内存缓冲区 */
    11 short buf[LENGTH*RATE*SIZE*CHANNELS/16];
    12 //unsigned char buf[2000];
    13 int main()
    14 {
    15   int fd;   /* 声音设备的文件描述符 */
    16   int arg;  /* 用于ioctl调用的参数 */
    17   int status;   /* 系统调用的返回值 */
    18   /* 打开声音设备 */
    19   fd = open("/dev/dsp", O_RDWR);
    20   if (fd < 0) {
    21     perror("open of /dev/dsp failed");
    22     exit(1);
    23   }
    24   /* 设置采样时的量化位数 */
    25   arg = SIZE;
    26   status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
    27   if (status == -1) 
    28     perror("SOUND_PCM_WRITE_BITS ioctl failed");
    29   if (arg != SIZE)
    30     perror("unable to set sample size");
    31   /* 设置采样时的声道数目 */
    32   arg = CHANNELS; 
    33   status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
    34   if (status == -1) 
    35     perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
    36   if (arg != CHANNELS)
    37     perror("unable to set number of channels");
    38   /* 设置采样时的采样频率 */
    39   arg = RATE;
    40   status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
    41   if (status == -1) 
    42     perror("SOUND_PCM_WRITE_WRITE ioctl failed");
    43   /* 循环,直到按下Control-C */
    44   while (1) {
    45     printf("Say something:
    ");
    46     status = read(fd, buf, 2*sizeof(buf)); /* 录音 */
    47     if (status != 2*sizeof(buf))
    48       perror("read wrong number of bytes");
    49     printf("You said:
    ");
    50     status = write(fd, buf, 2*sizeof(buf)); /* 回放 */
    51     if (status != 2*sizeof(buf))
    52       perror("wrote wrong number of bytes");
    53     /* 在继续录音前等待回放结束 */
    54     status = ioctl(fd, SOUND_PCM_SYNC, 0);
    55     if (status == -1)
    56       perror("SOUND_PCM_SYNC ioctl failed");
    57   }
    58 }

      下面的这个例子是录音并保存:

     1 #include <unistd.h>
     2 #include <fcntl.h>
     3 #include <sys/types.h>
     4 #include <sys/ioctl.h>
     5 #include <stdlib.h>
     6 #include <stdio.h>
     7 #include <linux/soundcard.h>
     8 #define LENGTH 3    /* 存储秒数 */
     9 #define RATE 16000   /* 采样频率 */
    10 
    11 #define SIZE 16     /* 量化位数 */
    12 #define CHANNELS 1  /* 声道数目 */
    13 /* 用于保存数字音频数据的内存缓冲区 */
    14 short buf[LENGTH*RATE*SIZE*CHANNELS/16];
    15 //unsigned char buf[2000];
    16 int main(int argc, char *argv[])
    17 {
    18   int fd;   /* 声音设备的文件描述符 */
    19   int arg;  /* 用于ioctl调用的参数 */
    20   int status;   /* 系统调用的返回值 */
    21   /* 打开声音设备 */
    22   fd = open("/dev/dsp", O_RDWR);
    23   if (fd < 0) {
    24     perror("open of /dev/dsp failed");
    25     exit(1);
    26   }
    27 
    28       char *fileOut = argv[1];
    29 
    30       FILE *outFp = fopen(fileOut,"w");
    31       if(outFp == NULL)
    32       {   
    33         fprintf(stderr, "failed to open pcm
    ");
    34         return -1; 
    35        }   
    36 
    37   /* 设置采样时的量化位数 */
    38   arg = SIZE;
    39   status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg);
    40   if (status == -1) 
    41     perror("SOUND_PCM_WRITE_BITS ioctl failed");
    42   if (arg != SIZE)
    43     perror("unable to set sample size");
    44   /* 设置采样时的声道数目 */
    45   arg = CHANNELS; 
    46   status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg);
    47   if (status == -1) 
    48     perror("SOUND_PCM_WRITE_CHANNELS ioctl failed");
    49   if (arg != CHANNELS)
    50     perror("unable to set number of channels");
    51   /* 设置采样时的采样频率 */
    52   arg = RATE;
    53   status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg);
    54   if (status == -1) 
    55     perror("SOUND_PCM_WRITE_WRITE ioctl failed");
    56   /* 循环,直到按下Control-C */
    57   while (1) {
    58     printf("Say something:
    ");
    59     status = read(fd, buf, 2*sizeof(buf)); /* 录音 */
    60     if (status != 2*sizeof(buf))
    61       perror("read wrong number of bytes");
    62     printf("You said:
    ");
    63     status = fwrite(buf, sizeof(char), status, outFp);
    64 
    65   }
    66 
    67   return 0;
    68 }

      

      参考文档:

    1 https://baike.baidu.com/item/ALSA/2078216?fr=aladdin

    2 https://www.ibm.com/developerworks/cn/linux/l-audio/

  • 相关阅读:
    anaconda 离线安装大包
    Openpose 安装问题解决
    Linux grep log文件及find命令学习
    整理了一些常用编程软件(方便自己下载)
    Docker安装es7.6和kibana7.6(并解决Unable to revive connection: http://192.168.162.139:9200/的问题)
    Jsr303分组校验和自定义注解校验
    Spring Cloud整合Oss
    Linux:vim
    Linux:挂载命令
    SpringBoot整合SpringSecurity:集中式项目
  • 原文地址:https://www.cnblogs.com/dylancao/p/9915186.html
Copyright © 2011-2022 走看看