当前位置:首页 > > 充电吧
[导读]音频录放框架 下面给出一个利用声卡上的DSP设备进行声音录制和回放的基本框架,它的功能是先录制几秒种音频数据,将其存放在内存缓冲区中,然后再进行回放,其所有的功能都是通过读写/dev/dsp设备文件来

音频录放框架 下面给出一个利用声卡上的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 < 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%

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