一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Java Sound API

 風(fēng)舞者 2007-02-09
Java Sound API是javaSE平臺提供底層的(low-level)處理聲音接口。
 
例外,java也提供了簡單的實用的高層媒體接口(higher-level) - JMF(Java Media Framework)。
 
Java Sound API 將需要處理的數(shù)字音頻分為:simpled-audio和midi,
分別提供Package來處理它們:
 
javax.sound.simpled
javax.sound.midi
 
同時SOUND API還提供了第三方的擴展接口:
 
javax.sound.simpled.spi
javax.sound.midi.spi
*注:spi : service provider interface
 
Sampled Audio
 
采樣音頻(simpled-audio)不僅包含從模擬信號采樣來的數(shù)字音頻,還包括電腦合成的。
稱作digital-audio更為合適。
 
為了能夠讓設(shè)備播放采樣聲音,程序需要處理 audio input, output device, audio data buffers。
還有混音處理(mix multiple streams of audio into one stream)。
 
SOUND API 可以使用3種方式傳輸聲音數(shù)據(jù):stream, buffered fashion, in-memory unbuffered fashion。
第三種方式適合數(shù)據(jù)量不大,能夠一次載入的所有數(shù)據(jù)的情形。這樣,聲音的響應(yīng)較快,循環(huán)和隨機定位也會很簡單。
 
使用SOUND API播放聲音至少需要3樣?xùn)|西:
l         formatted audio data,
l         a mixer,
l         a line.
 
Mixer
調(diào)音臺
technically the Mixer itself is also a kind of Line
 
Line
音頻數(shù)據(jù)管道。
 
Clip extends Line
將需要播放的音頻數(shù)據(jù)裝載進來。
preloads audio data from a sound file into clips
A Clip is a data line into which audio data can be loaded prior to playback. Because the data is
pre-loaded rather than streamed, the clip‘s duration is known before playback, and you can choose any
starting position in the media. Clips can be looped, meaning that upon playback, all the data between two
specified loop points will repeat a specified number of times, or indefinitely.
 
SourceDataLine extends Line
accept real-time stream of audio data
feed audio to the Mixer
A SourceDataLine receives audio data for playback. It provides methods for writing data to the
source data line‘s buffer for playback, and for determining how much data the line is prepared to receive
without blocking.
 
 
TargetDataLine
A TargetDataLine receives audio data from a mixer. Commonly, the mixer has captured audio data
from a port such as a microphone; it might process or mix this captured audio before placing the data in
the target data line‘s buffer. The TargetDataLine interface provides methods for reading the data
from the target data line‘s buffer and for determining how much data is currently available for reading.
 
Port extends Line
simple Line
 
Line 接口的繼承關(guān)系圖
 
 
AudioSystem
AudioSystem提供音頻資源的訪問服務(wù)。
通過AudioSystem,可以知道什么樣的資源可以被識別。
 
可從AudioSystem獲得的資源:
l        Mixers, AudioSystem類可以提供一張已經(jīng)安裝的Mixer列表
l        Lines
l        Format conversions
l        Files and streams
 
Mixer的獲得
Mixer.Info
AudioSystem.getMixerInfo():Mixer.Info
可以獲得一張Mixer信息列表。
 
每個Mixer.Info包含如下關(guān)鍵信息:
l        Name
l        Version
l        Vendor
l        Description
 
我機器上的Mixer列表,WinXP,JDK_1.4.2
[INFO 0]
INFO.NAME:Java Sound Audio Engine
INFO.VERSION:1.0
INFO.VERDOR:Sun Microsystems
INFO.DESCRIPTION:Software mixer and synthesizer
 
[INFO 1]
INFO.NAME:Microsoft ?ù??????÷
INFO.VERSION:Unknown Version
INFO.VERDOR:Unknown Vendor
INFO.DESCRIPTION:No details available
 
[INFO 2]
INFO.NAME:Realtek AC97 Audio
INFO.VERSION:Unknown Version
INFO.VERDOR:Unknown Vendor
INFO.DESCRIPTION:No details available
 
[INFO 3]
INFO.NAME:Realtek AC97 Audio
INFO.VERSION:5.10
INFO.VERDOR:Unknown Vendor
INFO.DESCRIPTION:Unknown Description
 
獲取Mixer
AudioSystem.getMixer( MixerInfo ):Mixer
 
如果只從Mixer.Info提供的信息無法確定需要的Mixer,
不妨創(chuàng)建出所有的Mixer,使用時檢查它們的能力,使用合適那個。
 
例如,你可能需要一個Mixer,能夠?qū)⒒煲艉玫臄?shù)據(jù)同時寫入一定數(shù)目的目標(biāo)數(shù)據(jù)管道(TargetDataLine.
使用Mixer.getMaxLines(Line.Info info):int來了解Mixer的輸出能力。info就是指定的TargetDataLine
 
獲得指定類型Line
2種方法獲得Line
l        直接由AudioSystem獲得,AudioSystem.getLine( Line.Info ):Line
l        Mixer獲得
 
AudioSystem直接獲得Line
static Line AudioSystem.getLine( Line.Info )
不同于Mixer.Info,Line.Info不是文本信息,而是Line的類信息。
 
Line.Info是抽象類,所以使用它的子類DataLine.Info,Port.Info
下面是通過Line.Info獲得Line的示例:
 
TargetDataLine line;
DataLine.Info info = new DataLine.Info(TargetDataLine.class,
    format); // format is an AudioFormat object
if (!AudioSystem.isLineSupported(info)) {
    // Handle the error.
}
// Obtain and open the line.
try {
    line = (TargetDataLine) AudioSystem.getLine(info);
    line.open(format);
} catch (LineUnavailableException ex) {
    // Handle the error.
    //...
}
 
Port.Info定義一系列靜態(tài)的Port.Info對象,MICROPHONE,SPEAKER,etc.
 
Mixer獲得Line
getSourceDataLine()
getTargetDataLine()
getLine()
 
AudioSystem對象模型
 
AudioPermission
音頻資源訪問許可。
 
利用JAVA-SOUND-API播放聲音
 
可以使用2Line來播放聲音,Clip,SourceDataLine。
Clip一次載入需要播放的聲音資源,而SourceDataLine 以流的方式傳輸聲音數(shù)據(jù)。
 
使用Clip
當(dāng)使用getLine()獲得Clip后,還要保證其他的程序在你播放前不能獲取它,調(diào)用open()方法獨占它:
void open( AudioInputStream stream );
void open( AudioFormat, byte[] data, int offset, int bufferSize );
 
Clip默認從音頻的開頭開始播放,除非使用setFramePosition(),setMicroSecondPosition()設(shè)定其他位置。
 
Clip.start()播放,Clip.stop()暫停。
 
getLevel(),獲得聲音高度。
 
isActive(),Clip是否正在播放。
 
 
使用SourceDataLine
 
open(AudioFormat),打開source dataLine,但不指定數(shù)據(jù),使用默認的buffer size。
 
open(AudioFormat, bufferSize),指定buffer size.
合理設(shè)置buffer size,保證開始載入的延時能夠被接受,又盡量減少IO訪問。
 
open()之后,調(diào)用start()容許SourceDataLine一有數(shù)據(jù)就開始播放,使用write()不停的輸入數(shù)據(jù)。
 
void write( byte[] b, int offset, int length );
 
SourceDataLine開始播放后,向Mixer傳輸數(shù)據(jù),當(dāng)Mixer開始向target傳輸數(shù)據(jù)時,SourceDataLine產(chǎn)生一個 START 事件。
這是SourceDataLine被認為是活動的(active)。
 
isRunning()表明Line是否start()了。
isActive()表明Line是否開始播放。
 
write()方法向buffer size 中寫入數(shù)據(jù),如果buffer已滿,還剩下一些數(shù)據(jù),該方法會阻塞;否則,是不阻塞的。
 
可以使用DataLine.available()知道buffer size還能寫入多少數(shù)據(jù)。
 
事實上,可以另開線程去使用write(),而不用考慮阻塞的問題。
 
drain()方法在所有數(shù)據(jù)播放完后返回。
 
所有在寫完數(shù)據(jù)后,調(diào)用drain(),到它返回時再是否Line。
line.write(b, offset, numBytesToWrite);
//this is the final invocation of write
line.drain();
line.stop();
line.close();
line = null;
 
flush()清空buffer中的剩余數(shù)據(jù),Linestop時才能調(diào)用。
 
有如下情形,Line會產(chǎn)生 STOP 事件:
l        調(diào)用drain()
l        調(diào)用stop()
l        調(diào)用flush()
l        輸出完舊的數(shù)據(jù),而新的數(shù)據(jù)未到時。
 
STOP事件意味著isActive()返回false.
 
start()調(diào)用之后,isRunning()都會返回true,知道stop()被調(diào)用。它不是依據(jù) STOP 事件產(chǎn)生返回值的。
 
isActive()是依據(jù)START STOP 事件的。
 
 
監(jiān)視Line的狀態(tài)
使用LineListener響應(yīng)Line的事件。
void Line.addLineListener( LineListener );
 
當(dāng)調(diào)用open(),close(),start(),stop()會產(chǎn)生OPEN,CLOSE,START,STOP事件。
 
多個Line 同步播放
有些Mixer提供方便的同步功能,對一組Lines使用open(),close(),start(),stop(),保證它們的同步。
 
可以使用如下方法,檢查Mixer是否支持同步功能:
boolean isSynchronizationSupported( Line[] lines, boolean maintainSync )
第二個參數(shù)表明同步精度,是采樣同步,還是只是start(),stop()保持同步,并不維護播放過程同步。
 
AudioFormat
音頻采樣的格式,不是音頻文件的格式。
 
l        編碼技術(shù),一般都是PCM( pulse code modulation )
l        聲道數(shù)目(1,單聲道;2,雙聲道;等等)
l        采樣頻率 sample rate
l        樣本的位數(shù) number of bits per sample
l        幀速率 Frame rate
l        Frame Size in bytes
l        Byte Order( big-endian or little-endian )
 
AudioFileFormat:
音頻文件格式。
The file type( WAV,AIFF,etc )
The file length in bytes
The length, in frames, of the audio data contained in the file
An AudioFormat that specifies data format of the audio data in the file
 
 
AudioInputStream extends InputStream
無須考慮文件的格式,就能操作Samples
 
讀取音頻文件
 
AudioSystem提供2中方法讀取音頻文件:
l        根據(jù)音頻文件中音頻數(shù)據(jù)的格式信息
l        使用一個指定了音頻數(shù)據(jù)格式的流
 
使用如下方法獲得音頻文件中音頻數(shù)據(jù)的格式信息:
static AudioFileFormat getAudioFileFormat(File);
static AudioFileFormat getAudioFileFormat(InputStream);
static AudioFileFormat getAudioFileFormat(URL);
 
利用如下方法獲得第二種方法提到的音頻數(shù)據(jù)流:
static AudioInputStream getAudioInputStream(File)
static AudioInputStream getAudioInputStream(InputStream)
static AudioInputStream getAudioInputStream(URL)
 
讀取音頻文件數(shù)據(jù)的步驟:
1)    獲得AudioInputStream對象
2)    創(chuàng)建一個字節(jié)數(shù)組,存放一次讀入的數(shù)據(jù)塊
3)    不斷地從audio流中讀入數(shù)據(jù),播放或處理數(shù)據(jù)。
示例代碼如下:
int totalFramesRead = 0;
File fileIn = new File(somePathName);
// somePathName is a pre-existing string whose value was
// based on a user selection.
try {
    AudioInputStream audioInputStream =
        AudioSystem.getAudioInputStream(fileIn);
    int bytesPerFrame =
        audioInputStream.getFormat().getFrameSize();
    // Set an arbitrary buffer size of 1024 frames.
    int numBytes = 1024 * bytesPerFrame;
    byte[] audioBytes = new byte[numBytes];
    try {
        int numBytesRead = 0;
        int numFramesRead = 0;
        // Try to read numBytes bytes from the file.
        while ((numBytesRead =
            audioInputStream.read(audioBytes)) != -1) {
        // Calculate the number of frames actually read.
        numFramesRead = numBytesRead / bytesPerFrame;
        totalFramesRead += numFramesRead;
        // Here, do something useful
        // with the audio data that‘s
        // now in the audioBytes array...
    }
    } catch (Exception ex) {
        // Handle the error...
    }
} catch (Exception e) {
    // Handle the error...
}
 
