Path: blob/master/src/java.desktop/share/classes/com/sun/media/sound/AudioFloatInputStream.java
41161 views
/*1* Copyright (c) 2007, 2013, 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.io.ByteArrayInputStream;28import java.io.File;29import java.io.IOException;30import java.io.InputStream;31import java.net.URL;3233import javax.sound.sampled.AudioFormat;34import javax.sound.sampled.AudioInputStream;35import javax.sound.sampled.AudioSystem;36import javax.sound.sampled.UnsupportedAudioFileException;3738/**39* This class is used to create AudioFloatInputStream from AudioInputStream and40* byte buffers.41*42* @author Karl Helgason43*/44public abstract class AudioFloatInputStream {4546private static class BytaArrayAudioFloatInputStream47extends AudioFloatInputStream {4849private int pos = 0;50private int markpos = 0;51private final AudioFloatConverter converter;52private final AudioFormat format;53private final byte[] buffer;54private final int buffer_offset;55private final int buffer_len;56private final int framesize_pc;5758BytaArrayAudioFloatInputStream(AudioFloatConverter converter,59byte[] buffer, int offset, int len) {60this.converter = converter;61this.format = converter.getFormat();62this.buffer = buffer;63this.buffer_offset = offset;64framesize_pc = format.getFrameSize() / format.getChannels();65this.buffer_len = len / framesize_pc;6667}6869@Override70public AudioFormat getFormat() {71return format;72}7374@Override75public long getFrameLength() {76return buffer_len;// / format.getFrameSize();77}7879@Override80public int read(float[] b, int off, int len) throws IOException {81if (b == null)82throw new NullPointerException();83if (off < 0 || len < 0 || len > b.length - off)84throw new IndexOutOfBoundsException();85if (pos >= buffer_len)86return -1;87if (len == 0)88return 0;89if (pos + len > buffer_len)90len = buffer_len - pos;91converter.toFloatArray(buffer, buffer_offset + pos * framesize_pc,92b, off, len);93pos += len;94return len;95}9697@Override98public long skip(long len) throws IOException {99if (pos >= buffer_len)100return -1;101if (len <= 0)102return 0;103if (pos + len > buffer_len)104len = buffer_len - pos;105pos += len;106return len;107}108109@Override110public int available() throws IOException {111return buffer_len - pos;112}113114@Override115public void close() throws IOException {116}117118@Override119public void mark(int readlimit) {120markpos = pos;121}122123@Override124public boolean markSupported() {125return true;126}127128@Override129public void reset() throws IOException {130pos = markpos;131}132}133134private static class DirectAudioFloatInputStream135extends AudioFloatInputStream {136137private final AudioInputStream stream;138private AudioFloatConverter converter;139private final int framesize_pc; // framesize / channels140private byte[] buffer;141142DirectAudioFloatInputStream(AudioInputStream stream) {143converter = AudioFloatConverter.getConverter(stream.getFormat());144if (converter == null) {145AudioFormat format = stream.getFormat();146AudioFormat newformat;147148AudioFormat[] formats = AudioSystem.getTargetFormats(149AudioFormat.Encoding.PCM_SIGNED, format);150if (formats.length != 0) {151newformat = formats[0];152} else {153float samplerate = format.getSampleRate();154int samplesizeinbits = format.getSampleSizeInBits();155int framesize = format.getFrameSize();156float framerate = format.getFrameRate();157samplesizeinbits = 16;158framesize = format.getChannels() * (samplesizeinbits / 8);159framerate = samplerate;160161newformat = new AudioFormat(162AudioFormat.Encoding.PCM_SIGNED, samplerate,163samplesizeinbits, format.getChannels(), framesize,164framerate, false);165}166167stream = AudioSystem.getAudioInputStream(newformat, stream);168converter = AudioFloatConverter.getConverter(stream.getFormat());169}170framesize_pc = stream.getFormat().getFrameSize()171/ stream.getFormat().getChannels();172this.stream = stream;173}174175@Override176public AudioFormat getFormat() {177return stream.getFormat();178}179180@Override181public long getFrameLength() {182return stream.getFrameLength();183}184185@Override186public int read(float[] b, int off, int len) throws IOException {187int b_len = len * framesize_pc;188if (buffer == null || buffer.length < b_len)189buffer = new byte[b_len];190int ret = stream.read(buffer, 0, b_len);191if (ret == -1)192return -1;193converter.toFloatArray(buffer, b, off, ret / framesize_pc);194return ret / framesize_pc;195}196197@Override198public long skip(long len) throws IOException {199long b_len = len * framesize_pc;200long ret = stream.skip(b_len);201if (ret == -1)202return -1;203return ret / framesize_pc;204}205206@Override207public int available() throws IOException {208return stream.available() / framesize_pc;209}210211@Override212public void close() throws IOException {213stream.close();214}215216@Override217public void mark(int readlimit) {218stream.mark(readlimit * framesize_pc);219}220221@Override222public boolean markSupported() {223return stream.markSupported();224}225226@Override227public void reset() throws IOException {228stream.reset();229}230}231232public static AudioFloatInputStream getInputStream(URL url)233throws UnsupportedAudioFileException, IOException {234return new DirectAudioFloatInputStream(AudioSystem235.getAudioInputStream(url));236}237238public static AudioFloatInputStream getInputStream(File file)239throws UnsupportedAudioFileException, IOException {240return new DirectAudioFloatInputStream(AudioSystem241.getAudioInputStream(file));242}243244public static AudioFloatInputStream getInputStream(InputStream stream)245throws UnsupportedAudioFileException, IOException {246return new DirectAudioFloatInputStream(AudioSystem247.getAudioInputStream(stream));248}249250public static AudioFloatInputStream getInputStream(251AudioInputStream stream) {252return new DirectAudioFloatInputStream(stream);253}254255public static AudioFloatInputStream getInputStream(AudioFormat format,256byte[] buffer, int offset, int len) {257AudioFloatConverter converter = AudioFloatConverter258.getConverter(format);259if (converter != null)260return new BytaArrayAudioFloatInputStream(converter, buffer,261offset, len);262263InputStream stream = new ByteArrayInputStream(buffer, offset, len);264long aLen = format.getFrameSize() == AudioSystem.NOT_SPECIFIED265? AudioSystem.NOT_SPECIFIED : len / format.getFrameSize();266AudioInputStream astream = new AudioInputStream(stream, format, aLen);267return getInputStream(astream);268}269270public abstract AudioFormat getFormat();271272public abstract long getFrameLength();273274public abstract int read(float[] b, int off, int len) throws IOException;275276public final int read(float[] b) throws IOException {277return read(b, 0, b.length);278}279280public final float read() throws IOException {281float[] b = new float[1];282int ret = read(b, 0, 1);283if (ret == -1 || ret == 0)284return 0;285return b[0];286}287288public abstract long skip(long len) throws IOException;289290public abstract int available() throws IOException;291292public abstract void close() throws IOException;293294public abstract void mark(int readlimit);295296public abstract boolean markSupported();297298public abstract void reset() throws IOException;299}300301302