我已使用以下方式将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 []
的两个元素答案 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();
}