Java - 使用LITTLE_ENDIAN从短到字节[2]

时间:2012-05-11 10:54:19

标签: java audio bytearray audio-recording

我在尝试将短值转换为字节时遇到了一些问题[2]。我正在使用它来对某些音频数据缓冲区进行一些转换(将增益应用于缓冲区)。首先,我加载音频缓冲区,如下所示:

mRecorder.read(buffer, 0, buffer.length);

缓冲区是

private byte[] buffer;

然后,我得到样本(记录的样本大小为16位),如下所示:

short sample = getShort(buffer[i*2], buffer[i*2+1]);

getShort定义如下:

/* 
 * 
 * Converts a byte[2] to a short, in LITTLE_ENDIAN format
 * 
 */
private short getShort(byte argB1, byte argB2)
{
    return (short)(argB1 | (argB2 << 8));
}

然后我将增益应用于样本:

sample *= rGain;

在此之后,我尝试从乘法样本中取回字节数组:

byte[] a = getByteFromShort(sample);

但这失败了,因为即使增益为1,声音也会产生很多噪音。

以下是getByteFromShort方法定义:

    private byte[] getByteFromShort(short x){
//variant 1 - noise
    byte[] a = new byte[2];
    a[0] = (byte)(x & 0xff);
    a[1] = (byte)((x >> 8) & 0xff);

//variant 2 - noise and almost broke my ears - very loud
//      ByteBuffer buffer = ByteBuffer.allocate(2);
//      buffer.putShort(x);
//      buffer.flip();

    return a;
}

所以问题是将short值转换为byte [2]。当增益为1.0时,声音充满噪音。

以下是完全增益申请方法:

for (int i=0; i<buffer.length/2; i++)
{ // 16bit sample size                      
    short curSample = getShort(buffer[i*2], buffer[i*2+1]);
if(rGain != 1){
    //apply gain
    curSample *= rGain;
    //convert back from short sample that was "gained" to byte data
    byte[] a = getByteFromShort(curSample);
    //modify buffer to contain the gained sample
    buffer[i*2] = a[0];
    buffer[i*2 + 1] = a[1];
}

   }

你们可以看看getByteFromShort方法并告诉我哪里错了吗?

感谢。

4 个答案:

答案 0 :(得分:4)

getByteFromShort()似乎没问题。

getShort(byte argB1, byte argB2)错了。当argB1为负时,它会产生不正确的结果。

应该是

return (short)((argB1 & 0xff) | (argB2 << 8));

答案 1 :(得分:0)

使用以下代码:

ret[0] = (byte)(x & 0xff);
ret[1] = (byte)((x >> 8) & 0xff);

答案 2 :(得分:0)

我会使用ByteBuffer

ByteBuffer buffer = ByteBuffer.allocate(8*1024);
mRecorder.read(buffer.array(), 0, buffer.capacity());
// using NIO
mRecorder.read(buffer);

while(buffer.remaining() > 1) {
    short s = bb.getShort(x);
    // do something with s
}

答案 3 :(得分:0)

ByteBuffer及其在java.nio中的同类群可以帮助解决这个问题。基本上,您将使用数据ByteBuffer.wrap(array)创建一个由数组支持的ByteBuffer。然后,您可以使用ByteBuffer.order()设置缓冲区的字节顺序,并使用get / put Int / Short / byte ...等函数来操作底层数组中的数据。