




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第8章 Linux下音頻設(shè)備編程,本章著重闡述了Linux下對(duì)音頻設(shè)備的編程方法。讀完本章,讀者將了解以下內(nèi)容: 音頻信號(hào)的數(shù)字化和相關(guān)概念; 音頻總線接口IIS的控制原理和控制程序; Linux下音頻設(shè)備編程的特點(diǎn)和操作方法; MPlayer媒體播放器在嵌入式Linux上的移植實(shí)例。,8.1 音頻信號(hào)基礎(chǔ),音頻信號(hào)是一種連續(xù)變化的模擬信號(hào),但計(jì)算機(jī)只能處理和記錄二進(jìn)制的數(shù)字信號(hào),而由自然音源得到的音頻信號(hào)必須經(jīng)過一定的變換,成為數(shù)字音頻信號(hào)之后,才能送到計(jì)算機(jī)中做進(jìn)一步的處理。,數(shù)字音頻信號(hào),模擬音頻信號(hào)數(shù)字化的典型方法是對(duì)時(shí)間坐標(biāo)按相等的時(shí)間間隔做采樣,對(duì)振幅做量化,單位時(shí)間內(nèi)的采樣次數(shù)稱
2、為采樣頻率。這樣,一段聲波被數(shù)字化后就可以變成一串?dāng)?shù)值,每個(gè)數(shù)值對(duì)應(yīng)相應(yīng)抽樣點(diǎn)的振幅值,按順序?qū)⑦@些數(shù)字排列起來就是數(shù)字音頻信號(hào)了。這就是模擬-數(shù)字轉(zhuǎn)化(ADC)過程。數(shù)字-模擬轉(zhuǎn)化(DAC)過程則相反,將連續(xù)的數(shù)字按采樣時(shí)的頻率和順序轉(zhuǎn)換成對(duì)應(yīng)的電壓。通俗一點(diǎn)講,音頻ADC/DAC就是錄音/放音。放音是數(shù)字音頻信號(hào)轉(zhuǎn)換成模擬音頻信號(hào),以驅(qū)動(dòng)耳機(jī)、功放等模擬設(shè)備,而錄音則是要將麥克風(fēng)等產(chǎn)生的模擬音頻信號(hào)轉(zhuǎn)換成數(shù)字音頻信號(hào),并最終轉(zhuǎn)換成計(jì)算機(jī)可以處理的通用音頻文件格式。 采樣就是每隔一定時(shí)間讀一次聲音信號(hào)的幅度,而量化則是將采樣得到的聲音信號(hào)幅度轉(zhuǎn)換為數(shù)字值。從本質(zhì)上講,采樣是時(shí)間上的數(shù)字化,而
3、量化則是幅度上的數(shù)字化。 采樣頻率的選擇應(yīng)該遵循奈奎斯特(Nyquist)采樣理論:采樣頻率高于輸入信號(hào)最高頻率的兩倍,就能從采樣信號(hào)序列重構(gòu)原始信號(hào)。為了保證聲音不失真,采樣頻率應(yīng)該在40kHz左右。常用的音頻采樣頻率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz等,如果采用更高的采樣頻率,還可以達(dá)到DVD的音質(zhì)。 量化是對(duì)模擬音頻信號(hào)的幅度進(jìn)行數(shù)字化,量化位數(shù)決定了模擬信號(hào)數(shù)字化以后的動(dòng)態(tài)范圍,常用的有8位、12位和16位。量化位越高,信號(hào)的動(dòng)態(tài)范圍越大,數(shù)字化后的音頻信號(hào)就越接近原始信號(hào),但所需要的存儲(chǔ)空間也越大。 聲道數(shù)是反映音
4、頻數(shù)字化質(zhì)量的另一個(gè)重要因素,它有單聲道、雙聲道和多聲道之分。雙聲道又稱為立體聲,在硬件中有兩條線路,音質(zhì)和音色都要優(yōu)于單聲道,但數(shù)字化后占據(jù)的存儲(chǔ)空間的大小要比單聲道多一倍。多聲道能提供更好的聽覺感受,不過占用的存儲(chǔ)空間也更大。,音頻文件格式,1MP3 MP3的全稱應(yīng)為MPEG1 Layer-3音頻文件。MPEG(Moving Picture Experts Group)在漢語中譯為活動(dòng)圖像專家組,特指活動(dòng)影音壓縮標(biāo)準(zhǔn),MPEG音頻文件是MPEG1標(biāo)準(zhǔn)中的聲音部分,也叫MPEG音頻層,它根據(jù)壓縮質(zhì)量和編碼復(fù)雜程度劃分為三層,即Layer-1、Layer-2、Layer-3,且分別對(duì)應(yīng)MP1、
5、MP2、MP3這三種聲音文件,并根據(jù)不同的用途,使用不同層次的編碼。MPEG音頻編碼的層次越高,編碼器越復(fù)雜,壓縮率也越高,MP1和MP2的壓縮率分別為4:1和6:18:1,而MP3的壓縮率則高達(dá)10:112:1,也就是說,一分鐘CD音質(zhì)的音樂,未經(jīng)壓縮需要10MB的存儲(chǔ)空間,而經(jīng)過MP3壓縮編碼后只有1MB左右。不過MP3對(duì)音頻信號(hào)采用的是有損壓縮方式,為了降低聲音失真度,MP3采取了“感官編碼技術(shù)”,即編碼時(shí)先對(duì)音頻文件進(jìn)行頻譜分析,然后用過濾器濾掉噪音電平,接著通過量化的方式將剩下的每一位打散排列,最后形成具有較高壓縮比的MP3文件,并使壓縮后的文件在回放時(shí)能夠達(dá)到比較接近原音源的聲音效
6、果。 2WMA WMA就是Windows Media Audio編碼后的文件格式,由微軟開發(fā)。WMA針對(duì)的不是單機(jī)市場(chǎng),而是網(wǎng)絡(luò)。它的競(jìng)爭(zhēng)對(duì)手就是網(wǎng)絡(luò)媒體市場(chǎng)中著名的Real Networks。微軟聲稱,在只有在64kbps的碼率情況下,WMA可以達(dá)到接近CD的音質(zhì)。與以往的編碼不同,WMA支持防復(fù)制功能,它支持通過Windows Media Rights Manager加入保護(hù),可以限制播放時(shí)間和播放次數(shù)甚至于播放的機(jī)器等。由于WMA支持流技術(shù),即一邊讀一邊播放,因此WMA可以很輕松的實(shí)現(xiàn)在線廣播。WMA有著優(yōu)秀的技術(shù)特征,在微軟的大力推廣下,這種格式被越來越多的人所接受。,3WAV 這是一
7、種古老的音頻文件格式,由微軟開發(fā)。WAV文件格式符合RIFF(Resource Interchange File Format,資源互換文件格式)規(guī)范。所有的WAV都有一個(gè)文件頭,這個(gè)文件頭保存了音頻流的編碼參數(shù)。WAV對(duì)音頻流的編碼沒有硬性規(guī)定,除了PCM之外,還有幾乎所有支持ACM規(guī)范的編碼都可以為WAV的音頻流進(jìn)行編碼。在Windows平臺(tái)下,基于PCM編碼的WAV是被支持得最好的音頻格式,所有音頻軟件都能完美支持。由于本身可以達(dá)到較高的音質(zhì)的要求,WAV也是音樂編輯創(chuàng)作的首選格式,適合保存音樂素材。因此,基于PCM編碼的WAV被作為一種中介的格式,常常使用在其他編碼的相互轉(zhuǎn)換之中,例如
8、,MP3轉(zhuǎn)換成WMA。 4Ogg Vorbis OGG是一個(gè)龐大的多媒體開發(fā)計(jì)劃的項(xiàng)目名稱,涉及視頻音頻等方面的編碼開發(fā)。整個(gè)OGG項(xiàng)目計(jì)劃的目的就是向任何人提供完全免費(fèi)的多媒體編碼方案,OGG的信念就是開源和免費(fèi)。Vorbis是OGG項(xiàng)目中音頻編碼的正式命名,目前Vorbis已經(jīng)開發(fā)成功,并且開發(fā)出了編碼器。Ogg Vorbis是高質(zhì)量的音頻編碼方案,官方數(shù)據(jù)顯示:Ogg Vorbis可以在相對(duì)較低的數(shù)據(jù)速率下實(shí)現(xiàn)比MP3更好的音質(zhì),而且它可以支持多聲道。多聲道音樂的興起,給音樂欣賞帶來了革命性的變化,尤其在欣賞交響時(shí),會(huì)帶來更多臨場(chǎng)感。這場(chǎng)革命性的變化是MP3無法適應(yīng)的,因?yàn)镸P3只能編碼
9、2個(gè)聲道。與MP3一樣,Ogg Vorbis是一種靈活開放的音頻編碼,能夠在編碼方案已經(jīng)固定下來后繼續(xù)對(duì)音質(zhì)進(jìn)行明顯的調(diào)節(jié)和新算法的改良。因此,它的聲音質(zhì)量將會(huì)越來越好。與MP3相似,Ogg Vorbis更像一個(gè)音頻編碼框架,可以不斷導(dǎo)入新技術(shù),逐步完善。,5RA RA就是RealAudio格式,這是因特網(wǎng)上接觸得非常多的一種格式。這種格式完全針對(duì)網(wǎng)絡(luò)上的媒體市場(chǎng),支持非常豐富的功能。這種格式最大的特點(diǎn)是可以根據(jù)聽眾的帶寬來控制碼率,在保證流暢的前提下盡可能提高音質(zhì)。RA可以支持多種音頻編碼,其中包括ATRAC3。和WMA一樣,RA不但支持邊讀邊放,也同樣支持使用特殊協(xié)議來隱匿文件的真實(shí)網(wǎng)絡(luò)地
10、址,從而實(shí)現(xiàn)只在線播放而不提供下載的欣賞方式。 6APE APE是Monkeys Audio提供的一種無損壓縮格式。由于Monkeys Audio提供了Winamp的插件支持,因此這就意味著壓縮后的文件不再是單純的壓縮格式,而是與MP3一樣可以播放的音頻文件格式。這種格式的壓縮比遠(yuǎn)低于其他格式,但由于能夠做到真正無損,因此獲得了不少發(fā)燒用戶的青睞?,F(xiàn)在有不少無損壓縮方案,APE是其中有著突出性能的格式,它具有令人滿意的壓縮比,以及飛快的壓縮速度,成為不少朋友私下交流發(fā)燒音樂的惟一選擇。 7AAC AAC(高級(jí)音頻編碼技術(shù),Advanced Audio Coding)是杜比實(shí)驗(yàn)室為音樂社區(qū)提供的
11、技術(shù),聲稱最大能容納48通道的音軌,采樣率達(dá)96kHz。AAC在320kbps的數(shù)據(jù)速率下能為5.1聲道音樂節(jié)目提供相當(dāng)于ITU-R廣播的品質(zhì)。AAC是遵循MPEG-2的規(guī)格所開發(fā)的技術(shù),與MP3比起來,它的音質(zhì)比較好,也能夠節(jié)省大約30%的存儲(chǔ)空間與帶寬。 8ATRAC 3 ATRAC3(Adaptive Transform Acoustic Coding3)由日本索尼公司開發(fā),是MD所采用的ATRAC的升級(jí)版,其壓縮率(約為ATRAC的2倍)和音質(zhì)均與MP3相當(dāng)。壓縮原理包括同時(shí)掩蔽、時(shí)效掩蔽和等響度曲線等,與MP3大致相同。ATRAC3的版權(quán)保護(hù)功能采用的是OpenMG。目前,對(duì)應(yīng)ATR
12、AC3的便攜式播放機(jī)主要是索尼公司自己的產(chǎn)品。不過,該公司已于2000年2月與富士通、日立、NEC、Rohm、三洋和TI等半導(dǎo)體制造商簽署了制造并銷售ATRAC3用LSI的專利許可協(xié)議。,WAVE文件格式剖析,WAVE文件作為多媒體中使用的聲波文件格式之一,是以RIFF格式為標(biāo)準(zhǔn)的。RIFF可以看成是一種樹形結(jié)構(gòu),其基本構(gòu)成單位為chunk,猶如樹形結(jié)構(gòu)中的節(jié)點(diǎn),每個(gè)chunk由辨別碼、數(shù)據(jù)大小,以及數(shù)據(jù)所組成。 WAVE文件的“RIFF”格式辨別碼為“WAVE”,整個(gè)文件由兩個(gè)chunk所組成,辨別碼分別是“fmt”和“data”。在“fmt”chunk下包含了一個(gè)PCM波形格式的數(shù)據(jù)結(jié)構(gòu),
13、在此之后是包含原始聲音信息的采樣數(shù)據(jù),這些數(shù)據(jù)是可以直接送到IIS總線的數(shù)字音頻信號(hào)。WAVE文件各部分內(nèi)容及格式如表8.1所示。 常見的聲音文件主要有兩種,分別對(duì)應(yīng)于單聲道和雙聲道。對(duì)于單聲道聲音文件,采樣速率是11.025kHz,采樣數(shù)據(jù)為8位的短整數(shù)(short int);而對(duì)于雙聲道立體聲聲音文件,采樣速率為44.1kHz,每次采樣數(shù)據(jù)為一個(gè)16位的整數(shù)(int),高8位和低8位分別代表左右兩個(gè)聲道。 WAVE文件數(shù)據(jù)塊包含以脈沖編碼調(diào)制(PCM)格式表示的樣本。WAVE文件是由樣本組織而成的。在WAVE文件中,聲道0代表左聲道,聲道1代表右聲道。在多聲道WAVE文件中,樣本是交替出現(xiàn)
14、的。例如,對(duì)于8位雙聲道的立體聲,存儲(chǔ)數(shù)據(jù)格式依次為:0聲道(左)、1聲道(右)、0聲道(左)、1聲道(右)。對(duì)于16位立體聲,存儲(chǔ)數(shù)據(jù)依次為:0聲道(左)低字節(jié)、0聲道(左)高字節(jié)、1聲道(右)低字節(jié)、1聲道(右)高字節(jié)。,8.2 基于IIS接口的音頻系統(tǒng),IIS接口控制原理,S3C2410X內(nèi)置了一個(gè)IIS總線控制器,該控制器實(shí)現(xiàn)到一個(gè)外部8/16位立體聲音頻編解碼器接口,支持IIS總線數(shù)據(jù)格式和MSB-justified數(shù)據(jù)格式。S3C2410X中有兩條串行數(shù)據(jù)線,一條是輸入信號(hào)數(shù)據(jù)線,一條是輸出信號(hào)數(shù)據(jù)線,以同時(shí)發(fā)送和接收數(shù)據(jù)。IIS接口有3種工作方式: 正常傳輸模式,正常模式下使用I
15、ISCON寄存器對(duì)FIFO進(jìn)行控制。如果傳輸FIFO緩存為空,IISCON的第7位被設(shè)置為“0”,表示不能繼續(xù)傳輸數(shù)據(jù),需要CPU對(duì)緩存進(jìn)行處理。如果傳輸FIFO緩存非空,IISCON的第7位被設(shè)置成“1”,表示可以繼續(xù)傳輸數(shù)據(jù)。同樣,數(shù)據(jù)接收時(shí),如果FIFO滿,標(biāo)識(shí)位是“0”,此時(shí),需要CPU對(duì)FIFO進(jìn)行處理,如果FIFO沒有滿,那么標(biāo)志位是“1”,這個(gè)時(shí)候可以繼續(xù)接收數(shù)據(jù)。 DMA模式,通過設(shè)置IISFCON寄存器可以使IIS接口工作于這種模式下。在這種模式中,F(xiàn)IFO寄存器組的控制權(quán)掌握在DMA控制器上,當(dāng)FIFO滿了,由DMA控制器對(duì)FIFO中的數(shù)據(jù)進(jìn)行處理。DMA模式的選擇由IIS
16、CON寄存器的第4位和第5位控制。 傳輸/接收模式,這種模式下,IIS數(shù)據(jù)可以同時(shí)接收和發(fā)送音頻數(shù)據(jù)。 IIS總線控制器結(jié)構(gòu)如圖8.2所示,各功能說明如下: 兩個(gè)5比特預(yù)除器IPSR,IPSA_A用于產(chǎn)生IIS總線接口的主時(shí)鐘,IPSA_B用做外部CODEC時(shí)鐘產(chǎn)生器。 16字節(jié)FIFO,在發(fā)送數(shù)據(jù)時(shí)數(shù)據(jù)被寫進(jìn)TxFIFO,在接收數(shù)據(jù)時(shí)數(shù)據(jù)從RxFIFO中讀取。 主IISCLK產(chǎn)生器SCLKG,在主模式下,有主時(shí)鐘產(chǎn)生串行位時(shí)鐘。 通道產(chǎn)生器和狀態(tài)機(jī)CHNC,IISCLK和IISLRCK有通道狀態(tài)機(jī)產(chǎn)生并控制。 16比特移位寄存器(SFTR),在發(fā)送數(shù)據(jù)時(shí),并行數(shù)據(jù)經(jīng)由SFTR變成串行數(shù)據(jù)輸出
17、;在數(shù)據(jù)接收時(shí),串行數(shù)據(jù)由SFTR轉(zhuǎn)變成并行數(shù)據(jù)。,音頻接口電路設(shè)計(jì),音頻接口程序設(shè)計(jì),1放音 放音程序代碼如下: #include 2410addr.h #include 2410lib.h #include def.h“ #include 2410iis.h void ChangeDMA2(void); void IIS_PortSetting(void); void _WrL3Addr(U8 data); void _WrL3Data(U8 data,int halt); void _irq DMA2_Done(void); void _irq DMA2_Rec_Done(void);
18、void _irq RxInt(void); void _irq Muting(void); #define L3C (14) /GPB4 = L3CLOCK #define L3D (13) /GPB3 = L3DATA #define L3M (12) /GPB2 = L3MODE #define PLAY 0 #define RECORD 1 /#define REC_LEN 0 x50000 /327,680 Bytes #define REC_LEN 0 x100000 /1,048,576 Bytes #define DataCount 0 x10000 /IIS Master/S
19、lave Data Rx/Tx Count #define DataDisplay 0 x100 /IIS Master Data Display Count #define PollMode 0 /1: Polling Mode #define DMA2Mode 1 /1: DMA2 Mode #define MICGain_Amp_Sel 0 /0: Input channel 2 Amp. 1: MIC Amp. unsigned char *Buf,*_temp; unsigned short *rec_buf; volatile unsigned int size = 0; vola
20、tile unsigned int fs = 0; volatile char which_Buf = 1; volatile char Rec_Done = 0; volatile char mute = 1; void PlayTest_Iis(void) unsigned int save_B, save_E, save_PB, save_PE; Uart_TxEmpty(0);,由于IIS時(shí)鐘從系統(tǒng)分頻得到,下面的代碼將系統(tǒng)PCLK降到33MHz,而且降頻后必須對(duì)串口重新進(jìn)行初始化。 ChangeClockDivider(1,1); /1:2:4 ChangeMPllValue(0 x
21、96,0 x5,0 x1); /FCLK=135.428571MHz (PCLK=33.857142MHz) Uart_Init(33857142,115200); Uart_Printf( IIS test (Play) using UDA1341 CODEC n); 然后將用到的端口保存起來,并進(jìn)行端口初始化。 save_B = rGPBCON; save_E = rGPECON; save_PB = rGPBUP; save_PE = rGPEUP; IIS_PortSetting(); IIS采用DMA方式進(jìn)行錄音和播放,因此需要進(jìn)行DMA中斷的注冊(cè)。 pISR_DMA2 = (uns
22、igned)DMA2_Done; 然后獲取語音數(shù)據(jù)及其大小、采樣頻率。 rINTSUBMSK = (BIT_SUB_RXD0); rINTMSK = (BIT_EINT0 | BIT_UART0 | BIT_DMA2); /Non-cacheable area = 0 x31000000 0 x33feffff Buf = (unsigned char *)0 x31000000; _temp = Buf; Uart_Printf(Download the PCM(no ADPCM) file by DNW(With header)!n); size = *(Buf) | *(Buf + 1)
23、1)1; fs = *(Buf + 0 x1c) | *(Buf + 0 x1d)8 | *(Buf + 0 x1e)16 | *(Buf + 0 x1f)24; 接著初始化UDA1341,設(shè)置為放音模式: Init1341(PLAY); 接著進(jìn)行DMA初始化: rDISRC2 = (int)(Buf + 0 x30); /0 x31000030(Remove header) rDISRCC2 = (01) + (00); /源地址位于系統(tǒng)總線AHB,地址遞增 rDIDST2 = (U32)IISFIFO); /IISFIFO rDIDSTC2 = (11) + (10); /目的地址位于外設(shè)
24、總線APB,地址固定 rDCON2 = (131)+(030)+(129)+(028)+(027)+(024)+ (123)+(022)+(120)+(size/4); /1010 0000 1001 xxxx xxxx xxxx xxxx xxxx /Handshake31,Sync PCLK30,CURR_TC Interrupt Request29, /Single Tx28, Single service27, /I2SSDO26:24, DMA source selected23,Auto-reload22, /Half-word21:20, size/219:0 rDMASKTRI
25、G2 = (02) + (11) + (00); /No-stop2, DMA2 channel On1, No-sw trigger0,IIS初始化: if(fs=44100) /11.2896MHz(256fs) rIISPSR = (2 start piling. 啟動(dòng)IIS。IIS啟動(dòng)后,將采用DMA方式播放語音數(shù)據(jù),播放完畢后將引發(fā)中斷,并重新播放語音數(shù)據(jù)??赏ㄟ^按任意鍵,決定播放是否結(jié)束。 /IIS Tx Start Uart_Printf(nPress any key to exit!n); rIISCON |= 0 x1; /IIS Interface start while(
26、!Uart_GetKey() if(rDSTAT2 ,2錄音 錄音程序在初始化等動(dòng)作上與放音類似,代碼如下: void Record_Iis(void) unsigned int save_B, save_E, save_PB, save_PE; Uart_TxEmpty(0); ChangeClockDivider(1,1); /1:2:4 ChangeMPllValue(0 x96,0 x5,0 x1); /FCLK=135428571Hz, PCLK=3.385714MHz Uart_Init(33857142,115200); Uart_Printf( Record test usin
27、g UDA1341 n); save_B = rGPBCON; save_E = rGPECON; save_PB = rGPBUP; save_PE = rGPEUP; IIS_PortSetting(); 錄音數(shù)據(jù)保存在rec_buf中: rec_buf = (unsigned short *)0 x31000000; pISR_DMA2 = (unsigned)DMA2_Rec_Done; pISR_EINT0 = (unsigned)Muting; rINTMSK = (BIT_DMA2); Init1341(RECORD); rDISRCC2 = (1 start piling. 開
28、始錄音: /Rx start rIISCON |= 0 x1;,錄音完畢將引發(fā)DMA2中斷,如下代碼等待錄音結(jié)束: while(!Rec_Done); rINTMSK = BIT_DMA2; Rec_Done = 0; /IIS Stop Delay(10); /For end of H/W Rx rIISCON = 0 x0; /IIS stop rDMASKTRIG2 = (12); /DMA2 stop rIISFCON = 0 x0; /For FIFO flush 錄音完畢,然后播放聲音: Uart_Printf(End of Record!n); Uart_Printf(Press
29、 any key to play recorded datan); Uart_Printf(If you want to mute or no mute push the EIN0 key repeatedlyn); Uart_Getch(); size = REC_LEN * 2; Uart_Printf(Size = %dn,size); Init1341(PLAY); pISR_DMA2 = (unsigned)DMA2_Done; rINTMSK = (BIT_DMA2 | BIT_EINT0); /DMA2 Initialize rDISRCC2 = (01) + (00); /AH
30、B, Increment rDISRC2 = (int)rec_buf; /0 x31000000 rDIDSTC2 = (11) + (10); /APB, Fixed rDIDST2 = (U32)IISFIFO); /IISFIFO rDCON2 = (131)+(030)+(129)+(028)+(027)+(024) +(123)+(022)+(120)+(size/2); /Handshake, sync PCLK, TC int, single tx, single service, I2SSDO, I2S request, /Auto-reload, half-word, si
31、ze/2 rDMASKTRIG2 = (02)+(11)+0; /No-stop, DMA2 channel on, No-sw trigger,/IIS Initialize /Master,Tx,L-ch=low,iis,16bit ch.,CDCLK=256fs,IISCLK=32fs rIISMOD = (0 start piling. Uart_Printf(Press any key to exit!n); rIISCON |= 0 x1; /IIS Tx Start while(!Uart_GetKey(); /IIS Tx Stop Delay(10); /For end of
32、 H/W Tx rIISCON = 0 x0; /IIS stop rDMASKTRIG2 = (12); /DMA2 stop rIISFCON = 0 x0; /For FIFO flush size = 0; rGPBCON = save_B; rGPECON = save_E; rGPBUP = save_PB; rGPEUP = save_PE; rINTMSK = (BIT_DMA2 | BIT_EINT0); ChangeMPllValue(0 xa1,0 x3,0 x1); / FCLK=202.8MHz Uart_Init(0,115200); mute = 1; ,8.3
33、音頻設(shè)備程序的實(shí)現(xiàn),在Linux下,音頻設(shè)備程序的實(shí)現(xiàn)與文件系統(tǒng)的操作密切相關(guān)。Linux將各種設(shè)備以文件的形式給出統(tǒng)一的接口,這樣的設(shè)計(jì)使得對(duì)設(shè)備的編程與對(duì)文件的操作基本相同,對(duì)Linux內(nèi)核的系統(tǒng)調(diào)用也基本一致,從而簡(jiǎn)化了設(shè)備編程。 如何對(duì)各種音頻設(shè)備進(jìn)行操作是在Linux上進(jìn)行音頻編程的關(guān)鍵,通過內(nèi)核提供的一組系統(tǒng)調(diào)用,應(yīng)用程序能夠訪問聲卡驅(qū)動(dòng)程序提供的各種音頻設(shè)備接口,這是在Linux下進(jìn)行音頻編程最簡(jiǎn)單也是最直接的方法。 聲卡不是Linux控制臺(tái)的一部分,它是一個(gè)特殊的設(shè)備。聲卡主要提供3個(gè)重要的特征: 數(shù)字取樣輸入/輸出; 頻率調(diào)制輸出; MIDI接口。 這3個(gè)特征都有它們自己的設(shè)
34、備驅(qū)動(dòng)程序接口,數(shù)字取樣的接口是/dev/dsp,頻率調(diào)制的接口/dev/sequencer,而MIDI接口是/dev/midi?;煲粼O(shè)備(如音量、平衡或者貝斯)可以通過/dev/mixer接口來控制。為了滿足兼容性的需要,還提供了一個(gè)/dev/audio設(shè)備,該設(shè)備可用于讀SUN_law的聲音數(shù)據(jù),但它是映射到數(shù)字取樣設(shè)備的。,音頻編程接口,程序員可以使用ioctl()來操作這些設(shè)備,ioctl()請(qǐng)求是在linux/soundcard.h中定義的,它們以SNDCTL_開頭。首先使用open系統(tǒng)調(diào)用建立起與硬件間的聯(lián)系,此時(shí)返回的文件描述符將作為隨后操作的標(biāo)識(shí);接著使用read系統(tǒng)調(diào)用從設(shè)備
35、接收數(shù)據(jù),或者使用write系統(tǒng)調(diào)用向設(shè)備寫入數(shù)據(jù),而其他所有不符合讀/寫這一基本模式的操作都可以由ioctl系統(tǒng)調(diào)用來完成;最后,使用close系統(tǒng)調(diào)用告訴Linux內(nèi)核不會(huì)再對(duì)該設(shè)備做進(jìn)一步的處理。 1open系統(tǒng)調(diào)用 系統(tǒng)調(diào)用open可以獲得對(duì)聲卡的訪問權(quán),同時(shí)還能為隨后的系統(tǒng)調(diào)用做好準(zhǔn)備,其函數(shù)原型如下所示:int open(const char *pathname, int flags, int mode); 參數(shù)pathname是將要被打開的設(shè)備文件的名稱,對(duì)于聲卡來講一般是/dev/dsp。參數(shù)flags用來指明應(yīng)該以什么方式打開設(shè)備文件,它可以是O_RDONLY、O_WRONL
36、Y或者O_RDWR,分別表示以只讀、只寫或者讀寫的方式打開設(shè)備文件;參數(shù)mode通常是可選的,它只有在指定的設(shè)備文件不存在時(shí)才會(huì)用到,指明新創(chuàng)建的文件應(yīng)該具有怎樣的權(quán)限。如果open系統(tǒng)調(diào)用能夠成功完成,它將返回一個(gè)正整數(shù)作為文件標(biāo)志符,在隨后的系統(tǒng)調(diào)用中需要用到該標(biāo)志符。如果open系統(tǒng)調(diào)用失敗,它將返回1,同時(shí)還會(huì)設(shè)置全局變量errno,指明是什么原因?qū)е铝隋e(cuò)誤的發(fā)生。 2read系統(tǒng)調(diào)用 read用來從聲卡讀取數(shù)據(jù):int read(int fd, char *buf, size_t count); 參數(shù)fd是設(shè)備文件的標(biāo)志符,它是通過之前的open系統(tǒng)調(diào)用獲得的;參數(shù)buf是指向緩沖區(qū)
37、的字符指針,它用來保存從聲卡獲得的數(shù)據(jù);參數(shù)count則用來限定從聲卡獲得的最大字節(jié)數(shù)。如果read系統(tǒng)調(diào)用成功完成,它將返回從聲卡實(shí)際讀取的字節(jié)數(shù),通常情況會(huì)比count的值小一些;如果read系統(tǒng)調(diào)用失敗,它將返回1,同時(shí)還會(huì)設(shè)置全局變量errno,來指明是什么原因?qū)е铝隋e(cuò)誤的發(fā)生。,3write系統(tǒng)調(diào)用 write用來向聲卡寫入數(shù)據(jù),其函數(shù)原型如下所示:size_t write(int fd, const char *buf, size_t count); 系統(tǒng)調(diào)用write和系統(tǒng)調(diào)用read在很大程度是類似的,差別只在于write是向聲卡寫入數(shù)據(jù),而read則是從聲卡讀入數(shù)據(jù)。參數(shù)fd
38、同樣是設(shè)備文件的標(biāo)志符,它也是通過之前的open系統(tǒng)調(diào)用獲得的;參數(shù)buf是指向緩沖區(qū)的字符指針,它保存著即將向聲卡寫入的數(shù)據(jù);參數(shù)count則用來限定向聲卡寫入的最大字節(jié)數(shù)。 如果write系統(tǒng)調(diào)用成功完成,它將返回向聲卡實(shí)際寫入的字節(jié)數(shù);如果write系統(tǒng)調(diào)用失敗,它將返回1,同時(shí)還會(huì)設(shè)置全局變量errno,來指明是什么原因?qū)е铝隋e(cuò)誤的發(fā)生。無論是read還是write,一旦調(diào)用之后,Linux內(nèi)核就會(huì)阻塞當(dāng)前應(yīng)用程序,直到數(shù)據(jù)成功地從聲卡讀出或者寫入為止。 4ioctl系統(tǒng)調(diào)用 系統(tǒng)調(diào)用ioctl可以對(duì)聲卡進(jìn)行控制,凡是對(duì)設(shè)備文件的操作不符合讀/寫基本模式的,都是通過ioctl來完成的,
39、它可以影響設(shè)備的行為,或者返回設(shè)備的狀態(tài),其函數(shù)原型如下所示:int ioctl(int fd, int request, .); 參數(shù)fd是設(shè)備文件的標(biāo)志符,它是在設(shè)備打開時(shí)獲得的;如果設(shè)備比較復(fù)雜,那么對(duì)它的控制請(qǐng)求相應(yīng)地也會(huì)有很多種,參數(shù)request的目的就是用來區(qū)分不同的控制請(qǐng)求;通常說來,在對(duì)設(shè)備進(jìn)行控制時(shí)還需要有其他參數(shù),這要根據(jù)不同的控制請(qǐng)求才能確定,并且可能是與硬件設(shè)備直接相關(guān)的。 5close系統(tǒng)調(diào)用 當(dāng)應(yīng)用程序使用完聲卡之后,需要用close系統(tǒng)調(diào)用將其關(guān)閉,以便及時(shí)釋放占用的硬件資源,其函數(shù)原型如下所示:int close(int fd); 參數(shù)fd是設(shè)備文件的標(biāo)志符,
40、它是在設(shè)備打開時(shí)獲得的。一旦應(yīng)用程序調(diào)用了close系統(tǒng)調(diào)用,Linux內(nèi)核就會(huì)釋放與之相關(guān)的各種資源,因此建議在不需要的時(shí)候盡量及時(shí)關(guān)閉已經(jīng)打開的設(shè)備。,音頻設(shè)備文件, /dev/sndstat 設(shè)備文件/dev/sndstat是聲卡驅(qū)動(dòng)程序提供的最簡(jiǎn)單的接口,通常它是一個(gè)只讀文件,作用也僅僅只限于匯報(bào)聲卡的當(dāng)前狀態(tài)。一般說來,/dev/sndstat是提供給最終用戶來檢測(cè)聲卡的,不宜用于程序當(dāng)中,因?yàn)樗械男畔⒍伎梢酝ㄟ^ioctl系統(tǒng)調(diào)用來獲得。 /dev/dsp 聲卡驅(qū)動(dòng)程序提供的/dev/dsp是用于數(shù)字采樣和數(shù)字錄音的設(shè)備文件,它對(duì)于Linux下的音頻編程來講非常重要。向該設(shè)備寫數(shù)據(jù)
41、即意味著激活聲卡上的D/A轉(zhuǎn)換器進(jìn)行放音,而從該設(shè)備讀數(shù)據(jù)則意味著激活聲卡上的A/D轉(zhuǎn)換器進(jìn)行錄音。目前,許多聲卡都提供有多個(gè)數(shù)字采樣設(shè)備,它們?cè)贚inux下可以通過/dev/dsp等設(shè)備文件進(jìn)行訪問。 /dev/audio /dev/audio類似于/dev/dsp,它兼容于Sun工作站上的音頻設(shè)備,使用的是mu-law編碼方式。由于設(shè)備文件/dev/audio主要出于對(duì)兼容性的考慮,所以在新開發(fā)的應(yīng)用程序中最好不要嘗試用它,而應(yīng)該以/dev/dsp進(jìn)行替代。對(duì)于應(yīng)用程序來說,同一時(shí)刻只能使用/dev/audio或者/dev/dsp其中之一,因?yàn)樗鼈兪窍嗤布牟煌浖涌凇?/dev/mi
42、xer 在聲卡的硬件電路中,混音器(mixer)是一個(gè)很重要的組成部分,它的作用是將多個(gè)信號(hào)組合或者疊加在一起,對(duì)于不同的聲卡來說,其混音器的作用可能各不相同。運(yùn)行在Linux內(nèi)核中的聲卡驅(qū)動(dòng)程序一般都會(huì)提供/dev/mixer這一設(shè)備文件,它是應(yīng)用程序?qū)煲羝鬟M(jìn)行操作的軟件接口。 /dev/sequencer 目前大多數(shù)聲卡驅(qū)動(dòng)程序還會(huì)提供/dev/sequencer設(shè)備文件,用來對(duì)聲卡內(nèi)建的波表合成器進(jìn)行操作,或者對(duì)MIDI總線上的樂器進(jìn)行控制,通常只用于計(jì)算機(jī)音樂軟件中。,音頻設(shè)備編程設(shè)計(jì),1DSP編程 DSP是數(shù)字信號(hào)處理器(Digital Signal Processor)的簡(jiǎn)稱,它
43、用來進(jìn)行數(shù)字信號(hào)處理的特殊芯片,聲卡使用它來實(shí)現(xiàn)模擬信號(hào)和數(shù)字信號(hào)的轉(zhuǎn)換。聲卡中的DSP設(shè)備實(shí)際上包含兩個(gè)組成部分:在以只讀方式打開時(shí),能夠使用A/D轉(zhuǎn)換器進(jìn)行聲音的輸入;而在以只寫方式打開時(shí),則能夠使用D/A轉(zhuǎn)換器進(jìn)行聲音的輸出。嚴(yán)格說來,Linux下的應(yīng)用程序要么以只讀方式打開/dev/dsp輸入聲音,要么以只寫方式打開/dev/dsp輸出聲音,但事實(shí)上,某些聲卡驅(qū)動(dòng)程序仍允許以讀寫的方式打開/dev/dsp,以便同時(shí)進(jìn)行聲音的輸入和輸出。 在從DSP設(shè)備讀取數(shù)據(jù)時(shí),從聲卡輸入的模擬信號(hào)經(jīng)過A/D轉(zhuǎn)換器變成數(shù)字采樣后的樣本,保存在聲卡驅(qū)動(dòng)程序的內(nèi)核緩沖區(qū)中,當(dāng)應(yīng)用程序通過read系統(tǒng)調(diào)用從
44、聲卡讀取數(shù)據(jù)時(shí),保存在內(nèi)核緩沖區(qū)中的數(shù)字采樣結(jié)果將被復(fù)制到應(yīng)用程序所指定的用戶緩沖區(qū)中。需要指出的是,聲卡采樣頻率是由內(nèi)核中的驅(qū)動(dòng)程序所決定的,而不取決于應(yīng)用程序從聲卡讀取數(shù)據(jù)的速度。如果應(yīng)用程序讀取數(shù)據(jù)的速度過慢,以致低于聲卡的采樣頻率,那么多余的數(shù)據(jù)將會(huì)被丟棄;如果讀取數(shù)據(jù)的速度過快,以致高于聲卡的采樣頻率,那么聲卡驅(qū)動(dòng)程序?qū)?huì)阻塞那些請(qǐng)求數(shù)據(jù)的應(yīng)用程序,直到新的數(shù)據(jù)到來為止。 在向DSP設(shè)備寫入數(shù)據(jù)時(shí),數(shù)字信號(hào)會(huì)經(jīng)過D/A轉(zhuǎn)換器變成模擬信號(hào),然后產(chǎn)生出聲音。應(yīng)用程序?qū)懭霐?shù)據(jù)的速度同樣應(yīng)該與聲卡的采樣頻率相匹配,過慢的話會(huì)產(chǎn)生聲音暫?;蛘咄nD的現(xiàn)象,而過快的話又會(huì)被內(nèi)核中的聲卡驅(qū)動(dòng)程序阻塞
45、,直到硬件有能力處理新的數(shù)據(jù)為止。 無論是從聲卡讀取數(shù)據(jù),或是向聲卡寫入數(shù)據(jù),事實(shí)上都具有特定的格式,默認(rèn)為8位無符號(hào)數(shù)據(jù)、單聲道、8kHz采樣率,如果默認(rèn)值無法達(dá)到要求,可以通過ioctl系統(tǒng)調(diào)用來改變它們。通常情況下,在應(yīng)用程序中打開設(shè)備文件/dev/dsp之后,接著就應(yīng)該為其設(shè)置恰當(dāng)?shù)母袷剑缓蟛拍軓穆暱ㄗx取或者寫入數(shù)據(jù)。,對(duì)聲卡進(jìn)行編程時(shí),首先要做的是打開與之對(duì)應(yīng)的硬件設(shè)備,這是借助于open系統(tǒng)調(diào)用來完成的,并且一般情況下使用的是/dev/dsp文件。采用何種模式對(duì)聲卡進(jìn)行操作也必須在打開設(shè)備時(shí)指定,對(duì)于不支持全雙工的聲卡來說,應(yīng)該使用只讀或者只寫的方式打開,只有那些支持全雙工的聲卡
46、,才能以讀寫的方式打開,并且還要依賴于驅(qū)動(dòng)程序的具體實(shí)現(xiàn)。Linux允許應(yīng)用程序多次打開或者關(guān)閉與聲卡對(duì)應(yīng)的設(shè)備文件,從而能夠很方便地在放音狀態(tài)和錄音狀態(tài)之間進(jìn)行切換,建議在進(jìn)行音頻編程時(shí)只要有可能就盡量使用只讀或者只寫的方式打開設(shè)備文件,因?yàn)檫@樣不僅能夠充分利用聲卡的硬件資源,而且還有利于驅(qū)動(dòng)程序的優(yōu)化。下面的代碼示范了如何以只寫方式打開聲卡進(jìn)行放音操作: int handle = open(/dev/dsp, O_WRONLY); if (handle = -1) perror(open /dev/dsp); return -1; 運(yùn)行在Linux內(nèi)核中的聲卡驅(qū)動(dòng)程序?qū)iT維護(hù)了一個(gè)緩沖區(qū),
47、其大小會(huì)影響到放音和錄音時(shí)的效果,使用ioctl系統(tǒng)調(diào)用可以對(duì)它的尺寸進(jìn)行恰當(dāng)?shù)脑O(shè)置。調(diào)節(jié)驅(qū)動(dòng)程序中緩沖區(qū)大小的操作不是必需的,如果沒有特殊的要求,一般采用默認(rèn)的緩沖區(qū)大小就可以了。但需要注意的是,緩沖區(qū)大小的設(shè)置通常應(yīng)緊跟在設(shè)備文件打開之后,這是因?yàn)閷?duì)聲卡的其他操作有可能會(huì)導(dǎo)致驅(qū)動(dòng)程序無法再修改其緩沖區(qū)的大小。下面的代碼示范了怎樣設(shè)置聲卡驅(qū)動(dòng)程序中的內(nèi)核緩沖區(qū)的大?。?int setting = 0 xnnnnssss; int result = ioctl(handle, SNDCTL_DSP_SETFRAGMENT, 在設(shè)置緩沖區(qū)大小時(shí),參數(shù)setting實(shí)際上由兩部分組成,其低16位標(biāo)
48、明緩沖區(qū)的尺寸,相應(yīng)的計(jì)算公式為buffer_size = 2ssss,即若參數(shù)setting低16位的值為16,那么相應(yīng)的緩沖區(qū)的大小會(huì)被設(shè)置為65536字節(jié)。參數(shù)setting的高16位則用來標(biāo)明分片(fragment)的最大序號(hào),它的取值范圍從2到0 x7FFF,其中0 x7FFF表示沒有任何限制。,接下來要做的是設(shè)置聲卡工作時(shí)的聲道數(shù)目,根據(jù)硬件設(shè)備和驅(qū)動(dòng)程序的具體情況,可以將其設(shè)置為0(單聲道,mono)或者1(立體聲,stereo)。下面的代碼示范了應(yīng)該怎樣設(shè)置聲道數(shù)目。 int channels = 0; / 0=mono 1=stereo int result = ioctl(
49、handle, SNDCTL_DSP_STEREO, ,利用聲卡上的DSP設(shè)備進(jìn)行聲音錄制和回放的完整程序,它的功能是先錄制幾秒鐘音頻數(shù)據(jù),將其存放在內(nèi)存緩沖區(qū)中,然后再進(jìn)行回放,其所有的功能都是通過讀寫/dev/dsp設(shè)備文件來完成的。 /* * sound.c */ #include #include #include #include #include #include #include #define LENGTH 3 /* 存儲(chǔ)秒數(shù) */ #define RATE 8000 /* 采樣頻率 */ #define SIZE 8 /* 量化位數(shù) */ #define CHANNELS 1
50、 /* 聲道數(shù)目 */ /* 用于保存數(shù)字音頻數(shù)據(jù)的內(nèi)存緩沖區(qū) */ unsigned char bufLENGTH*RATE*SIZE*CHANNELS/8; int main() int fd;/* 聲音設(shè)備的文件描述符 */ int arg;/* 用于ioctl調(diào)用的參數(shù) */ int status; /* 系統(tǒng)調(diào)用的返回值 */ /* 打開聲音設(shè)備 */ fd = open(/dev/dsp, O_RDWR); if (fd 0) perror(open of /dev/dsp failed); exit(1); /* 設(shè)置采樣時(shí)的量化位數(shù) */ arg = SIZE; status
51、= ioctl(fd, SOUND_PCM_WRITE_BITS, ,/* 設(shè)置采樣時(shí)的聲道數(shù)目 */ arg = CHANNELS; status = ioctl(fd, SOUND_PCM_WRITE_CHANNELS, ,2Mixer編程 混音器電路通常由兩個(gè)部分組成:輸入混音器和輸出混音器。輸入混音器負(fù)責(zé)從多個(gè)不同的信號(hào)源接收模擬信號(hào),這些信號(hào)源有時(shí)也被稱為混音通道或者混音設(shè)備。模擬信號(hào)通過增益控制器和由軟件控制的音量調(diào)節(jié)器后,在不同的混音通道中分別進(jìn)行調(diào)制,然后被送到輸入混音器中進(jìn)行聲音的合成?;煲羝魃系碾娮娱_關(guān)可以控制不同通道中的信號(hào)與混音器相連,有些聲卡只允許連接一個(gè)混音通道作為
52、錄音的音源,而有些聲卡則允許對(duì)混音通道做任意的連接。經(jīng)過輸入混音器處理后的信號(hào)仍然為模擬信號(hào),它們將被送到A/D轉(zhuǎn)換器進(jìn)行數(shù)字化處理。 輸出混音器的工作原理與輸入混音器類似,同樣也有多個(gè)信號(hào)源與混音器相連,并且事先都經(jīng)過了增益調(diào)節(jié)。當(dāng)輸出混音器對(duì)所有的模擬信號(hào)進(jìn)行混合之后,通常還會(huì)有一個(gè)總控增益調(diào)節(jié)器來控制輸出聲音的大小,此外,還有一些音調(diào)控制器來調(diào)節(jié)輸出聲音的音調(diào)。經(jīng)過輸出混音器處理后的信號(hào)也是模擬信號(hào),它們最終會(huì)被送給喇叭或者其他的模擬輸出設(shè)備。對(duì)混音器的編程包括如何設(shè)置增益控制器的增益,以及怎樣在不同的音源間進(jìn)行切換,這些操作通常是不連續(xù)的,而且不會(huì)像錄音或者放音那樣需要占用大量的計(jì)算機(jī)
53、資源。由于混音器的操作不符合典型的讀/寫操作模式,因此除了open和close兩個(gè)系統(tǒng)調(diào)用之外,大部分的操作都是通過ioctl系統(tǒng)調(diào)用來完成的。與/dev/dsp不同,/dev/mixer允許多個(gè)應(yīng)用程序同時(shí)訪問,并且混音器的設(shè)置值會(huì)一直保持到對(duì)應(yīng)的設(shè)備文件被關(guān)閉為止。 為了簡(jiǎn)化應(yīng)用程序的設(shè)計(jì),Linux上的聲卡驅(qū)動(dòng)程序大多都支持將混音器的ioctl操作直接應(yīng)用到聲音設(shè)備上,也就是說,如果已經(jīng)打開了/dev/dsp,那么就不用再打開/dev/mixer來對(duì)混音器進(jìn)行操作,而是可以直接用打開/dev/dsp時(shí)得到的文件標(biāo)志符來設(shè)置混音器。聲卡上的混音器由多個(gè)混音通道組成,它們可以通過驅(qū)動(dòng)程序提供
54、的設(shè)備文件/dev/mixer進(jìn)行編程。對(duì)混音器的操作是通過ioctl系統(tǒng)調(diào)用來完成的,并且所有控制命令都由SOUND_MIXER或者M(jìn)IXER開頭,表8.3列出了常用的幾個(gè)混音器控制命令。,對(duì)聲卡的輸入增益和輸出增益進(jìn)行調(diào)節(jié)是混音器的一個(gè)主要作用,目前大部分聲卡采用的是8位或者16位的增益控制器,但作為程序員來講并不需要關(guān)心這些,因?yàn)槁暱?qū)動(dòng)程序會(huì)負(fù)責(zé)將它們變換成百分比的形式,也就是說,無論是輸入增益還是輸出增益,其取值范圍都是從0到100。在進(jìn)行混音器編程時(shí),可以使用SOUND_MIXER_READ宏來讀取混音通道的增益大小,例如,在獲取麥克風(fēng)的輸入增益時(shí),可以使用如下的代碼: int v
55、ol; ioctl(fd, SOUND_MIXER_READ(SOUND_MIXER_MIC), ,在編寫實(shí)用的音頻程序時(shí),混音器是在涉及兼容性時(shí)需要重點(diǎn)考慮的一個(gè)對(duì)象,這是因?yàn)椴煌穆暱ㄋ峁┑幕煲羝髻Y源是有所區(qū)別的。聲卡驅(qū)動(dòng)程序提供了多個(gè)ioctl系統(tǒng)調(diào)用來獲得混音器的信息,它們通常返回一個(gè)整型的位掩碼(bitmask),其中每一位分別代表一個(gè)特定的混音通道,如果相應(yīng)的位為1,則說明與之對(duì)應(yīng)的混音通道是可用的。例如,通過SOUND_ MIXER_READ_DEVMASK返回的位掩碼,可以查詢出能夠被聲卡支持的每一個(gè)混音通道,而通過SOUND_MIXER_READ_RECMAS返回的位掩碼,
56、則可以查詢出能夠被當(dāng)做錄音源的每一個(gè)通道。下面的代碼可以用來檢查CD輸入是否是一個(gè)有效的混音通道。 ioctl(fd, SOUND_MIXER_READ_DEVMASK, 此外,所有的混音通道都有單聲道和雙聲道的區(qū)別,如果需要知道哪些混音通道提供了對(duì)立體聲的支持,可以通過SOUND_MIXER_READ_STEREODEVS來獲得。,一個(gè)簡(jiǎn)單的混音器控制程序,利用它可以對(duì)各種混音通道的增益進(jìn)行調(diào)節(jié),其所有的功能都是通過讀寫/dev/mixer設(shè)備文件來完成的。 #include #include #include #include #include #include /* 用來存儲(chǔ)所有可用混音設(shè)備的名稱 */ const char *sound_device_names = SOUND_DEVICE_NAMES; int fd; /* 混音設(shè)備所對(duì)應(yīng)的文件描述符 */ int devmask, stereodevs; /* 混音器信息對(duì)應(yīng)的位圖掩碼 */
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 人群結(jié)構(gòu)分析報(bào)告范文
- 侵權(quán)事實(shí)調(diào)查報(bào)告范文
- 2025年度餐飲行業(yè)品牌推廣個(gè)人勞動(dòng)合同
- 二零二五年度房地產(chǎn)代銷代建與品牌推廣合同
- 二零二五年度新能源汽車租賃公司與個(gè)人節(jié)能補(bǔ)貼協(xié)議
- 二零二五年度養(yǎng)老機(jī)構(gòu)租賃合同終止及服務(wù)質(zhì)量保證協(xié)議
- 二零二五年度金融產(chǎn)品代理合同終止條件及風(fēng)險(xiǎn)控制
- 2025年度軌道交通工程設(shè)計(jì)合同
- 二零二五年度股東借款給公司數(shù)字化轉(zhuǎn)型及升級(jí)服務(wù)合同
- 二零二五年度農(nóng)村房屋未登記產(chǎn)權(quán)過戶協(xié)議
- 《肺癌課件:基本概念與臨床表現(xiàn)》
- 產(chǎn)品九宮格產(chǎn)品賣點(diǎn)課件
- 政府采購汽車采購競(jìng)爭(zhēng)性談判文件
- 新生兒休克的早期識(shí)別
- 小班音樂教案及教學(xué)反思《小動(dòng)物怎樣叫》
- Windows Server 2012 R2系統(tǒng)管理與服務(wù)器配置 教案全套 項(xiàng)目1-10
- 智能制造概論 課件 第1、2章 智能制造的發(fā)展歷程、能制造系統(tǒng)架構(gòu)與基本理念
- 水廠建設(shè)可行性方案
- 口腔種植術(shù)質(zhì)量評(píng)估指南(2023年版)
- 雙橫臂獨(dú)立懸架設(shè)計(jì)計(jì)算說明書
- 中國空白地圖(打印)
評(píng)論
0/150
提交評(píng)論