红联Linux门户
Linux帮助

在Linux操作系统中编程声音设备实例

发布时间:2006-11-21 09:38:06来源:红联作者:flycocoon
  Linux下的声音设备编程比大多数人想象的要简单得多。一般说来,我们常用的声音设备是内部扬声器和声卡,它们都对应/dev目录下的一个或多个设备文件,我们象打开普通文件一样打开它们,用ioctl()函数设置一些参数,然后对这些打开的特殊文件进写操作。

  由于这些文件不是普通的文件,所以我们不能用ANSI C(标准C)的fopen、fclose等来操作文件,而应该使用系统文件I/O处理函数(open、read、write、lseek和close)来处理这些设备文件。ioctl()或许是Linux下最庞杂的函数,它可以控制各种文件的属性,在Linux声音设备编程中,最重要的就是使用此函数正确设置必要的参数。

  下面我们举两个实际的例子来说明如何实现Linux下的声音编程。由于此类编程涉及到系统设备的读写,所以,很多时候需要你有root权限,如果你将下面的例子编译后不能正确执行,那么,首先请你检查是否是因为没有操纵某个设备的权限。

  对内部扬声器编程内部扬声器是控制台的一部分,所以它对应的设备文件为/dev/console。变量KIOCSOUND在头文件 /usr /include /linux /kd.h中声明,ioctl函数使用它可以来控制扬声器的发声,使用规则为:

锟斤拷锟斤拷:
  ioctl ( fd, KIOCSOUND, (int) tone);


  fd为文件设备号,tone 是音频值。当tone为0时,终止发声。必须一提的是它所理解的音频和我们平常以为的音频是不同的,由于计算机主板定时器的时钟频率为1.19MHZ,所以要进行正确的发声,必须进行如下的转换:扬声器音频值=1190000/我们期望的音频值。

  扬声器发声时间的长短我们通过函数usleep(unsigned long usec)来控制。它是在头文件/usr /include /unistd.h中定义的,让程序睡眠usec微秒。下面即是让扬声器按指定的长度和音频发声的程序的完整清单:

锟斤拷锟斤拷:
#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 440 /* 设定一个合适的频率 */
#define DEFAULT_LENGTH 200 /* 200 微秒,发声的长度是以微秒为单位的*/
#define DEFAULT_REPS 1 /* 默认不重复发声 */
#define DEFAULT_DELAY 100 /* 同样以微秒为单位*/

/* 定义一个结构,存储所需的数据*/
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);
}

/ * 分析运行参数,各项意义如下:
* "-f <以HZ为单位的频率值 >"
* "-l <以毫秒为单位的发声时长 >"
* "-r <重复次数 >"
* "-d <以毫秒为单位的间歇时长 >"
*/
void parse_command_line(char **argv, beep_parms_t *result) {
char *arg0 = *(argv++);
while ( *argv ) {
if ( !strcmp( *argv,"-f" )) { /*频率*/
int freq = atoi ( *( ++argv ) );
if ( ( freq <= 0 ) | | ( freq > 10000 ) ) {
fprintf ( stderr, "Bad parameter: frequency must be from 1..10000\n" );
exit (1) ;
} else {
result->freq = freq;
argv++;
}
} else if ( ! strcmp ( *argv, "-l" ) ) { /*时长*/
int length = atoi ( *(++argv ) );
if (length < 0) {
fprintf(stderr, "Bad parameter: length must be >= 0\n");
exit(1);
} else {
result->length = length;
argv++;
}
} else if (!strcmp(*argv, "-r")) { /*重复次数*/
int reps = atoi(*(++argv));
if (reps < 0) {
fprintf(stderr, "Bad parameter: reps must be >= 0\n");
exit(1);
} else {
result->reps = reps;
argv++;
}
} else if (!strcmp(*argv, "-d")) { /* 延时 */
int delay = atoi(*(++argv));
if (delay < 0) {
fprintf(stderr, "Bad parameter: delay must be >= 0\n");
exit(1);
} else {
result->delay = delay;
argv++;
}
} else {
fprintf(stderr, "Bad parameter: %s\n", *argv);
usage_bail(arg0);
}
}
}

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, &parms);

