现在的位置: 首页 > 综合 > 正文

大家都在转载的Linux声音设备编程——可我却实现不了

2019年05月28日 ⁄ 综合 ⁄ 共 3850字 ⁄ 字号 评论关闭

在网上看到一段关于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;
}

抱歉!评论已关闭.