Java TargetDataLine + AudioFormat 与帧大小 + 帧速率大于 1 个单个样本

问题描述 投票:0回答:1

当调用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?

javasound
1个回答
0
投票
缓冲区大小不是类的一部分

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 描述还包含所有使用的变量和术语的定义。

© www.soinside.com 2019 - 2024. All rights reserved.