gpt4 book ai didi

Java - 将 16 位有符号 pcm 音频数据数组转换为 double 组

转载 作者:搜寻专家 更新时间:2023-11-01 02:39:26 26 4
gpt4 key购买 nike

我正在从事一个涉及音频处理的项目。

我正在从文件中提取一段音频,然后想对其进行一些处理。问题是我将音频数据作为字节数组获取,而我的处理是在 double 数组上(后来也在 Complex 数组上......)。

我的问题是如何正确地将接收到的字节数组转换为 double 组以继续?

这是我的输入代码:

AudioFormat format = new AudioFormat(8000, 16, 1, true, true);
AudioInputStream in = AudioSystem.getAudioInputStream(WAVfile);
AudioInputStream din = null;
AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
8000,
16,
1,
2,
8000,
true);
din = AudioSystem.getAudioInputStream(decodedFormat, in);
TargetDataLine fileLine = AudioSystem.getTargetDataLine(decodedFormat);
fileLine .open(format);
fileLine .start();

int numBytesRead;
byte[] targetData = new byte[256]; // (samplingRate / 1000) * 32ms

while (true) {
numBytesRead = din.read(targetData, 0, targetData.length);

if (numBytesRead == -1) {
break;
}

double[] convertedData;
// Conversion code goes here...

processAudio(convertedData);
}

到目前为止,我已经研究了关于这个站点和其他站点的不同问题的不同答案。我试过使用 ByteBuffer 和位转换,但它们都没有给我看起来正确的结果(我的另一个成员在 Python 中对同一个文件做了同样的事情所以我有一个引用结果应该是什么大约是……

我错过了什么?如何正确地将字节转换为 double ?如果我只想在 targetData 中捕获文件的 32ms,targerData 的长度应该是多少?那么 convertedData 的长度是多少?

提前致谢。

最佳答案

使用 NIO 缓冲区的转换应该不难。您所要做的就是应用一个因子,将 16 位范围标准化为 [-1.0…1.0] 范围。

嗯,it isn’t so easy , 但对于大多数实际用途而言,决定一个因素就足够了:

AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 
8000, 16, 1, 2, 8000, true);
try(AudioInputStream in = AudioSystem.getAudioInputStream(WAVfile);
AudioInputStream din = AudioSystem.getAudioInputStream(decodedFormat, in);
ReadableByteChannel inCh = Channels.newChannel(din)) {

ByteBuffer inBuf=ByteBuffer.allocate(256);
final double factor=2.0/(1<<16);
while(inCh.read(inBuf) != -1) {
inBuf.flip();
double[] convertedData=new double[inBuf.remaining()/2];
DoubleBuffer outBuf=DoubleBuffer.wrap(convertedData);
while(inBuf.remaining()>=2) {
outBuf.put(inBuf.getShort()*factor);
}
assert !outBuf.hasRemaining();
inBuf.compact();
processAudio(convertedData);
}
}

上面的解决方案有效地使用了 …/(double)0x8000 变体。因为我不知道 processAudio 对提供的缓冲区做了什么,例如无论是否保留对它的引用,循环都会在每次迭代中分配一个新缓冲区,但将其更改为可重用缓冲区应该很容易。使用预分配缓冲区时,您只需要关心读取/转换的 double 的实际数量。

关于Java - 将 16 位有符号 pcm 音频数据数组转换为 double 组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37673482/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com