寫音頻文件
通過下列方法知道AudioSystem支持哪些音頻文件格式寫入:
static boolean isFileTypeSupported( AudioFileFormat.Type,AudioInputStream );
 
static AudioFileFormat.Type[] getAudioFileTypes();
 
static AudioFileFormat.Type[] getAudioFileTypes(AudioInputStream);
 
利用AudioSystem.write()方法向文件寫入指定格式的音頻數(shù)據(jù):
static int write( AudioInputStream, AudioFileFormat.Type, File );
 
文件或數(shù)據(jù)格式轉(zhuǎn)換
“Java Sound Programmer Guide” – chapter 7
Audio File Format Convertion
Audio Data Format Convertion
 
 
PCM
PCM 脈沖編碼調(diào)制是Pulse Code Modulation的縮寫。
PCM通過抽樣、量化、編碼三個步驟將連續(xù)變化的模擬信號轉(zhuǎn)換為數(shù)字編碼。
PCM是數(shù)字音頻中最佳的保真水準(zhǔn),近似看成“無損”編碼。
PCM編碼的優(yōu)點是音質(zhì)好,缺點是數(shù)據(jù)量大。
 
JAVA SOUND API對于其它編碼格式,在播放前都會轉(zhuǎn)換成PCM格式。
 
 
 
