驱动篇:音频设备驱动(二)(摘录)

驱动篇:音频设备驱动(二)

mixer 编程
声卡上的混音器由多个混音通道组成,它们可以通过驱动程序提供的设备文件/dev/mixer 进行编程。 对混音器的操作一般都通过 ioctl()系统调用来完成, 所有控制命令都以 SOUND_MIXER 或者 MIXER 开头
在这里插入图片描述
在这里插入图片描述对声卡的输入增益和输出增益进行调节是混音器的一个主要作用,目前大部分声卡采用的是 8 位或者 16 位的增益控制器,声卡驱动程序会将它们变换成百分比的形式,也就是说无论是输入增益还是输出增益,其取值范围都是从 0~100。
(1)SOUND_MIXER_READ 宏。
在进行混音器编程时,可以使用 SOUND_MIXER_READ 宏来读取混音通道的增益大小,例如,如下代码可以获得麦克风的输入增益:

ioctl(fd, SOUND_MIXER_READ(SOUND_MIXER_MIC), &vol);

对于只有一个混音通道的单声道设备来说,返回的增益大小保存在低位字节中。而对于支持多个混音通道的双声道设备来说,返回的增益大小实际上包括两个部分,分别代表左、右两个声道的值,其中低位字节保存左声道的音量,而高位字节则保存右声道的音量。下面的代码可以从返回值中依次提取左右声道的增益大小:

int left, right;
left = vol & 0xff;
right = (vol & 0xff00) >> 8;

(2)SOUND_MIXER_WRITE 宏。
如果想设置混音通道的增益大小,则可以通过 SOUND_MIXER_WRITE 宏来实现,例如下面的语句可以用来设置麦克风的输入增益:

vol = (right << 8) + left;
ioctl(fd, SOUND_MIXER_WRITE(SOUND_MIXER_MIC), &vol);

(3)查询 MIXER 信息。
声卡驱动程序提供了多个 ioctl()系统调用来获得混音器的信息,它们通常返回一个整型的位掩码,其中每一位分别代表一个特定的混音通道,如果相应的位为 1,则说明与之对应的混音通道是可用的。通过 SOUND_MIXER_READ_DEVMASK 返回的位掩码查询出能够被声卡支持的每一个混音通道,而通过 SOUND_MIXER_READ_RECMAS 返回的位掩码则可以查询出能够被当作录音源的每一个通道。例如,如下代码可用来检查 CD 输入是否是一个有效的混音通道:

ioctl(fd, SOUND_MIXER_READ_DEVMASK, &devmask);
if (devmask & SOUND_MIXER_CD)
printf("The CD input is supported");

如下代码可用来检查 CD 输入是否是一个有效的录音源:

ioctl(fd, SOUND_MIXER_READ_RECMASK, &recmask);
if (recmask & SOUND_MIXER_CD)
printf("The CD input can be a recording source");

大多数声卡提供了多个录音源,通过 SOUND_MIXER_READ_RECSRC 可以查询出当前正在使用的录音源,同一时刻可使用两个或两个以上的录音源,具体由声卡硬件本身决定。相应地,使用SOUND_MIXER_WRITE_RECSRC 可以设置声卡当前使用的录音源,如下代码可以将 CD 输入作为声卡的录音源使用。

devmask = SOUND_MIXER_CD;
ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &devmask);

此外,所有的混音通道都有单声道和双声道的区别,如果需要知道哪些混音通道提供了对立体声的支持,可以通过 SOUND_MIXER_READ_STEREODEVS 来获得。
代码清单 17.4 的程序实现了利用/dev/mixer 接口对混音器进行编程的过程,该程序可对各种混音通道的增益进行调节。
OSS mixer 接口应用编程范例

 #include <unistd.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/ioctl.h>
 #include <fcntl.h>
 #include <linux/soundcard.h>
 /* 用来存储所有可用混音设备的名称 */
 const char *sound_device_names[] = SOUND_DEVICE_NAMES;
 int fd; /* 混音设备所对应的文件描述符 */
 int devmask, stereodevs; /* 混音器信息对应的 bit 掩码 */
 char *name;
 /* 显示命令的使用方法及所有可用的混音设备 */
 void usage()
 {
int i;
fprintf(stderr,"usage:%s<device><left-gain%%><right-gain%%>\n""
           ""%s <device> <gain%%>\n\n""Where <device> is one of:\n", name,name);
for(i = 0; i < SOUND_MIXER_NRDEVICES; i++)
if ((1 << i) &devmask)
/* 只显示有效的混音设备 */
fprintf(stderr, "%s ", sound_device_names[i]);
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 < SOUND_MIXER_NRDEVICES; i++)
if (((1 << i) &devmask) && !strcmp(dev,
sound_device_names[i]))
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 << i) &stereodevs))
{
fprintf(stderr, "warning: %s is not a stereo device\n", dev);
}
/* 将两个声道的值合到同一变量中 */
level = (right << 8) + left;
/* 设置增益 */
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;
 }



编 译 上 述 程 序 为 可 执 行 文 件 mixer , 执 行 ./mixer <device> <left-gain%>
<right-gain%>./mixer <device> <gain%>可设置增益,
device 可以是 vol、 pcm、 speaker、
line、mic、cd、igain、line1、phin、video。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值