2013-02-23 38 views
2

我正在學習如何將JSpeex用於VoIP應用程序,以後我會爲了教育目的而編寫這些應用程序。作爲試圖理解如何使用JSpeex,我決定寫一個簡單的回聲應用程序。基本上,它從音頻輸入線讀取輸入,編碼數據(使用Speex),然後解碼數據,並將其寫入音頻輸出線。但是,當我運行該應用程序時,我聽到的所有內容都是靜態的,沒有任何聲音。我試圖修改音頻格式,我如何初始化解碼器和編碼器,所有這些我都沒有運氣。任何人都可以看看代碼,並試圖指出我做錯了什麼?謝謝。當播放解碼後的Speex數據時,我聽到的只是靜態的

代碼:

(?有沒有更好的方式來粘貼代碼,因爲當我貼吧,凸顯了這一切,並按下代碼按鈕,壓痕得到弄糟。)

import java.util.Arrays; 

import javax.sound.sampled.AudioFormat; 
import javax.sound.sampled.AudioSystem; 
import javax.sound.sampled.DataLine; 
import javax.sound.sampled.LineUnavailableException; 
import javax.sound.sampled.SourceDataLine; 
import javax.sound.sampled.TargetDataLine; 

import org.xiph.speex.SpeexDecoder; 
import org.xiph.speex.SpeexEncoder; 

public class SpeexTest { 

    public static void main(String[] args) throws Exception { 
    int sample_rate = 8000; 
    int sample_size = 16; 
    int channels = 1; 
    AudioFormat format = new AudioFormat(sample_rate, sample_size, 
     channels, true, true); 
    TargetDataLine line_in; 
    DataLine.Info info_in = new DataLine.Info(TargetDataLine.class, format); 
    try { 
     line_in = (TargetDataLine) AudioSystem.getLine(info_in); 
     line_in.open(format); 
    } catch (LineUnavailableException ex) { 
     ex.printStackTrace(); 
     return; 
    } 
    DataLine.Info info_out = new DataLine.Info(SourceDataLine.class, format); 
    SourceDataLine line_out; 
    try { 
     line_out = (SourceDataLine) AudioSystem.getLine(info_out); 
     line_out.open(format); 
    } catch (LineUnavailableException ex) { 
     ex.printStackTrace(); 
     return; 
    } 
    SpeexEncoder encoder = new SpeexEncoder(); 
    SpeexDecoder decoder = new SpeexDecoder(); 
    encoder.init(1, 1, sample_rate, channels); 
    decoder.init(1, sample_rate, channels, false); 
    int raw_block_size = encoder.getFrameSize() * channels 
     * (sample_size/8); 
    byte[] buffer = new byte[raw_block_size * 2]; 
    line_in.start(); 
    line_out.start(); 
    while (true) { 
     int read = line_in.read(buffer, 0, raw_block_size); 
     if (!encoder.processData(buffer, 0, raw_block_size)) { 
     System.err.println("Could not encode data!"); 
     break; 
     } 
     int encoded = encoder.getProcessedData(buffer, 0); 
     System.out.println(encoded 
      + " bytes resulted as a result of encoding " + read 
      + " raw bytes."); 
     byte[] encoded_data = new byte[encoded]; 
     System.arraycopy(buffer, 0, encoded_data, 0, encoded); 
     decoder.processData(encoded_data, 0, encoded); 
     byte[] decoded_data = new byte[decoder.getProcessedDataByteSize()]; 
     int decoded = decoder.getProcessedData(decoded_data, 0); 
     System.out.println(decoded 
      + " bytes resulted as a result of decoding " + encoded 
      + " encoded bytes."); 
     line_out.write(decoded_data, 0, decoded); 
    } 
    } 
} 

這裏有一些輸出(相同的總是重複):

15 bytes resulted as a result of encoding 640 raw bytes. 
640 bytes resulted as a result of decoding 15 encoded bytes. 

回答

2

JSpeex輸入/輸出是little-endian。在編碼之前或解碼之後交換字節,或者打開DataLine s與

AudioFormat format = new AudioFormat(sample_rate, sample_size, 
      channels, true, false); 
+0

哇!這樣一個簡單的修復!萬分感謝。 – 2013-02-25 01:08:40

相關問題