免费注册 查看新帖 |

Chinaunix

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

Linux音频编程2 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-10 15:47 |只看该作者 |倒序浏览

Linux音频编程2
4.3 音频录放框架
下面给出一个利用声卡上的DSP设备进行声音录制和回放的基本框架,它的功能是先录制几秒种音频数据,将其存放在内存缓冲区中,然后再进行回放,其所有的功能都是通过读写/dev/dsp设备文件来完成的:
/* * sound.c */#include #include #include #include #include #include #include  #define LENGTH 3    /* 存储秒数 */#define RATE 8000   /* 采样频率 */#define SIZE 8      /* 量化位数 */#define CHANNELS 1 /* 声道数目 */ /* 用于保存数字音频数据的内存缓冲区 */unsigned char buf[LENGTH*RATE*SIZE*CHANNELS/8]; int main(){ int fd; /* 声音设备的文件描述符 */ int arg; /* 用于ioctl调用的参数 */ int status;   /* 系统调用的返回值 */  /* 打开声音设备 */ fd = open("/dev/dsp", O_RDWR); if (fd     perror("open of /dev/dsp failed");    exit(1); }  /* 设置采样时的量化位数 */ arg = SIZE; status = ioctl(fd, SOUND_PCM_WRITE_BITS, &arg); if (status == -1)    perror("SOUND_PCM_WRITE_BITS ioctl failed"); if (arg != SIZE)    perror("unable to set sample size");  /* 设置采样时的声道数目 */ arg = CHANNELS;   status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, &arg); if (status == -1)    perror("SOUND_PCM_WRITE_CHANNELS ioctl failed"); if (arg != CHANNELS)    perror("unable to set number of channels");  /* 设置采样时的采样频率 */ arg = RATE; status = ioctl(fd, SOUND_PCM_WRITE_RATE, &arg); if (status == -1)    perror("SOUND_PCM_WRITE_WRITE ioctl failed");  /* 循环,直到按下Control-C */ while (1) {    printf("Say something:\n");    status = read(fd, buf, sizeof(buf)); /* 录音 */    if (status != sizeof(buf))      perror("read wrong number of bytes");     printf("You said:\n");    status = write(fd, buf, sizeof(buf)); /* 回放 */    if (status != sizeof(buf))      perror("wrote wrong number of bytes");     /* 在继续录音前等待回放结束 */    status = ioctl(fd, SOUND_PCM_SYNC, 0);     if (status == -1)      perror("SOUND_PCM_SYNC ioctl failed"); }}

4.4 混音器框架
下面再给出一个对混音器进行编程的基本框架,利用它可以对各种混音通道的增益进行调节,其所有的功能都是通过读写/dev/mixer设备文件来完成的:
/* * mixer.c */#include #include #include #include #include #include  /* 用来存储所有可用混音设备的名称 */const char *sound_device_names[] = SOUND_DEVICE_NAMES; int fd;                  /* 混音设备所对应的文件描述符 */int devmask, stereodevs; /* 混音器信息对应的位图掩码 */char *name; /* 显示命令的使用方法及所有可用的混音设备 */void usage(){ int i;  fprintf(stderr, "usage: %s   \n"       "       %s  \n\n"       "Where  is one of:\n", name, name); for (i = 0 ; i     if ((1 只显示有效的混音设备 */      fprintf(stderr, "%s ", sound_device_names); fprintf(stderr, "\n"); exit(1);} int main(int argc, char *argv[]){ int left, right, level; /* 增益设置 */ int status;              /* 系统调用的返回值 */ int device;              /* 选用的混音设备 */ char *dev;               /* 混音设备的名称 */ int i;  name = argv[0];  /* 以只读方式打开混音设备 */ fd = open("/dev/mixer", O_RDONLY); if (fd == -1) {    perror("unable to open /dev/mixer");    exit(1); }   /* 获得所需要的信息 */ status = ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devmask); if (status == -1)    perror("SOUND_MIXER_READ_DEVMASK ioctl failed"); status = ioctl(fd, SOUND_MIXER_READ_STEREODEVS, &stereodevs); if (status == -1)    perror("SOUND_MIXER_READ_STEREODEVS ioctl failed");  /* 检查用户输入 */ if (argc != 3 && argc != 4)    usage();  /* 保存用户输入的混音器名称 */ dev = argv[1];  /* 确定即将用到的混音设备 */ for (i = 0 ; i     if (((1       break; if (i == SOUND_MIXER_NRDEVICES) { /* 没有找到匹配项 */    fprintf(stderr, "%s is not a valid mixer device\n", dev);    usage(); }  /* 查找到有效的混音设备 */ device = i;  /* 获取增益值 */ if (argc == 4) {    /* 左、右声道均给定 */    left = atoi(argv[2]);    right = atoi(argv[3]); } else {    /* 左、右声道设为相等 */    left = atoi(argv[2]);    right = atoi(argv[2]); }   /* 对非立体声设备给出警告信息 */ if ((left != right) && !((1     fprintf(stderr, "warning: %s is not a stereo device\n", dev); }   /* 将两个声道的值合到同一变量中 */ level = (right    /* 设置增益 */ status = ioctl(fd, MIXER_WRITE(device), &level); if (status == -1) {    perror("MIXER_WRITE ioctl failed");    exit(1); }  /* 获得从驱动返回的左右声道的增益 */ left = level & 0xff; right = (level & 0xff00) >> 8;  /* 显示实际设置的增益 */ fprintf(stderr, "%s gain set to %d%% / %d%%\n", dev, left, right);  /* 关闭混音设备 */ close(fd); return 0;}

编译好上面的程序之后,先不带任何参数执行一遍,此时会列出声卡上所有可用的混音通道:
[xiaowp@linuxgam sound]$ ./mixerusage: ./mixer          ./mixer  Where  is one of:vol pcm speaker line mic cd igain line1 phin video

之后就可以很方便地设置各个混音通道的增益大小了,例如下面的命令就能够将CD输入的左、右声道的增益分别设置为80%和90%:
[xiaowp@linuxgam sound]$ ./mixer cd 80 90cd gain set to 80% / 90%

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP