如果您使用的是Android的AudioRecord以及录制和回放AudioTrack类,请记住,一个16位单声道音频采样是默认小尾数。如果您正在使用DataInputStream类的readDouble()方法读取字节,它将无差别地读取Big endian中的64位,所以字节按错误的顺序读取。但请记住,即使readDouble将读取小字节的字节,或者如果您的音频是Big endian,它也会读取64位,并将它们视为一个大的double值,实际上,每个样本表示带符号的short从-32768到+32767(假设它已经签名)。如果将其转换为数字信号处理的双精度值,则最好将其归一化为-1.0至+1.0范围,除以32767.0f(否则,请不要将其转换为第一名)。当你在double上完成你的DSP时,将它乘以32767并将其转换回小端。这里有一个快速和肮脏的方式去做:

try{

for(int offset=0; offset < buff_size; offset+= 2) //increment index by two because 16bit mono sample is 2 bytes long

{

//reads 2 bytes from stream and stores them in buff at offset. returns number of bytes read.

if (dis.read(buff,offset, 2) > 0){

//where buff is an array of bytes

// Low Byte High Byte Left Shift

double sample= ((buff[offset + 0]) | (buff[offset + 1] << 8));

/*Explanation: First We take the High Byte and shift it 8 Bytes to the left. In Java, this promotes it to an integer(32 bits).

* Next we merge the int representing High Byte and the Low Byte byte with a bitwise OR operator

* 00000000 0000000 10101111 00000000

* OR 10110000 =

* 00000000 0000000 10101111 10110000 Now our bytes are in the Big Endian order required for primitive types */

//since 2 bytes is a short which has range -32768 to +32767, we divide by 32768 to normalize to -1.0 to +1.0 range for DSP

sample = sample /32768.0;

sample = sample * .5;

//convert it back to small endian

int nsample = (int) Math.round(sample * 32767.0);//expands it to the range of -32768 to 32767 range of short, round, & truncate

buff[offset + 1] = (byte) ((nsample >> 8) & 0xFF); //isolate and extract the high byte

buff[offset + 0] = (byte) (nsample & 0xFF); //isolate the low byte with MASK

}

}

track.write(buff, 0, buff_size);

}catch(Exception e){

//

}

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