Path: blob/master/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatConverter.java
41161 views
/*1* Copyright (c) 2007, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.media.sound;2627import java.nio.ByteBuffer;28import java.nio.ByteOrder;29import java.nio.DoubleBuffer;30import java.nio.FloatBuffer;3132import javax.sound.sampled.AudioFormat;33import javax.sound.sampled.AudioFormat.Encoding;3435/**36* This class is used to convert between 8,16,24,32,32+ bit signed/unsigned37* big/litle endian fixed/floating point byte buffers and float buffers.38*39* @author Karl Helgason40*/41public abstract class AudioFloatConverter {4243/***************************************************************************44*45* LSB Filter, used filter least significant byte in samples arrays.46*47* Is used filter out data in lsb byte when SampleSizeInBits is not48* dividable by 8.49*50**************************************************************************/5152private static class AudioFloatLSBFilter extends AudioFloatConverter {5354private final AudioFloatConverter converter;5556private final int offset;5758private final int stepsize;5960private final byte mask;6162private byte[] mask_buffer;6364AudioFloatLSBFilter(AudioFloatConverter converter, AudioFormat format) {65int bits = format.getSampleSizeInBits();66boolean bigEndian = format.isBigEndian();67this.converter = converter;68stepsize = (bits + 7) / 8;69offset = bigEndian ? (stepsize - 1) : 0;70int lsb_bits = bits % 8;71if (lsb_bits == 0)72mask = (byte) 0x00;73else if (lsb_bits == 1)74mask = (byte) 0x80;75else if (lsb_bits == 2)76mask = (byte) 0xC0;77else if (lsb_bits == 3)78mask = (byte) 0xE0;79else if (lsb_bits == 4)80mask = (byte) 0xF0;81else if (lsb_bits == 5)82mask = (byte) 0xF8;83else if (lsb_bits == 6)84mask = (byte) 0xFC;85else if (lsb_bits == 7)86mask = (byte) 0xFE;87else88mask = (byte) 0xFF;89}9091@Override92public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,93byte[] out_buff, int out_offset) {94byte[] ret = converter.toByteArray(in_buff, in_offset, in_len,95out_buff, out_offset);9697int out_offset_end = in_len * stepsize;98for (int i = out_offset + offset; i < out_offset_end; i += stepsize) {99out_buff[i] = (byte) (out_buff[i] & mask);100}101102return ret;103}104105@Override106public float[] toFloatArray(byte[] in_buff, int in_offset,107float[] out_buff, int out_offset, int out_len) {108if (mask_buffer == null || mask_buffer.length < in_buff.length)109mask_buffer = new byte[in_buff.length];110System.arraycopy(in_buff, 0, mask_buffer, 0, in_buff.length);111int in_offset_end = out_len * stepsize;112for (int i = in_offset + offset; i < in_offset_end; i += stepsize) {113mask_buffer[i] = (byte) (mask_buffer[i] & mask);114}115float[] ret = converter.toFloatArray(mask_buffer, in_offset,116out_buff, out_offset, out_len);117return ret;118}119120}121122/***************************************************************************123*124* 64 bit float, little/big-endian125*126**************************************************************************/127128// PCM 64 bit float, little-endian129private static class AudioFloatConversion64L extends AudioFloatConverter {130ByteBuffer bytebuffer = null;131132DoubleBuffer floatbuffer = null;133134double[] double_buff = null;135136@Override137public float[] toFloatArray(byte[] in_buff, int in_offset,138float[] out_buff, int out_offset, int out_len) {139int in_len = out_len * 8;140if (bytebuffer == null || bytebuffer.capacity() < in_len) {141bytebuffer = ByteBuffer.allocate(in_len).order(142ByteOrder.LITTLE_ENDIAN);143floatbuffer = bytebuffer.asDoubleBuffer();144}145bytebuffer.position(0);146floatbuffer.position(0);147bytebuffer.put(in_buff, in_offset, in_len);148if (double_buff == null149|| double_buff.length < out_len + out_offset)150double_buff = new double[out_len + out_offset];151floatbuffer.get(double_buff, out_offset, out_len);152int out_offset_end = out_offset + out_len;153for (int i = out_offset; i < out_offset_end; i++) {154out_buff[i] = (float) double_buff[i];155}156return out_buff;157}158159@Override160public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,161byte[] out_buff, int out_offset) {162int out_len = in_len * 8;163if (bytebuffer == null || bytebuffer.capacity() < out_len) {164bytebuffer = ByteBuffer.allocate(out_len).order(165ByteOrder.LITTLE_ENDIAN);166floatbuffer = bytebuffer.asDoubleBuffer();167}168floatbuffer.position(0);169bytebuffer.position(0);170if (double_buff == null || double_buff.length < in_offset + in_len)171double_buff = new double[in_offset + in_len];172int in_offset_end = in_offset + in_len;173for (int i = in_offset; i < in_offset_end; i++) {174double_buff[i] = in_buff[i];175}176floatbuffer.put(double_buff, in_offset, in_len);177bytebuffer.get(out_buff, out_offset, out_len);178return out_buff;179}180}181182// PCM 64 bit float, big-endian183private static class AudioFloatConversion64B extends AudioFloatConverter {184ByteBuffer bytebuffer = null;185186DoubleBuffer floatbuffer = null;187188double[] double_buff = null;189190@Override191public float[] toFloatArray(byte[] in_buff, int in_offset,192float[] out_buff, int out_offset, int out_len) {193int in_len = out_len * 8;194if (bytebuffer == null || bytebuffer.capacity() < in_len) {195bytebuffer = ByteBuffer.allocate(in_len).order(196ByteOrder.BIG_ENDIAN);197floatbuffer = bytebuffer.asDoubleBuffer();198}199bytebuffer.position(0);200floatbuffer.position(0);201bytebuffer.put(in_buff, in_offset, in_len);202if (double_buff == null203|| double_buff.length < out_len + out_offset)204double_buff = new double[out_len + out_offset];205floatbuffer.get(double_buff, out_offset, out_len);206int out_offset_end = out_offset + out_len;207for (int i = out_offset; i < out_offset_end; i++) {208out_buff[i] = (float) double_buff[i];209}210return out_buff;211}212213@Override214public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,215byte[] out_buff, int out_offset) {216int out_len = in_len * 8;217if (bytebuffer == null || bytebuffer.capacity() < out_len) {218bytebuffer = ByteBuffer.allocate(out_len).order(219ByteOrder.BIG_ENDIAN);220floatbuffer = bytebuffer.asDoubleBuffer();221}222floatbuffer.position(0);223bytebuffer.position(0);224if (double_buff == null || double_buff.length < in_offset + in_len)225double_buff = new double[in_offset + in_len];226int in_offset_end = in_offset + in_len;227for (int i = in_offset; i < in_offset_end; i++) {228double_buff[i] = in_buff[i];229}230floatbuffer.put(double_buff, in_offset, in_len);231bytebuffer.get(out_buff, out_offset, out_len);232return out_buff;233}234}235236/***************************************************************************237*238* 32 bit float, little/big-endian239*240**************************************************************************/241242// PCM 32 bit float, little-endian243private static class AudioFloatConversion32L extends AudioFloatConverter {244ByteBuffer bytebuffer = null;245246FloatBuffer floatbuffer = null;247248@Override249public float[] toFloatArray(byte[] in_buff, int in_offset,250float[] out_buff, int out_offset, int out_len) {251int in_len = out_len * 4;252if (bytebuffer == null || bytebuffer.capacity() < in_len) {253bytebuffer = ByteBuffer.allocate(in_len).order(254ByteOrder.LITTLE_ENDIAN);255floatbuffer = bytebuffer.asFloatBuffer();256}257bytebuffer.position(0);258floatbuffer.position(0);259bytebuffer.put(in_buff, in_offset, in_len);260floatbuffer.get(out_buff, out_offset, out_len);261return out_buff;262}263264@Override265public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,266byte[] out_buff, int out_offset) {267int out_len = in_len * 4;268if (bytebuffer == null || bytebuffer.capacity() < out_len) {269bytebuffer = ByteBuffer.allocate(out_len).order(270ByteOrder.LITTLE_ENDIAN);271floatbuffer = bytebuffer.asFloatBuffer();272}273floatbuffer.position(0);274bytebuffer.position(0);275floatbuffer.put(in_buff, in_offset, in_len);276bytebuffer.get(out_buff, out_offset, out_len);277return out_buff;278}279}280281// PCM 32 bit float, big-endian282private static class AudioFloatConversion32B extends AudioFloatConverter {283ByteBuffer bytebuffer = null;284285FloatBuffer floatbuffer = null;286287@Override288public float[] toFloatArray(byte[] in_buff, int in_offset,289float[] out_buff, int out_offset, int out_len) {290int in_len = out_len * 4;291if (bytebuffer == null || bytebuffer.capacity() < in_len) {292bytebuffer = ByteBuffer.allocate(in_len).order(293ByteOrder.BIG_ENDIAN);294floatbuffer = bytebuffer.asFloatBuffer();295}296bytebuffer.position(0);297floatbuffer.position(0);298bytebuffer.put(in_buff, in_offset, in_len);299floatbuffer.get(out_buff, out_offset, out_len);300return out_buff;301}302303@Override304public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,305byte[] out_buff, int out_offset) {306int out_len = in_len * 4;307if (bytebuffer == null || bytebuffer.capacity() < out_len) {308bytebuffer = ByteBuffer.allocate(out_len).order(309ByteOrder.BIG_ENDIAN);310floatbuffer = bytebuffer.asFloatBuffer();311}312floatbuffer.position(0);313bytebuffer.position(0);314floatbuffer.put(in_buff, in_offset, in_len);315bytebuffer.get(out_buff, out_offset, out_len);316return out_buff;317}318}319320/***************************************************************************321*322* 8 bit signed/unsigned323*324**************************************************************************/325326// PCM 8 bit, signed327private static class AudioFloatConversion8S extends AudioFloatConverter {328@Override329public float[] toFloatArray(byte[] in_buff, int in_offset,330float[] out_buff, int out_offset, int out_len) {331int ix = in_offset;332int ox = out_offset;333for (int i = 0; i < out_len; i++) {334byte x = in_buff[ix++];335out_buff[ox++] = x > 0 ? x / 127.0f : x / 128.0f;336}337return out_buff;338}339340@Override341public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,342byte[] out_buff, int out_offset) {343int ix = in_offset;344int ox = out_offset;345for (int i = 0; i < in_len; i++) {346final float x = in_buff[ix++];347out_buff[ox++] = (byte) (x > 0 ? x * 127 : x * 128);348}349return out_buff;350}351}352353// PCM 8 bit, unsigned354private static class AudioFloatConversion8U extends AudioFloatConverter {355@Override356public float[] toFloatArray(byte[] in_buff, int in_offset,357float[] out_buff, int out_offset, int out_len) {358int ix = in_offset;359int ox = out_offset;360for (int i = 0; i < out_len; i++) {361byte x = (byte) (in_buff[ix++] - 128);362out_buff[ox++] = x > 0 ? x / 127.0f : x / 128.0f;363}364return out_buff;365}366367@Override368public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,369byte[] out_buff, int out_offset) {370int ix = in_offset;371int ox = out_offset;372for (int i = 0; i < in_len; i++) {373float x = in_buff[ix++];374out_buff[ox++] = (byte) (128 + (x > 0 ? x * 127 : x * 128));375}376return out_buff;377}378}379380/***************************************************************************381*382* 16 bit signed/unsigned, little/big-endian383*384**************************************************************************/385386// PCM 16 bit, signed, little-endian387private static class AudioFloatConversion16SL extends AudioFloatConverter {388@Override389public float[] toFloatArray(byte[] in_buff, int in_offset,390float[] out_buff, int out_offset, int out_len) {391int ix = in_offset;392int len = out_offset + out_len;393for (int ox = out_offset; ox < len; ox++) {394short x = (short) (in_buff[ix++] & 0xFF | (in_buff[ix++] << 8));395out_buff[ox] = x > 0 ? x / 32767.0f : x / 32768.0f;396}397return out_buff;398}399400@Override401public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,402byte[] out_buff, int out_offset) {403int ox = out_offset;404int len = in_offset + in_len;405for (int ix = in_offset; ix < len; ix++) {406float f = in_buff[ix];407short x = (short) (f > 0 ? f * 32767 : f * 32768);408out_buff[ox++] = (byte) x;409out_buff[ox++] = (byte) (x >>> 8);410}411return out_buff;412}413}414415// PCM 16 bit, signed, big-endian416private static class AudioFloatConversion16SB extends AudioFloatConverter {417@Override418public float[] toFloatArray(byte[] in_buff, int in_offset,419float[] out_buff, int out_offset, int out_len) {420int ix = in_offset;421int ox = out_offset;422for (int i = 0; i < out_len; i++) {423short x = (short) ((in_buff[ix++] << 8) | (in_buff[ix++] & 0xFF));424out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f;425}426return out_buff;427}428429@Override430public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,431byte[] out_buff, int out_offset) {432int ix = in_offset;433int ox = out_offset;434for (int i = 0; i < in_len; i++) {435float f = in_buff[ix++];436short x = (short) (f > 0 ? f * 32767.0f : f * 32768.0f);437out_buff[ox++] = (byte) (x >>> 8);438out_buff[ox++] = (byte) x;439}440return out_buff;441}442}443444// PCM 16 bit, unsigned, little-endian445private static class AudioFloatConversion16UL extends AudioFloatConverter {446@Override447public float[] toFloatArray(byte[] in_buff, int in_offset,448float[] out_buff, int out_offset, int out_len) {449int ix = in_offset;450int ox = out_offset;451for (int i = 0; i < out_len; i++) {452int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8);453x -= 32768;454out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f;455}456return out_buff;457}458459@Override460public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,461byte[] out_buff, int out_offset) {462int ix = in_offset;463int ox = out_offset;464for (int i = 0; i < in_len; i++) {465float f = in_buff[ix++];466int x = 32768 + (int) (f > 0 ? f * 32767 : f * 32768);467out_buff[ox++] = (byte) x;468out_buff[ox++] = (byte) (x >>> 8);469}470return out_buff;471}472}473474// PCM 16 bit, unsigned, big-endian475private static class AudioFloatConversion16UB extends AudioFloatConverter {476@Override477public float[] toFloatArray(byte[] in_buff, int in_offset,478float[] out_buff, int out_offset, int out_len) {479int ix = in_offset;480int ox = out_offset;481for (int i = 0; i < out_len; i++) {482int x = ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);483x -= 32768;484out_buff[ox++] = x > 0 ? x / 32767.0f : x / 32768.0f;485}486return out_buff;487}488489@Override490public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,491byte[] out_buff, int out_offset) {492int ix = in_offset;493int ox = out_offset;494for (int i = 0; i < in_len; i++) {495float f = in_buff[ix++];496int x = 32768 + (int) (f > 0 ? f * 32767 : f * 32768);497out_buff[ox++] = (byte) (x >>> 8);498out_buff[ox++] = (byte) x;499}500return out_buff;501}502}503504/***************************************************************************505*506* 24 bit signed/unsigned, little/big-endian507*508**************************************************************************/509510// PCM 24 bit, signed, little-endian511private static class AudioFloatConversion24SL extends AudioFloatConverter {512@Override513public float[] toFloatArray(byte[] in_buff, int in_offset,514float[] out_buff, int out_offset, int out_len) {515int ix = in_offset;516int ox = out_offset;517for (int i = 0; i < out_len; i++) {518int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)519| ((in_buff[ix++] & 0xFF) << 16);520if (x > 0x7FFFFF)521x -= 0x1000000;522out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;523}524return out_buff;525}526527@Override528public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,529byte[] out_buff, int out_offset) {530int ix = in_offset;531int ox = out_offset;532for (int i = 0; i < in_len; i++) {533float f = in_buff[ix++];534int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);535if (x < 0)536x += 0x1000000;537out_buff[ox++] = (byte) x;538out_buff[ox++] = (byte) (x >>> 8);539out_buff[ox++] = (byte) (x >>> 16);540}541return out_buff;542}543}544545// PCM 24 bit, signed, big-endian546private static class AudioFloatConversion24SB extends AudioFloatConverter {547@Override548public float[] toFloatArray(byte[] in_buff, int in_offset,549float[] out_buff, int out_offset, int out_len) {550int ix = in_offset;551int ox = out_offset;552for (int i = 0; i < out_len; i++) {553int x = ((in_buff[ix++] & 0xFF) << 16)554| ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);555if (x > 0x7FFFFF)556x -= 0x1000000;557out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;558}559return out_buff;560}561562@Override563public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,564byte[] out_buff, int out_offset) {565int ix = in_offset;566int ox = out_offset;567for (int i = 0; i < in_len; i++) {568float f = in_buff[ix++];569int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);570if (x < 0)571x += 0x1000000;572out_buff[ox++] = (byte) (x >>> 16);573out_buff[ox++] = (byte) (x >>> 8);574out_buff[ox++] = (byte) x;575}576return out_buff;577}578}579580// PCM 24 bit, unsigned, little-endian581private static class AudioFloatConversion24UL extends AudioFloatConverter {582@Override583public float[] toFloatArray(byte[] in_buff, int in_offset,584float[] out_buff, int out_offset, int out_len) {585int ix = in_offset;586int ox = out_offset;587for (int i = 0; i < out_len; i++) {588int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)589| ((in_buff[ix++] & 0xFF) << 16);590x -= 0x800000;591out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;592}593return out_buff;594}595596@Override597public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,598byte[] out_buff, int out_offset) {599int ix = in_offset;600int ox = out_offset;601for (int i = 0; i < in_len; i++) {602float f = in_buff[ix++];603int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);604x += 0x800000;605out_buff[ox++] = (byte) x;606out_buff[ox++] = (byte) (x >>> 8);607out_buff[ox++] = (byte) (x >>> 16);608}609return out_buff;610}611}612613// PCM 24 bit, unsigned, big-endian614private static class AudioFloatConversion24UB extends AudioFloatConverter {615@Override616public float[] toFloatArray(byte[] in_buff, int in_offset,617float[] out_buff, int out_offset, int out_len) {618int ix = in_offset;619int ox = out_offset;620for (int i = 0; i < out_len; i++) {621int x = ((in_buff[ix++] & 0xFF) << 16)622| ((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);623x -= 0x800000;624out_buff[ox++] = x > 0 ? x / 8388607.0f : x / 8388608.0f;625}626return out_buff;627}628629@Override630public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,631byte[] out_buff, int out_offset) {632int ix = in_offset;633int ox = out_offset;634for (int i = 0; i < in_len; i++) {635float f = in_buff[ix++];636int x = (int) (f > 0 ? f * 8388607.0f : f * 8388608.0f);637x += 8388608;638out_buff[ox++] = (byte) (x >>> 16);639out_buff[ox++] = (byte) (x >>> 8);640out_buff[ox++] = (byte) x;641}642return out_buff;643}644}645646/***************************************************************************647*648* 32 bit signed/unsigned, little/big-endian649*650**************************************************************************/651652// PCM 32 bit, signed, little-endian653private static class AudioFloatConversion32SL extends AudioFloatConverter {654@Override655public float[] toFloatArray(byte[] in_buff, int in_offset,656float[] out_buff, int out_offset, int out_len) {657int ix = in_offset;658int ox = out_offset;659for (int i = 0; i < out_len; i++) {660int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |661((in_buff[ix++] & 0xFF) << 16) |662((in_buff[ix++] & 0xFF) << 24);663out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);664}665return out_buff;666}667668@Override669public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,670byte[] out_buff, int out_offset) {671int ix = in_offset;672int ox = out_offset;673for (int i = 0; i < in_len; i++) {674int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);675out_buff[ox++] = (byte) x;676out_buff[ox++] = (byte) (x >>> 8);677out_buff[ox++] = (byte) (x >>> 16);678out_buff[ox++] = (byte) (x >>> 24);679}680return out_buff;681}682}683684// PCM 32 bit, signed, big-endian685private static class AudioFloatConversion32SB extends AudioFloatConverter {686@Override687public float[] toFloatArray(byte[] in_buff, int in_offset,688float[] out_buff, int out_offset, int out_len) {689int ix = in_offset;690int ox = out_offset;691for (int i = 0; i < out_len; i++) {692int x = ((in_buff[ix++] & 0xFF) << 24) |693((in_buff[ix++] & 0xFF) << 16) |694((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);695out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);696}697return out_buff;698}699700@Override701public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,702byte[] out_buff, int out_offset) {703int ix = in_offset;704int ox = out_offset;705for (int i = 0; i < in_len; i++) {706int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);707out_buff[ox++] = (byte) (x >>> 24);708out_buff[ox++] = (byte) (x >>> 16);709out_buff[ox++] = (byte) (x >>> 8);710out_buff[ox++] = (byte) x;711}712return out_buff;713}714}715716// PCM 32 bit, unsigned, little-endian717private static class AudioFloatConversion32UL extends AudioFloatConverter {718@Override719public float[] toFloatArray(byte[] in_buff, int in_offset,720float[] out_buff, int out_offset, int out_len) {721int ix = in_offset;722int ox = out_offset;723for (int i = 0; i < out_len; i++) {724int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8) |725((in_buff[ix++] & 0xFF) << 16) |726((in_buff[ix++] & 0xFF) << 24);727x -= 0x80000000;728out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);729}730return out_buff;731}732733@Override734public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,735byte[] out_buff, int out_offset) {736int ix = in_offset;737int ox = out_offset;738for (int i = 0; i < in_len; i++) {739int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);740x += 0x80000000;741out_buff[ox++] = (byte) x;742out_buff[ox++] = (byte) (x >>> 8);743out_buff[ox++] = (byte) (x >>> 16);744out_buff[ox++] = (byte) (x >>> 24);745}746return out_buff;747}748}749750// PCM 32 bit, unsigned, big-endian751private static class AudioFloatConversion32UB extends AudioFloatConverter {752753@Override754public float[] toFloatArray(byte[] in_buff, int in_offset,755float[] out_buff, int out_offset, int out_len) {756int ix = in_offset;757int ox = out_offset;758for (int i = 0; i < out_len; i++) {759int x = ((in_buff[ix++] & 0xFF) << 24) |760((in_buff[ix++] & 0xFF) << 16) |761((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);762x -= 0x80000000;763out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);764}765return out_buff;766}767768@Override769public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,770byte[] out_buff, int out_offset) {771int ix = in_offset;772int ox = out_offset;773for (int i = 0; i < in_len; i++) {774int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);775x += 0x80000000;776out_buff[ox++] = (byte) (x >>> 24);777out_buff[ox++] = (byte) (x >>> 16);778out_buff[ox++] = (byte) (x >>> 8);779out_buff[ox++] = (byte) x;780}781return out_buff;782}783}784785/***************************************************************************786*787* 32+ bit signed/unsigned, little/big-endian788*789**************************************************************************/790791// PCM 32+ bit, signed, little-endian792private static class AudioFloatConversion32xSL extends AudioFloatConverter {793794private final int xbytes;795796AudioFloatConversion32xSL(int xbytes) {797this.xbytes = xbytes;798}799800@Override801public float[] toFloatArray(byte[] in_buff, int in_offset,802float[] out_buff, int out_offset, int out_len) {803int ix = in_offset;804int ox = out_offset;805for (int i = 0; i < out_len; i++) {806ix += xbytes;807int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)808| ((in_buff[ix++] & 0xFF) << 16)809| ((in_buff[ix++] & 0xFF) << 24);810out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);811}812return out_buff;813}814815@Override816public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,817byte[] out_buff, int out_offset) {818int ix = in_offset;819int ox = out_offset;820for (int i = 0; i < in_len; i++) {821int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);822for (int j = 0; j < xbytes; j++) {823out_buff[ox++] = 0;824}825out_buff[ox++] = (byte) x;826out_buff[ox++] = (byte) (x >>> 8);827out_buff[ox++] = (byte) (x >>> 16);828out_buff[ox++] = (byte) (x >>> 24);829}830return out_buff;831}832}833834// PCM 32+ bit, signed, big-endian835private static class AudioFloatConversion32xSB extends AudioFloatConverter {836837private final int xbytes;838839AudioFloatConversion32xSB(int xbytes) {840this.xbytes = xbytes;841}842843@Override844public float[] toFloatArray(byte[] in_buff, int in_offset,845float[] out_buff, int out_offset, int out_len) {846int ix = in_offset;847int ox = out_offset;848for (int i = 0; i < out_len; i++) {849int x = ((in_buff[ix++] & 0xFF) << 24)850| ((in_buff[ix++] & 0xFF) << 16)851| ((in_buff[ix++] & 0xFF) << 8)852| (in_buff[ix++] & 0xFF);853ix += xbytes;854out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);855}856return out_buff;857}858859@Override860public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,861byte[] out_buff, int out_offset) {862int ix = in_offset;863int ox = out_offset;864for (int i = 0; i < in_len; i++) {865int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);866out_buff[ox++] = (byte) (x >>> 24);867out_buff[ox++] = (byte) (x >>> 16);868out_buff[ox++] = (byte) (x >>> 8);869out_buff[ox++] = (byte) x;870for (int j = 0; j < xbytes; j++) {871out_buff[ox++] = 0;872}873}874return out_buff;875}876}877878// PCM 32+ bit, unsigned, little-endian879private static class AudioFloatConversion32xUL extends AudioFloatConverter {880881private final int xbytes;882883AudioFloatConversion32xUL(int xbytes) {884this.xbytes = xbytes;885}886887@Override888public float[] toFloatArray(byte[] in_buff, int in_offset,889float[] out_buff, int out_offset, int out_len) {890int ix = in_offset;891int ox = out_offset;892for (int i = 0; i < out_len; i++) {893ix += xbytes;894int x = (in_buff[ix++] & 0xFF) | ((in_buff[ix++] & 0xFF) << 8)895| ((in_buff[ix++] & 0xFF) << 16)896| ((in_buff[ix++] & 0xFF) << 24);897x -= 0x80000000;898out_buff[ox++] = x * (1.0f / (float)0x7FFFFFFF);899}900return out_buff;901}902903@Override904public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,905byte[] out_buff, int out_offset) {906int ix = in_offset;907int ox = out_offset;908for (int i = 0; i < in_len; i++) {909int x = (int) (in_buff[ix++] * (float)0x7FFFFFFF);910x += 0x80000000;911for (int j = 0; j < xbytes; j++) {912out_buff[ox++] = 0;913}914out_buff[ox++] = (byte) x;915out_buff[ox++] = (byte) (x >>> 8);916out_buff[ox++] = (byte) (x >>> 16);917out_buff[ox++] = (byte) (x >>> 24);918}919return out_buff;920}921}922923// PCM 32+ bit, unsigned, big-endian924private static class AudioFloatConversion32xUB extends AudioFloatConverter {925926private final int xbytes;927928AudioFloatConversion32xUB(int xbytes) {929this.xbytes = xbytes;930}931932@Override933public float[] toFloatArray(byte[] in_buff, int in_offset,934float[] out_buff, int out_offset, int out_len) {935int ix = in_offset;936int ox = out_offset;937for (int i = 0; i < out_len; i++) {938int x = ((in_buff[ix++] & 0xFF) << 24) |939((in_buff[ix++] & 0xFF) << 16) |940((in_buff[ix++] & 0xFF) << 8) | (in_buff[ix++] & 0xFF);941ix += xbytes;942x -= 0x80000000;943out_buff[ox++] = x * (1.0f / 2147483647.0f);944}945return out_buff;946}947948@Override949public byte[] toByteArray(float[] in_buff, int in_offset, int in_len,950byte[] out_buff, int out_offset) {951int ix = in_offset;952int ox = out_offset;953for (int i = 0; i < in_len; i++) {954int x = (int) (in_buff[ix++] * 2147483647.0f);955x += 0x80000000;956out_buff[ox++] = (byte) (x >>> 24);957out_buff[ox++] = (byte) (x >>> 16);958out_buff[ox++] = (byte) (x >>> 8);959out_buff[ox++] = (byte) x;960for (int j = 0; j < xbytes; j++) {961out_buff[ox++] = 0;962}963}964return out_buff;965}966}967968public static AudioFloatConverter getConverter(AudioFormat format) {969AudioFloatConverter conv = null;970if (format.getFrameSize() == 0)971return null;972if (format.getFrameSize() !=973((format.getSampleSizeInBits() + 7) / 8) * format.getChannels()) {974return null;975}976if (format.getEncoding().equals(Encoding.PCM_SIGNED)) {977if (format.isBigEndian()) {978if (format.getSampleSizeInBits() <= 8) {979conv = new AudioFloatConversion8S();980} else if (format.getSampleSizeInBits() > 8 &&981format.getSampleSizeInBits() <= 16) {982conv = new AudioFloatConversion16SB();983} else if (format.getSampleSizeInBits() > 16 &&984format.getSampleSizeInBits() <= 24) {985conv = new AudioFloatConversion24SB();986} else if (format.getSampleSizeInBits() > 24 &&987format.getSampleSizeInBits() <= 32) {988conv = new AudioFloatConversion32SB();989} else if (format.getSampleSizeInBits() > 32) {990conv = new AudioFloatConversion32xSB(((format991.getSampleSizeInBits() + 7) / 8) - 4);992}993} else {994if (format.getSampleSizeInBits() <= 8) {995conv = new AudioFloatConversion8S();996} else if (format.getSampleSizeInBits() > 8 &&997format.getSampleSizeInBits() <= 16) {998conv = new AudioFloatConversion16SL();999} else if (format.getSampleSizeInBits() > 16 &&1000format.getSampleSizeInBits() <= 24) {1001conv = new AudioFloatConversion24SL();1002} else if (format.getSampleSizeInBits() > 24 &&1003format.getSampleSizeInBits() <= 32) {1004conv = new AudioFloatConversion32SL();1005} else if (format.getSampleSizeInBits() > 32) {1006conv = new AudioFloatConversion32xSL(((format1007.getSampleSizeInBits() + 7) / 8) - 4);1008}1009}1010} else if (format.getEncoding().equals(Encoding.PCM_UNSIGNED)) {1011if (format.isBigEndian()) {1012if (format.getSampleSizeInBits() <= 8) {1013conv = new AudioFloatConversion8U();1014} else if (format.getSampleSizeInBits() > 8 &&1015format.getSampleSizeInBits() <= 16) {1016conv = new AudioFloatConversion16UB();1017} else if (format.getSampleSizeInBits() > 16 &&1018format.getSampleSizeInBits() <= 24) {1019conv = new AudioFloatConversion24UB();1020} else if (format.getSampleSizeInBits() > 24 &&1021format.getSampleSizeInBits() <= 32) {1022conv = new AudioFloatConversion32UB();1023} else if (format.getSampleSizeInBits() > 32) {1024conv = new AudioFloatConversion32xUB(((1025format.getSampleSizeInBits() + 7) / 8) - 4);1026}1027} else {1028if (format.getSampleSizeInBits() <= 8) {1029conv = new AudioFloatConversion8U();1030} else if (format.getSampleSizeInBits() > 8 &&1031format.getSampleSizeInBits() <= 16) {1032conv = new AudioFloatConversion16UL();1033} else if (format.getSampleSizeInBits() > 16 &&1034format.getSampleSizeInBits() <= 24) {1035conv = new AudioFloatConversion24UL();1036} else if (format.getSampleSizeInBits() > 24 &&1037format.getSampleSizeInBits() <= 32) {1038conv = new AudioFloatConversion32UL();1039} else if (format.getSampleSizeInBits() > 32) {1040conv = new AudioFloatConversion32xUL(((1041format.getSampleSizeInBits() + 7) / 8) - 4);1042}1043}1044} else if (format.getEncoding().equals(Encoding.PCM_FLOAT)) {1045if (format.getSampleSizeInBits() == 32) {1046if (format.isBigEndian())1047conv = new AudioFloatConversion32B();1048else1049conv = new AudioFloatConversion32L();1050} else if (format.getSampleSizeInBits() == 64) {1051if (format.isBigEndian())1052conv = new AudioFloatConversion64B();1053else1054conv = new AudioFloatConversion64L();1055}10561057}10581059if ((format.getEncoding().equals(Encoding.PCM_SIGNED) ||1060format.getEncoding().equals(Encoding.PCM_UNSIGNED)) &&1061(format.getSampleSizeInBits() % 8 != 0)) {1062conv = new AudioFloatLSBFilter(conv, format);1063}10641065if (conv != null)1066conv.format = format;1067return conv;1068}10691070private AudioFormat format;10711072public final AudioFormat getFormat() {1073return format;1074}10751076public abstract float[] toFloatArray(byte[] in_buff, int in_offset,1077float[] out_buff, int out_offset, int out_len);10781079public final float[] toFloatArray(byte[] in_buff, float[] out_buff,1080int out_offset, int out_len) {1081return toFloatArray(in_buff, 0, out_buff, out_offset, out_len);1082}10831084public final float[] toFloatArray(byte[] in_buff, int in_offset,1085float[] out_buff, int out_len) {1086return toFloatArray(in_buff, in_offset, out_buff, 0, out_len);1087}10881089public final float[] toFloatArray(byte[] in_buff, float[] out_buff,1090int out_len) {1091return toFloatArray(in_buff, 0, out_buff, 0, out_len);1092}10931094public final float[] toFloatArray(byte[] in_buff, float[] out_buff) {1095return toFloatArray(in_buff, 0, out_buff, 0, out_buff.length);1096}10971098public abstract byte[] toByteArray(float[] in_buff, int in_offset,1099int in_len, byte[] out_buff, int out_offset);11001101public final byte[] toByteArray(float[] in_buff, int in_len,1102byte[] out_buff, int out_offset) {1103return toByteArray(in_buff, 0, in_len, out_buff, out_offset);1104}11051106public final byte[] toByteArray(float[] in_buff, int in_offset, int in_len,1107byte[] out_buff) {1108return toByteArray(in_buff, in_offset, in_len, out_buff, 0);1109}11101111public final byte[] toByteArray(float[] in_buff, int in_len,1112byte[] out_buff) {1113return toByteArray(in_buff, 0, in_len, out_buff, 0);1114}11151116public final byte[] toByteArray(float[] in_buff, byte[] out_buff) {1117return toByteArray(in_buff, 0, in_buff.length, out_buff, 0);1118}1119}112011211122