![c語言發(fā)聲程序_第1頁](http://file4.renrendoc.com/view/802f9351311cd866892c79d1943fb064/802f9351311cd866892c79d1943fb0641.gif)
![c語言發(fā)聲程序_第2頁](http://file4.renrendoc.com/view/802f9351311cd866892c79d1943fb064/802f9351311cd866892c79d1943fb0642.gif)
![c語言發(fā)聲程序_第3頁](http://file4.renrendoc.com/view/802f9351311cd866892c79d1943fb064/802f9351311cd866892c79d1943fb0643.gif)
![c語言發(fā)聲程序_第4頁](http://file4.renrendoc.com/view/802f9351311cd866892c79d1943fb064/802f9351311cd866892c79d1943fb0644.gif)
![c語言發(fā)聲程序_第5頁](http://file4.renrendoc.com/view/802f9351311cd866892c79d1943fb064/802f9351311cd866892c79d1943fb0645.gif)
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
字號:c語言經典教程:發(fā)聲技術問題:樂譜的1、2、3、4、5、6、7,加上高低音可以譜出動聽的曲子,請編寫程序,使計算機能夠播放歌曲。[分析]播放歌曲意味著讓計算機發(fā)聲,聲音從PC機內的揚聲器發(fā)出,所以這個問題將與硬件揚聲器電路有關。[解答]解決這一編程問題,讓我們首先簡單了解一下計算機發(fā)聲的原理。在PC機的系統(tǒng)板上裝有定時與計數器8253芯片,還有8255可編程并行接口芯片,由它們組成的硬件電路可用來產生PC機內揚聲器的聲音,對于286、386、486、586等PC微機,由于采用了超大規(guī)模集成電路,因而看不到這些芯片,它們均集成在外圍電路芯片上了。當我們操作計算機時,常常聽到的發(fā)聲,就是由軟件控制這些電路而產生的。聲音的長短和音調的高低,均可由程序進行控制。在揚聲器電路中,定時器的頻率決定了揚聲器發(fā)音的頻率,所以可通過設定定時器電路的頻率來使揚聲器發(fā)出不同的聲音。對定時器電路進行頻率設定時,首先對其命令寄存器(口地址為0x43)寫命令字,如寫入 0xb6,這可用outporb(0x43,0xb6);來實現,則表示選擇該定時器的第二個通道,計數頻率先送低8位(二進制),后送高8位。接著用口地址0x42送頻率計數值,先送低8位,后送高8位,即用outportb(0x42,低8位頻率計數值)和outportb(0x42,高8位頻率計數值)來實現。通過這兩步使定時器電路產生一系列方波信號,此信號是否能推動揚聲器發(fā)音,還要看由8255產生的門控信號和送數信號是否為1,而它們也可編程,口地址為0x61。為了不影響8255口地址61H中的其他高位,應先輸入口地址6lH的現有值bits,即用bits=inportb(0x61)來實現,然后就可用outportb(0x61,bits|3)來允許發(fā)聲,而用outportb(0x61,bits&0xfc)來禁止發(fā)聲,且不改變8255其它位原來的值,關于這方面的詳細內容可以參閱IBMPC/XT接口技術方面書籍有關內容。5.1聲音函數編寫音樂程序播放歌曲,最簡單的方法是可以直接使用TURBOC在dos.h中提供的有關發(fā)聲的函數sound()和nosound()。sound()函數用于產生聲音,其原型如下:voidsound(unsignedfrequency);該函數的入口參數為揚聲器要產生聲音的頻率。與sound()函數相反,nosound()函數用于關閉揚聲器,其原型為:voidnosound(void);該函數沒有入口和出口參數,它只是簡單地把口地址61H中的低2位清0。在利用函數sound產生指定頻率的聲音后,一般要過一段時間后再調用函數nosound關閉揚聲器,這樣我們才能清楚地聽到一個聲音。如果揚聲器剛打開就關閉,我們是很難聽到一個聲音的。某個頻率的聲音延續(xù)時間的長短是重要的,它將直接影響音響效果。這需要使用TURBOC提供了專門的延時函數delay,其原型說明如下:voiddelay(unsignedmilliseconds);該函數中斷程序的執(zhí)行,中斷的時間由milliseconds指定。例程3-36:該程序每間隔10000millisecondspc揚聲器發(fā)出不同頻率的聲音,直到頻率大于5000hz。#include<dos.h>main(){intfreq;for(freq=50;freq<5000;freq+=50){sound(freq);delay(10000);}nosound();}如果不能使用上述現成的函數sound()和nosound(),當然我們也可以采用上節(jié)中的方法,用I/O 接口的輸入輸出函數,自己編寫產生聲音和關閉聲音的函數。下面可供參考的函數SOUND()與TURBOC提供的產生聲音函數sound()的算法類似:首先函數SOUND()中使用了一個由一個整數和兩個字符組成的聯(lián)合,其目的在于方便地把一個16位數分解成兩個8位數。為了打開揚聲器,需要把口地址61H的低2位置位,但又不能影響其他高位,為此,先輸入口地址61H中的現有值,與3邏輯或后再輸出到口地址61H。voidSOUND(unsignedfrequency){union{unsigneddivisor;unsignedcharc[2];}tone;/* 定義由一個整數和兩個字符組成的聯(lián)合*/tone.divisor=119328/frequency;/*計算該頻率對應的定時器計數值 */
outportb(0x43,0xb6); /*通知定時器采用新的計數outportb(0x43,0xb6); /*通知定時器采用新的計數*/outportb(0x42,tone.c[0]);/*計數低字節(jié)先送到定時器*/outportb(0x42,tone.c[1]); /* 計數高字節(jié)后送到定時器*/outportb(0x61,inportb(0x61)|3); /* 使定時器到喇叭的輸出有效 */}如下供參考的函數NOSOUND(),為了不影響口地址61H中的其他高位,應先輸入口地址6lH的現有值.在屏蔽掉低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é)拍數,其中的0.5表示節(jié)拍數,每個音的音長=音長基數X\u33410X拍數如第一個“1”的音長為600X0.5=3000表3-18頻率與音階的對照表低音6頻率131147165176196220247中音6頻率262296330349392440494高音6頻率523587659699784880988最高音16頻率1047117513191397156817601976知道了這些知識,就容易編制一個樂譜驅動程序。思路是將各個頻率存儲在一個二維數組中,根據音階字符、音符和節(jié)拍數,得到發(fā)音的音長,使用sound函數發(fā)音,使用delay函數控制。5.3問題實現5.3.1調用sound()和unsound()下面的程序(例程3-37)先開辟兩個數組freq[96]和dely[96]分別用于存儲聲音的頻率和延時。采用圖形方式,利用printtext()函數在屏幕上分別顯示字符串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 中的函數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()改寫前一實現,播放一段不同的曲目。/*例程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. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度建筑安全施工材料質量檢測合同
- 2025年度體育用品批發(fā)采購合同體育
- 2025年度生態(tài)毛竹綠色采購合同示范文本
- 2025年度專業(yè)賽車隊雇傭駕駛員及教練團隊合同
- 綿陽2025上半年四川綿陽安州區(qū)面向區(qū)內考調機關事業(yè)單位工作人員30人筆試歷年參考題庫附帶答案詳解
- 紹興浙江紹興市外服派駐越城機關單位景點講解員招聘筆試歷年參考題庫附帶答案詳解
- 醫(yī)用氧氣項目融資計劃書
- 深圳廣東深圳市南山區(qū)教育系統(tǒng)招聘財務人員(勞務派遣)7人筆試歷年參考題庫附帶答案詳解
- 柳州廣西柳州市第六中學參加廣西2025屆綜合性高校畢業(yè)生就業(yè)雙選會招聘教師3人筆試歷年參考題庫附帶答案詳解
- 杭州浙江杭州市生態(tài)環(huán)境局桐廬分局招聘編外工作人員筆試歷年參考題庫附帶答案詳解
- 2024版金礦居間合同協(xié)議書
- 2025內蒙古匯能煤化工限公司招聘300人高頻重點提升(共500題)附帶答案詳解
- 小學英語 國際音標 練習及答案
- 優(yōu)秀班主任經驗交流課件-班主任經驗交流課件
- HP-DL380-Gen10-服務器用戶手冊
- 2023年廣州金融控股集團有限公司招聘筆試題庫及答案解析
- YB∕T 105-2014 冶金石灰物理檢驗方法
- 血液科品管圈匯報-PPT課件
- 騙提個人住房公積金檢討書
- 管道保溫及面積計算公式
- 江西省日照小時數
評論
0/150
提交評論