2017-07-16 76 views
0

我有一个用Java编写的应用程序,需要播放音频。我使用OpenAL(使用java-openal库)进行任务,但是我想使用OpenOL直接不支持的WSOLA。我发现了一个名为TarsosDSP的java本地库,它支持WSOLA。支持SourceDataLine格式的问题

该库使用标准Java API进行音频输出。在SourceDataLine的安装过程中出现的问题:

IllegalArgumentException: No line matching interface SourceDataLine supporting format PCM_UNSIGNED 16000.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian is supported. 

我确信这个问题不是由缺少权限引起的(运行它作为在Linux +根试了一下在Windows 10),而且在不使用其他SourceDataLines该项目。

经过修改格式之后,我发现格式在从PCM_UNSIGNED更改为PCM_SIGNED时被接受。这似乎是一个小问题,因为只有将字节范围表单无符号地移动到带符号应该很容易。然而奇怪的是,它不是本地支持的。

那么,有没有一些解决方案,我不需要修改源数据?

谢谢,1月

回答

1

您不必手动移动字节范围。在创建AudioInputStream之后,您将创建另一个带有签名格式并连接到第一个未签名流的AudioInputStream。如果您使用签名流读取数据,Sound API会自动转换格式。这样你就不需要修改源数据。

File fileWithUnsignedFormat; 

AudioInputStream sourceInputStream; 
AudioInputStream targetInputStream; 

AudioFormat sourceFormat; 
AudioFormat targetFormat; 

SourceDataLine sourceDataLine; 

sourceInputStream = AudioSystem.getAudioInputStream(fileWithUnsignedFormat); 
sourceFormat = sourceInputStream.getFormat(); 

targetFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
    sourceFormat.getSampleRate(), 
    sourceFormat.getSampleSizeInBits(), 
    sourceFormat.getChannels(), 
    sourceFormat.getFrameSize(), 
    sourceFormat.getFrameRate(), 
    false); 

targetInputStream = AudioSystem.getAudioInputStream(targetFormat, sourceInputStream); 

DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, targetFormat); 
sourceDataLine = (SourceDataLine) AudioSystem.getLine(dataLineInfo); 

sourceDataLine.open(targetFormat); 
sourceLine.start(); 


// schematic 
targetInputStream.read(byteArray, 0, byteArray.length); 
sourceDataLine.write(byteArray, 0, byteArray.length);