alin
   
發文: 223
積分: 3
|
於 2004-07-21 11:30
     
chuang5089 ask:
Can i ask some java sound quest ..
Do you have any idea for my question
1. record sound from java api 2. play sound from java api 3. something like record sound by mic on thread 2000 second and play it, like i can use inputstream method record sound and outputstream methoud play just what i say from mic
4. 1 and 2 condiction without use create file
Best regard
---- 分隔線 ---- 分隔線 ---- 分隔線 ----
基本上, 你可以使用 JDK 1.4 裡的 javax.sound.sampled 套件來達到簡單的錄音然後再播放的功能
錄音和放音的功能需要用到的幾個主要Class有以下幾個
javax.sound.sampled.AudioFormat 設定錄音的線路要路程什麼格式
javax.sound.sampled.AudioInputStream AudioInputStream 繼承自InputStream, 基本上就是一個串流的輸入
javax.sound.sampled.AudioSystem 可以透過這一個物件去取得系統中可供使用的硬體有哪些
javax.sound.sampled.TargetDataLine 可以透過 TargetDataLine 取得有哪些可供錄音的線路存在
javax.sound.sampled.SourceDataLine 可以透過 SourceDataLine 取得有哪些可供播音的線路存在
下面節錄自 JDK /demo的一小段錄音部分的範例程式 (下載位置http://java.sun.com/products/java-media/sound/samples/JavaSoundDemo/)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| AudioFormat format = formatControls.getFormat();
DataLine.Info info = new DataLine.Info( TargetDataLine.class, format );
AudioFormat[] afs = info.getFormats();
System.out.println("Support formating recording folowing.......\r\n");
for (int i = 0; i < afs.length; i++) {
System.out.println("afs["+i+"]=" + afs[i].toString());
}
if ( !AudioSystem.isLineSupported( info ) ) {
shutDown( "Line matching " + info + " not supported." );
return;
}
try {
line = ( TargetDataLine ) AudioSystem.getLine( info );
line.open( format, line.getBufferSize() );
}
catch ( LineUnavailableException ex ) {
shutDown( "Unable to open the line: " + ex );
return;
}
catch ( SecurityException ex ) {
shutDown( ex.toString() );
showInfoDialog();
return;
}
catch ( Exception ex ) {
shutDown( ex.toString() );
return;
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
int frameSizeInBytes = format.getFrameSize();
int bufferLengthInFrames = line.getBufferSize() / 8;
int bufferLengthInBytes = bufferLengthInFrames * frameSizeInBytes;
byte[] data = new byte[bufferLengthInBytes];
int numBytesRead;
line.start();
while ( thread != null ) {
if ( ( numBytesRead = line.read( data, 0, bufferLengthInBytes ) ) == -1 ) {
break;
}
out.write( data, 0, numBytesRead );
}
line.stop();
line.close();
line = null;
try {
out.flush();
out.close();
}
catch ( IOException ex ) {
System.out.println( "run() CapturePanel error : " + ex.getMessage() );
}
byte audioBytes[] = out.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream( audioBytes );
audioInputStream = new AudioInputStream( bais, format,
audioBytes.length /
frameSizeInBytes );
long milliseconds = ( long ) ( ( audioInputStream.getFrameLength() * 1000 ) /
format.getFrameRate() );
duration = milliseconds / 1000.0;
try {
audioInputStream.reset();
}
catch ( Exception ex ) {
System.out.println( "reset error : " + ex.getMessage() );
return;
}
|
裡面主要在做的事情就是 1.先確定音檔格式 2.找到相關的硬體資料 3.透過 ( TargetDataLine ) AudioSystem.getLine( info ); 取得一個可以錄音的線路 4.取得線路後, 可以將 TargetDataLine 這一個物件, 看做和 File 一樣的物件 (類似啦~) 這時錄音開始的時候, 聲音的輸入將會視作一般的 InputStream 放在線路的Buffer中 然後, 再用 ByteArrayPutputStream 將 線路中的 InputStream 取出來, 轉換成AudioInputStream 即可
假如想要將 AudioInputStream 裡面的資料及時播放出來, 需要做像上述的動作 就是先取得 AudioFormat, 取得播音的線路 (SourceDataLine), 檢查播音線路是否支援欲播放的格式 假如可以救播放
先說到這裡吧, 因為需要處理的物件實在太多了, 所以無法一一說明, 建議先去把範例程式下載回來, 跑個幾遍 有問題時我們再來慢慢討論, ok?
 
|