c語言發(fā)聲程序_第1頁
c語言發(fā)聲程序_第2頁
c語言發(fā)聲程序_第3頁
c語言發(fā)聲程序_第4頁
c語言發(fā)聲程序_第5頁
已閱讀5頁,還剩17頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

字號:c語言經典教程:發(fā)聲技術問題:樂譜的1、2、3、4、5、6、7,加上高低音可以譜出動聽的曲子,請編寫程序,使計算機能夠播放歌曲。[分析]播放歌曲意味著讓計算機發(fā)聲,聲音從PC機內的揚聲器發(fā)出,所以這個問題將與硬件揚聲器電路有關。[解答]解決這一編程問題,讓我們首先簡單了解一下計算機發(fā)聲的原理。在PC機的系統(tǒng)板上裝有定時與計數(shù)器8253芯片,還有8255可編程并行接口芯片,由它們組成的硬件電路可用來產生PC機內揚聲器的聲音,對于286、386、486、586等PC微機,由于采用了超大規(guī)模集成電路,因而看不到這些芯片,它們均集成在外圍電路芯片上了。當我們操作計算機時,常常聽到的發(fā)聲,就是由軟件控制這些電路而產生的。聲音的長短和音調的高低,均可由程序進行控制。在揚聲器電路中,定時器的頻率決定了揚聲器發(fā)音的頻率,所以可通過設定定時器電路的頻率來使揚聲器發(fā)出不同的聲音。對定時器電路進行頻率設定時,首先對其命令寄存器(口地址為0x43)寫命令字,如寫入 0xb6,這可用outporb(0x43,0xb6);來實現(xiàn),則表示選擇該定時器的第二個通道,計數(shù)頻率先送低8位(二進制),后送高8位。接著用口地址0x42送頻率計數(shù)值,先送低8位,后送高8位,即用outportb(0x42,低8位頻率計數(shù)值)和outportb(0x42,高8位頻率計數(shù)值)來實現(xiàn)。通過這兩步使定時器電路產生一系列方波信號,此信號是否能推動揚聲器發(fā)音,還要看由8255產生的門控信號和送數(shù)信號是否為1,而它們也可編程,口地址為0x61。為了不影響8255口地址61H中的其他高位,應先輸入口地址6lH的現(xiàn)有值bits,即用bits=inportb(0x61)來實現(xiàn),然后就可用outportb(0x61,bits|3)來允許發(fā)聲,而用outportb(0x61,bits&0xfc)來禁止發(fā)聲,且不改變8255其它位原來的值,關于這方面的詳細內容可以參閱IBMPC/XT接口技術方面書籍有關內容。5.1聲音函數(shù)編寫音樂程序播放歌曲,最簡單的方法是可以直接使用TURBOC在dos.h中提供的有關發(fā)聲的函數(shù)sound()和nosound()。sound()函數(shù)用于產生聲音,其原型如下:voidsound(unsignedfrequency);該函數(shù)的入口參數(shù)為揚聲器要產生聲音的頻率。與sound()函數(shù)相反,nosound()函數(shù)用于關閉揚聲器,其原型為:voidnosound(void);該函數(shù)沒有入口和出口參數(shù),它只是簡單地把口地址61H中的低2位清0。在利用函數(shù)sound產生指定頻率的聲音后,一般要過一段時間后再調用函數(shù)nosound關閉揚聲器,這樣我們才能清楚地聽到一個聲音。如果揚聲器剛打開就關閉,我們是很難聽到一個聲音的。某個頻率的聲音延續(xù)時間的長短是重要的,它將直接影響音響效果。這需要使用TURBOC提供了專門的延時函數(shù)delay,其原型說明如下:voiddelay(unsignedmilliseconds);該函數(shù)中斷程序的執(zhí)行,中斷的時間由milliseconds指定。例程3-36:該程序每間隔10000millisecondspc揚聲器發(fā)出不同頻率的聲音,直到頻率大于5000hz。#include<dos.h>main(){intfreq;for(freq=50;freq<5000;freq+=50){sound(freq);delay(10000);}nosound();}如果不能使用上述現(xiàn)成的函數(shù)sound()和nosound(),當然我們也可以采用上節(jié)中的方法,用I/O 接口的輸入輸出函數(shù),自己編寫產生聲音和關閉聲音的函數(shù)。下面可供參考的函數(shù)SOUND()與TURBOC提供的產生聲音函數(shù)sound()的算法類似:首先函數(shù)SOUND()中使用了一個由一個整數(shù)和兩個字符組成的聯(lián)合,其目的在于方便地把一個16位數(shù)分解成兩個8位數(shù)。為了打開揚聲器,需要把口地址61H的低2位置位,但又不能影響其他高位,為此,先輸入口地址61H中的現(xiàn)有值,與3邏輯或后再輸出到口地址61H。voidSOUND(unsignedfrequency){union{unsigneddivisor;unsignedcharc[2];}tone;/* 定義由一個整數(shù)和兩個字符組成的聯(lián)合*/tone.divisor=119328/frequency;/*計算該頻率對應的定時器計數(shù)值 */