/* 打开控制台,失败则结束程序*/
if ( ( console_fd = open ( "/dev/console", O_WRONLY ) ) == -1 ) {
fprintf(stderr, "Failed to open console.\n");
perror("open");
exit(1);
}

/* 真正开始让扬声器发声*/
for (i = 0; i < parms.reps; i++) {
/* 数字1190000从何而来,不得而知*/
int magical_fairy_number = 1190000/parms.freq;

ioctl(console_fd, KIOCSOUND, magical_fairy_number); /* 开始发声 */
usleep(1000*parms.length); /*等待... */
ioctl(console_fd, KIOCSOUND, 0); /* 停止发声*/
usleep(1000*parms.delay); /* 等待... */
} /* 重复播放*/
return EXIT_SUCCESS;
}


  将上面的例子稍作扩展,用户即可以让扬声器唱歌。只要找到五线谱或简谱的音阶、音长、节拍和频率、发声时长、间隔的对应关系就可以了。我现在还记得以前在DOS下编写出《世上只有妈妈好》时的兴奋。最后,说一些提外话,这其实是一个很简单的程序,但是我们却用了很长的篇幅,希望读者从以上的代码里能体会到写好的程序的一些方法,或许最重要的是添加注释吧。一个程序的注释永远不会嫌多,即便你写的时候觉得它根本是多余,但相信我,相信曾这样告诉我们的许多优秀的程序员:养成写很多注释的习惯。
文章评论

