Linux音频编程2 音频录放框架
扫描二维码
随时随地手机看文章
/*
* 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 < 0) {
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 nn"
"Where 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 devicen", 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 devicen", 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;
}
编译好上面的程序之后,先不带任何参数执行一遍,此时会列出声卡上所有可用的混音通道:
[xiaowp@linuxgam sound]$ ./mixer
usage: ./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 90
cd gain set to 80% / 90%