DAC:digital-to-analog converter,數(shù)模轉(zhuǎn)換器
 
 
Decibel:分貝。pl.decibels
 
PAN:聲象,該通道信號在左右音箱之間的立體聲位置。
GAIN:增益
REVERB:數(shù)字混響。
 
Acoustics:聲學(xué)
資源
《Java Sound programmer guide》

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    国产一级精品色特级色国产| 国产内射在线激情一区| 色综合久久六月婷婷中文字幕| 五月婷婷六月丁香狠狠| 亚洲深夜精品福利一区| 久久久精品日韩欧美丰满| 国产无摭挡又爽又色又刺激| 日韩精品亚洲精品国产精品| 亚洲欧美黑人一区二区| 日韩成人动画在线观看| 最近最新中文字幕免费| 国产欧美日韩视频91| 老司机精品视频在线免费| 中文字幕人妻日本一区二区 | 久久天堂夜夜一本婷婷| 日本高清一区免费不卡| 人妻内射精品一区二区| 国产成人亚洲精品青草天美| 欧美黄色成人真人视频| 欧美一区二区三区视频区| 日本不卡在线视频你懂的| 麻豆最新出品国产精品| 亚洲日本加勒比在线播放| 国产一区二区三区口爆在线| 欧美又大又黄刺激视频| 亚洲中文字幕乱码亚洲| 久久福利视频视频一区二区 | 精品亚洲香蕉久久综合网| 厕所偷拍一区二区三区视频| 国内九一激情白浆发布| 冬爱琴音一区二区中文字幕| 91爽人人爽人人插人人爽| 激情五月激情婷婷丁香| 91精品国产av一区二区| 丰满人妻少妇精品一区二区三区| 亚洲欧美日韩国产成人| 国产免费一区二区不卡| 亚洲国产成人一区二区在线观看| 一本色道久久综合狠狠躁| 国产精品欧美激情在线观看| 久久三级国外久久久三级|