Java實現音頻播放--JavaSound API編寫音頻處理程序

上傳人:文*** 文檔編號:28970818 上傳時間:2021-09-22 格式:DOC 頁數:13 大?。?7.92KB
收藏 版權申訴 舉報 下載
Java實現音頻播放--JavaSound API編寫音頻處理程序_第1頁
第1頁 / 共13頁
Java實現音頻播放--JavaSound API編寫音頻處理程序_第2頁
第2頁 / 共13頁
Java實現音頻播放--JavaSound API編寫音頻處理程序_第3頁
第3頁 / 共13頁

下載文檔到電腦,查找使用更方便

0 積分

下載資源

還剩頁未讀,繼續(xù)閱讀

資源描述:

《Java實現音頻播放--JavaSound API編寫音頻處理程序》由會員分享,可在線閱讀,更多相關《Java實現音頻播放--JavaSound API編寫音頻處理程序(13頁珍藏版)》請在裝配圖網上搜索。

1、一、JavaSound的體系結構二、JavaSound混頻原理三、音頻數據與存儲格式四、設計音樂播放器五、播放音樂六、支持更多的音頻格式桌面PC的性能日益提高,Java虛擬機的優(yōu)化技術也不斷獲得突破,這一切使得用Java處理實時信號成為可能。本文將通過設計和構造一個支持實時MP3、WAV和Ogg音頻格式解碼/回放的Java音樂播放器,闡述用JavaSound API編寫音頻處理程序的思路和一般過程。JavaSound是一個小巧的低層API,支持數字音頻和MIDI數據的記錄/回放。在JDK 1.3.0之前,JavaSound是一個標準的Java擴展API,但從Java 2的1.3.0版開始,Ja

2、vaSound就被包含到JDK之中。由于Java有著跨平臺(操作系統、硬件平臺)的特點,基于JavaSound的音頻處理程序(包括本文的程序)能夠在任何實現了Java 1.3+的系統上運行,無需加裝任何支持軟件。一、JavaSound的體系結構當前JDK的JavaSound API隨同Java媒體框架(JMF,Java Media Framework)一起發(fā)布,主頁在 1.1以及更高的版本。除了JDK實現的JavaSound API之外,還有一個源代碼開放的JavaSound實現是Tritonus,主頁在http:/www.tritonus.org/。圖一描述了JavaSound API的體系

3、結構,虛線表示Sun的JavaSound標準定義的API調用。上面一根虛線表示我們編寫音頻處理程序要調用的API,JavaSound API包含在javax.sound.sampled和javax.sound.midi包中。兩根虛線之間的部分就是JavaSound API的具體實現。圖一:JavaSound體系結構就象上面一根虛線表示的API具有統一標準一樣,在所有的JavaSound實現中,圖一下面一根虛線表示的SPI(服務提供者接口, Service Provider Interface)也是統一的。SPI的作用是以插件(Plug-In)的形式提供自定義的擴展模塊,我們只要提供與SPI兼容

4、的插件擴展模塊,就可以在不改變API的情況下擴展音頻處理程序的能力。SPI包含在java.sound.sampled.spi和javax.sound.midi.spi包中。例如,假設有一個只能播放WAV文件的程序,我們只要增加一個支持MP3文件解碼的插件模塊,就可以在不改動播放程序的任何一行代碼的前提下,為這個播放程序添加播放MP3的能力。二、JavaSound混頻原理圖二闡述了JavaSound的混頻器原理。在處理輸入音頻的應用中,對于來自各種音頻輸入端口的信號,例如麥克風、CD播放器、磁帶播放器,等等,我們可以在它們到達TargetDataLine之前,利用混頻器控制輸入混頻,最后在程序中

5、通過TargetDataLine獲得數字化的音頻輸入流。圖二:JavaSound混頻器類似地,在處理輸出音頻的應用中,混頻器用來對一系列來自SourceDataLine的數據進行混頻處理,經處理后的信號可輸出到各種輸出端口,例如揚聲器、耳機等。SourceDataLine是一個可寫入音頻信號數字流的設備,例如,我們可以從一個WAV文件讀取內容寫入到SourceDataLine,然后再通過揚聲器輸出。輸入到混頻器的信號可以來源于剪輯。剪輯(Clip)是一個包含一段完整音頻數據流的設備,或者說,剪輯就是一個緩沖在內存中的完整音頻數據流。在一些要求反復播放音樂片段的場合,例如游戲的背景音樂,剪輯是很

6、有用的。圖三描述了JavaSound API中一些常用的類、接口及其關系,所有圖三顯示的類、接口都通過Line這個基本接口統一起來。Line接口用來關閉/打開設備、注冊事件監(jiān)聽器,以及提供一些用來調整聲音效果的對象,例如調整音量大小的對象。AudioSystem在JavaSound體系中起著一個工廠(Factory)類的作用,提供了一系列的靜態(tài)方法,我們通過這些靜態(tài)方法來獲取JavaSound系統默認配置的資源(所謂靜態(tài)方法,就是可以在不創(chuàng)建AudioSystem實例的情況下直接調用的方法)。圖三:常用的JavaSound類順便說明一下,在當前(JDK 1.4)實現的JavaSound的默認配