共有 2236 条评论

  1. 203.121.67.* 于 2007-08-12 00:44:23发表:

    Hi, my sites: :
    free mp3 = free music download = free music video = download music for free = limewire music downloads = free country music downloads = free music = free music video = music downloads pc =
    http://www.fixgrout.com/cgi/musicpage15.html free mp3 :: http://www.fixgrout.com/cgi/musicpage47.html music downloads pc :: http://mywebpage.netscape.com/music5site/download-music.htm free country music downloads :: http://www.viktorschreckengost.org/portal_memberdata/portraits/bergds limewire music downloads :: http://musicdownloads4free.angelfire.com/free-music.html free music ipods :: http://www.fixgrout.com/cgi/musicpage35.html free download music :: http://www.fixgrout.com/cgi/musicpage31.html mp3 downloads :: http://mywebpage.netscape.com/music5site/download-music.htm free music to download :: http://www.fixgrout.com/cgi/musicpage17.html music downloads pc :: http://idisk.mac.com/fmp3musicdownloads/Public/music.html FREE MUSIC DOWNLOADS :: http://mywebpage.netscape.com/free5mp3/mp3music.html free music ipods ::
    free mp3 .. download music for free .. free mp3 music downloads .. free music downloads .. free music for ipod .. free ipod music downloads .. free download music ..

  2. 203.223.159.* 于 2007-08-11 21:19:05发表:

    Thanks boys :
    free mp3 = free limewire = free music downloading = free limewire = download music for free = free mp3 downloads = free music video = download music video = music downloads pc =
    http://www.fixgrout.com/cgi/musicpage15.html free mp3 :: http://www.fixgrout.com/cgi/musicpage47.html free music downloads :: http://mywebpage.netscape.com/music5site/download-music.htm mp3 downloads :: http://www.viktorschreckengost.org/portal_memberdata/portraits/bergds free mp3 :: http://musicdownloads4free.angelfire.com/free-music.html legal music downloads :: http://www.fixgrout.com/cgi/musicpage35.html mp3 downloads :: http://www.fixgrout.com/cgi/musicpage31.html free country music downloads :: http://mywebpage.netscape.com/music5site/download-music.htm limewire music downloads :: http://www.fixgrout.com/cgi/musicpage17.html music downloads pc :: http://idisk.mac.com/fmp3musicdownloads/Public/music.html FREE MUSIC DOWNLOADS :: http://mywebpage.netscape.com/free5mp3/mp3music.html music download ::
    free mp3 .. FREE MUSIC DOWNLOADS .. music .. free music downloads .. free music .. music download free .. music downloads ..

  3. 203.223.159.* 于 2007-08-11 21:19:01发表:

    Thanks boys :
    free mp3 = free limewire = free music downloading = free limewire = download music for free = free mp3 downloads = free music video = download music video = music downloads pc =
    http://www.fixgrout.com/cgi/musicpage15.html free mp3 :: http://www.fixgrout.com/cgi/musicpage47.html free music downloads :: http://mywebpage.netscape.com/music5site/download-music.htm mp3 downloads :: http://www.viktorschreckengost.org/portal_memberdata/portraits/bergds free mp3 :: http://musicdownloads4free.angelfire.com/free-music.html legal music downloads :: http://www.fixgrout.com/cgi/musicpage35.html mp3 downloads :: http://www.fixgrout.com/cgi/musicpage31.html free country music downloads :: http://mywebpage.netscape.com/music5site/download-music.htm limewire music downloads :: http://www.fixgrout.com/cgi/musicpage17.html music downloads pc :: http://idisk.mac.com/fmp3musicdownloads/Public/music.html FREE MUSIC DOWNLOADS :: http://mywebpage.netscape.com/free5mp3/mp3music.html music download ::
    free mp3 .. FREE MUSIC DOWNLOADS .. music .. free music downloads .. free music .. music download free .. music downloads ..

  4. 203.121.69.* 于 2007-08-08 04:58:08发表:

    Hi boys! :
    free mp3 = free ipod music downloads = free mp3 music downloads = Free Music Downloads = limewire = download music for free = free mp3 downloads = free music download = music downloads pc =
    http://www.fixgrout.com/cgi/musicpage15.html free mp3 :: http://www.fixgrout.com/cgi/musicpage47.html how to download music :: http://mywebpage.netscape.com/music5site/download-music.htm free music download :: http://www.viktorschreckengost.org/portal_memberdata/portraits/bergds mp3 downloads :: http://musicdownloads4free.angelfire.com/free-music.html download music video :: http://www.fixgrout.com/cgi/musicpage35.html free music ipods :: http://www.fixgrout.com/cgi/musicpage31.html free music :: http://mywebpage.netscape.com/music5site/download-music.htm free music download sites :: http://www.fixgrout.com/cgi/musicpage17.html music downloads pc :: http://idisk.mac.com/fmp3musicdownloads/Public/music.html Free Music Downloads :: http://mywebpage.netscape.com/free5mp3/mp3music.html free download music ::
    free mp3 .. free music for ipod .. free mp3 music downloads .. limewire music downloads .. limewire .. download music for free .. free ipod music downloads ..

  5. 203.121.69.* 于 2007-08-08 04:57:52发表:

    Hi boys! :
    free mp3 = free ipod music downloads = free mp3 music downloads = Free Music Downloads = limewire = download music for free = free mp3 downloads = free music download = music downloads pc =
    http://www.fixgrout.com/cgi/musicpage15.html free mp3 :: http://www.fixgrout.com/cgi/musicpage47.html how to download music :: http://mywebpage.netscape.com/music5site/download-music.htm free music download :: http://www.viktorschreckengost.org/portal_memberdata/portraits/bergds mp3 downloads :: http://musicdownloads4free.angelfire.com/free-music.html download music video :: http://www.fixgrout.com/cgi/musicpage35.html free music ipods :: http://www.fixgrout.com/cgi/musicpage31.html free music :: http://mywebpage.netscape.com/music5site/download-music.htm free music download sites :: http://www.fixgrout.com/cgi/musicpage17.html music downloads pc :: http://idisk.mac.com/fmp3musicdownloads/Public/music.html Free Music Downloads :: http://mywebpage.netscape.com/free5mp3/mp3music.html free download music ::
    free mp3 .. free music for ipod .. free mp3 music downloads .. limewire music downloads .. limewire .. download music for free .. free ipod music downloads ..