仓酷云

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 924|回复: 14
打印 上一主题 下一主题

[其他Linux] 来看看:Linux中声响设备编程先容

[复制链接]
冷月葬花魂 该用户已被删除
跳转到指定楼层
楼主
发表于 2015-1-16 10:58:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
为什么我使用一个命令的时候,系统告诉我找不到该目录,我要如何限制使用者的权限等问题,这些问题其实都不是很难的。
Linux下的声响设备编程比年夜多半人设想的要复杂很多。一样平常说来,我们经常使用的声响设备是外部扬声器和声卡,它们都对应/dev目次下的一个或多个设备文件,我们象翻开一般文件一样翻开它们,用ioctl()函数设置一些参数,然后对这些翻开的特别文件进写操纵。
因为这些文件不是一般的文件,以是我们不克不及用ANSIC(尺度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(unsignedlongusec)来把持。它是在头文件/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>
/*设定默许值*/
#defineDEFAULT_FREQ440/*设定一个符合的频次*/
#defineDEFAULT_LENGTH200/*200微秒,发声的长度是以微秒为单元的*/
#defineDEFAULT_REPS1/*默许不反复发声*/
#defineDEFAULT_DELAY100/*一样以微秒为单元*/
/*界说一个布局,存储所需的数据*/
typedefstruct{
intfreq;/*我们希冀输入的频次,单元为Hz*/
intlength;/*发声长度,以微秒为单元*/
intreps;/*反复的次数*/
intdelay;/*两次发声距离,以微秒为单元*/
}beep_parms_t;
/*打印匡助信息并加入*/
voidusage_bail(constchar*executable_name){
printf("Usage:
        %s[-ffrequency][-llength][-rreps][-ddelay]
",
executable_name);
exit(1);
}
/*剖析运转参数,各项意义以下:
*"-f<以HZ为单元的频次值>"
*"-l<以毫秒为单元的发声时长>"
*"-r<反复次数>"
*"-d<以毫秒为单元的间歇时长>"
*/
voidparse_command_line(char**argv,beep_parms_t*result){
char*arg0=*(argv++);
while(*argv){
if(!strcmp(*argv,"-f")){/*频次*/
intfreq=atoi(*(++argv));
if((freq<=0)||(freq>10000)){
fprintf(stderr,"Badpa
1234下一页


学习python,无论你是打算拿他当主要开发语言,还是当辅助开发语言,你都应该学习他,因为有些时间我们耗不起。
冷月葬花魂 该用户已被删除
沙发
 楼主| 发表于 2015-1-16 12:12:58 | 只看该作者

来看看:Linux中声响设备编程先容

尽我能力帮助他人,在帮助他人的同时你会深刻巩固知识。
rameter:frequencymustbefrom1..10000\n");
exit(1);
}else{
result->freq=freq;
argv++;
}
}elseif(!strcmp(*argv,"-l")){/*时长*/
intlength=atoi(*(++argv));
if(length<0){
fprintf(stderr,"Badparameter:lengthmustbe>=0\n");
exit(1);
}else{
result->length=length;
argv++;
}
}elseif(!strcmp(*argv,"-r")){/*反复次数*/
intreps=atoi(*(++argv));
if(reps<0){
fprintf(stderr,"Badparameter:repsmustbe>=0\n");
exit(1);
}else{
result->reps=reps;
argv++;
}
}elseif(!strcmp(*argv,"-d")){/*延时*/
intdelay=atoi(*(++argv));
if(delay<0){
fprintf(stderr,"Badparameter:delaymustbe>=0\n");
exit(1);
}else{
result->delay=delay;
argv++;
}
}else{
fprintf(stderr,"Badparameter:%s\n",*argv);
usage_bail(arg0);
}
}
}
intmain(intargc,char**argv){
intconsole_fd;
inti;/*轮回计数器*/
/*设发声参数为默许值*/
beep_parms_tparms={DEFAULT_FREQ,DEFAULT_LENGTH,DEFAULT_REPS,
DEFAULT_DELAY};
/*剖析参数,大概的话更新发声参数*/
parse_command_line(argv,&parms);
/*翻开把持台,失利则停止程序*/
if((console_fd=open("/dev/console",O_WRONLY))==-1){
fprintf(stderr,"Failedtoopenconsole.\n");
perror("open");
exit(1);
}
/*真正入手下手让扬声器发声*/
for(i=0;i<parms.reps;i++){
/*数字1190000从何而来,不得而知*/
intmagical_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);/*守候...*/
}/*反复播放*/
returnEXIT_SUCCESS;
}</P>将下面的例子稍作扩大,用户便可以让扬声器唱歌。只需找到五线谱或简谱的音阶、音长、节奏和频次、发声时长、距离的对
上一页1234下一页


写学习日记,这是学习历程的见证,同时我坚持认为是增强学习信念的法宝。以上是我学习Linux的心得体会,希望对大家的学习有所帮助,由于水平有限,本文难免有所欠缺,望请指正。
冷月葬花魂 该用户已被删除
板凳
 楼主| 发表于 2015-1-16 12:17:39 | 只看该作者

来看看:Linux中声响设备编程先容

尽我能力帮助他人,在帮助他人的同时你会深刻巩固知识。
应干系就能够了。我如今还记得之前在DOS下编写出《世上只要妈妈好》时的镇静。最初,说一些提外话,这实际上是一个很复杂的程序,可是我们却用了很长的篇幅,但愿读者从以上的代码里能体味到写好的程序的一些办法,也许最主要的是增加正文吧。一个程序的正文永久不会嫌多,即使你写的时分以为它基本是过剩,但信任我,信任曾如许告知我们的很多优异的程序员:养成写良多正文的习气。</P>对声卡编程
只需我们不是举行诸如驱动设备开辟之类的事情,对声卡的编程和下面对扬声器的编程没有甚么实质的区分。当你试图来编写诸如CD播放器、MP3播放器之类的庞大的程序时,你的事情是取取得与CDROM把持、MP3解码之类的信息,而读写体系设备的这一步在Linux下超互设想的复杂。比方,Linux下最复杂的播放wav的程序只要一行:cp{GetProperty(Content)}lt;>/dev/audio。将它写成一个shell文件,一样是一个程序(shell编程)。
我们起首必要晓得一台呆板上是不是有声卡,一个反省的举措是反省文件/dev/sndstat文件,假如翻开此文件毛病,而且毛病号是ENODEV,则申明此呆板没有安装声卡。除此以外,试着往翻开文件/dev/dsp也能够来反省是不是安装了声卡。
Linux下和声卡相干的文件有很多,如收罗数字样本的/dev/dsp文件,针对混音器的/dev/mixer文件和用于音序器的/dev/sequencer等。文件/dev/audio是一个基于兼容性思索的声响设备文件,它实践是到上述数字设备的一个映照,它最年夜的特征也许是对诸如wav这类文件格局的间接撑持。我们上面的例子即便用了此设备文件完成了一个复杂的灌音机:我们从声卡设备(固然要用麦克风)读取音频数据,并将它寄存到文件test.wav中往。要播放这个wav文件,只需如后面所述,利用命令cptest.wav>/dev/audio便可,固然你也能够用Linux下其他的多媒体软件来播放这个文件。
上面便是完全的程序清单:
/*此文件中界说了上面一切形如SND_的变量*/
#include
#include
#include
#include
#include
main()
{
/*id:读取音频文件形貌符;fd:写进的文件形貌符。i,j为一时变量*/
intid,fd,i,j;
/*存储音频数据的缓冲区,能够调剂*/
chartestbuf[4096];
/*翻开声卡设备,失利则加入*/
if((id=open("/dev/audio",O_RDWR))<0){
fprintf(stderr,"Cantopensounddevice!\n");
exit(-1);
}
/*翻开输入文件,失利则加入*/
if((fd=open("test.wav",O_RDWR))<0){
fprintf(stderr,"Cantopenoutputfile!\n");
exit(-1);
}
/*设置得当的参数,使得声响设备事情一般*/
/*具体情形请参考Linux关于声卡编程的文档*/
i=0;
ioctl(id,SNDCTL_DSP_RESET,(char*)&i);
ioctl(id,SNDCTL_DSP_SYNC,(char*)&i);
i=1;
ioctl(id,SNDCTL_DSP_NONBLOCK,(char*)&i);
i=8000;
ioctl(id,SNDCTL_DSP_SPEED,(char*)&i);
i=1;
ioctl(id,SNDCTL_DSP_CHANNELS,(char*)&i);
i=8;
ioctl(id,SNDCTL_DSP_SETFMT,(char*)&i);
i=3;
ioctl(id,SNDCTL_DSP_SETTRIGGER,(char*)&i);
i=3;
ioctl(id,SNDCTL_DSP_SETFRAGMENT,(char*)&i);
i=1;
ioctl(id,SNDCTL_DSP_PROFILE,(char*)&i);
/*读取必定数目的音频数据,并将之写到输入文件中往*/
for(j=0;j<10;){
i=read(id,testbuf,4096);
&n
上一页1234下一页


初学阶段只要把上课时候学习过的命令练熟就可以了.单靠学习各种命令而成为高手是不可能的。
冷月葬花魂 该用户已被删除
地板
 楼主| 发表于 2015-1-16 12:26:25 | 只看该作者

来看看:Linux中声响设备编程先容

给你装的系统里为ubuntu12.04,它已经封装的很臃肿了,但是考虑到你没有很多时间投入其中,所以给你装了它,但是怎么用它提高开发效率,需要你在学习的过程中不断总结;
bsp;if(i>0){
write(fd,filebuf,i);
j++;
}
}
/*封闭输出、输入文件*/
close(fd);
close(id);
}</P></p>
上一页1234


只要了解了Linux的基础之后,应该就可以很轻易的解决掉这方面的问题。而有些朋友们常常一接触Linux就是希望构架网站,根本没有想到要先了解一下Linux的基础。这是相当困难的。
愤怒的大鸟 该用户已被删除
5#
发表于 2015-1-18 15:28:58 | 只看该作者
选择一些适于初学者的Linux社区。
再现理想 该用户已被删除
6#
发表于 2015-1-27 09:42:59 | 只看该作者
再次,Linux是用C语言编写的,我们有学习C语言的基础,读程序和编写代码方面存在的困难小一点,也是我们能较快掌握的原因之一。?
莫相离 该用户已被删除
7#
发表于 2015-2-5 12:33:02 | 只看该作者
Linux只是个内核!这点很重要,你必须理解这一点。只有一个内核是不能构成一个操作系统的。
飘飘悠悠 该用户已被删除
8#
发表于 2015-2-11 21:52:57 | 只看该作者
熟悉操作是日常学习Linux中的三大法宝。以下是作者学习Linux的一些个人经验,供参考:
小妖女 该用户已被删除
9#
发表于 2015-3-2 21:08:49 | 只看该作者
我想即使Linux高手也很难快速准确精练的回答你。
兰色精灵 该用户已被删除
10#
发表于 2015-3-11 07:43:02 | 只看该作者
一些显而易见的小错误还是用vi改正比较方便。以后的大一点的程序就得在Linux下调试了,因为有的头文件在VC里面说找不到。?
山那边是海 该用户已被删除
11#
发表于 2015-3-18 04:27:39 | 只看该作者
眼看这个学期的Linux课程已经告一段落了,我觉得有必要写一遍心得体会来总结一下这学期对着门课程的学习。
老尸 该用户已被删除
12#
发表于 2015-3-25 17:01:23 | 只看该作者
熟悉并掌握安装Linux,安装是学习的前提。目前较常见的安装方法有二种:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|仓酷云 鄂ICP备14007578号-2

GMT+8, 2024-12-23 16:42

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表