我正在尝试在 Linux 上使用 Java 播放音频缓冲区。
尝试打开线路时出现以下异常(而不是在我向其写入音频时)...
Exception in thread "main" java.lang.IllegalArgumentException: No line matching interface SourceDataLine supporting format PCM_FLOAT 44100.0 Hz, 16 bit, mono, 2 bytes/frame, is supported.
public boolean open()
{
try {
int smpSizeInBits = bytesPerSmp * 8;
int frameSize = bytesPerSmp * channels; // just an fyi, frameSize does not always == bytesPerSmp * channels for non PCM encodings
int frameRate = (int)smpRate; // again this might not be the case for non PCM encodings.
boolean isBigEndian = false;
AudioFormat af = new AudioFormat(AudioFormat.Encoding.PCM_FLOAT , smpRate, smpSizeInBits, channels, frameSize, frameRate, isBigEndian);
DataLine.Info info = new DataLine.Info(SourceDataLine.class, af);
int bufferSizeInBytes = bufferSizeInFrames * channels * bytesPerSmp;
line = (SourceDataLine) AudioSystem.getLine(info);
line.open(af, bufferSizeInBytes);
open = true;
}
catch(LineUnavailableException e) {
System.out.println("PcmFloatPlayer: Unable to open, line unavailble.");
}
return open;
}
我想知道我对 PCM_FLOAT 编码是什么的假设实际上是不正确的。
我有一些读入 wav 文件的代码。wavfile 是单声道、16 位、未压缩格式。然后我将音频转换为 -1.0 到 1.0 范围内的浮点数进行处理。
我假设 PCM_FLOAT 编码只是原始 PCM 数据,已转换为 -1.0 和 1.0 之间的浮点值。这个对吗?
然后我假设 SourceDataLine 会根据我传递的格式信息(单声道、16 位、2 字节/帧)将浮动音频转换为适当的格式。这个假设又是不正确的吗?
我必须将我的 float -1.0 到 1.0 音频转换回我想要的输出格式,并将 SourceDataLine 设置为 PCM_SIGNED(假设这是我想要的格式)吗?
编辑:
另外,当我使用 PCM_FLOAT 调用 AudioSystem.getTargetEncodings() 时,它会返回三个编码。这是否意味着它将接受 PCM_FLOAT,并能够根据底层音频系统支持的内容转换为返回的编码?
AudioFormat.Encoding[] encodings = AudioSystem.getTargetEncodings(AudioFormat.Encoding.PCM_FLOAT);
for(AudioFormat.Encoding e : encodings)
System.out.println(e);
结果是...
PCM_SIGNED PCM_UNSIGNED PCM_FLOAT