7、置中,輸入聲音來自本地聲卡的麥克風,輸出聲音到本地聲卡的揚聲器。應當說當前實現的JavaSound對端口和混頻器的支持還不完善,但對于包括本文音樂播放器在內的許多應用來說,默認實現的JavaSound配置已經足夠了。三、音頻數據與存儲格式取樣得到的音頻數據也就是從TargetDataLine輸入或從SourceDataLine輸出的數據,必須符合音頻格式的標準。音頻數據的格式選項由AudioFormat類封裝,主要選項包括:編碼方式,可以是PCM(Pulse Code Modulation,脈沖編碼調制)、MP3等;通道數量;取樣率;幀速率;等等。音頻數據可以用多種格式保存到磁盤上。在Java

8、Sound參考實現中,直接支持的文件格式包括WAV(Windows)、AIFF(主要用于Apple的Macintosh)以及AU(主要用于UNIX),音頻文件的格式由AudioFileFormat類指定。并非所有音頻數據格式都可以保存到任意音頻文件格式(或從音頻文件回放),具體由平臺和操作系統的類型決定。為簡單計,本文的播放器只考慮包含PCM Mono或Stereo數據的WAV文件,這是當前流行的音頻數據/文件格式組合,常用于CD音質的音頻數據。壓縮的音頻數據(例如MP3和Ogg Vorbis)通常有各自特殊的存儲格式(如.MP3和.OGG),通常不以WAV/AIFF/AU格式存儲。四、設計音

9、樂播放器我們要編寫的音樂播放器(圖四)由表一所示的幾個類構成。鑒于構造用戶界面往往需要大量的代碼,且這些代碼通常可以用IDE自動生成,所以下文只對一些關鍵的GUI元素略作介紹,不再給出完整的代碼。圖四:播放器的用戶界面播放器的用戶界面主要由一個帶菜單的JFrame框架、一個名稱為filenamesList的JList和幾個JButton構成。框架有一個私有的TestBase成員,其實例在GUIInit()方法的末尾通過pBase = new TestBase()語句初始化。表一用戶界面中的按鈕用類似下面的代碼創(chuàng)建,其中addBttnIconText()是一個私有方法,它把一個圖標放到按鈕的文字

10、標簽之上。Java程序的用戶界面和Windows界面風格迥異,建議讀者使用Java開發(fā)工具自帶的圖標,或者從Java圖標庫下載(例如JButton playBttn = new JButton();.addBttnIconText(playBttn, 播放, Play24.gif); playBttn.addActionListener(new java.awt.event.ActionListener() public void actionPerformed(ActionEvent e) playClick(e); );當用戶點擊一個按鈕,與該按鈕對應的xxxClick()事件句柄函數開始

11、執(zhí)行。播放器共有5個按鈕,相應的事件句柄也有5個:playClick(“播放”按鈕),stopClick(“停止”按鈕),pauseClick(“暫停”按鈕),prevClick(“后退”按鈕),nextClick(“前進”按鈕)。例如,點擊“播放”按鈕時,playClick()句柄首先獲得JList中選中的文件,然后調用TestBase實例中的playFile()輔助方法播放文件。playClick()句柄的代碼如下所示,注意它把音樂文件及其所在目錄連接起來的方法是操作系統中立的。void playClick(ActionEvent e) String fileToPlay = (Strin

12、g) filenamesList.getSelectedValue(); if (fileToPlay != null) pBase.playFile(searchDir + System.getProperty(file.separator) + fileToPlay); stopClick()和pauseClick()方法分別調用TestBase中的stop()和pause()方法。prevClick()和nextClick()句柄的任務稍微復雜一點。首先,它們要調用TestBase中的stop()方法中止當前的播放動作,然后選中JList中當前項目的前一項或后一項,最后調用playCli

13、ck()播放新選中的音樂文件,如下所示。void prevClick(ActionEvent e) pBase.stop(); filenamesList.setSelectedIndex( filenamesList.getSelectedIndex() - 1); playClick(e); void nextClick(ActionEvent e) pBase.stop(); filenamesList.setSelectedIndex(filenamesList.getSelectedIndex()+1) % curPlayListLength); playClick(e); 五、播放

14、音樂TestBase類包含主要的播放邏輯。例如,當用戶點擊“播放”按鈕,TestBase類中的play()方法開始執(zhí)行。public void play() if (!stopped) | (paused) return; if (playerThread = null) playerThread = new Thread(this); playerThread.start(); try Thread.sleep(500); catch (Exception ex) synchronized(synch) stopped = false; synch.notifyAll(); play()方法

