我实现了以下算法将PCM 16位音频数据转换为8位:
if(encoding == AudioFormat.ENCODING_PCM_8BIT){
int len = data.length;
data1 = new byte[len/2];
int tempint;
for (int k = 0, i=1; i < len; i+=2, k++) {
tempint = ((int)data[i]) ^ 0x00000080;
data1[k] = (byte)tempint;
}
data=null;
}
其中data is byte[]
。运行此代码后,输出contains a lot of noise
并建议我在这里做错了。 What should I do besides dropping the lower byte?
[编辑]:修改了代码:
if(encoding == AudioFormat.ENCODING_PCM_8BIT){
int len = data.length;
data1 = new byte[len/2];
for (int i = 0; i < len/2; i++) {
data1[i] = data[i*2+1];
}
}
the input/output looks like:
Original data(counter:0) = 4
Original data(counter:1) = -1
Original data(counter:2) = 75
Original data(counter:3) = -1
Original data(counter:4) = 16
Original data(counter:5) = -1
Original data(counter:6) = 44
Original data(counter:7) = -1
Original data(counter:8) = 7
Original data(counter:9) = -1
Original data(counter:10) = 22
Original data(counter:11) = -1
Original data(counter:12) = 22
Original data(counter:13) = -1
Original data(counter:14) = 12
Original data(counter:15) = -1
Output data:(counter:0) = -1
Output data:(counter:1) = -1
Output data:(counter:2) = -1
Output data:(counter:3) = -1
Output data:(counter:4) = -1
Output data:(counter:5) = -1
Output data:(counter:6) = -1
Output data:(counter:7) = -1
Output data:(counter:8) = -1
Output data:(counter:9) = -1
Output data:(counter:10) = -1
Output data:(counter:11) = -1
Output data:(counter:12) = -1
Output data:(counter:13) = -1
Output data:(counter:14) = -1
Output data:(counter:15) = -1
如果我丢弃第一个或第二个字节无关紧要,噪音仍然存在。这里我删掉了第一个字节(而不是第二个字节)
答案 0 :(得分:5)
以下算法大大减少了噪音量,但无法完全消除它:
if(encoding == AudioFormat.ENCODING_PCM_8BIT){
ShortBuffer intBuf = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
short[] samples16Bit = new short[intBuf.remaining()];
intBuf.get(samples16Bit);
data1 = new byte[samples16Bit.length];
for (int i = 0; i < samples16Bit.length; i++) {
data1[i] = (byte)((samples16Bit[i] / 256)+128);
}
}
答案 1 :(得分:3)
您遇到的噪音只是由您将音频转换为的音域引起的。 16Bit信号的本底噪声为-96dB,而8Bit信号的本底噪声为-48dB。就这些数字而言,这似乎并不多,但这是一个巨大的差异。下采样算法几乎总是采用某种抖动来减少与转换相关的噪声量。您可以通过编程方式在8Bit中创建正弦波或使用任何体面的音频程序并只是聆听结果,从而非常轻松地演示质量(和噪声级别)的差异。你会发现8Bit并不是真正的品质。用16Bit正弦波重复实验进行比较。这不是你,这是比特范围。
答案 2 :(得分:0)
为什么不呢?
int len = data.length;
data1 = new byte[len/2];
for (int i=0; i < len/2; ++i)
data1[i] = data[i*2];
我假设您的数据是bigendian。如果是LE,这应该有效:
int len = data.length;
data1 = new byte[len/2];
for (int i=0; i < len/2; ++i)
data1[i] = data[i*2+1];
答案 3 :(得分:-2)
由于多种原因,你有很多噪音。 您首先只填充数组的每个其他值,您未填充的值将自动为零,这会极大地扭曲波形。其次您只是选取原始数据的前8位,这表示如果数据点的前8位恰好全为零,则丢失特定数据点的所有信息,信息可能位于较高位。
一个天真的建议是缩放所有数据点(如果签名则除以2 ^ 7),使得最高数据点最多为8位,您仍然会丢失信息并引入失真,因为您被迫保存数据在整数和整数除法中将强制在相同(接近)范围内的值在除法后相等,但这应该更少嘈杂:)
感谢下面的评论,如果您只从原始数据中获取所有其他数据点,则会引入称为Aliasing的失真。