float [] 16位到byte []

时间:2014-07-29 11:13:21

标签: java android

我已使用以下方式将byte[]转换为float[]

public voidcheckingActivity(byte[] data, int numbytes) {
    size_data_proc = data.length / 2;
    float[] data_proc = new float[size_data_proc];
    for (int i = 0; i < data.length; i += 2) {
        data_proc[i / 2] = data[i] | (data[i + 1] << 8);
    }
}

因为我正在读取16位音频样本。

现在我需要逆过程:我有一个float[],其中包含16位样本,我想转换为byte[]

所以,我想我必须创建一个大小为byte[]的{​​{1}}但是如何获得float*2 s的值?

感谢

编辑:

为了更加精确,我捕获了200 ms的16位音频块。处理这些块我需要浮点数样本,所以我必须在float的一个元素中组合2个字节的字节数组。 这个过程是下面的代码。

在进程之后我需要以字节为单位重新转换浮点样本,所以我需要float []的每个元素都是byte []

的两个元素

2 个答案:

答案 0 :(得分:2)

Android中的音频数据通常是小端16位带符号PCM。我认为你可能会颠倒字节顺序(但它已经有一段时间了)。此外,如果您不屏蔽最不重要的字节,由于自动符号扩展,您将获得虚假的音频伪像。

对于那些修补程序,您的代码应该看起来像这样:

public void checkingActivity(byte[] data {
    float[] data_proc = new float[size_data_proc];

    for (int i = 0; i < data.length; i += 2) {
        data_proc[i / 2] = (int) (data[i] << 8) | (int) (data[i+1] & 0x00ff);
    }

}

然后反向操作如下:

public byte[] floatArrayToBytes(float[] data {
    byte[] bytes = new byte[data.length * 2];
    float  scale = 1.0f;
    int    ix    = 0;

    for (float sample: data) {
        int value = sample * scale;
        bytes[ix++] = (byte) ((value >> 8) & 0x00ff);
        bytes[ix++] = (byte) (value & 0x00ff);
    }

 return bytes;

}

如果您正在使用浮点值,则可能需要将音频标准化为-1.0f到+ 1.0f的范围。

答案 1 :(得分:0)

您可以使用java.nio.ByteBuffer类:

public static byte[] float2ByteArray(final float[] value) {
    ByteBuffer buffer = ByteBuffer.allocate(4 * value.length);// a float has 4 bytes
    for (float f : value) {
        buffer.putFloat(f);
    }
    return buffer.array();
}