15、首先確認播放器當前已被終止播放,而不是暫停播放。然后它檢查這是不是第一次調用play():如果是,則創(chuàng)建一個playerThread線程。我們用一個獨立的線程負責音樂播放,這樣,無論播放器正在讀取文件、解碼,還是正在把音頻數據輸出到揚聲器,用戶界面總是可操作的。啟動線程之后,play()方法鎖定靜態(tài)synch同步對象,將stopped標記設置為false,然后通知正在等待的線程(playerThread線程在開始播放音樂文件之前,會等待靜態(tài)synch對象上的提醒通知)。playerThread線程啟動后,它的run()方法開始運行。這個線程一直執(zhí)行while循環(huán),直到threadExit標記變

16、成true為止。在while循環(huán)中,線程首先等待“開始播放”的信號(當用戶點擊“播放”按鈕時),然后播放音樂。表二列出了描述播放器狀態(tài)的各個標記及其含義。public void run() while (! threadExit) waitforSignal(); if (! stopped) playMusic(); 表二playMusic()方法利用JavaSound API播放當前選中的文件。首先要通過AudioSystem類獲得一個AudioInputStream。然后,利用AudioInputStream的getFormat()獲知音頻數據的格式。在此基礎上,我們試圖通過getLin

17、e()方法獲得一個支持該種格式的SourceDataLine。如果要播放的是WAV文件,現在我們已經有了非壓縮的PCM格式的音頻數據,可以用line對象開始播放音頻。ais= AudioSystem.getAudioInputStream(new File(fileToPlay);if (ais != null) baseFormat = ais.getFormat(); line = getLine(baseFormat); . 如果音頻數據是壓縮格式的,如MP3或Ogg,必須先進行一次轉換把MP3/Ogg解碼成PCM。解碼主要包括三個步驟:1、創(chuàng)建一個解壓縮結果的定制AudioFormat

18、(PCM編碼),但保留和原壓縮流一樣的取樣率、通道信息等。2、創(chuàng)建一個AudioInputStream把原來的AudioInputStream轉換成新的AudioFormat格式。3、獲得一個處理解碼后格式的SourceDataLine。如下所示:AudioFormat decodedFormat = new AudioFormat( AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16, baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat

19、.getSampleRate(), false);ais = AudioSystem.getAudioInputStream(decodedFormat, ais);line = getLine(decodedFormat);getLine()方法的返回值是一個與參數中指定的AudioFormat兼容的SourceDataLine。如果不能獲得兼容的SourceDataLine,getLine()返回null。在getLine()方法中,我們首先創(chuàng)建和填充一個DataLine.Info結構,調用AudioSystem.getLine()方法,將info結構傳遞給AudioSystem類工廠。p

20、rivate SourceDataLine getLine(AudioFormat audioFormat) SourceDataLine res = null; DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat); try res = (SourceDataLine) AudioSystem.getLine(info); res.open(audioFormat); catch (Exception e) return res; 準備好AudioInputStream和SourceDataLine

21、之后,playMusic()剩余的任務已經很簡單:用一個循環(huán)從AudioInputStream讀取數據,然后寫入到SourceDataLine。int inBytes = 0; while (inBytes != -1) & (!stopped) & (!threadExit) try inBytes = ais.read(audioData, 0, BUFFER_SIZE);catch (IOException e) e.printStackTrace(); if (inBytes = 0) intoutBytes = line.write(audioData, 0, inBytes); i

22、f (paused) waitforSignal();六、支持更多的音頻格式假設已經在test目錄下準備好了所有的.java文件,執(zhí)行javac *.java即可順利編譯,執(zhí)行java test.TestPlayer就可以啟動圖一的播放器。但現在播放器只能播放有限的文件,因為JDK實現的JavaSound只支持WAV、AIFF和AU。但是,我們可以用JavaSound SPI為播放器增加對MP3和Ogg Vorbis的支持,只要下載和安裝相應的插件Jar文件即可。Java版的Vorbis解碼器可以從JavaCraft(對于MP3支持,JavaZoom也提供了一個兼容JavaSound的純Java解碼器,稱為JavaLayer(解開下載得到的文件,把所有Jar文件放到播放器所在目錄。用下面的命令啟動播放器:java -classpath .;.jogg-0.0.5.jar;.jorbis-0.0.12.jar;.jl020.jar;.mp3sp.jar;.vorbisspi0.6.jar test.TestPlayer。如果你下載的解碼器版本不同,啟動命令也要作相應地改動。把SPI擴展插件加入到了播放器的classpath之后,JavaSound就會在運行時自動使用它們。

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

相關資源

更多
正為您匹配相似的精品文檔
關于我們 - 網站聲明 - 網站地圖 - 資源地圖 - 友情鏈接 - 網站客服 - 聯系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網版權所有   聯系電話:18123376007

備案號:ICP2024067431-1 川公網安備51140202000466號


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務平臺,本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對上載內容本身不做任何修改或編輯。若文檔所含內容侵犯了您的版權或隱私,請立即通知裝配圖網,我們立即給予刪除!