829N/A/*
6321N/A * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
829N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
829N/A *
829N/A * This code is free software; you can redistribute it and/or modify it
829N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
829N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
829N/A *
829N/A * This code is distributed in the hope that it will be useful, but WITHOUT
829N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
829N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
829N/A * version 2 for more details (a copy is included in the LICENSE file that
829N/A * accompanied this code).
829N/A *
829N/A * You should have received a copy of the GNU General Public License version
829N/A * 2 along with this work; if not, write to the Free Software Foundation,
829N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
829N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
829N/A */
829N/Apackage com.sun.media.sound;
829N/A
829N/Aimport java.io.IOException;
829N/Aimport java.io.InputStream;
829N/Aimport javax.sound.sampled.AudioFormat;
829N/Aimport javax.sound.sampled.AudioInputStream;
829N/Aimport javax.sound.sampled.AudioSystem;
829N/Aimport javax.sound.sampled.AudioFormat.Encoding;
829N/A
829N/A/**
829N/A * Wavetable oscillator for pre-loaded data.
829N/A *
829N/A * @author Karl Helgason
829N/A */
6321N/Apublic final class ModelByteBufferWavetable implements ModelWavetable {
829N/A
829N/A private class Buffer8PlusInputStream extends InputStream {
829N/A
6321N/A private final boolean bigendian;
6321N/A private final int framesize_pc;
829N/A int pos = 0;
829N/A int pos2 = 0;
829N/A int markpos = 0;
829N/A int markpos2 = 0;
829N/A
6321N/A Buffer8PlusInputStream() {
829N/A framesize_pc = format.getFrameSize() / format.getChannels();
829N/A bigendian = format.isBigEndian();
829N/A }
829N/A
829N/A public int read(byte[] b, int off, int len) throws IOException {
829N/A int avail = available();
829N/A if (avail <= 0)
829N/A return -1;
829N/A if (len > avail)
829N/A len = avail;
829N/A byte[] buff1 = buffer.array();
829N/A byte[] buff2 = buffer8.array();
829N/A pos += buffer.arrayOffset();
829N/A pos2 += buffer8.arrayOffset();
829N/A if (bigendian) {
829N/A for (int i = 0; i < len; i += (framesize_pc + 1)) {
829N/A System.arraycopy(buff1, pos, b, i, framesize_pc);
829N/A System.arraycopy(buff2, pos2, b, i + framesize_pc, 1);
829N/A pos += framesize_pc;
829N/A pos2 += 1;
829N/A }
829N/A } else {
829N/A for (int i = 0; i < len; i += (framesize_pc + 1)) {
829N/A System.arraycopy(buff2, pos2, b, i, 1);
829N/A System.arraycopy(buff1, pos, b, i + 1, framesize_pc);
829N/A pos += framesize_pc;
829N/A pos2 += 1;
829N/A }
829N/A }
829N/A pos -= buffer.arrayOffset();
829N/A pos2 -= buffer8.arrayOffset();
829N/A return len;
829N/A }
829N/A
829N/A public long skip(long n) throws IOException {
829N/A int avail = available();
829N/A if (avail <= 0)
829N/A return -1;
829N/A if (n > avail)
829N/A n = avail;
829N/A pos += (n / (framesize_pc + 1)) * (framesize_pc);
829N/A pos2 += n / (framesize_pc + 1);
829N/A return super.skip(n);
829N/A }
829N/A
829N/A public int read(byte[] b) throws IOException {
829N/A return read(b, 0, b.length);
829N/A }
829N/A
829N/A public int read() throws IOException {
829N/A byte[] b = new byte[1];
829N/A int ret = read(b, 0, 1);
829N/A if (ret == -1)
829N/A return -1;
829N/A return 0 & 0xFF;
829N/A }
829N/A
829N/A public boolean markSupported() {
829N/A return true;
829N/A }
829N/A
829N/A public int available() throws IOException {
829N/A return (int)buffer.capacity() + (int)buffer8.capacity() - pos - pos2;
829N/A }
829N/A
829N/A public synchronized void mark(int readlimit) {
829N/A markpos = pos;
829N/A markpos2 = pos2;
829N/A }
829N/A
829N/A public synchronized void reset() throws IOException {
829N/A pos = markpos;
829N/A pos2 = markpos2;
829N/A
829N/A }
829N/A }
829N/A
829N/A private float loopStart = -1;
829N/A private float loopLength = -1;
6321N/A private final ModelByteBuffer buffer;
829N/A private ModelByteBuffer buffer8 = null;
829N/A private AudioFormat format = null;
829N/A private float pitchcorrection = 0;
829N/A private float attenuation = 0;
829N/A private int loopType = LOOP_TYPE_OFF;
829N/A
829N/A public ModelByteBufferWavetable(ModelByteBuffer buffer) {
829N/A this.buffer = buffer;
829N/A }
829N/A
829N/A public ModelByteBufferWavetable(ModelByteBuffer buffer,
829N/A float pitchcorrection) {
829N/A this.buffer = buffer;
829N/A this.pitchcorrection = pitchcorrection;
829N/A }
829N/A
829N/A public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format) {
829N/A this.format = format;
829N/A this.buffer = buffer;
829N/A }
829N/A
829N/A public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format,
829N/A float pitchcorrection) {
829N/A this.format = format;
829N/A this.buffer = buffer;
829N/A this.pitchcorrection = pitchcorrection;
829N/A }
829N/A
829N/A public void set8BitExtensionBuffer(ModelByteBuffer buffer) {
829N/A buffer8 = buffer;
829N/A }
829N/A
829N/A public ModelByteBuffer get8BitExtensionBuffer() {
829N/A return buffer8;
829N/A }
829N/A
829N/A public ModelByteBuffer getBuffer() {
829N/A return buffer;
829N/A }
829N/A
829N/A public AudioFormat getFormat() {
829N/A if (format == null) {
829N/A if (buffer == null)
829N/A return null;
829N/A InputStream is = buffer.getInputStream();
829N/A AudioFormat format = null;
829N/A try {
829N/A format = AudioSystem.getAudioFileFormat(is).getFormat();
829N/A } catch (Exception e) {
829N/A //e.printStackTrace();
829N/A }
829N/A try {
829N/A is.close();
829N/A } catch (IOException e) {
829N/A //e.printStackTrace();
829N/A }
829N/A return format;
829N/A }
829N/A return format;
829N/A }
829N/A
829N/A public AudioFloatInputStream openStream() {
829N/A if (buffer == null)
829N/A return null;
829N/A if (format == null) {
829N/A InputStream is = buffer.getInputStream();
829N/A AudioInputStream ais = null;
829N/A try {
829N/A ais = AudioSystem.getAudioInputStream(is);
829N/A } catch (Exception e) {
829N/A //e.printStackTrace();
829N/A return null;
829N/A }
829N/A return AudioFloatInputStream.getInputStream(ais);
829N/A }
829N/A if (buffer.array() == null) {
829N/A return AudioFloatInputStream.getInputStream(new AudioInputStream(
2713N/A buffer.getInputStream(), format,
2713N/A buffer.capacity() / format.getFrameSize()));
829N/A }
829N/A if (buffer8 != null) {
829N/A if (format.getEncoding().equals(Encoding.PCM_SIGNED)
829N/A || format.getEncoding().equals(Encoding.PCM_UNSIGNED)) {
829N/A InputStream is = new Buffer8PlusInputStream();
829N/A AudioFormat format2 = new AudioFormat(
829N/A format.getEncoding(),
829N/A format.getSampleRate(),
829N/A format.getSampleSizeInBits() + 8,
829N/A format.getChannels(),
829N/A format.getFrameSize() + (1 * format.getChannels()),
829N/A format.getFrameRate(),
829N/A format.isBigEndian());
829N/A
829N/A AudioInputStream ais = new AudioInputStream(is, format2,
829N/A buffer.capacity() / format.getFrameSize());
829N/A return AudioFloatInputStream.getInputStream(ais);
829N/A }
829N/A }
829N/A return AudioFloatInputStream.getInputStream(format, buffer.array(),
829N/A (int)buffer.arrayOffset(), (int)buffer.capacity());
829N/A }
829N/A
829N/A public int getChannels() {
829N/A return getFormat().getChannels();
829N/A }
829N/A
829N/A public ModelOscillatorStream open(float samplerate) {
829N/A // ModelWavetableOscillator doesn't support ModelOscillatorStream
829N/A return null;
829N/A }
829N/A
829N/A // attenuation is in cB
829N/A public float getAttenuation() {
829N/A return attenuation;
829N/A }
829N/A // attenuation is in cB
829N/A public void setAttenuation(float attenuation) {
829N/A this.attenuation = attenuation;
829N/A }
829N/A
829N/A public float getLoopLength() {
829N/A return loopLength;
829N/A }
829N/A
829N/A public void setLoopLength(float loopLength) {
829N/A this.loopLength = loopLength;
829N/A }
829N/A
829N/A public float getLoopStart() {
829N/A return loopStart;
829N/A }
829N/A
829N/A public void setLoopStart(float loopStart) {
829N/A this.loopStart = loopStart;
829N/A }
829N/A
829N/A public void setLoopType(int loopType) {
829N/A this.loopType = loopType;
829N/A }
829N/A
829N/A public int getLoopType() {
829N/A return loopType;
829N/A }
829N/A
829N/A public float getPitchcorrection() {
829N/A return pitchcorrection;
829N/A }
829N/A
829N/A public void setPitchcorrection(float pitchcorrection) {
829N/A this.pitchcorrection = pitchcorrection;
829N/A }
829N/A}