📄 floatsamplebuffer.java
字号:
"FloatSampleBuffer: invalid channel number."); } return (float[]) channels.get(channel); } public Object[] getAllChannels() { Object[] res=new Object[getChannelCount()]; for (int ch=0; ch<getChannelCount(); ch++) { res[ch]=getChannel(ch); } return res; } /** * Set the number of bits for dithering. * Typically, a value between 0.2 and 0.9 gives best results. * <p>Note: this value is only used, when dithering is actually performed. */ public void setDitherBits(float ditherBits) { if (ditherBits<=0) { throw new IllegalArgumentException("DitherBits must be greater than 0"); } this.ditherBits=ditherBits; } public float getDitherBits() { return ditherBits; } /** * Sets the mode for dithering. * This can be one of: * <ul><li>DITHER_MODE_AUTOMATIC: it is decided automatically, * whether dithering is necessary - in general when sample size is * decreased. * <li>DITHER_MODE_ON: dithering will be forced * <li>DITHER_MODE_OFF: dithering will not be done. * </ul> */ public void setDitherMode(int mode) { if (mode!=DITHER_MODE_AUTOMATIC && mode!=DITHER_MODE_ON && mode!=DITHER_MODE_OFF) { throw new IllegalArgumentException("Illegal DitherMode"); } this.ditherMode=mode; } public int getDitherMode() { return ditherMode; } /////////////////////////////// "low level" conversion functions //////////////////////////////// public int getFormatType(int ssib, boolean signed, boolean bigEndian) { int bytesPerSample=ssib/8; int res=0; if (ssib==8) { res=F_8; } else if (ssib==16) { res=F_16; } else if (ssib==24) { res=F_24; } else if (ssib==32) { res=F_32; } if (res==0) { throw new IllegalArgumentException ("FloatSampleBuffer: unsupported sample size of " +ssib+" bits per sample."); } if (!signed && bytesPerSample>1) { throw new IllegalArgumentException ("FloatSampleBuffer: unsigned samples larger than " +"8 bit are not supported"); } if (signed) { res|=F_SIGNED; } if (bigEndian && (ssib!=8)) { res|=F_BIGENDIAN; } return res; } private static final float twoPower7=128.0f; private static final float twoPower15=32768.0f; private static final float twoPower23=8388608.0f; private static final float twoPower31=2147483648.0f; private static final float invTwoPower7=1/twoPower7; private static final float invTwoPower15=1/twoPower15; private static final float invTwoPower23=1/twoPower23; private static final float invTwoPower31=1/twoPower31; /*public*/ private static void convertByteToFloat(byte[] input, int inputOffset, int bytesPerFrame, int formatType, float[] output, int outputOffset, int sampleCount) { //if (TDebug.TraceAudioConverter) { // TDebug.out("FloatSampleBuffer.convertByteToFloat, formatType=" // +formatType2Str(formatType)); //} int sample; int endCount = outputOffset + sampleCount; for (sample = outputOffset; sample < endCount; sample++) { // do conversion switch (formatType) { case CT_8S: output[sample]= ((float) input[inputOffset])*invTwoPower7; break; case CT_8U: output[sample]= ((float) ((input[inputOffset] & 0xFF)-128))*invTwoPower7; break; case CT_16SB: output[sample]= ((float) ((input[inputOffset]<<8) | (input[inputOffset+1] & 0xFF)))*invTwoPower15; break; case CT_16SL: output[sample]= ((float) ((input[inputOffset+1]<<8) | (input[inputOffset] & 0xFF)))*invTwoPower15; break; case CT_24SB: output[sample]= ((float) ((input[inputOffset]<<16) | ((input[inputOffset+1] & 0xFF)<<8) | (input[inputOffset+2] & 0xFF)))*invTwoPower23; break; case CT_24SL: output[sample]= ((float) ((input[inputOffset+2]<<16) | ((input[inputOffset+1] & 0xFF)<<8) | (input[inputOffset] & 0xFF)))*invTwoPower23; break; case CT_32SB: output[sample]= ((float) ((input[inputOffset]<<24) | ((input[inputOffset+1] & 0xFF)<<16) | ((input[inputOffset+2] & 0xFF)<<8) | (input[inputOffset+3] & 0xFF)))*invTwoPower31; break; case CT_32SL: output[sample]= ((float) ((input[inputOffset+3]<<24) | ((input[inputOffset+2] & 0xFF)<<16) | ((input[inputOffset+1] & 0xFF)<<8) | (input[inputOffset] & 0xFF)))*invTwoPower31; break; default: throw new IllegalArgumentException ("Unsupported formatType="+formatType); } inputOffset += bytesPerFrame; } } protected byte quantize8(float sample) { if (doDither) { sample+=random.nextFloat()*ditherBits; } if (sample>=127.0f) { return (byte) 127; } else if (sample<=-128) { return (byte) -128; } else { return (byte) (sample<0?(sample-0.5f):(sample+0.5f)); } } protected int quantize16(float sample) { if (doDither) { sample+=random.nextFloat()*ditherBits; } if (sample>=32767.0f) { return 32767; } else if (sample<=-32768.0f) { return -32768; } else { return (int) (sample<0?(sample-0.5f):(sample+0.5f)); } } protected int quantize24(float sample) { if (doDither) { sample+=random.nextFloat()*ditherBits; } if (sample>=8388607.0f) { return 8388607; } else if (sample<=-8388608.0f) { return -8388608; } else { return (int) (sample<0?(sample-0.5f):(sample+0.5f)); } } protected int quantize32(float sample) { if (doDither) { sample+=random.nextFloat()*ditherBits; } if (sample>=2147483647.0f) { return 2147483647; } else if (sample<=-2147483648.0f) { return -2147483648; } else { return (int) (sample<0?(sample-0.5f):(sample+0.5f)); } } // should be static and public, but dithering needs class members private void convertFloatToByte(float[] input, int sampleCount, byte[] output, int offset, int bytesPerFrame, int formatType) { //if (TDebug.TraceAudioConverter) { // TDebug.out("FloatSampleBuffer.convertFloatToByte, formatType=" // +"formatType2Str(formatType)); //} // let's see whether dithering is necessary switch (ditherMode) { case DITHER_MODE_AUTOMATIC: doDither=(originalFormatType & F_SAMPLE_WIDTH_MASK)> (formatType & F_SAMPLE_WIDTH_MASK); break; case DITHER_MODE_ON: doDither=true; break; case DITHER_MODE_OFF: doDither=false; break; } if (doDither && random==null) { // create the random number generator for dithering random=new Random(); } int inIndex; int iSample; for (inIndex=0; inIndex<sampleCount; inIndex++) { // do conversion switch (formatType) { case CT_8S: output[offset]=quantize8(input[inIndex]*twoPower7); break; case CT_8U: output[offset]=(byte) (quantize8(input[inIndex]*twoPower7)+128); break; case CT_16SB: iSample=quantize16(input[inIndex]*twoPower15); output[offset]=(byte) (iSample >> 8); output[offset+1]=(byte) (iSample & 0xFF); break; case CT_16SL: iSample=quantize16(input[inIndex]*twoPower15); output[offset+1]=(byte) (iSample >> 8); output[offset]=(byte) (iSample & 0xFF); break; case CT_24SB: iSample=quantize24(input[inIndex]*twoPower23); output[offset]=(byte) (iSample >> 16); output[offset+1]=(byte) ((iSample >>> 8) & 0xFF); output[offset+2]=(byte) (iSample & 0xFF); break; case CT_24SL: iSample=quantize24(input[inIndex]*twoPower23); output[offset+2]=(byte) (iSample >> 16); output[offset+1]=(byte) ((iSample >>> 8) & 0xFF); output[offset]=(byte) (iSample & 0xFF); break; case CT_32SB: iSample=quantize32(input[inIndex]*twoPower31); output[offset]=(byte) (iSample >> 24); output[offset+1]=(byte) ((iSample >>> 16) & 0xFF); output[offset+2]=(byte) ((iSample >>> 8) & 0xFF); output[offset+3]=(byte) (iSample & 0xFF); break; case CT_32SL: iSample=quantize32(input[inIndex]*twoPower31); output[offset+3]=(byte) (iSample >> 24); output[offset+2]=(byte) ((iSample >>> 16) & 0xFF); output[offset+1]=(byte) ((iSample >>> 8) & 0xFF); output[offset]=(byte) (iSample & 0xFF); break; default: throw new IllegalArgumentException ("Unsupported formatType="+formatType); } offset+=bytesPerFrame; } } /** * Debugging function */ private static String formatType2Str(int formatType) { String res=""+formatType+": "; switch (formatType & F_SAMPLE_WIDTH_MASK) { case F_8: res+="8bit"; break; case F_16: res+="16bit"; break; case F_24: res+="24bit"; break; case F_32: res+="32bit"; break; } res+=((formatType & F_SIGNED)==F_SIGNED)?" signed":" unsigned"; if ((formatType & F_SAMPLE_WIDTH_MASK)!=F_8) { res+=((formatType & F_BIGENDIAN)==F_BIGENDIAN)? " big endian":" little endian"; } return res; }}/*** FloatSampleBuffer.java ***/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -