程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java聲音技術詳解

Java聲音技術詳解

編輯:關於JAVA

聲音可以創造意境,觸發遐想,當與虛擬圖像相結合時,更加可以讓整個世界充滿幻覺。聲音是多媒體技術的基礎。這就是Sun公司的JAVA媒體技術開發小組忙於准備Java Sound 1.0 API並將其包含於下一版本的JAVA開發工具庫中的原因。

在JAVA2平台出現之前,JAVA語言只能處理電話音質的聲音,以單聲道8KHZ的采樣頻率存儲為μ-law AU文件。JAVA2平台增加了對AIFF,WAV以及三種MIDI文件類型的支持。所支持的三種MIDI文件格式為MIDI文件類型0、MIDI文件類型1、以及RMF。

應用程序接口API1.0版提供了一個易於使用的工具集,使程序員可以訪問底層的合成與演奏引擎,從而擴展了JAVA聲音的應用。其中兩個重要的領域是創建數字化音頻以及樂器指令數字化接口MIDI。由於提供了大量的底層支持功能,所以程序員能輸入輸出聲音,控制MIDI設備,並能查詢系統運作情況。

聲音文件類型簡介

主要的聲音文件類型如下:

AU - (擴展名為AU或SND)適用於短的聲音文件,為Solaris和下一代機器的通用文件格式,也是JAVA平台的標准的音頻格式。AU類型文件使用的三種典型音頻格式為: 8位μ-law類型(通常采樣頻率為8kHz), 8位線性類型,以及16位線性類型。

WAV - (擴展名為WAV)由 Microsoft和 IBM共同開發,對WAV的支持已經被加進Windows 95並且被延伸到Windows 98. WAV文件能存儲各種格式包括μ-law,a-law和 PCM (線性)數據。他們幾乎能被所有支持聲音的Windows應用程序播放。

AIFF - (擴展名為AIF或IEF)音頻互換文件格式是為Macintosh計算機和Silicon Graphics (SGI)計算機所共用的標准音頻文件格式。AIFF和 AIFF-C幾乎是相同的,除了後者支持例如μ-law和 IMA ADPCM類型的壓縮。

MIDI - (擴展名為MID)樂器數字接口MIDI是為音樂制造業所認可的標准,主要用於控制諸如合成器和聲卡之類的設備。

MIDI文件不包含數字音頻采樣,而是包括一系列指令,這些指令控制把來自不同樂器上的音符序列合成樂曲。一些MIDI文件包含附加指令來為各種合成設置進行編程。

大多數合成器支持MIDI標准,所以在一個合成器上制作的音樂能夠在另一個上播放。 有 MIDI接口的計算機能操縱 MIDI數據以產生新音樂或音響效果。例如,一個完整的音樂作品可以通過一個軟件驅動的命令轉換成全新的形式。

JAVA聲音引擎支持兩種MIDI文件類型:

MIDI類型0文件-包含僅僅一個序列,所有相關的樂器部分被包含在同一個邏輯 "磁道"上。

MIDI類型1文件-包含多重的 "磁道"使得不同的樂器被邏輯地分開,從而使對聲音的操作和重組更加容易。

RMF - (擴展名為RMF)混合音樂格式是由Beatnik設計出來的混合文件類型,通過交互式設定將MIDI和音頻采樣封裝在一起。RMF好比是一個所有音樂相關文件的容器。RMF也包含對有關版權的詳細文件說明的支持。RMF文件可以包含多個由不同藝術家創作的存儲為MIDI類型或音頻采樣類型的作品,每個都關聯著相關的版權信息。

對聲音引擎的選擇

在1997年,SUN的JAVA媒體開發組試圖找到一種方法,以增強聲音的處理能力並為將來提供一個堅實的平台。根據JAVA媒體開發組經理Michael Bundschuh所說, "我們想要非常高質量的播放引擎以處理所有的從八位μ-law級直到 CD質量聲音的每一件操作。 我們希望輕松跨越所有平台,諸如Solaris平台, Windows, Mac以及其他。我們也想要高度發展了的能夠跨越不同平台的MIDI能力。為上述目的,合理的選擇是Beatnik的音頻引擎(從前是Headspace。)"

SUN取得了Beatnik的音頻引擎使用許可,把它當作JAVA聲音應用程序接口API的基礎。

Thomas Dolby Robertson-Beatnik簡介

在90年代初之前,Thomas Dolby Robertson的職業完全在音樂方面。他1982推出的"她用科學照亮了我"是一部早期的MTV巨作。整個80年代,他都在不斷地作曲和錄音,使用一種非結構化音樂制作軟件。但是在 1990,通過一次為Guggenheim博物館演示虛擬現實的合作,他開始思考能否做一些提高音樂制作能力的工作。

"我當時正伏在 C程序員的肩上,並且我突然認識到為做記錄做了大量的工作,可是沒有為演奏時的交互做任何事情。"有了這樣的想法,Robertson在1992年建立了Headspace,雇用月光作曲組來幫助實現他的觀點。Headspace於1996年成為公司,現在被稱為Beatnik。

JAVA聲音音頻引擎

JAVA聲音引擎為多媒體創建,同時考慮了游戲設計和發布WEB內容。用標准的 MIDI文件、RMF文件、並且/或來自任何源的采樣,該引擎將播放音樂或制造音響效果,同時盡可能少用CPU。它提供完全的播放控制,具有混合音響的能力並可實時地回應用戶的輸入。

JAVA聲音引擎是軟件 MIDI合成器,采樣播放設備,以及16位立體混聲器。它支持混合直到64位的立體MIDI聲音和音頻采樣。它直接支持MIDI類型0和類型1文件以及從8位設備到16位樂器的波表合成。該引擎支持所有通用的 MIDI控制器並且包含象回聲處理, LFO (控制過濾器或立體聲設備)之類的特性,以及ADSR信封 (播放時整形采樣)。

即使用上所有的功能,JAVA聲音引擎在一個90Mhz的奔騰計算機上也占用不超過30%的CPU時間。它還能通過有選擇地禁用不需要的特性,使其變得更加高效一些。另外,它發布了存儲在壓縮的RMF音樂文件中的豐富的內容。Thomas Dolby Robertson的"她用科學照亮了我",一首7分21秒的歌曲,如存儲為CD音質的文件足足占用70M字節空間。如果以RMF格式存儲只需大約636 KB,是120:1的減少,同時絲毫不減音質。

JAVA平台聲音的簡要歷史

在JDK 1.0.x及JDK 1.1.x下, AudioClip接口提供下列機能:

l AudioClip接口

播放

循環

停止

恢復和播放聲音最簡單的方法是通過Applet類的play()方法。調用play()方法有如下二種方式:

play()-帶有一個參數,一個 URL對象,裝載並演奏儲存在 URL處的聲音片斷。

play()-帶有二個參數,基本 URL和文件夾路徑名,裝載並演奏聲音文件。第一參數經常是對getCodeBase()或 getDocumentBase()的調用。

下列代碼片斷舉例說明了直接播放 hello.au的方法。AU文件與小應用程序位於相同文件夾或目錄。

play(getCodeBase(), "hello.au");

play()一旦被調用立刻開始恢復和播放聲音。如果聲音文件不能被查找,將不會有出錯信息,僅僅是沉默。

啟動和停止聲音文件,或循環播放,你必須用 applet的 getAudioClip方法把它裝載進入 AudioClip對象,類似上面play()方法的參數,getAudioClip方法要用一個或兩個參數,當作播放的指示。 第一個或唯一的一個參數是 URL參數,用來指示聲音文件的位置,第二參數是文件夾路徑指針。

下列代碼行舉例說明加載聲音文件進入剪貼對象:

AudioClip co = getAudioClip(getCodeBase(), "horns.wav");

getAudioClip()方法僅僅能被applet內調用。隨著JAVA2的引入,應用程序也能用Applet類的newAudioClip方法裝入聲音文件。前一例子可以改寫如下以用於Java應用程序:

AudioClip co = newAudioClip("horns.wav");

在你已創建 AudioClip對象之後,你能用該對象調用play()、loop()以及stop()方法。如果 getAudioClip或 newAudioClip方法不能找到指定的聲音文件, AudioClip對象的值將是空的。試著播放空對象會導致出錯,所以標准的過程首先是對該條件進行檢測。

接下來是一個完整的程序設計示例,該程序將產生一個applet,當鼠標在該小應用程序applet范圍內按下時會播放 flute+hrn+mrmba.au音樂樣本。此AU示例文件與applet在相同目錄或文件夾下的。

import java.applet.*;
import java.awt.event.*;
public class PlayAudio extends Applet
implements MouseListener {
AudioClip audio;
public void init() {
audio = getAudioClip(getDocumentBase(),
"flute+hrn+mrmba.au");
addMouseListener(this);
}
public void mousePressed(MouseEvent evt) {
if (audio != null) audio.play();
}
public void mouseEntered (MouseEvent me) {
}
public void mouseExited (MouseEvent me) {
}
public void mouseClicked (MouseEvent me) {
}
public void mouseReleased(MouseEvent me) {
}
}

注意: 在許多JAVA2技術書籍中,mouseDown()方法確實是JAVA 1.0事件模型的一部分。使用該方法會有一定的危險,因為該方法在將來可能不會被支持。在JAVA2平台下將MouseListener與mousePressed結合使用是優先的選擇。

API 1.0-質的飛躍

注意:下列備注是以JAVA API的早期版本0.86為基礎的。雖然目前這裡討論的大多數對象和概念與過去保持一致,但由於該API版本已經終止,出現某些改變的可能是存在的。

JAVA聲音 1.0 API為JAVA平台定義了一整套的基本的底層音頻處理功能。它提供如下接口為:

音頻捕獲和播放

IDI合成及序列化

這兩個主要的功能模塊在各自的程序包中提供。

javax.media.sound.sampled-該程序包明確地說明了捕獲、混合以及回播數字采樣音頻的界面。

javax.media.sound.MIDI-該程序包提供MIDI合成、序列化以及事件傳送的界面。

JAVA 1.0 API具備如下特性:

數字音頻

頻捕獲-從輸入源例如麥克風進行數據捕獲。

音和重播-將各種輸入源的聲音混合並重播。

制與編碼-調整增益、定位、回音處理等等,以及進行格式轉換。

態及其提示-當重播開始和結束、設備打開或關閉以及其他相關事件發生時接收事件。

對MIDI的支持

MIDI消息-交換消息(打開音符,關閉音符,諸如此類)

合成-從MIDI數據裝入樂器並產生聲音。

序列化-裝入一個MIDI序列,開始和停止播放,以及調整節奏。

工具

件輸入輸出-讀寫通用音頻文件例如WAV,AIFF及MIDI

置-查詢系統來獲得組件和設備的信息;安裝或取消編碼、文件分析器和設備等。

數字化音頻

通道

Kara Kytle, JAVA聲音 API主管工程師和系統設計師說:"Channel是音頻管道中的基本功能部件"。實現Channel界面的類代表著該"管道"的一個元素,例如硬件設備,一個聲音合成器,或者是一個單音頻流。

InputChannel和 OutputChannel繼承了Channel,分別用於讀入被捕獲的數據和為播放寫數據。子界面Clip支持對預裝入的音頻數據循環播放和重新定位。Device表示任何用於捕獲、播放或混和音頻的硬件或軟件設備。

該界面的層次結構如下圖所示。參考包javax.media.sound.sampled。

當一個Channel打開時,它為自己保留了系統資源 ,並且當它結束時,這些資源被釋放給其他的應用程序和對象使用。用isOpen()方法可以查詢Channel是打開還是關閉的。數據的處理通常由子界面方法比如read()方法來啟動,這部分在InputChannel界面說明描述 (請看JAVA聲音 API的說明書)。

處理方法使Channel處於負責輸入或輸出音頻數據的狀態。用isActive方法可以識別Channel是否處於這種狀態。通過調用pause()方法可以使通道處於暫停狀態,此狀態可以通過isPaused()方法判別。當通道被暫停時,有三種選擇:保留數據(缺省),用flush()方法丟棄內部緩沖器中的數據,或用drain()方法使內部緩存中的數據被立即處理。

對象事先可以注冊,這樣每當通道狀態改變時它都可以收到通告信息。該注冊對象必須實現Channel.Listener界面,該界面僅包含一個方法update()。當Channel打開、結束、啟動、及停止時,該方法都將被調用。當Channel開始或停止活動以及開始或停止捕獲數據時,會產生start或stop事件。

輸入通道

InputChannel是被捕獲的音頻數據的源頭。該界面提供了方法,可從 InputChannel緩沖器讀取被捕獲的數據,並判斷當前可讀的數據量。如果應用程序試圖讀過多的數據,該讀方法阻塞,直到所需讀取數據達到為止。

輸出通道

OutputChannel接收用於播放的音頻數據。這接口提供方法,將要播放的數據寫入OutputChannel的緩沖區,並能判斷該通道不間斷可接收的數據量。如果應用程序試圖寫過量的數據,該讀方法阻塞,直到有足夠數據為止。

剪貼

Clip接口表示一個特殊的通道,它可以在播放之前先裝入音頻數據。由於數據是預裝入的,而不是流入的,所以clip可以支持持續查詢、循環播放、以及重新定位播放。

設備

Device界面為表示音頻設備的類提供方法。音頻設備可以是共享的也可是獨占的系統資源,它可以是基於硬件的,也可基於軟件的,還可是同時基於兩者的。它能被重復地打開和關閉,它能時常說明它的內在特性及支持的音頻格式。同時,它也提供信息對象來描述設備。

JAVA聲音 API進一步描述三種設備子界面:

InputDevice

InputDevice界面提供一個方法getInputChannel來獲得一個InputChannel對象,從中捕獲可讀的音頻數據。

OutputDevice

OutputDevice界面提供一個方法getOutputChannel來獲得一個OutputChannel對象,音頻數據可以寫入該輸出通道,並予播放。

Mixer

Mixer支持多個InputChannel和/或Clip。 另外,它提供了查詢方法,從中可得到它所支持的通道數量,它也提供了支持同步暫停和喚醒多個通道播放的方法。

控件

通道和音頻端口 (比如揚聲器和麥克風)一般能支持一組控件比如增益和定位。通過將它的類作為參數傳給getControl()方法,JAVA聲音 API的通道對象和端口對象可以獲得一個特別的控件。

編碼器

Codecs可以對音頻數據編碼和解碼,允許在不同格式和編碼之間轉換。JAVA聲音 API通過AudioSystem類中的方法為這些轉換提供了高級接口。如果給了一個特殊的音頻流,應用程序會查詢音頻系統來找到相應的轉換,從而得到指定格式的音頻流。

文件和流

音頻流是與音頻數據格式和數據長度相關的輸入流,文件流是與文件類型和數據長度相關的輸入流。JAVA聲音 API在AudioSystem類中為音頻文件和音頻流之間的轉換提供了接口。

查詢和訪問安裝組件

AudioSystem類充當到采樣音頻系統資源入口的角色。該類允許程序員查詢和訪問輸入設備、輸出設備以及安裝好的混音設備。另外,AudioSystem包含許多在不同音頻數據格式間轉換的方法。它也提供一些方法,使得在不需要對設備直接操作的情況下,直接獲得輸入通道或輸出通道。

系統配置-服務提供者界面(SPI)

對采樣音頻系統的配置是由javax.media.sound.sampled.spi包來完成的。通過 AudioConfig類的方法,可以在系統中安裝或卸載設備,並且可以建立起缺省狀態。服務提供者可以希望提供和安裝他們自己的編碼器和分析器。這個包提供了完成這種功能的機制。

下面的圖描述了音頻輸入和輸出的功能流。

MIDI

javax.media.sound.MIDI程序包描述了 MIDI事件傳送、合成、以及序列化的界面。下面介紹該程序包中所用到的主要概念。

傳送

基本的MIDI傳送界面是 MidiDevice。所有設備為列出其所支持的模式和查詢當前模式提供了方法。設備支持監聽器,可以監聽各種事件如打開和關閉事件,並且有一個信息對象來描述設備狀態。

通常,設備是MIDI事件的傳送器或接收器之一。傳送器界面提供了一些方法來設置和查詢接收器,該接收器接收由該傳送器發送出的MIDI事件。接收器為接收MIDI事件提供方法。

基本的 MidiEvent對象是通過一個消息說明事件類型、數據長度、以及狀態。它也為涉及MIDI計時的設備例如音序器提供准確的計時信號。

合成器

