在网上看到一段关于Linux的扬声器控制的代码,科室自己先试编译了一下发现并不讷讷个实现,能不能帮忙看看。我将它保存成sound.在终端中用gcc编译 gcc -o sound sound.c,原来有错,我秀改后能编成功了,后来运行 ./sound 确没有声音。
1.我是在虚拟机里装的Linux
2.我以为是频率参数设置的问题(人耳听觉频率在20HZ-20KHZ)于是我改了,结果…… 真的是
#include<fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/ioctl.h>
#include<sys/types.h>
#include<linux/kd.h>
/* 设定默认值 */
#define DEFAULT_FREQ 1440 /* 设定一个合适的频率 人耳的听觉频率20HZ-20khz */
#define DEFAULT_LENGTH 2000 /* 200 微秒,发声的长度是以微秒为单位的*/
#define DEFAULT_REPS 1 /* 默认不重复发声 */
#define DEFAULT_DELAY 100 /* 同样以微秒为单位*/
/*
C调音阶-频率对照表
音阶 n 1 2 3 4 5 6 7 8 9 10 11 12
Do Do# Re Re# Mi Fa Fa# So So# La La# Si
低 频率 262 277 294 311 330 349 370 392 415 440 464 494
音 简谱 1。 2。 3。 4。 5。 6。 7。
中 频率 523 554 587 622 659 698 740 784 831 880 932 988
音 简谱 1 2 3 4 5 6 7
高 频率 1046 1109 1175 1245 1318 1397 1480 1568 1661 1760 1865 1976
音 简谱 1。 2。 3。 4。 5。 6。 7。
*/
int fresqs[10]={1046, 1109, 1175, 1245, 1318, 1397, 1480, 1568 ,1661,1760};
int freqsmiddle[12]={523, 554 , 587 , 622 ,659 , 698 , 740 , 784 ,831 , 880 , 932 , 988};
int freqslow[12]={262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 464, 494};
/* 定义一个结构,存储所需的数据*/
typedef struct {
int freq; /* 我们期望输出的频率,单位为Hz */
int length; /* 发声长度,以微秒为单位*/
int reps; /* 重复的次数*/
int delay; /* 两次发声间隔,以微秒为单位*/
} beep_parms_t;
/*显示参数设置选择*/
void usage_bail ( const char *executable_name ) {
printf ( "Usage: /n /t%s [f frequency] [l length] [r reps] [d delay] /n ",
executable_name );
exit(1);
}
int putofreq(char i);
/* 分析运行参数,各项意义如下
* "f <以HZ为单位的频率值 >"
* "l <以毫秒为单位的发声时长 >"
* "r <重复次数 >"
* "d <以毫秒为单位的间歇时长 >"
*/
void parse_command_line(char **argv,int argc, beep_parms_t *result) {
int freq ; /*频率*/
int length ;/*时长*/
int delay; /* 延时 */
int reps;/*重复次数*/
int c;
while ((c = getopt(argc, argv, "f:r:d:l")) != -1) {
switch (c) {
case 'f':
freq = atoi ( optarg ); /*字符串装换成整数*/
if ( ( freq <= 0 )||( freq > 10000 ) ) {
fprintf ( stderr, "输出有误请输入频率范围在 1..10000/n" );
/*格式化输出数据文件*/
exit (1) ;
} else {
result->freq = freq;
argv++;
}
break;
case 'l':
length = atoi ( optarg );
if (length < 0) {
fprintf(stderr, "Bad parameter: length must be >= 0/n");
exit(1);
} else {
result->length = length;int
}
break;
case 'd':
delay = atoi(optarg);
if (delay < 0) {
fprintf(stderr, "Bad parameter: delay must be >= 0/n");
exit(1);
} else {
result->delay = delay;
}
break;
case 'r':
reps = atoi(optarg);
if (reps < 0) {
fprintf(stderr, "Bad parameter: reps must be >= 0/n");
exit(1);
} else {
result->reps = reps;
}
break;
case '?':
fprintf(stderr, "Bad parameter: %s/n", *argv);
usage_bail(*argv);
exit(0);
}
}
}
int main(int argc, char **argv) {
int console_fd;
int i; /* 循环计数器 */
/* 设发声参数为默认值*/
beep_parms_t parms = {DEFAULT_FREQ, DEFAULT_LENGTH, DEFAULT_REPS,
DEFAULT_DELAY};
/* 分析参数,可能的话更新发声参数*/
parse_command_line(argv,argc, &parms);
// setuid(0);
setuid(getuid());
/*setuid 设置真实的用户识别码,getuid取得真实用户识别码*/
/* 打开控制台,失败则结束程序*/
if ( ( console_fd = open ( "/dev/console", O_WRONLY ) ) == -1 ) {
fprintf(stderr, "Failed to open console./n");
perror("open");
exit(1);
}
/*
perror ( )用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到 标 准 错误 (stderr)
O_WRONLY 写文件
┌————┬————————————————————┐
│access值│意义 │
├————┼————————————————————┤
│O_RDONLY│读文件 │
│O_WRONLY│写文件 │
│O_RDWR │即读也写 │
│O_NDELAY│没有使用;对UNIX系统兼容 │
│O_APPEND│即读也写,但每次写总是在文件尾添加 │
│O_CREAT │若文件存在,此标志无用;若不存在,建新文件 │
│O_TRUNC │若文件存在,则长度被截为0,属性不变 │
│O_EXCL │未用;对UNIX系统兼容 │
│O_BINARY│此标志可显示地给出以二进制方式打开文件 │
│O_TEXT │此标志可用于显示地给出以文本方式打开文件│
└————┴————————————————————┘
*/
/* 真正开始让扬声器发声*/
for (i = 0; i <8; i++) {
/* 数字1190000计算机主板定时器的时钟频率为1.19MHZ*/
int magical_fairy_number = 1190000/fresqs;
ioctl(console_fd, KIOCSOUND, magical_fairy_number); /* 开始发声 */
usleep(1000*parms.length); /*等待... */
ioctl(console_fd, KIOCSOUND, 0); /* 停止发声*/
usleep(1000*parms.delay); /* 等待... */
} /* 重复播放*/
return EXIT_SUCCESS;
}
大家都在转载的Linux声音设备编程——可我却实现不了
最新推荐文章于 2024-09-08 16:25:03 发布