当调用AudioSystem.getLine(TargetDataLine.class, audioFormat)时,AudioFormat的frameSize和frameRate有必须严格指定帧大小恰好等于一个样本,并且frameRate等于sampleRate吗?
以下代码有效(从“编译和运行没有错误”的意义上来说),但似乎效率非常低,因为每次它捕获一个2字节样本时,它似乎都会困扰我的代码:
AudioFormat format= new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 48000, 16, 1, 2, 48000, true);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine line = (TargetDataLine) AudioSystem.getLine(info);
...但是如果我尝试将每个帧放大 10 倍,并将帧速率降低相同的量,AudioSystem.getLine() 将返回 null:
// causes AudioSystem.getLine() to return null
AudioFormat lessFrequent = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 48000, 16, 1, 20, 4800, true);
...说实话,我真的希望它缓冲更长的帧,并且每 100 毫秒才打扰我一次:
// pure fantasy:
AudioFormat ideal = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 48000, 16, 1, 9600, 10, true);
我是否做错了什么,或者发生这种情况是因为当今的计算机(例如 2023 Macbook Pro)不再具有能够捕获到自己的内存并定期自动进行 DMA 处理的声卡,而不会在每一步中干扰 CPU ...所以现在,帧率和采样率现在必须相同?
假设许多/大多数(但不是所有)计算机要求帧速率和帧大小具有与“恰好一个样本”相对应的值,是否有任何方法(使用 Java API)让程序发现当前计算机是否崩溃属于该类别,或者它是否能够捕获具有较大且频率较低的帧的音频?如果可以...它认为可以接受的范围或精确值?或者,您/用户是否确实希望在黑暗中盲目地尝试不同的排列,直到其中之一最终返回非空 TargetDataLine?
AudioFormat
。但是可以使用
SourceDataLine
方法为用于发送和接收数据的线路
TargetDataLine
或
.open()
指定缓冲区大小。我还没有使用过不同的
AudioFormat
构造函数,一直只使用这个:
public AudioFormat(AudioFormat.Encoding encoding,
float sampleRate,
int sampleSizeInBits,
int channels,
int frameSize,
float frameRate,
boolean bigEndian)
为了让事情变得简单,我坚持使用标准的“CD 质量”格式:
encoding = AudioFormat.Encoding.PCM_SIGNED
sampleRate = 44100
sampleSizeInBits = 16
channels = 2 // stereo
frameSize = 4 // 2 bytes per sample x 2 channels
frameRate = 44100
bigEndian = false
我猜您有带有 48000 fps 音频数据的工具或外部源。在
AudioFormat 的 API 文档中,还有许多其他构造函数。有一个不需要单个帧的字节大小。 AudioFormat
的 API 描述还包含所有使用的变量和术语的定义。