| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
package com.sun.media.sound;  | 
 | 
 | 
 | 
import java.io.IOException;  | 
 | 
import java.io.InputStream;  | 
 | 
import java.util.ArrayList;  | 
 | 
import java.util.Arrays;  | 
 | 
 | 
 | 
import javax.sound.sampled.AudioFormat;  | 
 | 
import javax.sound.sampled.AudioInputStream;  | 
 | 
import javax.sound.sampled.AudioSystem;  | 
 | 
import javax.sound.sampled.AudioFormat.Encoding;  | 
 | 
import javax.sound.sampled.spi.FormatConversionProvider;  | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
public final class AudioFloatFormatConverter extends FormatConversionProvider { | 
 | 
 | 
 | 
    private static class AudioFloatFormatConverterInputStream extends  | 
 | 
            InputStream { | 
 | 
        private final AudioFloatConverter converter;  | 
 | 
 | 
 | 
        private final AudioFloatInputStream stream;  | 
 | 
 | 
 | 
        private float[] readfloatbuffer;  | 
 | 
 | 
 | 
        private final int fsize;  | 
 | 
 | 
 | 
        AudioFloatFormatConverterInputStream(AudioFormat targetFormat,  | 
 | 
                AudioFloatInputStream stream) { | 
 | 
            this.stream = stream;  | 
 | 
            converter = AudioFloatConverter.getConverter(targetFormat);  | 
 | 
            fsize = ((targetFormat.getSampleSizeInBits() + 7) / 8);  | 
 | 
        }  | 
 | 
 | 
 | 
        public int read() throws IOException { | 
 | 
            byte[] b = new byte[1];  | 
 | 
            int ret = read(b);  | 
 | 
            if (ret < 0)  | 
 | 
                return ret;  | 
 | 
            return b[0] & 0xFF;  | 
 | 
        }  | 
 | 
 | 
 | 
        public int read(byte[] b, int off, int len) throws IOException { | 
 | 
 | 
 | 
            int flen = len / fsize;  | 
 | 
            if (readfloatbuffer == null || readfloatbuffer.length < flen)  | 
 | 
                readfloatbuffer = new float[flen];  | 
 | 
            int ret = stream.read(readfloatbuffer, 0, flen);  | 
 | 
            if (ret < 0)  | 
 | 
                return ret;  | 
 | 
            converter.toByteArray(readfloatbuffer, 0, ret, b, off);  | 
 | 
            return ret * fsize;  | 
 | 
        }  | 
 | 
 | 
 | 
        public int available() throws IOException { | 
 | 
            int ret = stream.available();  | 
 | 
            if (ret < 0)  | 
 | 
                return ret;  | 
 | 
            return ret * fsize;  | 
 | 
        }  | 
 | 
 | 
 | 
        public void close() throws IOException { | 
 | 
            stream.close();  | 
 | 
        }  | 
 | 
 | 
 | 
        public synchronized void mark(int readlimit) { | 
 | 
            stream.mark(readlimit * fsize);  | 
 | 
        }  | 
 | 
 | 
 | 
        public boolean markSupported() { | 
 | 
            return stream.markSupported();  | 
 | 
        }  | 
 | 
 | 
 | 
        public synchronized void reset() throws IOException { | 
 | 
            stream.reset();  | 
 | 
        }  | 
 | 
 | 
 | 
        public long skip(long n) throws IOException { | 
 | 
            long ret = stream.skip(n / fsize);  | 
 | 
            if (ret < 0)  | 
 | 
                return ret;  | 
 | 
            return ret * fsize;  | 
 | 
        }  | 
 | 
 | 
 | 
    }  | 
 | 
 | 
 | 
    private static class AudioFloatInputStreamChannelMixer extends  | 
 | 
            AudioFloatInputStream { | 
 | 
 | 
 | 
        private final int targetChannels;  | 
 | 
 | 
 | 
        private final int sourceChannels;  | 
 | 
 | 
 | 
        private final AudioFloatInputStream ais;  | 
 | 
 | 
 | 
        private final AudioFormat targetFormat;  | 
 | 
 | 
 | 
        private float[] conversion_buffer;  | 
 | 
 | 
 | 
        AudioFloatInputStreamChannelMixer(AudioFloatInputStream ais,  | 
 | 
                int targetChannels) { | 
 | 
            this.sourceChannels = ais.getFormat().getChannels();  | 
 | 
            this.targetChannels = targetChannels;  | 
 | 
            this.ais = ais;  | 
 | 
            AudioFormat format = ais.getFormat();  | 
 | 
            targetFormat = new AudioFormat(format.getEncoding(), format  | 
 | 
                    .getSampleRate(), format.getSampleSizeInBits(),  | 
 | 
                    targetChannels, (format.getFrameSize() / sourceChannels)  | 
 | 
                            * targetChannels, format.getFrameRate(), format  | 
 | 
                            .isBigEndian());  | 
 | 
        }  | 
 | 
 | 
 | 
        public int available() throws IOException { | 
 | 
            return (ais.available() / sourceChannels) * targetChannels;  | 
 | 
        }  | 
 | 
 | 
 | 
        public void close() throws IOException { | 
 | 
            ais.close();  | 
 | 
        }  | 
 | 
 | 
 | 
        public AudioFormat getFormat() { | 
 | 
            return targetFormat;  | 
 | 
        }  | 
 | 
 | 
 | 
        public long getFrameLength() { | 
 | 
            return ais.getFrameLength();  | 
 | 
        }  | 
 | 
 | 
 | 
        public void mark(int readlimit) { | 
 | 
            ais.mark((readlimit / targetChannels) * sourceChannels);  | 
 | 
        }  | 
 | 
 | 
 | 
        public boolean markSupported() { | 
 | 
            return ais.markSupported();  | 
 | 
        }  | 
 | 
 | 
 | 
        public int read(float[] b, int off, int len) throws IOException { | 
 | 
            int len2 = (len / targetChannels) * sourceChannels;  | 
 | 
            if (conversion_buffer == null || conversion_buffer.length < len2)  | 
 | 
                conversion_buffer = new float[len2];  | 
 | 
            int ret = ais.read(conversion_buffer, 0, len2);  | 
 | 
            if (ret < 0)  | 
 | 
                return ret;  | 
 | 
            if (sourceChannels == 1) { | 
 | 
                int cs = targetChannels;  | 
 | 
                for (int c = 0; c < targetChannels; c++) { | 
 | 
                    for (int i = 0, ix = off + c; i < len2; i++, ix += cs) { | 
 | 
                        b[ix] = conversion_buffer[i];  | 
 | 
                    }  | 
 | 
                }  | 
 | 
            } else if (targetChannels == 1) { | 
 | 
                int cs = sourceChannels;  | 
 | 
                for (int i = 0, ix = off; i < len2; i += cs, ix++) { | 
 | 
                    b[ix] = conversion_buffer[i];  | 
 | 
                }  | 
 | 
                for (int c = 1; c < sourceChannels; c++) { | 
 | 
                    for (int i = c, ix = off; i < len2; i += cs, ix++) { | 
 | 
                        b[ix] += conversion_buffer[i];  | 
 | 
                    }  | 
 | 
                }  | 
 | 
                float vol = 1f / ((float) sourceChannels);  | 
 | 
                for (int i = 0, ix = off; i < len2; i += cs, ix++) { | 
 | 
                    b[ix] *= vol;  | 
 | 
                }  | 
 | 
            } else { | 
 | 
                int minChannels = Math.min(sourceChannels, targetChannels);  | 
 | 
                int off_len = off + len;  | 
 | 
                int ct = targetChannels;  | 
 | 
                int cs = sourceChannels;  | 
 | 
                for (int c = 0; c < minChannels; c++) { | 
 | 
                    for (int i = off + c, ix = c; i < off_len; i += ct, ix += cs) { | 
 | 
                        b[i] = conversion_buffer[ix];  | 
 | 
                    }  | 
 | 
                }  | 
 | 
                for (int c = minChannels; c < targetChannels; c++) { | 
 | 
                    for (int i = off + c; i < off_len; i += ct) { | 
 | 
                        b[i] = 0;  | 
 | 
                    }  | 
 | 
                }  | 
 | 
            }  | 
 | 
            return (ret / sourceChannels) * targetChannels;  | 
 | 
        }  | 
 | 
 | 
 | 
        public void reset() throws IOException { | 
 | 
            ais.reset();  | 
 | 
        }  | 
 | 
 | 
 | 
        public long skip(long len) throws IOException { | 
 | 
            long ret = ais.skip((len / targetChannels) * sourceChannels);  | 
 | 
            if (ret < 0)  | 
 | 
                return ret;  | 
 | 
            return (ret / sourceChannels) * targetChannels;  | 
 | 
        }  | 
 | 
 | 
 | 
    }  | 
 | 
 | 
 | 
    private static class AudioFloatInputStreamResampler extends  | 
 | 
            AudioFloatInputStream { | 
 | 
 | 
 | 
        private final AudioFloatInputStream ais;  | 
 | 
 | 
 | 
        private final AudioFormat targetFormat;  | 
 | 
 | 
 | 
        private float[] skipbuffer;  | 
 | 
 | 
 | 
        private SoftAbstractResampler resampler;  | 
 | 
 | 
 | 
        private final float[] pitch = new float[1];  | 
 | 
 | 
 | 
        private final float[] ibuffer2;  | 
 | 
 | 
 | 
        private final float[][] ibuffer;  | 
 | 
 | 
 | 
        private float ibuffer_index = 0;  | 
 | 
 | 
 | 
        private int ibuffer_len = 0;  | 
 | 
 | 
 | 
        private final int nrofchannels;  | 
 | 
 | 
 | 
        private float[][] cbuffer;  | 
 | 
 | 
 | 
        private final int buffer_len = 512;  | 
 | 
 | 
 | 
        private final int pad;  | 
 | 
 | 
 | 
        private final int pad2;  | 
 | 
 | 
 | 
        private final float[] ix = new float[1];  | 
 | 
 | 
 | 
        private final int[] ox = new int[1];  | 
 | 
 | 
 | 
        private float[][] mark_ibuffer = null;  | 
 | 
 | 
 | 
        private float mark_ibuffer_index = 0;  | 
 | 
 | 
 | 
        private int mark_ibuffer_len = 0;  | 
 | 
 | 
 | 
        AudioFloatInputStreamResampler(AudioFloatInputStream ais,  | 
 | 
                AudioFormat format) { | 
 | 
            this.ais = ais;  | 
 | 
            AudioFormat sourceFormat = ais.getFormat();  | 
 | 
            targetFormat = new AudioFormat(sourceFormat.getEncoding(), format  | 
 | 
                    .getSampleRate(), sourceFormat.getSampleSizeInBits(),  | 
 | 
                    sourceFormat.getChannels(), sourceFormat.getFrameSize(),  | 
 | 
                    format.getSampleRate(), sourceFormat.isBigEndian());  | 
 | 
            nrofchannels = targetFormat.getChannels();  | 
 | 
            Object interpolation = format.getProperty("interpolation"); | 
 | 
            if (interpolation != null && (interpolation instanceof String)) { | 
 | 
                String resamplerType = (String) interpolation;  | 
 | 
                if (resamplerType.equalsIgnoreCase("point")) | 
 | 
                    this.resampler = new SoftPointResampler();  | 
 | 
                if (resamplerType.equalsIgnoreCase("linear")) | 
 | 
                    this.resampler = new SoftLinearResampler2();  | 
 | 
                if (resamplerType.equalsIgnoreCase("linear1")) | 
 | 
                    this.resampler = new SoftLinearResampler();  | 
 | 
                if (resamplerType.equalsIgnoreCase("linear2")) | 
 | 
                    this.resampler = new SoftLinearResampler2();  | 
 | 
                if (resamplerType.equalsIgnoreCase("cubic")) | 
 | 
                    this.resampler = new SoftCubicResampler();  | 
 | 
                if (resamplerType.equalsIgnoreCase("lanczos")) | 
 | 
                    this.resampler = new SoftLanczosResampler();  | 
 | 
                if (resamplerType.equalsIgnoreCase("sinc")) | 
 | 
                    this.resampler = new SoftSincResampler();  | 
 | 
            }  | 
 | 
            if (resampler == null)  | 
 | 
                resampler = new SoftLinearResampler2();   | 
 | 
                                                          | 
 | 
            pitch[0] = sourceFormat.getSampleRate() / format.getSampleRate();  | 
 | 
            pad = resampler.getPadding();  | 
 | 
            pad2 = pad * 2;  | 
 | 
            ibuffer = new float[nrofchannels][buffer_len + pad2];  | 
 | 
            ibuffer2 = new float[nrofchannels * buffer_len];  | 
 | 
            ibuffer_index = buffer_len + pad;  | 
 | 
            ibuffer_len = buffer_len;  | 
 | 
        }  | 
 | 
 | 
 | 
        public int available() throws IOException { | 
 | 
            return 0;  | 
 | 
        }  | 
 | 
 | 
 | 
        public void close() throws IOException { | 
 | 
            ais.close();  | 
 | 
        }  | 
 | 
 | 
 | 
        public AudioFormat getFormat() { | 
 | 
            return targetFormat;  | 
 | 
        }  | 
 | 
 | 
 | 
        public long getFrameLength() { | 
 | 
            return AudioSystem.NOT_SPECIFIED;   | 
 | 
        }  | 
 | 
 | 
 | 
        public void mark(int readlimit) { | 
 | 
            ais.mark((int) (readlimit * pitch[0]));  | 
 | 
            mark_ibuffer_index = ibuffer_index;  | 
 | 
            mark_ibuffer_len = ibuffer_len;  | 
 | 
            if (mark_ibuffer == null) { | 
 | 
                mark_ibuffer = new float[ibuffer.length][ibuffer[0].length];  | 
 | 
            }  | 
 | 
            for (int c = 0; c < ibuffer.length; c++) { | 
 | 
                float[] from = ibuffer[c];  | 
 | 
                float[] to = mark_ibuffer[c];  | 
 | 
                for (int i = 0; i < to.length; i++) { | 
 | 
                    to[i] = from[i];  | 
 | 
                }  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        public boolean markSupported() { | 
 | 
            return ais.markSupported();  | 
 | 
        }  | 
 | 
 | 
 | 
        private void readNextBuffer() throws IOException { | 
 | 
 | 
 | 
            if (ibuffer_len == -1)  | 
 | 
                return;  | 
 | 
 | 
 | 
            for (int c = 0; c < nrofchannels; c++) { | 
 | 
                float[] buff = ibuffer[c];  | 
 | 
                int buffer_len_pad = ibuffer_len + pad2;  | 
 | 
                for (int i = ibuffer_len, ix = 0; i < buffer_len_pad; i++, ix++) { | 
 | 
                    buff[ix] = buff[i];  | 
 | 
                }  | 
 | 
            }  | 
 | 
 | 
 | 
            ibuffer_index -= (ibuffer_len);  | 
 | 
 | 
 | 
            ibuffer_len = ais.read(ibuffer2);  | 
 | 
            if (ibuffer_len >= 0) { | 
 | 
                while (ibuffer_len < ibuffer2.length) { | 
 | 
                    int ret = ais.read(ibuffer2, ibuffer_len, ibuffer2.length  | 
 | 
                            - ibuffer_len);  | 
 | 
                    if (ret == -1)  | 
 | 
                        break;  | 
 | 
                    ibuffer_len += ret;  | 
 | 
                }  | 
 | 
                Arrays.fill(ibuffer2, ibuffer_len, ibuffer2.length, 0);  | 
 | 
                ibuffer_len /= nrofchannels;  | 
 | 
            } else { | 
 | 
                Arrays.fill(ibuffer2, 0, ibuffer2.length, 0);  | 
 | 
            }  | 
 | 
 | 
 | 
            int ibuffer2_len = ibuffer2.length;  | 
 | 
            for (int c = 0; c < nrofchannels; c++) { | 
 | 
                float[] buff = ibuffer[c];  | 
 | 
                for (int i = c, ix = pad2; i < ibuffer2_len; i += nrofchannels, ix++) { | 
 | 
                    buff[ix] = ibuffer2[i];  | 
 | 
                }  | 
 | 
            }  | 
 | 
 | 
 | 
        }  | 
 | 
 | 
 | 
        public int read(float[] b, int off, int len) throws IOException { | 
 | 
 | 
 | 
            if (cbuffer == null || cbuffer[0].length < len / nrofchannels) { | 
 | 
                cbuffer = new float[nrofchannels][len / nrofchannels];  | 
 | 
            }  | 
 | 
            if (ibuffer_len == -1)  | 
 | 
                return -1;  | 
 | 
            if (len < 0)  | 
 | 
                return 0;  | 
 | 
            int offlen = off + len;  | 
 | 
            int remain = len / nrofchannels;  | 
 | 
            int destPos = 0;  | 
 | 
            int in_end = ibuffer_len;  | 
 | 
            while (remain > 0) { | 
 | 
                if (ibuffer_len >= 0) { | 
 | 
                    if (ibuffer_index >= (ibuffer_len + pad))  | 
 | 
                        readNextBuffer();  | 
 | 
                    in_end = ibuffer_len + pad;  | 
 | 
                }  | 
 | 
 | 
 | 
                if (ibuffer_len < 0) { | 
 | 
                    in_end = pad2;  | 
 | 
                    if (ibuffer_index >= in_end)  | 
 | 
                        break;  | 
 | 
                }  | 
 | 
 | 
 | 
                if (ibuffer_index < 0)  | 
 | 
                    break;  | 
 | 
                int preDestPos = destPos;  | 
 | 
                for (int c = 0; c < nrofchannels; c++) { | 
 | 
                    ix[0] = ibuffer_index;  | 
 | 
                    ox[0] = destPos;  | 
 | 
                    float[] buff = ibuffer[c];  | 
 | 
                    resampler.interpolate(buff, ix, in_end, pitch, 0,  | 
 | 
                            cbuffer[c], ox, len / nrofchannels);  | 
 | 
                }  | 
 | 
                ibuffer_index = ix[0];  | 
 | 
                destPos = ox[0];  | 
 | 
                remain -= destPos - preDestPos;  | 
 | 
            }  | 
 | 
            for (int c = 0; c < nrofchannels; c++) { | 
 | 
                int ix = 0;  | 
 | 
                float[] buff = cbuffer[c];  | 
 | 
                for (int i = c + off; i < offlen; i += nrofchannels) { | 
 | 
                    b[i] = buff[ix++];  | 
 | 
                }  | 
 | 
            }  | 
 | 
            return len - remain * nrofchannels;  | 
 | 
        }  | 
 | 
 | 
 | 
        public void reset() throws IOException { | 
 | 
            ais.reset();  | 
 | 
            if (mark_ibuffer == null)  | 
 | 
                return;  | 
 | 
            ibuffer_index = mark_ibuffer_index;  | 
 | 
            ibuffer_len = mark_ibuffer_len;  | 
 | 
            for (int c = 0; c < ibuffer.length; c++) { | 
 | 
                float[] from = mark_ibuffer[c];  | 
 | 
                float[] to = ibuffer[c];  | 
 | 
                for (int i = 0; i < to.length; i++) { | 
 | 
                    to[i] = from[i];  | 
 | 
                }  | 
 | 
            }  | 
 | 
 | 
 | 
        }  | 
 | 
 | 
 | 
        public long skip(long len) throws IOException { | 
 | 
            if (len < 0)  | 
 | 
                return 0;  | 
 | 
            if (skipbuffer == null)  | 
 | 
                skipbuffer = new float[1024 * targetFormat.getFrameSize()];  | 
 | 
            float[] l_skipbuffer = skipbuffer;  | 
 | 
            long remain = len;  | 
 | 
            while (remain > 0) { | 
 | 
                int ret = read(l_skipbuffer, 0, (int) Math.min(remain,  | 
 | 
                        skipbuffer.length));  | 
 | 
                if (ret < 0) { | 
 | 
                    if (remain == len)  | 
 | 
                        return ret;  | 
 | 
                    break;  | 
 | 
                }  | 
 | 
                remain -= ret;  | 
 | 
            }  | 
 | 
            return len - remain;  | 
 | 
 | 
 | 
        }  | 
 | 
 | 
 | 
    }  | 
 | 
 | 
 | 
    private final Encoding[] formats = {Encoding.PCM_SIGNED, | 
 | 
                                        Encoding.PCM_UNSIGNED,  | 
 | 
                                        Encoding.PCM_FLOAT};  | 
 | 
 | 
 | 
    public AudioInputStream getAudioInputStream(Encoding targetEncoding,  | 
 | 
            AudioInputStream sourceStream) { | 
 | 
        if (sourceStream.getFormat().getEncoding().equals(targetEncoding))  | 
 | 
            return sourceStream;  | 
 | 
        AudioFormat format = sourceStream.getFormat();  | 
 | 
        int channels = format.getChannels();  | 
 | 
        Encoding encoding = targetEncoding;  | 
 | 
        float samplerate = format.getSampleRate();  | 
 | 
        int bits = format.getSampleSizeInBits();  | 
 | 
        boolean bigendian = format.isBigEndian();  | 
 | 
        if (targetEncoding.equals(Encoding.PCM_FLOAT))  | 
 | 
            bits = 32;  | 
 | 
        AudioFormat targetFormat = new AudioFormat(encoding, samplerate, bits,  | 
 | 
                channels, channels * bits / 8, samplerate, bigendian);  | 
 | 
        return getAudioInputStream(targetFormat, sourceStream);  | 
 | 
    }  | 
 | 
 | 
 | 
    public AudioInputStream getAudioInputStream(AudioFormat targetFormat,  | 
 | 
            AudioInputStream sourceStream) { | 
 | 
        if (!isConversionSupported(targetFormat, sourceStream.getFormat()))  | 
 | 
            throw new IllegalArgumentException("Unsupported conversion: " | 
 | 
                    + sourceStream.getFormat().toString() + " to "  | 
 | 
                    + targetFormat.toString());  | 
 | 
        return getAudioInputStream(targetFormat, AudioFloatInputStream  | 
 | 
                .getInputStream(sourceStream));  | 
 | 
    }  | 
 | 
 | 
 | 
    public AudioInputStream getAudioInputStream(AudioFormat targetFormat,  | 
 | 
            AudioFloatInputStream sourceStream) { | 
 | 
 | 
 | 
        if (!isConversionSupported(targetFormat, sourceStream.getFormat()))  | 
 | 
            throw new IllegalArgumentException("Unsupported conversion: " | 
 | 
                    + sourceStream.getFormat().toString() + " to "  | 
 | 
                    + targetFormat.toString());  | 
 | 
        if (targetFormat.getChannels() != sourceStream.getFormat()  | 
 | 
                .getChannels())  | 
 | 
            sourceStream = new AudioFloatInputStreamChannelMixer(sourceStream,  | 
 | 
                    targetFormat.getChannels());  | 
 | 
        if (Math.abs(targetFormat.getSampleRate()  | 
 | 
                - sourceStream.getFormat().getSampleRate()) > 0.000001)  | 
 | 
            sourceStream = new AudioFloatInputStreamResampler(sourceStream,  | 
 | 
                    targetFormat);  | 
 | 
        return new AudioInputStream(new AudioFloatFormatConverterInputStream(  | 
 | 
                targetFormat, sourceStream), targetFormat, sourceStream  | 
 | 
                .getFrameLength());  | 
 | 
    }  | 
 | 
 | 
 | 
    public Encoding[] getSourceEncodings() { | 
 | 
        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED, | 
 | 
                Encoding.PCM_FLOAT };  | 
 | 
    }  | 
 | 
 | 
 | 
    public Encoding[] getTargetEncodings() { | 
 | 
        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED, | 
 | 
                Encoding.PCM_FLOAT };  | 
 | 
    }  | 
 | 
 | 
 | 
    public Encoding[] getTargetEncodings(AudioFormat sourceFormat) { | 
 | 
        if (AudioFloatConverter.getConverter(sourceFormat) == null)  | 
 | 
            return new Encoding[0];  | 
 | 
        return new Encoding[] { Encoding.PCM_SIGNED, Encoding.PCM_UNSIGNED, | 
 | 
                Encoding.PCM_FLOAT };  | 
 | 
    }  | 
 | 
 | 
 | 
    public AudioFormat[] getTargetFormats(Encoding targetEncoding,  | 
 | 
            AudioFormat sourceFormat) { | 
 | 
        if (AudioFloatConverter.getConverter(sourceFormat) == null)  | 
 | 
            return new AudioFormat[0];  | 
 | 
        int channels = sourceFormat.getChannels();  | 
 | 
 | 
 | 
        ArrayList<AudioFormat> formats = new ArrayList<AudioFormat>();  | 
 | 
 | 
 | 
        if (targetEncoding.equals(Encoding.PCM_SIGNED))  | 
 | 
            formats.add(new AudioFormat(Encoding.PCM_SIGNED,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, false));  | 
 | 
        if (targetEncoding.equals(Encoding.PCM_UNSIGNED))  | 
 | 
            formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, 8, channels, channels,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, false));  | 
 | 
 | 
 | 
        for (int bits = 16; bits < 32; bits += 8) { | 
 | 
            if (targetEncoding.equals(Encoding.PCM_SIGNED)) { | 
 | 
                formats.add(new AudioFormat(Encoding.PCM_SIGNED,  | 
 | 
                        AudioSystem.NOT_SPECIFIED, bits, channels, channels  | 
 | 
                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));  | 
 | 
                formats.add(new AudioFormat(Encoding.PCM_SIGNED,  | 
 | 
                        AudioSystem.NOT_SPECIFIED, bits, channels, channels  | 
 | 
                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));  | 
 | 
            }  | 
 | 
            if (targetEncoding.equals(Encoding.PCM_UNSIGNED)) { | 
 | 
                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,  | 
 | 
                        AudioSystem.NOT_SPECIFIED, bits, channels, channels  | 
 | 
                                * bits / 8, AudioSystem.NOT_SPECIFIED, true));  | 
 | 
                formats.add(new AudioFormat(Encoding.PCM_UNSIGNED,  | 
 | 
                        AudioSystem.NOT_SPECIFIED, bits, channels, channels  | 
 | 
                                * bits / 8, AudioSystem.NOT_SPECIFIED, false));  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        if (targetEncoding.equals(Encoding.PCM_FLOAT)) { | 
 | 
            formats.add(new AudioFormat(Encoding.PCM_FLOAT,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, false));  | 
 | 
            formats.add(new AudioFormat(Encoding.PCM_FLOAT,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, 32, channels, channels * 4,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, true));  | 
 | 
            formats.add(new AudioFormat(Encoding.PCM_FLOAT,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, false));  | 
 | 
            formats.add(new AudioFormat(Encoding.PCM_FLOAT,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, 64, channels, channels * 8,  | 
 | 
                    AudioSystem.NOT_SPECIFIED, true));  | 
 | 
        }  | 
 | 
 | 
 | 
        return formats.toArray(new AudioFormat[formats.size()]);  | 
 | 
    }  | 
 | 
 | 
 | 
    public boolean isConversionSupported(AudioFormat targetFormat,  | 
 | 
            AudioFormat sourceFormat) { | 
 | 
        if (AudioFloatConverter.getConverter(sourceFormat) == null)  | 
 | 
            return false;  | 
 | 
        if (AudioFloatConverter.getConverter(targetFormat) == null)  | 
 | 
            return false;  | 
 | 
        if (sourceFormat.getChannels() <= 0)  | 
 | 
            return false;  | 
 | 
        if (targetFormat.getChannels() <= 0)  | 
 | 
            return false;  | 
 | 
        return true;  | 
 | 
    }  | 
 | 
 | 
 | 
    public boolean isConversionSupported(Encoding targetEncoding,  | 
 | 
            AudioFormat sourceFormat) { | 
 | 
        if (AudioFloatConverter.getConverter(sourceFormat) == null)  | 
 | 
            return false;  | 
 | 
        for (int i = 0; i < formats.length; i++) { | 
 | 
            if (targetEncoding.equals(formats[i]))  | 
 | 
                return true;  | 
 | 
        }  | 
 | 
        return false;  | 
 | 
    }  | 
 | 
 | 
 | 
}  |