如何对MIXER操作

来源:互联网 发布:淘宝店铺模版 编辑:程序博客网 时间:2024/05/08 14:39

mixer编程


    最近在写一个MP3程序 正好要用到音量控制 顺便把收集到的资料分享一下

声卡上的混音器由多个混音通道组成,它们可以通过驱动程序提供的设备文件/dev/mixer进行编程。对混音器的操作一般都通过ioctl()系统调用来完成,所有控制命令都以SOUND_MIXER或者MIXER开头,表17.1列出了常用的混音器控制命令。

 

表17.1混音器常用命令

命 令 作 用

SOUND_MIXER_VOLUME主音量调节

SOUND_MIXER_BASS低音控制

SOUND_MIXER_TREBLE高音控制

SOUND_MIXER_SYNTHFM合成器

SOUND_MIXER_PCM主D/A转换器

SOUND_MIXER_SPEAKERPC喇叭

SOUND_MIXER_LINE音频线输入

SOUND_MIXER_MIC麦克风输入

SOUND_MIXER_CDCD输入

SOUND_MIXER_IMIX放音音量

SOUND_MIXER_ALTPCM从D/A 转换器

SOUND_MIXER_RECLEV录音音量

SOUND_MIXER_IGAIN输入增益

SOUND_MIXER_OGAIN输出增益

SOUND_MIXER_LINE1声卡的第1输入

SOUND_MIXER_LINE2声卡的第2输入

SOUND_MIXER_LINE3声卡的第3输入

 

对声卡的输入增益和输出增益进行调节是混音器的一个主要作用,目前大部分声卡采用的是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 recordingsource");

 

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

 

devmask = SOUND_MIXER_CD;

ioctl(fd, SOUND_MIXER_WRITE_RECSRC,&devmask);

 

此外,所有的混音通道都有单声道和双声道的区别,如果需要知道哪些混音通道提供了对立体声的支持,可以通过SOUND_MIXER_READ_STEREODEVS来获得。

代码清单17.4的程序实现了利用/dev/mixer接口对混音器进行编程的过程,该程序可对各种混音通道的增益进行调节。

 

代码清单17.4 OSSmixer接口应用编程范例

 #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;

  intfd;

10  int devmask,stereodevs;

11  char *name;

12

13 void usage()

14 {

15   int i;

16   fprintf(stderr, "usage: %s <device><left-gain%%><right-gain%%>\n"

17     "%s <device><gain%%>\n\n""Where<device> is one of:\n", name,name);

18   for (i = 0; i < SOUND_MIXER_NRDEVICES;i++)

19     if ((1 << i)&devmask)

20    

21       fprintf(stderr, "%s ", sound_device_names[i]);

22   fprintf(stderr, "\n");

23   exit(1);

24 }

25

26 int main(int argc, char*argv[])

27 {

28   int left, right, level;

29   int status;

30   int device;

31   char *dev;

32   int i;

33   name = argv[0];

34   

35   fd = open("/dev/mixer", O_RDONLY);

36   if (fd == - 1)

37   {

38     perror("unable to open /dev/mixer");

39     exit(1);

40   }

41

42   

43   status = ioctl(fd, SOUND_MIXER_READ_DEVMASK,&devmask);

44   if (status == - 1)

45     perror("SOUND_MIXER_READ_DEVMASK ioctl failed");

46   status = ioctl(fd, SOUND_MIXER_READ_STEREODEVS,&stereodevs);

47   if (status == - 1)

48     perror("SOUND_MIXER_READ_STEREODEVS ioctl failed");

49   

50   if (argc != 3 && argc !=4)

51     usage();

52   

53   dev = argv[1];

54   

55   for (i = 0; i < SOUND_MIXER_NRDEVICES;i++)

56      if(((1 << i) &devmask)&& !strcmp(dev,sound_device_names[i]))

57       break;

58   if (i == SOUND_MIXER_NRDEVICES)

59   {

60      

61     fprintf(stderr, "%s is not a valid mixer device\n",dev);

62     usage();

63   }

64   

65   device = i;

66   

67   if (argc == 4)

68   {

69     

70     left = atoi(argv[2]);

71     right = atoi(argv[3]);

72   }

73   else

74   {

75     

76     left = atoi(argv[2]);

77     right = atoi(argv[2]);

78   }

79

80   

81   if ((left != right) && !((1<< i)&stereodevs))

82   {

83     fprintf(stderr, "warning: %s is not a stereo device\n",dev);

84   }

85

86   

87   level = (right << 8) +left;

88

89   

90   status = ioctl(fd, MIXER_WRITE(device),&level);

91   if (status == - 1)

92   {

93     perror("MIXER_WRITE ioctl failed");

94     exit(1);

95   }

96   

97   left = level &0xff;

98   right = (level &0xff00)>> 8;

99   

100  fprintf(stderr, "%s gain set to %d%% / %d%%\n", dev, left,right);

101  

102  close(fd);

103  return 0;

104 }

 

编译上述程序为可执行文件mixer,执行./mixer <device><left-gain%><right-gain%>或./mixer <device><gain%>可设置增益,device可以是vol、pcm、speaker、line、mic、cd、igain、line1、phin、video。

原创粉丝点击