|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
package com.sun.media.sound; |
|
|
|
import java.io.IOException; |
|
import java.io.InputStream; |
|
import javax.sound.sampled.AudioFormat; |
|
import javax.sound.sampled.AudioInputStream; |
|
import javax.sound.sampled.AudioSystem; |
|
import javax.sound.sampled.AudioFormat.Encoding; |
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
public final class ModelByteBufferWavetable implements ModelWavetable { |
|
|
|
private class Buffer8PlusInputStream extends InputStream { |
|
|
|
private final boolean bigendian; |
|
private final int framesize_pc; |
|
int pos = 0; |
|
int pos2 = 0; |
|
int markpos = 0; |
|
int markpos2 = 0; |
|
|
|
Buffer8PlusInputStream() { |
|
framesize_pc = format.getFrameSize() / format.getChannels(); |
|
bigendian = format.isBigEndian(); |
|
} |
|
|
|
public int read(byte[] b, int off, int len) throws IOException { |
|
int avail = available(); |
|
if (avail <= 0) |
|
return -1; |
|
if (len > avail) |
|
len = avail; |
|
byte[] buff1 = buffer.array(); |
|
byte[] buff2 = buffer8.array(); |
|
pos += buffer.arrayOffset(); |
|
pos2 += buffer8.arrayOffset(); |
|
if (bigendian) { |
|
for (int i = 0; i < len; i += (framesize_pc + 1)) { |
|
System.arraycopy(buff1, pos, b, i, framesize_pc); |
|
System.arraycopy(buff2, pos2, b, i + framesize_pc, 1); |
|
pos += framesize_pc; |
|
pos2 += 1; |
|
} |
|
} else { |
|
for (int i = 0; i < len; i += (framesize_pc + 1)) { |
|
System.arraycopy(buff2, pos2, b, i, 1); |
|
System.arraycopy(buff1, pos, b, i + 1, framesize_pc); |
|
pos += framesize_pc; |
|
pos2 += 1; |
|
} |
|
} |
|
pos -= buffer.arrayOffset(); |
|
pos2 -= buffer8.arrayOffset(); |
|
return len; |
|
} |
|
|
|
public long skip(long n) throws IOException { |
|
int avail = available(); |
|
if (avail <= 0) |
|
return -1; |
|
if (n > avail) |
|
n = avail; |
|
pos += (n / (framesize_pc + 1)) * (framesize_pc); |
|
pos2 += n / (framesize_pc + 1); |
|
return super.skip(n); |
|
} |
|
|
|
public int read(byte[] b) throws IOException { |
|
return read(b, 0, b.length); |
|
} |
|
|
|
public int read() throws IOException { |
|
byte[] b = new byte[1]; |
|
int ret = read(b, 0, 1); |
|
if (ret == -1) |
|
return -1; |
|
return 0 & 0xFF; |
|
} |
|
|
|
public boolean markSupported() { |
|
return true; |
|
} |
|
|
|
public int available() throws IOException { |
|
return (int)buffer.capacity() + (int)buffer8.capacity() - pos - pos2; |
|
} |
|
|
|
public synchronized void mark(int readlimit) { |
|
markpos = pos; |
|
markpos2 = pos2; |
|
} |
|
|
|
public synchronized void reset() throws IOException { |
|
pos = markpos; |
|
pos2 = markpos2; |
|
|
|
} |
|
} |
|
|
|
private float loopStart = -1; |
|
private float loopLength = -1; |
|
private final ModelByteBuffer buffer; |
|
private ModelByteBuffer buffer8 = null; |
|
private AudioFormat format = null; |
|
private float pitchcorrection = 0; |
|
private float attenuation = 0; |
|
private int loopType = LOOP_TYPE_OFF; |
|
|
|
public ModelByteBufferWavetable(ModelByteBuffer buffer) { |
|
this.buffer = buffer; |
|
} |
|
|
|
public ModelByteBufferWavetable(ModelByteBuffer buffer, |
|
float pitchcorrection) { |
|
this.buffer = buffer; |
|
this.pitchcorrection = pitchcorrection; |
|
} |
|
|
|
public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format) { |
|
this.format = format; |
|
this.buffer = buffer; |
|
} |
|
|
|
public ModelByteBufferWavetable(ModelByteBuffer buffer, AudioFormat format, |
|
float pitchcorrection) { |
|
this.format = format; |
|
this.buffer = buffer; |
|
this.pitchcorrection = pitchcorrection; |
|
} |
|
|
|
public void set8BitExtensionBuffer(ModelByteBuffer buffer) { |
|
buffer8 = buffer; |
|
} |
|
|
|
public ModelByteBuffer get8BitExtensionBuffer() { |
|
return buffer8; |
|
} |
|
|
|
public ModelByteBuffer getBuffer() { |
|
return buffer; |
|
} |
|
|
|
public AudioFormat getFormat() { |
|
if (format == null) { |
|
if (buffer == null) |
|
return null; |
|
InputStream is = buffer.getInputStream(); |
|
AudioFormat format = null; |
|
try { |
|
format = AudioSystem.getAudioFileFormat(is).getFormat(); |
|
} catch (Exception e) { |
|
//e.printStackTrace(); |
|
} |
|
try { |
|
is.close(); |
|
} catch (IOException e) { |
|
//e.printStackTrace(); |
|
} |
|
return format; |
|
} |
|
return format; |
|
} |
|
|
|
public AudioFloatInputStream openStream() { |
|
if (buffer == null) |
|
return null; |
|
if (format == null) { |
|
InputStream is = buffer.getInputStream(); |
|
AudioInputStream ais = null; |
|
try { |
|
ais = AudioSystem.getAudioInputStream(is); |
|
} catch (Exception e) { |
|
|
|
return null; |
|
} |
|
return AudioFloatInputStream.getInputStream(ais); |
|
} |
|
if (buffer.array() == null) { |
|
return AudioFloatInputStream.getInputStream(new AudioInputStream( |
|
buffer.getInputStream(), format, |
|
buffer.capacity() / format.getFrameSize())); |
|
} |
|
if (buffer8 != null) { |
|
if (format.getEncoding().equals(Encoding.PCM_SIGNED) |
|
|| format.getEncoding().equals(Encoding.PCM_UNSIGNED)) { |
|
InputStream is = new Buffer8PlusInputStream(); |
|
AudioFormat format2 = new AudioFormat( |
|
format.getEncoding(), |
|
format.getSampleRate(), |
|
format.getSampleSizeInBits() + 8, |
|
format.getChannels(), |
|
format.getFrameSize() + (1 * format.getChannels()), |
|
format.getFrameRate(), |
|
format.isBigEndian()); |
|
|
|
AudioInputStream ais = new AudioInputStream(is, format2, |
|
buffer.capacity() / format.getFrameSize()); |
|
return AudioFloatInputStream.getInputStream(ais); |
|
} |
|
} |
|
return AudioFloatInputStream.getInputStream(format, buffer.array(), |
|
(int)buffer.arrayOffset(), (int)buffer.capacity()); |
|
} |
|
|
|
public int getChannels() { |
|
return getFormat().getChannels(); |
|
} |
|
|
|
public ModelOscillatorStream open(float samplerate) { |
|
|
|
return null; |
|
} |
|
|
|
|
|
public float getAttenuation() { |
|
return attenuation; |
|
} |
|
|
|
public void setAttenuation(float attenuation) { |
|
this.attenuation = attenuation; |
|
} |
|
|
|
public float getLoopLength() { |
|
return loopLength; |
|
} |
|
|
|
public void setLoopLength(float loopLength) { |
|
this.loopLength = loopLength; |
|
} |
|
|
|
public float getLoopStart() { |
|
return loopStart; |
|
} |
|
|
|
public void setLoopStart(float loopStart) { |
|
this.loopStart = loopStart; |
|
} |
|
|
|
public void setLoopType(int loopType) { |
|
this.loopType = loopType; |
|
} |
|
|
|
public int getLoopType() { |
|
return loopType; |
|
} |
|
|
|
public float getPitchcorrection() { |
|
return pitchcorrection; |
|
} |
|
|
|
public void setPitchcorrection(float pitchcorrection) { |
|
this.pitchcorrection = pitchcorrection; |
|
} |
|
} |