outportb(0x43,0xb6); /*通知定時器采用新的計數(shù)outportb(0x43,0xb6); /*通知定時器采用新的計數(shù)*/outportb(0x42,tone.c[0]);/*計數(shù)低字節(jié)先送到定時器*/outportb(0x42,tone.c[1]); /* 計數(shù)高字節(jié)后送到定時器*/outportb(0x61,inportb(0x61)|3); /* 使定時器到喇叭的輸出有效 */}如下供參考的函數(shù)NOSOUND(),為了不影響口地址61H中的其他高位,應先輸入口地址6lH的現(xiàn)有值.在屏蔽掉低2位后再輸出到口地址61H。voidNOSOUND(void){outportb(0x61,inportb(0x61)&0xfc)); /* 使定時器到喇叭的輸出無效*/}5.2計算機樂譜表3-18是頻率與音階的對照表。我們可以通過該表編制出自己的驅動程序。編制樂譜程序一般在原樂譜的基礎上添加一些控制字符來完成。如:_11176323262就是孟庭葦演唱的“羞答答的玫瑰靜俏俏地開”的第一句歌詞的樂譜。在計算機中可以表述為:600H10.5H10.5H10.5M70.5M61H31H20.5H30.5H20.5M60.5H22第一個為音長基準,一般為300,600,900,1200。后面字H1表示高音的1,音階的設置如下:最高音:在音符前加“E”;高音:在音符前加“計”;中音:在音符前加“M”;低音:在音符前加“L”;再后面的字為節(jié)拍數(shù),其中的0.5表示節(jié)拍數(shù),每個音的音長=音長基數(shù)X\u33410X拍數(shù)如第一個“1”的音長為600X0.5=3000表3-18頻率與音階的對照表低音6頻率131147165176196220247中音6頻率262296330349392440494高音6頻率523587659699784880988最高音16頻率1047117513191397156817601976知道了這些知識,就容易編制一個樂譜驅動程序。思路是將各個頻率存儲在一個二維數(shù)組中,根據音階字符、音符和節(jié)拍數(shù),得到發(fā)音的音長,使用sound函數(shù)發(fā)音,使用delay函數(shù)控制。5.3問題實現(xiàn)5.3.1調用sound()和unsound()下面的程序(例程3-37)先開辟兩個數(shù)組freq[96]和dely[96]分別用于存儲聲音的頻率和延時。采用圖形方式,利用printtext()函數(shù)在屏幕上分別顯示字符串Welcome!","Pleasepressanykeytostart ","Enjoyyourself!”,"Pressanykeytoend!"和"Thankyou!ByeBye "printtext()定義如下:voidprinttext(unsignedchar*temp[],inti){setcolor(4);〃設置顏色為redsettextstyle(TRIPLEX_FONT,HORIZ_DIR,3);//設置字符的字體,方向和大小outtextxy(100,40+i*50,temp[i]); //顯示字符串}另外,在此程序中還調用了conio.h 中的函數(shù)kbhit(),用于判斷是否有鍵按下,當沒有鍵按下時返回0。/*例程3-37*/#include<dos.h>#include<graphics.h>voidprinttext(unsignedchar*temp[],inti);//用于在屏幕上顯示字符串main(){inti,graphdriver,graphmode;unsignedchar*temp[4];intfreq[96]={784,660,588,660,523,523,588.494.440.523.392.392,330.392.440.523.784.440.523.392,784.1048.880.784.660.784.588.588,588.660.494.440.392.440.523.588,330.523.440.392.440.523.392.392,660.784.494.588.440.523.392.392,330,392,330,392,392,440,494,588,440,440,392,440,523.588.784.660.588.660.588.523.440.392,330,523,440,523,440,392,330,392,440,523,392,392,660,784,588,660,588,523,494,440,784,784};intdely[96]={25,50,12,12,50,50,25,50,12,12,50,50,50,38,12,38,12,12,12,25,38.12.12.12.12.12.50.50,38.12.25.25.38.12.25.25,25.25.12.12.12.12.50.50,38.12.25.25.12.12.50.25,12.12.12.12.12.12.12.12.50.25.12.12,38.12.25.25.25.12.12.25.12.12,50.50.12.12.12.12.12.12.12.12,50,25,12,12,12,12,12,12,25,25,50,50};graphdriver=DETECT;graphmode=0;temp[0]="Welcome!";temp[1]="Pleasepressanykeytostart temp[2]="Enjoyyourself!";temp[3]="Pressanykeytoend!";temp[4]="Thankyou!ByeBye ";〃系統(tǒng)初始化initgraph(&graphdriver,&graphmode,〃〃);〃系統(tǒng)初始化cleardevice();〃清除屏幕settextjustify(LEFT_TEXT,CENTER_TEXT);//設置字符排列方式for(i=0;i<2;i++)printtext(temp,i);getch();for(i=2;i<4;i++)printtext(temp,i);i=0;!sound(freq[i]); //揚聲器根據頻率發(fā)聲delay(1100*dely[i]); //聲音延時i++;nosound();//關閉揚聲器printtext(temp,4);getch();closegraph();//關閉圖形模式voidprinttext(unsignedchar*temp[],inti)voidsetcolor(4);// 設置顏色設置字符的字體,方向//在所指定的坐標出settextstyle(TRIPLEX_FONT,HORIZ_DIR,3);//和大小設置字符的字體,方向//在所指定的坐標出outtextxy(100,40+i*50,temp[i]);顯示字符串5.3.2調用inportb()和outportb()這個程序(例程3-38)利用3.5.2節(jié)的SOUND()和UNSOUND()改寫前一實現(xiàn),播放一段不同的曲目。/*例程3-38*/#include<dos.h>#include<graphics.h>voidprinttext(unsignedchar*temp[],inti);voidSOUND(unsignedfrequency);voidNOSOUND(void);main(){inti,graphdriver,graphmode;unsignedchar*temp[4];intfreq[87]={196,262,262,262,330,294,262,294,330,294,262,330,394,440,440,394,330,330,262,294,262,294,330,294,262,230,230,196,262,440,394,330,330,262,294,262,294,440,394,330,330,394,440,523,394,330,330,262,294,262,294,330,294,262,230,230,196,262,440,394,330,330,262,294,262,294,440,394,330,330,394,440,523,394,330,330,262,294,262,294,330,294,262,230,230,196,262};intdely[87]={25,38,12,25,25,38,12,25,12,12,56,25,25,50,25,38,12,12,12,38,12,25,12,12,38,12,25,25,100,25,38.12.12.12.38.12.25.25.38.12.25.25.100.25.38,12.12.12.38.12.25.12.12.38.12.25.25.100.25.38,12,12,12,38,12,25,25,38,12,25,25,100,25,38,12,12,12,38,12,25,12,12,38,12,25,25,100}graphdriver=DETECT;graphmode=0;temp[0]="Welcome!";temp[1]="Pleasepressanykeytostart ";temp[2]="Enjoyyourself!";temp[3]="Pre

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論