用Java设置音频采样位深度



这是我的代码。我使用javax.sound.sampled.*作为音频类。

byte[] myAudioByteArray = new byte[]{0, 127,    127, 127, -127, 127};
ByteArrayInputStream bais = new ByteArrayInputStream(myAudioByteArray);
AudioInputStream stream = new AudioInputStream(bais, new AudioFormat(SampleRate.R_44100, 24, 1, true, false), myAudioByteArray.length)

振幅是位深度,那么java如何允许您设置每个样本的位深度?我已经将生成的文件的位深度设置为24位深度,因此理论上我应该能够将样本设置在特定的深度范围(16777216)。问题是,我不知道如何处理输入ByteArrayInputStream对象的字节,然后这些字节进入AudioInputStream对象,因为它们是签名的。我想也许你可以把这些字节转换成它们的二进制表示,然后把其中的3个组合起来,得到16777216范围内的3个字节,但据我所知,这个理论是不正确的。

我想也许你可以将字节转换为它们的二进制表示,然后将其中的3个字节组合起来,得到16777216范围的3个比特,但据我所知,这个理论是不正确的。

不确定,为什么这对你不起作用。

每个样本都必须进行编码,可以是big-endian,也可以是little-endian。以下是音频处理库jipes中的一些方法,展示了如何将字节解码为从小端或大端到int:的样本

private static int byteToIntLittleEndian(final byte[] buf, final int offset, final int bytesPerSample) {
int sample = 0;
for (int byteIndex = 0; byteIndex < bytesPerSample; byteIndex++) {
final int aByte = buf[offset + byteIndex] & 0xff;
sample += aByte << 8 * (byteIndex);
}
return sample;
}
private static int byteToIntBigEndian(final byte[] buf, final int offset, final int bytesPerSample) {
int sample = 0;
for (int byteIndex = 0; byteIndex < bytesPerSample; byteIndex++) {
final int aByte = buf[offset + byteIndex] & 0xff;
sample += aByte << (8 * (bytesPerSample - byteIndex - 1));
}
return sample;
}

一旦值被解码,你仍然需要投射到你的目标区间。如果你对2字节的格式感兴趣,即比特深度为16,你可以简单地这样做:

final int sample = byteToIntLittleEndian(buf, sampleOffset, bytesPerChannel);
final short shortSample = (short)sample;

演员阵容负责处理溢出。

对于3个字节,它稍微复杂一些。您需要首先知道值的范围。注意,因为您对有符号值感兴趣,所以它不是[0,2^24],而是:

/**
* A constant holding the minimum value a <code>signed24bit</code> can
* have, -2<sup>22</sup>.
*/
private static final int MIN_VALUE_24BIT = -2 << 22;
/**
* A constant holding the maximum value a <code>signed24bit</code> can
* have, 2<sup>22</sup>-1.
*/
private static final int MAX_VALUE_24BIT = -MIN_VALUE_24BIT-1;

然后你用它来转换成一个有符号的样本值,如下所示:

final int sample = byteToIntLittleEndian(bud, sampleOffset, bytesPerChannel);
final int threeByteSample = sample > MAX_VALUE_24BIT ? sample + MIN_VALUE_24BIT + MIN_VALUE_24BIT : sample;

最新更新