合成器界面是一種生成聲音的特殊類型的接收器。它也提供一些方法來管理聲音庫和樂器。另外,合成器可以支持一組全局的非-MIDI控件例如增益和定位。它也提供對一組MIDI通道的訪問,實際上,聲音就是通過這些通道產生的。

MidiChannel界面提供一組方法來表達公用的MIDI聲音消息例如 noteON, noteOff以及controlChange。還支持對當前通道狀態的查詢。

序列化

Sequencer界面繼承了MidiDevice,它提供了完成基本MIDI序列化操作的方法。音序器可以裝載和播放一個序列,查詢和設置節奏,並且控制主從同步方式。一個應用程序還可以通過注冊使得音序器在處理設備單元和控制器事件時通知自己。

文件和序列化

序列化對象代表一個來自一個或多個磁道的MIDI序列以及相關的計時信息。一個磁道對象包含一系列加上時間標記的MIDI事件。

JAVA聲音 API在 MidiSystem類中為在MIDI文件和序列化對象之間轉換提供了高級的接口。

查詢和訪問已經安裝了的組件

MidiSystem類充當MIDI音樂系統入口的角色。它提供相關設備的信息並對之進行訪問,這些設備包括傳送器,接收器,合成器,以及音序器。它也提供了對SoundBank對象的訪問。

系統配置-服務提供者接口(SPI)

MIDI系統的配置由javax.media.sound.midi.spi包來完成的。通過MidiConfig類的方法,設備可以安裝到系統中或從中卸載,並且可以建立起缺省狀態。服務提供者可以希望提供和安裝他們自己的文件和聲音庫分析器。該SPI程序包中包括了完成這種功能的機制。

現在讓我們看看能用這些類和方法做什麼。請仔細檢查一下。

ToySynth應用程序

ToySynth應用程序試驗了早期對JAVA聲音 API存取的方式,主要是通過提供一系列設備設置,包括MIDI通道選擇、音量控制、立體聲定位、回聲處理、以及其他選項。通過敲擊鍵盤就可以演奏使用指定設備的樂曲,而這些設備又都是通過JAVA聲音引擎來實現的。

完整的ToySynth.java代碼樣本。

JAVA聲音 API的市場目標

JAVA聲音 API為各種各樣的應用程序提供了聲音支持。下面列舉一些可能的應用。

通信框架

通過計算機召開遠程會議

在計算機上實現電話功能

內容發布系統

音樂

信息流

媒體傳播

交互式應用程序

游戲

WEB站點

產生動態內容

工具集

內容產生

各種工具

在此基礎上我們能做什麼?

JAVA 2通過 AudioClip界面來訪問JAVA聲音音頻引擎。隨著1.0 API的發布,我們所曾經探索的應用領域,就將提供給各地的開發人員使用。

"現在,我們通過在JAVA2平台中加入真實聲音的支持,啟動了計算機桌面多媒體市場。以後,我們將看見我們的JAVA聲音API技術廣泛應用於專業人員、普通用戶以及國際互連網上的音頻應用", Michael Bundschuh說。

電影和錄音帶公司通過使用JAVA聲音 API技術可以獲得專業質量音頻效果。在JAVA聲音引擎中實現支持24位音頻和多通道配置將鼓勵專業人員開發出高級的聲音編輯和播放應用程序。

根據 Kara Kytle所說,對更多的音頻數據類型例如MP3的支持已經被提到議事日程。"另一個議程是從外部設備對MIDI數據進行捕獲。這將很快實現。"她說。

"JAVA聲音 API技術已經可以很好地適用於通過WEB的音頻播放。"Bundschuh說。"但是我們總是跟蹤最新的技術,並且開發象MP3這樣的技術,同時還要保護音樂文件的安全傳送。我們計劃在JAVA聲音 API今後的版本中提供對上述技術的支持"。

隨著最近市場的發展,象播放基於WEB音樂上的競爭策略一樣,大家都已經把發展數字化聲音放在中心的位置。新的媒體技術不斷湧現,聲音將扮演核心的角色。JAVA聲音 1.0 API將適時地加入到新的關鍵應用程序開發行列中來。

現可以得到ToySynth.java程序代碼

該程序通過圖形形象地表示出一個合成器的樣子,通過鼠標去按合成器上的鍵來演奏樂曲。你可以通過聲音設置以及其他選項去改變聲音的基調。好好玩吧。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved