Desktop Runtime

This commit is contained in:
PeytonPlayz595 2024-09-08 08:21:36 -07:00
parent 97f389ae46
commit 9ec5c931a6
243 changed files with 58229 additions and 23278 deletions

View File

@ -5,6 +5,11 @@
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Minecraft Client/libraries/natives"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/teavm/java">
<attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="Minecraft Client/libraries/natives"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="module" value="true"/>
@ -12,7 +17,14 @@
</classpathentry>
<classpathentry kind="lib" path="jars/teavm-jso-0.6.1.jar"/>
<classpathentry kind="lib" path="jars/teavm-jso-apis-0.6.1.jar"/>
<classpathentry kind="lib" path="jars/jzlib-1.1.3.jar"/>
<classpathentry kind="lib" path="jars/teavm-interop-0.6.1.jar"/>
<classpathentry kind="lib" path="jars/jzlib-1.1.3.jar"/>
<classpathentry kind="lib" path="jars/lwjgl.jar">
<attributes>
<attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="jars/natives"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="jars/lwjgl_util.jar"/>
<classpathentry kind="lib" path="jars/Java-WebSocket-1.5.1-with-dependencies.jar"/>
<classpathentry kind="output" path="output"/>
</classpath>

View File

@ -18,7 +18,7 @@
<link>
<name>libraries</name>
<type>2</type>
<locationURI>$%7BPARENT-1-PROJECT_LOC%7D/libraries</locationURI>
<locationURI>$%7BPARENT-1-PROJECT_LOC%7D/jars</locationURI>
</link>
</linkedResources>
<filteredResources>

View File

@ -17,7 +17,8 @@ apply plugin: 'eclipse'
sourceSets {
main {
java {
srcDir 'src/'
srcDir 'src/main/java'
srcDir 'src/teavm/java'
}
}
}

19
debugRuntime.launch Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/Minecraft Client_1"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="net.PeytonPlayz585.Client"/>
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="Minecraft Client"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="Minecraft Client"/>
</launchConfiguration>

Binary file not shown.

BIN
jars/lwjgl.jar Normal file

Binary file not shown.

BIN
jars/lwjgl_util.jar Normal file

Binary file not shown.

BIN
jars/natives/OpenAL32.dll Normal file

Binary file not shown.

BIN
jars/natives/OpenAL64.dll Normal file

Binary file not shown.

Binary file not shown.

BIN
jars/natives/liblwjgl.so Normal file

Binary file not shown.

BIN
jars/natives/liblwjgl64.so Normal file

Binary file not shown.

BIN
jars/natives/libopenal.so Normal file

Binary file not shown.

BIN
jars/natives/libopenal64.so Normal file

Binary file not shown.

BIN
jars/natives/lwjgl.dll Normal file

Binary file not shown.

BIN
jars/natives/lwjgl64.dll Normal file

Binary file not shown.

BIN
jars/natives/openal.dylib Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,586 @@
package de.cuina.fireandfuel;
/*
* CodecJLayerMP3 - an ICodec interface for Paulscode Sound System
* Copyright (C) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see http://www.gnu.org/licenses/lgpl.txt
*/
import java.io.BufferedInputStream;
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.Decoder;
import javazoom.jl.decoder.Header;
import javazoom.jl.decoder.Obuffer;
import javazoom.mp3spi.DecodedMpegAudioInputStream;
import paulscode.sound.ICodec;
import paulscode.sound.SoundBuffer;
import paulscode.sound.SoundSystemConfig;
import paulscode.sound.SoundSystemLogger;
/**
* The CodecJLayer class provides an ICodec interface to the external JLayer
* library.
*
* <b><br>
* <br>
* This software is based on or using the JLayer and mp3spi library from
* http://www.javazoom.net/javalayer/javalayer.html and Tritonus library from
* http://www.tritonus.org/.
*
* JLayer, mp3spi and Tritonus library are released under the conditions of
* GNU Library General Public License version 2 or (at your option)
* any later version of the License.
* </b><br>
*/
public class CodecJLayerMP3 implements ICodec
{
/**
* Used to return a current value from one of the synchronized
* boolean-interface methods.
*/
private static final boolean GET = false;
/**
* Used to set the value in one of the synchronized boolean-interface
* methods.
*/
private static final boolean SET = true;
/**
* Used when a parameter for one of the synchronized boolean-interface
* methods is not applicable.
*/
private static final boolean XXX = false;
/**
* True if there is no more data to read in.
*/
private boolean endOfStream = false;
/**
* True if the stream has finished initializing.
*/
private boolean initialized = false;
private Decoder decoder;
private Bitstream bitstream;
private DMAISObuffer buffer;
private Header mainHeader;
/**
* Audio format to use when playing back the wave data.
*/
private AudioFormat myAudioFormat = null;
/**
* Input stream to use for reading in pcm data.
*/
private DecodedMpegAudioInputStream myAudioInputStream = null;
/**
* Processes status messages, warnings, and error messages.
*/
private SoundSystemLogger logger;
public CodecJLayerMP3()
{
logger = SoundSystemConfig.getLogger();
}
@Override
public void reverseByteOrder(boolean b)
{
}
@Override
public boolean initialize(URL url)
{
initialized(SET, false);
cleanup();
if(url == null)
{
errorMessage("url null in method 'initialize'");
cleanup();
return false;
}
try
{
bitstream = new Bitstream(new BufferedInputStream(url.openStream()));
decoder = new Decoder();
mainHeader = bitstream.readFrame();
buffer = new DMAISObuffer(2);
decoder.setOutputBuffer(buffer);
int channels;
if(mainHeader.mode() < 3)
channels = 2;
else channels = 1;
bitstream.closeFrame();
bitstream.close();
myAudioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED,
mainHeader.frequency(), 16, channels, channels * 2, mainHeader.frequency(),
false);
AudioFormat mpegAudioFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, -1.0f,
16, channels, channels * 2, -1.0f, false);
myAudioInputStream = new DecodedMpegAudioInputStream(myAudioFormat,
new AudioInputStream(new BufferedInputStream(url.openStream()),
mpegAudioFormat, -1));
myAudioInputStream.skip((int)(myAudioInputStream.getFormat().getFrameRate() * 0.018f) * myAudioInputStream.getFormat().getFrameSize());
} catch (Exception e)
{
errorMessage("Unable to set up input streams in method " + "'initialize'");
printStackTrace(e);
cleanup();
return false;
}
if(myAudioInputStream == null)
{
errorMessage("Unable to set up audio input stream in method " + "'initialize'");
cleanup();
return false;
}
endOfStream(SET, false);
initialized(SET, true);
return true;
}
@Override
public boolean initialized()
{
return initialized(GET, XXX);
}
@Override
public SoundBuffer read()
{
if(myAudioInputStream == null)
{
endOfStream(SET, true);
return null;
}
// Get the format for the audio data:
AudioFormat audioFormat = myAudioInputStream.getFormat();
// Check to make sure there is an audio format:
if(audioFormat == null)
{
errorMessage("Audio Format null in method 'read'");
endOfStream(SET, true);
return null;
}
// Variables used when reading from the audio input stream:
int bytesRead = 0, cnt = 0;
// Allocate memory for the audio data:
byte[] streamBuffer = new byte[SoundSystemConfig.getStreamingBufferSize()];
try
{
// Read until buffer is full or end of stream is reached:
while((!endOfStream(GET, XXX)) && (bytesRead < streamBuffer.length))
{
myAudioInputStream.execute();
if((cnt = myAudioInputStream.read(streamBuffer, bytesRead, streamBuffer.length
- bytesRead)) < 0)
{
endOfStream(SET, true);
break;
}
// keep track of how many bytes were read:
bytesRead += cnt;
}
} catch (IOException ioe)
{
/*
* errorMessage( "Exception thrown while reading from the " +
* "AudioInputStream (location #3)." ); printStackTrace( e ); return
* null;
*/// TODO: Figure out why this exceptions is being thrown at end of
// MP3 files!
endOfStream(SET, true);
return null;
} catch (ArrayIndexOutOfBoundsException e)
{
//this exception is thrown at the end of the mp3's
endOfStream(SET, true);
return null;
}
// Return null if no data was read:
if(bytesRead <= 0)
{
endOfStream(SET, true);
return null;
}
// Insert the converted data into a ByteBuffer:
// byte[] data = convertAudioBytes(streamBuffer,
// audioFormat.getSampleSizeInBits() == 16);
// Wrap the data into a SoundBuffer:
SoundBuffer buffer = new SoundBuffer(streamBuffer, audioFormat);
// Return the result:
return buffer;
}
@Override
public SoundBuffer readAll()
{
// Check to make sure there is an audio format:
if(myAudioFormat == null)
{
errorMessage("Audio Format null in method 'readAll'");
return null;
}
// Array to contain the audio data:
byte[] fullBuffer = null;
// Determine how much data will be read in:
int fileSize = myAudioFormat.getChannels() * (int) myAudioInputStream.getFrameLength()
* myAudioFormat.getSampleSizeInBits() / 8;
if(fileSize > 0)
{
// Allocate memory for the audio data:
fullBuffer = new byte[myAudioFormat.getChannels()
* (int) myAudioInputStream.getFrameLength()
* myAudioFormat.getSampleSizeInBits() / 8];
int read = 0, total = 0;
try
{
// Read until the end of the stream is reached:
while((read = myAudioInputStream.read(fullBuffer, total, fullBuffer.length - total)) != -1
&& total < fullBuffer.length)
{
total += read;
}
} catch (IOException e)
{
errorMessage("Exception thrown while reading from the "
+ "AudioInputStream (location #1).");
printStackTrace(e);
return null;
}
} else
{
// Total file size unknown.
// Variables used when reading from the audio input stream:
int totalBytes = 0, bytesRead = 0, cnt = 0;
byte[] smallBuffer = null;
// Allocate memory for a chunk of data:
smallBuffer = new byte[SoundSystemConfig.getFileChunkSize()];
// Read until end of file or maximum file size is reached:
while((!endOfStream(GET, XXX)) && (totalBytes < SoundSystemConfig.getMaxFileSize()))
{
bytesRead = 0;
cnt = 0;
try
{
// Read until small buffer is filled or end of file reached:
while(bytesRead < smallBuffer.length)
{
myAudioInputStream.execute();
if((cnt = myAudioInputStream.read(smallBuffer, bytesRead,
smallBuffer.length - bytesRead)) < 0)
{
endOfStream(SET, true);
break;
}
bytesRead += cnt;
}
} catch (IOException e)
{
errorMessage("Exception thrown while reading from the "
+ "AudioInputStream (location #2).");
printStackTrace(e);
return null;
}
// Reverse byte order if necessary:
// if( reverseBytes )
// reverseBytes( smallBuffer, 0, bytesRead );
// Keep track of the total number of bytes read:
totalBytes += bytesRead;
// Append the small buffer to the full buffer:
fullBuffer = appendByteArrays(fullBuffer, smallBuffer, bytesRead);
}
}
// Insert the converted data into a ByteBuffer
// byte[] data = convertAudioBytes( fullBuffer,
// myAudioFormat.getSampleSizeInBits() == 16 );
// Wrap the data into an SoundBuffer:
SoundBuffer soundBuffer = new SoundBuffer(fullBuffer, myAudioFormat);
// Close the audio input stream
try
{
myAudioInputStream.close();
} catch (IOException e)
{
}
// Return the result:
return soundBuffer;
}
@Override
public boolean endOfStream()
{
return endOfStream(GET, XXX);
}
@Override
public void cleanup()
{
if(myAudioInputStream != null)
try
{
myAudioInputStream.close();
} catch (Exception e)
{
}
}
@Override
public AudioFormat getAudioFormat()
{
return myAudioFormat;
}
/**
* Internal method for synchronizing access to the boolean 'initialized'.
*
* @param action
* GET or SET.
* @param value
* New value if action == SET, or XXX if action == GET.
* @return True if steam is initialized.
*/
private synchronized boolean initialized(boolean action, boolean value)
{
if(action == SET)
initialized = value;
return initialized;
}
/**
* Internal method for synchronizing access to the boolean 'endOfStream'.
*
* @param action
* GET or SET.
* @param value
* New value if action == SET, or XXX if action == GET.
* @return True if end of stream was reached.
*/
private synchronized boolean endOfStream(boolean action, boolean value)
{
if(action == SET)
endOfStream = value;
return endOfStream;
}
/**
* Reverse-orders all bytes contained in the specified array.
*
* @param buffer
* Array containing audio data.
*/
public static void reverseBytes(byte[] buffer)
{
reverseBytes(buffer, 0, buffer.length);
}
/**
* Reverse-orders the specified range of bytes contained in the specified
* array.
*
* @param buffer
* Array containing audio data.
* @param offset
* Array index to begin.
* @param size
* number of bytes to reverse-order.
*/
public static void reverseBytes(byte[] buffer, int offset, int size)
{
byte b;
for(int i = offset; i < (offset + size); i += 2)
{
b = buffer[i];
buffer[i] = buffer[i + 1];
buffer[i + 1] = b;
}
}
/**
* Prints an error message.
*
* @param message
* Message to print.
*/
private void errorMessage(String message)
{
logger.errorMessage("CodecJLayerMP3", message, 0);
}
/**
* Prints an exception's error message followed by the stack trace.
*
* @param e
* Exception containing the information to print.
*/
private void printStackTrace(Exception e)
{
logger.printStackTrace(e, 1);
}
/**
* Creates a new array with the second array appended to the end of the
* first array.
*
* @param arrayOne
* The first array.
* @param arrayTwo
* The second array.
* @param length
* How many bytes to append from the second array.
* @return Byte array containing information from both arrays.
*/
private static byte[] appendByteArrays(byte[] arrayOne, byte[] arrayTwo, int length)
{
byte[] newArray;
if(arrayOne == null && arrayTwo == null)
{
// no data, just return
return null;
} else if(arrayOne == null)
{
// create the new array, same length as arrayTwo:
newArray = new byte[length];
// fill the new array with the contents of arrayTwo:
System.arraycopy(arrayTwo, 0, newArray, 0, length);
arrayTwo = null;
} else if(arrayTwo == null)
{
// create the new array, same length as arrayOne:
newArray = new byte[arrayOne.length];
// fill the new array with the contents of arrayOne:
System.arraycopy(arrayOne, 0, newArray, 0, arrayOne.length);
arrayOne = null;
} else
{
// create the new array large enough to hold both arrays:
newArray = new byte[arrayOne.length + length];
System.arraycopy(arrayOne, 0, newArray, 0, arrayOne.length);
// fill the new array with the contents of both arrays:
System.arraycopy(arrayTwo, 0, newArray, arrayOne.length, length);
arrayOne = null;
arrayTwo = null;
}
return newArray;
}
private static class DMAISObuffer extends Obuffer
{
private int m_nChannels;
private byte[] m_abBuffer;
private int[] m_anBufferPointers;
private boolean m_bIsBigEndian;
public DMAISObuffer(int nChannels)
{
m_nChannels = nChannels;
m_abBuffer = new byte[OBUFFERSIZE * nChannels];
m_anBufferPointers = new int[nChannels];
reset();
}
public void append(int nChannel, short sValue)
{
byte bFirstByte;
byte bSecondByte;
if(m_bIsBigEndian)
{
bFirstByte = (byte) ((sValue >>> 8) & 0xFF);
bSecondByte = (byte) (sValue & 0xFF);
} else
// little endian
{
bFirstByte = (byte) (sValue & 0xFF);
bSecondByte = (byte) ((sValue >>> 8) & 0xFF);
}
m_abBuffer[m_anBufferPointers[nChannel]] = bFirstByte;
m_abBuffer[m_anBufferPointers[nChannel] + 1] = bSecondByte;
m_anBufferPointers[nChannel] += m_nChannels * 2;
}
public void set_stop_flag()
{
}
public void close()
{
}
public void write_buffer(int nValue)
{
}
public void clear_buffer()
{
}
public void reset()
{
for(int i = 0; i < m_nChannels; i++)
{
/*
* Points to byte location, implicitly assuming 16 bit samples.
*/
m_anBufferPointers[i] = i * 2;
}
}
}
}

View File

@ -0,0 +1,224 @@
/*
* 11/19/04 1.0 moved to LGPL.
*
* 12/12/99 0.0.7 Implementation stores single bits
* as ints for better performance. mdm@techie.com.
*
* 02/28/99 0.0 Java Conversion by E.B, javalayer@javazoom.net
*
* Adapted from the public c code by Jeff Tsay.
*
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Implementation of Bit Reservoir for Layer III.
* <p>
* The implementation stores single bits as a word in the buffer. If
* a bit is set, the corresponding word in the buffer will be non-zero.
* If a bit is clear, the corresponding word is zero. Although this
* may seem wasteful, this can be a factor of two quicker than
* packing 8 bits to a byte and extracting.
* <p>
*/
// REVIEW: there is no range checking, so buffer underflow or overflow
// can silently occur.
final class BitReserve
{
/**
* Size of the internal buffer to store the reserved bits.
* Must be a power of 2. And x8, as each bit is stored as a single
* entry.
*/
private static final int BUFSIZE = 4096*8;
/**
* Mask that can be used to quickly implement the
* modulus operation on BUFSIZE.
*/
private static final int BUFSIZE_MASK = BUFSIZE-1;
private int offset, totbit, buf_byte_idx;
private final int[] buf = new int[BUFSIZE];
private int buf_bit_idx;
BitReserve()
{
offset = 0;
totbit = 0;
buf_byte_idx = 0;
}
/**
* Return totbit Field.
*/
public int hsstell()
{
return(totbit);
}
/**
* Read a number bits from the bit stream.
* @param N the number of
*/
public int hgetbits(int N)
{
totbit += N;
int val = 0;
int pos = buf_byte_idx;
if (pos+N < BUFSIZE)
{
while (N-- > 0)
{
val <<= 1;
val |= ((buf[pos++]!=0) ? 1 : 0);
}
}
else
{
while (N-- > 0)
{
val <<= 1;
val |= ((buf[pos]!=0) ? 1 : 0);
pos = (pos+1) & BUFSIZE_MASK;
}
}
buf_byte_idx = pos;
return val;
}
/**
* Read 1 bit from the bit stream.
*/
/*
public int hget1bit_old()
{
int val;
totbit++;
if (buf_bit_idx == 0)
{
buf_bit_idx = 8;
buf_byte_idx++;
}
// BUFSIZE = 4096 = 2^12, so
// buf_byte_idx%BUFSIZE == buf_byte_idx & 0xfff
val = buf[buf_byte_idx & BUFSIZE_MASK] & putmask[buf_bit_idx];
buf_bit_idx--;
val = val >>> buf_bit_idx;
return val;
}
*/
/**
* Returns next bit from reserve.
*
* @return 0 if next bit is reset, or 1 if next bit is set.
*/
public int hget1bit()
{
totbit++;
int val = buf[buf_byte_idx];
buf_byte_idx = (buf_byte_idx+1) & BUFSIZE_MASK;
return val;
}
/**
* Retrieves bits from the reserve.
*/
/*
public int readBits(int[] out, int len)
{
if (buf_bit_idx == 0)
{
buf_bit_idx = 8;
buf_byte_idx++;
current = buf[buf_byte_idx & BUFSIZE_MASK];
}
// save total number of bits returned
len = buf_bit_idx;
buf_bit_idx = 0;
int b = current;
int count = len-1;
while (count >= 0)
{
out[count--] = (b & 0x1);
b >>>= 1;
}
totbit += len;
return len;
}
*/
/**
* Write 8 bits into the bit stream.
*/
public void hputbuf(int val)
{
int ofs = offset;
buf[ofs++] = val & 0x80;
buf[ofs++] = val & 0x40;
buf[ofs++] = val & 0x20;
buf[ofs++] = val & 0x10;
buf[ofs++] = val & 0x08;
buf[ofs++] = val & 0x04;
buf[ofs++] = val & 0x02;
buf[ofs++] = val & 0x01;
if (ofs==BUFSIZE)
offset = 0;
else
offset = ofs;
}
/**
* Rewind N bits in Stream.
*/
public void rewindNbits(int N)
{
totbit -= N;
buf_byte_idx -= N;
if (buf_byte_idx<0)
buf_byte_idx += BUFSIZE;
}
/**
* Rewind N bytes in Stream.
*/
public void rewindNbytes(int N)
{
int bits = (N << 3);
totbit -= bits;
buf_byte_idx -= bits;
if (buf_byte_idx<0)
buf_byte_idx += BUFSIZE;
}
}

View File

@ -0,0 +1,659 @@
/*
* 11/19/04 1.0 moved to LGPL.
*
* 11/17/04 Uncomplete frames discarded. E.B, javalayer@javazoom.net
*
* 12/05/03 ID3v2 tag returned. E.B, javalayer@javazoom.net
*
* 12/12/99 Based on Ibitstream. Exceptions thrown on errors,
* Temporary removed seek functionality. mdm@techie.com
*
* 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net
*
* 04/14/97 : Added function prototypes for new syncing and seeking
* mechanisms. Also made this file portable. Changes made by Jeff Tsay
*
* @(#) ibitstream.h 1.5, last edit: 6/15/94 16:55:34
* @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
* @(#) Berlin University of Technology
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
/**
* The <code>Bistream</code> class is responsible for parsing
* an MPEG audio bitstream.
*
* <b>REVIEW:</b> much of the parsing currently occurs in the
* various decoders. This should be moved into this class and associated
* inner classes.
*/
public final class Bitstream implements BitstreamErrors
{
/**
* Synchronization control constant for the initial
* synchronization to the start of a frame.
*/
static byte INITIAL_SYNC = 0;
/**
* Synchronization control constant for non-initial frame
* synchronizations.
*/
static byte STRICT_SYNC = 1;
// max. 1730 bytes per frame: 144 * 384kbit/s / 32000 Hz + 2 Bytes CRC
/**
* Maximum size of the frame buffer.
*/
private static final int BUFFER_INT_SIZE = 433;
/**
* The frame buffer that holds the data for the current frame.
*/
private final int[] framebuffer = new int[BUFFER_INT_SIZE];
/**
* Number of valid bytes in the frame buffer.
*/
private int framesize;
/**
* The bytes read from the stream.
*/
private byte[] frame_bytes = new byte[BUFFER_INT_SIZE*4];
/**
* Index into <code>framebuffer</code> where the next bits are
* retrieved.
*/
private int wordpointer;
/**
* Number (0-31, from MSB to LSB) of next bit for get_bits()
*/
private int bitindex;
/**
* The current specified syncword
*/
private int syncword;
/**
* Audio header position in stream.
*/
private int header_pos = 0;
/**
*
*/
private boolean single_ch_mode;
//private int current_frame_number;
//private int last_frame_number;
private final int bitmask[] = {0, // dummy
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,
0x0001FFFF };
private final PushbackInputStream source;
private final Header header = new Header();
private final byte syncbuf[] = new byte[4];
private Crc16[] crc = new Crc16[1];
private byte[] rawid3v2 = null;
private boolean firstframe = true;
/**
* Construct a IBitstream that reads data from a
* given InputStream.
*
* @param in The InputStream to read from.
*/
public Bitstream(InputStream in)
{
if (in==null) throw new NullPointerException("in");
in = new BufferedInputStream(in);
loadID3v2(in);
firstframe = true;
//source = new PushbackInputStream(in, 1024);
source = new PushbackInputStream(in, BUFFER_INT_SIZE*4);
closeFrame();
//current_frame_number = -1;
//last_frame_number = -1;
}
/**
* Return position of the first audio header.
* @return size of ID3v2 tag frames.
*/
public int header_pos()
{
return header_pos;
}
/**
* Load ID3v2 frames.
* @param in MP3 InputStream.
* @author JavaZOOM
*/
private void loadID3v2(InputStream in)
{
int size = -1;
try
{
// Read ID3v2 header (10 bytes).
in.mark(10);
size = readID3v2Header(in);
header_pos = size;
}
catch (IOException e)
{}
finally
{
try
{
// Unread ID3v2 header (10 bytes).
in.reset();
}
catch (IOException e)
{}
}
// Load ID3v2 tags.
try
{
if (size > 0)
{
rawid3v2 = new byte[size];
in.read(rawid3v2,0,rawid3v2.length);
}
}
catch (IOException e)
{}
}
/**
* Parse ID3v2 tag header to find out size of ID3v2 frames.
* @param in MP3 InputStream
* @return size of ID3v2 frames + header
* @throws IOException
* @author JavaZOOM
*/
private int readID3v2Header(InputStream in) throws IOException
{
byte[] id3header = new byte[4];
int size = -10;
in.read(id3header,0,3);
// Look for ID3v2
if ( (id3header[0]=='I') && (id3header[1]=='D') && (id3header[2]=='3'))
{
in.read(id3header,0,3);
int majorVersion = id3header[0];
int revision = id3header[1];
in.read(id3header,0,4);
size = (int) (id3header[0] << 21) + (id3header[1] << 14) + (id3header[2] << 7) + (id3header[3]);
}
return (size+10);
}
/**
* Return raw ID3v2 frames + header.
* @return ID3v2 InputStream or null if ID3v2 frames are not available.
*/
public InputStream getRawID3v2()
{
if (rawid3v2 == null) return null;
else
{
ByteArrayInputStream bain = new ByteArrayInputStream(rawid3v2);
return bain;
}
}
/**
* Close the Bitstream.
* @throws BitstreamException
*/
public void close() throws BitstreamException
{
try
{
source.close();
}
catch (IOException ex)
{
throw newBitstreamException(STREAM_ERROR, ex);
}
}
/**
* Reads and parses the next frame from the input source.
*
* @return the Header describing details of the frame read,
* or null if the end of the stream has been reached.
*/
public Header readFrame() throws BitstreamException
{
Header result = null;
try
{
result = readNextFrame();
// E.B, Parse VBR (if any) first frame.
if (firstframe == true)
{
result.parseVBR(frame_bytes);
firstframe = false;
}
}
catch (BitstreamException ex)
{
if ((ex.getErrorCode()==INVALIDFRAME))
{
// Try to skip this frame.
//System.out.println("INVALIDFRAME");
try
{
closeFrame();
result = readNextFrame();
}
catch (BitstreamException e)
{
if ((e.getErrorCode()!=STREAM_EOF))
{
// wrap original exception so stack trace is maintained.
throw newBitstreamException(e.getErrorCode(), e);
}
}
}
else if ((ex.getErrorCode()!=STREAM_EOF))
{
// wrap original exception so stack trace is maintained.
throw newBitstreamException(ex.getErrorCode(), ex);
}
}
return result;
}
/**
* Read next MP3 frame.
*
* @return MP3 frame header.
* @throws BitstreamException
*/
private Header readNextFrame() throws BitstreamException
{
if (framesize == -1)
{
nextFrame();
}
return header;
}
/**
* Read next MP3 frame.
*
* @throws BitstreamException
*/
private void nextFrame() throws BitstreamException
{
// entire frame is read by the header class.
header.read_header(this, crc);
}
/**
* Unreads the bytes read from the frame.
*
* @throws BitstreamException
*/
// REVIEW: add new error codes for this.
public void unreadFrame() throws BitstreamException
{
if (wordpointer==-1 && bitindex==-1 && (framesize>0))
{
try
{
source.unread(frame_bytes, 0, framesize);
}
catch (IOException ex)
{
throw newBitstreamException(STREAM_ERROR);
}
}
}
/**
* Close MP3 frame.
*/
public void closeFrame()
{
framesize = -1;
wordpointer = -1;
bitindex = -1;
}
/**
* Determines if the next 4 bytes of the stream represent a
* frame header.
*/
public boolean isSyncCurrentPosition(int syncmode) throws BitstreamException
{
int read = readBytes(syncbuf, 0, 4);
int headerstring = ((syncbuf[0] << 24) & 0xFF000000) | ((syncbuf[1] << 16) & 0x00FF0000) | ((syncbuf[2] << 8) & 0x0000FF00) | ((syncbuf[3] << 0) & 0x000000FF);
try
{
source.unread(syncbuf, 0, read);
}
catch (IOException ex)
{
}
boolean sync = false;
switch (read)
{
case 0:
sync = true;
break;
case 4:
sync = isSyncMark(headerstring, syncmode, syncword);
break;
}
return sync;
}
// REVIEW: this class should provide inner classes to
// parse the frame contents. Eventually, readBits will
// be removed.
public int readBits(int n)
{
return get_bits(n);
}
public int readCheckedBits(int n)
{
// REVIEW: implement CRC check.
return get_bits(n);
}
protected BitstreamException newBitstreamException(int errorcode)
{
return new BitstreamException(errorcode, null);
}
protected BitstreamException newBitstreamException(int errorcode, Throwable throwable)
{
return new BitstreamException(errorcode, throwable);
}
/**
* Get next 32 bits from bitstream.
* They are stored in the headerstring.
* syncmod allows Synchro flag ID
* The returned value is False at the end of stream.
*/
int syncHeader(byte syncmode) throws BitstreamException
{
boolean sync;
int headerstring;
// read additional 2 bytes
int bytesRead = readBytes(syncbuf, 0, 3);
if (bytesRead!=3) throw newBitstreamException(STREAM_EOF, null);
headerstring = ((syncbuf[0] << 16) & 0x00FF0000) | ((syncbuf[1] << 8) & 0x0000FF00) | ((syncbuf[2] << 0) & 0x000000FF);
do
{
headerstring <<= 8;
if (readBytes(syncbuf, 3, 1)!=1)
throw newBitstreamException(STREAM_EOF, null);
headerstring |= (syncbuf[3] & 0x000000FF);
sync = isSyncMark(headerstring, syncmode, syncword);
}
while (!sync);
//current_frame_number++;
//if (last_frame_number < current_frame_number) last_frame_number = current_frame_number;
return headerstring;
}
public boolean isSyncMark(int headerstring, int syncmode, int word)
{
boolean sync = false;
if (syncmode == INITIAL_SYNC)
{
//sync = ((headerstring & 0xFFF00000) == 0xFFF00000);
sync = ((headerstring & 0xFFE00000) == 0xFFE00000); // SZD: MPEG 2.5
}
else
{
sync = ((headerstring & 0xFFF80C00) == word) &&
(((headerstring & 0x000000C0) == 0x000000C0) == single_ch_mode);
}
// filter out invalid sample rate
if (sync)
sync = (((headerstring >>> 10) & 3)!=3);
// filter out invalid layer
if (sync)
sync = (((headerstring >>> 17) & 3)!=0);
// filter out invalid version
if (sync)
sync = (((headerstring >>> 19) & 3)!=1);
return sync;
}
/**
* Reads the data for the next frame. The frame is not parsed
* until parse frame is called.
*/
int read_frame_data(int bytesize) throws BitstreamException
{
int numread = 0;
numread = readFully(frame_bytes, 0, bytesize);
framesize = bytesize;
wordpointer = -1;
bitindex = -1;
return numread;
}
/**
* Parses the data previously read with read_frame_data().
*/
void parse_frame() throws BitstreamException
{
// Convert Bytes read to int
int b=0;
byte[] byteread = frame_bytes;
int bytesize = framesize;
// Check ID3v1 TAG (True only if last frame).
//for (int t=0;t<(byteread.length)-2;t++)
//{
// if ((byteread[t]=='T') && (byteread[t+1]=='A') && (byteread[t+2]=='G'))
// {
// System.out.println("ID3v1 detected at offset "+t);
// throw newBitstreamException(INVALIDFRAME, null);
// }
//}
for (int k=0;k<bytesize;k=k+4)
{
int convert = 0;
byte b0 = 0;
byte b1 = 0;
byte b2 = 0;
byte b3 = 0;
b0 = byteread[k];
if (k+1<bytesize) b1 = byteread[k+1];
if (k+2<bytesize) b2 = byteread[k+2];
if (k+3<bytesize) b3 = byteread[k+3];
framebuffer[b++] = ((b0 << 24) &0xFF000000) | ((b1 << 16) & 0x00FF0000) | ((b2 << 8) & 0x0000FF00) | (b3 & 0x000000FF);
}
wordpointer = 0;
bitindex = 0;
}
/**
* Read bits from buffer into the lower bits of an unsigned int.
* The LSB contains the latest read bit of the stream.
* (1 <= number_of_bits <= 16)
*/
public int get_bits(int number_of_bits)
{
int returnvalue = 0;
int sum = bitindex + number_of_bits;
// E.B
// There is a problem here, wordpointer could be -1 ?!
if (wordpointer < 0) wordpointer = 0;
// E.B : End.
if (sum <= 32)
{
// all bits contained in *wordpointer
returnvalue = (framebuffer[wordpointer] >>> (32 - sum)) & bitmask[number_of_bits];
// returnvalue = (wordpointer[0] >> (32 - sum)) & bitmask[number_of_bits];
if ((bitindex += number_of_bits) == 32)
{
bitindex = 0;
wordpointer++; // added by me!
}
return returnvalue;
}
// E.B : Check that ?
//((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0];
//wordpointer++; // Added by me!
//((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0];
int Right = (framebuffer[wordpointer] & 0x0000FFFF);
wordpointer++;
int Left = (framebuffer[wordpointer] & 0xFFFF0000);
returnvalue = ((Right << 16) & 0xFFFF0000) | ((Left >>> 16)& 0x0000FFFF);
returnvalue >>>= 48 - sum; // returnvalue >>= 16 - (number_of_bits - (32 - bitindex))
returnvalue &= bitmask[number_of_bits];
bitindex = sum - 32;
return returnvalue;
}
/**
* Set the word we want to sync the header to.
* In Big-Endian byte order
*/
void set_syncword(int syncword0)
{
syncword = syncword0 & 0xFFFFFF3F;
single_ch_mode = ((syncword0 & 0x000000C0) == 0x000000C0);
}
/**
* Reads the exact number of bytes from the source
* input stream into a byte array.
*
* @param b The byte array to read the specified number
* of bytes into.
* @param offs The index in the array where the first byte
* read should be stored.
* @param len the number of bytes to read.
*
* @exception BitstreamException is thrown if the specified
* number of bytes could not be read from the stream.
*/
private int readFully(byte[] b, int offs, int len)
throws BitstreamException
{
int nRead = 0;
try
{
while (len > 0)
{
int bytesread = source.read(b, offs, len);
if (bytesread == -1)
{
while (len-->0)
{
b[offs++] = 0;
}
break;
//throw newBitstreamException(UNEXPECTED_EOF, new EOFException());
}
nRead = nRead + bytesread;
offs += bytesread;
len -= bytesread;
}
}
catch (IOException ex)
{
throw newBitstreamException(STREAM_ERROR, ex);
}
return nRead;
}
/**
* Similar to readFully, but doesn't throw exception when
* EOF is reached.
*/
private int readBytes(byte[] b, int offs, int len)
throws BitstreamException
{
int totalBytesRead = 0;
try
{
while (len > 0)
{
int bytesread = source.read(b, offs, len);
if (bytesread == -1)
{
break;
}
totalBytesRead += bytesread;
offs += bytesread;
len -= bytesread;
}
}
catch (IOException ex)
{
throw newBitstreamException(STREAM_ERROR, ex);
}
return totalBytesRead;
}
}

View File

@ -0,0 +1,72 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 11/17/04 INVALIDFRAME code added. javalayer@javazoom.net
* 12/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* This interface describes all error codes that can be thrown
* in <code>BistreamException</code>s.
*
* @see BitstreamException
*
* @author MDM 12/12/99
* @since 0.0.6
*/
public interface BitstreamErrors extends JavaLayerErrors
{
/**
* An undetermined error occurred.
*/
public static final int UNKNOWN_ERROR = BITSTREAM_ERROR + 0;
/**
* The header describes an unknown sample rate.
*/
public static final int UNKNOWN_SAMPLE_RATE = BITSTREAM_ERROR + 1;
/**
* A problem occurred reading from the stream.
*/
public static final int STREAM_ERROR = BITSTREAM_ERROR + 2;
/**
* The end of the stream was reached prematurely.
*/
public static final int UNEXPECTED_EOF = BITSTREAM_ERROR + 3;
/**
* The end of the stream was reached.
*/
public static final int STREAM_EOF = BITSTREAM_ERROR + 4;
/**
* Frame data are missing.
*/
public static final int INVALIDFRAME = BITSTREAM_ERROR + 5;
/**
*
*/
public static final int BITSTREAM_LAST = 0x1ff;
}

View File

@ -0,0 +1,71 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 12/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Instances of <code>BitstreamException</code> are thrown
* when operations on a <code>Bitstream</code> fail.
* <p>
* The exception provides details of the exception condition
* in two ways:
* <ol><li>
* as an error-code describing the nature of the error
* </li><br></br><li>
* as the <code>Throwable</code> instance, if any, that was thrown
* indicating that an exceptional condition has occurred.
* </li></ol></p>
*
* @since 0.0.6
* @author MDM 12/12/99
*/
public class BitstreamException extends JavaLayerException
implements BitstreamErrors
{
private int errorcode = UNKNOWN_ERROR;
public BitstreamException(String msg, Throwable t)
{
super(msg, t);
}
public BitstreamException(int errorcode, Throwable t)
{
this(getErrorString(errorcode), t);
this.errorcode = errorcode;
}
public int getErrorCode()
{
return errorcode;
}
public static String getErrorString(int errorcode)
{
// REVIEW: use resource bundle to map error codes
// to locale-sensitive strings.
return "Bitstream errorcode "+Integer.toHexString(errorcode);
}
}

View File

@ -0,0 +1,57 @@
/*
* 11/19/04 1.0 moved to LGPL.
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Work in progress.
*/
public interface Control
{
/**
* Starts playback of the media presented by this control.
*/
public void start();
/**
* Stops playback of the media presented by this control.
*/
public void stop();
public boolean isPlaying();
public void pause();
public boolean isRandomAccess();
/**
* Retrieves the current position.
*/
public double getPosition();
/**
*
*/
public void setPosition(double d);
}

View File

@ -0,0 +1,70 @@
/*
* 11/19/04 : 1.0 moved to LGPL.
*
* 02/12/99 : Java Conversion by E.B , javalayer@javazoom.net
*
* @(#) crc.h 1.5, last edit: 6/15/94 16:55:32
* @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
* @(#) Berlin University of Technology
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* 16-Bit CRC checksum
*/
public final class Crc16
{
private static short polynomial=(short)0x8005;
private short crc;
/**
* Dummy Constructor
*/
public Crc16()
{
crc = (short) 0xFFFF;
}
/**
* Feed a bitstring to the CRC calculation (0 < length <= 32).
*/
public void add_bits (int bitstring, int length)
{
int bitmask = 1 << (length - 1);
do
if (((crc & 0x8000) == 0) ^ ((bitstring & bitmask) == 0 ))
{
crc <<= 1;
crc ^= polynomial;
}
else
crc <<= 1;
while ((bitmask >>>= 1) != 0);
}
/**
* Return the calculated checksum.
* Erase it for next calls to add_bits().
*/
public short checksum()
{
short sum = crc;
crc = (short) 0xFFFF;
return sum;
}
}

View File

@ -0,0 +1,356 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 01/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* The <code>Decoder</code> class encapsulates the details of
* decoding an MPEG audio frame.
*
* @author MDM
* @version 0.0.7 12/12/99
* @since 0.0.5
*/
public class Decoder implements DecoderErrors
{
private static final Params DEFAULT_PARAMS = new Params();
/**
* The Bitstream from which the MPEG audio frames are read.
*/
//private Bitstream stream;
/**
* The Obuffer instance that will receive the decoded
* PCM samples.
*/
private Obuffer output;
/**
* Synthesis filter for the left channel.
*/
private SynthesisFilter filter1;
/**
* Synthesis filter for the right channel.
*/
private SynthesisFilter filter2;
/**
* The decoder used to decode layer III frames.
*/
private LayerIIIDecoder l3decoder;
private LayerIIDecoder l2decoder;
private LayerIDecoder l1decoder;
private int outputFrequency;
private int outputChannels;
private Equalizer equalizer = new Equalizer();
private Params params;
private boolean initialized;
/**
* Creates a new <code>Decoder</code> instance with default
* parameters.
*/
public Decoder()
{
this(null);
}
/**
* Creates a new <code>Decoder</code> instance with default
* parameters.
*
* @param params The <code>Params</code> instance that describes
* the customizable aspects of the decoder.
*/
public Decoder(Params params0)
{
if (params0==null)
params0 = DEFAULT_PARAMS;
params = params0;
Equalizer eq = params.getInitialEqualizerSettings();
if (eq!=null)
{
equalizer.setFrom(eq);
}
}
public static Params getDefaultParams() throws CloneNotSupportedException
{
return (Params)DEFAULT_PARAMS.clone();
}
public void setEqualizer(Equalizer eq)
{
if (eq==null)
eq = Equalizer.PASS_THRU_EQ;
equalizer.setFrom(eq);
float[] factors = equalizer.getBandFactors();
if (filter1!=null)
filter1.setEQ(factors);
if (filter2!=null)
filter2.setEQ(factors);
}
/**
* Decodes one frame from an MPEG audio bitstream.
*
* @param header The header describing the frame to decode.
* @param bitstream The bitstream that provides the bits for te body of the frame.
*
* @return A SampleBuffer containing the decoded samples.
*/
public Obuffer decodeFrame(Header header, Bitstream stream)
throws DecoderException
{
if (!initialized)
{
initialize(header);
}
int layer = header.layer();
output.clear_buffer();
FrameDecoder decoder = retrieveDecoder(header, stream, layer);
decoder.decodeFrame();
output.write_buffer(1);
return output;
}
/**
* Changes the output buffer. This will take effect the next time
* decodeFrame() is called.
*/
public void setOutputBuffer(Obuffer out)
{
output = out;
}
/**
* Retrieves the sample frequency of the PCM samples output
* by this decoder. This typically corresponds to the sample
* rate encoded in the MPEG audio stream.
*
* @param the sample rate (in Hz) of the samples written to the
* output buffer when decoding.
*/
public int getOutputFrequency()
{
return outputFrequency;
}
/**
* Retrieves the number of channels of PCM samples output by
* this decoder. This usually corresponds to the number of
* channels in the MPEG audio stream, although it may differ.
*
* @return The number of output channels in the decoded samples: 1
* for mono, or 2 for stereo.
*
*/
public int getOutputChannels()
{
return outputChannels;
}
/**
* Retrieves the maximum number of samples that will be written to
* the output buffer when one frame is decoded. This can be used to
* help calculate the size of other buffers whose size is based upon
* the number of samples written to the output buffer. NB: this is
* an upper bound and fewer samples may actually be written, depending
* upon the sample rate and number of channels.
*
* @return The maximum number of samples that are written to the
* output buffer when decoding a single frame of MPEG audio.
*/
public int getOutputBlockSize()
{
return Obuffer.OBUFFERSIZE;
}
protected DecoderException newDecoderException(int errorcode)
{
return new DecoderException(errorcode, null);
}
protected DecoderException newDecoderException(int errorcode, Throwable throwable)
{
return new DecoderException(errorcode, throwable);
}
protected FrameDecoder retrieveDecoder(Header header, Bitstream stream, int layer)
throws DecoderException
{
FrameDecoder decoder = null;
// REVIEW: allow channel output selection type
// (LEFT, RIGHT, BOTH, DOWNMIX)
switch (layer)
{
case 3:
if (l3decoder==null)
{
l3decoder = new LayerIIIDecoder(stream,
header, filter1, filter2,
output, OutputChannels.BOTH_CHANNELS);
}
decoder = l3decoder;
break;
case 2:
if (l2decoder==null)
{
l2decoder = new LayerIIDecoder();
l2decoder.create(stream,
header, filter1, filter2,
output, OutputChannels.BOTH_CHANNELS);
}
decoder = l2decoder;
break;
case 1:
if (l1decoder==null)
{
l1decoder = new LayerIDecoder();
l1decoder.create(stream,
header, filter1, filter2,
output, OutputChannels.BOTH_CHANNELS);
}
decoder = l1decoder;
break;
}
if (decoder==null)
{
throw newDecoderException(UNSUPPORTED_LAYER, null);
}
return decoder;
}
private void initialize(Header header)
throws DecoderException
{
// REVIEW: allow customizable scale factor
float scalefactor = 32700.0f;
int mode = header.mode();
int layer = header.layer();
int channels = mode==Header.SINGLE_CHANNEL ? 1 : 2;
// set up output buffer if not set up by client.
if (output==null)
output = new SampleBuffer(header.frequency(), channels);
float[] factors = equalizer.getBandFactors();
filter1 = new SynthesisFilter(0, scalefactor, factors);
// REVIEW: allow mono output for stereo
if (channels==2)
filter2 = new SynthesisFilter(1, scalefactor, factors);
outputChannels = channels;
outputFrequency = header.frequency();
initialized = true;
}
/**
* The <code>Params</code> class presents the customizable
* aspects of the decoder.
* <p>
* Instances of this class are not thread safe.
*/
public static class Params implements Cloneable
{
private OutputChannels outputChannels = OutputChannels.BOTH;
private Equalizer equalizer = new Equalizer();
public Params()
{
}
public Object clone() throws CloneNotSupportedException {
try
{
return super.clone();
}
catch (CloneNotSupportedException ex)
{
throw new InternalError(this+": "+ex);
}
}
public void setOutputChannels(OutputChannels out)
{
if (out==null)
throw new NullPointerException("out");
outputChannels = out;
}
public OutputChannels getOutputChannels()
{
return outputChannels;
}
/**
* Retrieves the equalizer settings that the decoder's equalizer
* will be initialized from.
* <p>
* The <code>Equalizer</code> instance returned
* cannot be changed in real time to affect the
* decoder output as it is used only to initialize the decoders
* EQ settings. To affect the decoder's output in realtime,
* use the Equalizer returned from the getEqualizer() method on
* the decoder.
*
* @return The <code>Equalizer</code> used to initialize the
* EQ settings of the decoder.
*/
public Equalizer getInitialEqualizerSettings()
{
return equalizer;
}
};
}

View File

@ -0,0 +1,45 @@
/*
* 09/26/08 throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org)
* 11/19/04 1.0 moved to LGPL.
* 01/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* This interface provides constants describing the error
* codes used by the Decoder to indicate errors.
*
* @author MDM
*/
public interface DecoderErrors extends JavaLayerErrors
{
public static final int UNKNOWN_ERROR = DECODER_ERROR + 0;
/**
* Layer not supported by the decoder.
*/
public static final int UNSUPPORTED_LAYER = DECODER_ERROR + 1;
/**
* Illegal allocation in subband layer. Indicates a corrupt stream.
*/
public static final int ILLEGAL_SUBBAND_ALLOCATION = DECODER_ERROR + 2;
}

View File

@ -0,0 +1,59 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 01/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* The <code>DecoderException</code> represents the class of
* errors that can occur when decoding MPEG audio.
*
* @author MDM
*/
public class DecoderException extends JavaLayerException
implements DecoderErrors
{
private int errorcode = UNKNOWN_ERROR;
public DecoderException(String msg, Throwable t)
{
super(msg, t);
}
public DecoderException(int errorcode, Throwable t)
{
this(getErrorString(errorcode), t);
this.errorcode = errorcode;
}
public int getErrorCode()
{
return errorcode;
}
public static String getErrorString(int errorcode)
{
// REVIEW: use resource file to map error codes
// to locale-sensitive strings.
return "Decoder errorcode "+Integer.toHexString(errorcode);
}
}

View File

@ -0,0 +1,227 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 12/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* The <code>Equalizer</code> class can be used to specify
* equalization settings for the MPEG audio decoder.
* <p>
* The equalizer consists of 32 band-pass filters.
* Each band of the equalizer can take on a fractional value between
* -1.0 and +1.0.
* At -1.0, the input signal is attenuated by 6dB, at +1.0 the signal is
* amplified by 6dB.
*
* @see Decoder
*
* @author MDM
*/
public final class Equalizer
{
/**
* Equalizer setting to denote that a given band will not be
* present in the output signal.
*/
public static final float BAND_NOT_PRESENT = Float.NEGATIVE_INFINITY;
public static final Equalizer PASS_THRU_EQ = new Equalizer();
private static final int BANDS = 32;
private final float[] settings = new float[BANDS];
/**
* Creates a new <code>Equalizer</code> instance.
*/
public Equalizer()
{
}
// private Equalizer(float b1, float b2, float b3, float b4, float b5,
// float b6, float b7, float b8, float b9, float b10, float b11,
// float b12, float b13, float b14, float b15, float b16,
// float b17, float b18, float b19, float b20);
public Equalizer(float[] settings)
{
setFrom(settings);
}
public Equalizer(EQFunction eq)
{
setFrom(eq);
}
public void setFrom(float[] eq)
{
reset();
int max = (eq.length > BANDS) ? BANDS : eq.length;
for (int i=0; i<max; i++)
{
settings[i] = limit(eq[i]);
}
}
public void setFrom(EQFunction eq)
{
reset();
int max = BANDS;
for (int i=0; i<max; i++)
{
settings[i] = limit(eq.getBand(i));
}
}
/**
* Sets the bands of this equalizer to the value the bands of
* another equalizer. Bands that are not present in both equalizers are ignored.
*/
public void setFrom(Equalizer eq)
{
if (eq!=this)
{
setFrom(eq.settings);
}
}
/**
* Sets all bands to 0.0
*/
public void reset()
{
for (int i=0; i<BANDS; i++)
{
settings[i] = 0.0f;
}
}
/**
* Retrieves the number of bands present in this equalizer.
*/
public int getBandCount()
{
return settings.length;
}
public float setBand(int band, float neweq)
{
float eq = 0.0f;
if ((band>=0) && (band<BANDS))
{
eq = settings[band];
settings[band] = limit(neweq);
}
return eq;
}
/**
* Retrieves the EQ setting for a given band.
*/
public float getBand(int band)
{
float eq = 0.0f;
if ((band>=0) && (band<BANDS))
{
eq = settings[band];
}
return eq;
}
private float limit(float eq)
{
if (eq==BAND_NOT_PRESENT)
return eq;
if (eq > 1.0f)
return 1.0f;
if (eq < -1.0f)
return -1.0f;
return eq;
}
/**
* Retrieves an array of floats whose values represent a
* scaling factor that can be applied to linear samples
* in each band to provide the equalization represented by
* this instance.
*
* @return an array of factors that can be applied to the
* subbands.
*/
float[] getBandFactors()
{
float[] factors = new float[BANDS];
for (int i=0, maxCount=BANDS; i<maxCount; i++)
{
factors[i] = getBandFactor(settings[i]);
}
return factors;
}
/**
* Converts an equalizer band setting to a sample factor.
* The factor is determined by the function f = 2^n where
* n is the equalizer band setting in the range [-1.0,1.0].
*
*/
float getBandFactor(float eq)
{
if (eq==BAND_NOT_PRESENT)
return 0.0f;
float f = (float)Math.pow(2.0, eq);
return f;
}
public abstract static class EQFunction
{
/**
* Returns the setting of a band in the equalizer.
*
* @param band The index of the band to retrieve the setting
* for.
*
* @return the setting of the specified band. This is a value between
* -1 and +1.
*/
public float getBand(int band)
{
return 0.0f;
}
}
}

View File

@ -0,0 +1,39 @@
/*
* 09/26/08 throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org)
* 11/19/04 1.0 moved to LGPL.
* 12/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Implementations of FrameDecoder are responsible for decoding
* an MPEG audio frame.
*
*/
//REVIEW: the interface currently is too thin. There should be
// methods to specify the output buffer, the synthesis filters and
// possibly other objects used by the decoder.
public interface FrameDecoder
{
/**
* Decodes one frame of MPEG audio.
*/
public void decodeFrame() throws DecoderException;
}

View File

@ -0,0 +1,778 @@
/*
* 11/19/04 : 1.0 moved to LGPL.
* VBRI header support added, E.B javalayer@javazoom.net
*
* 12/04/03 : VBR (XING) header support added, E.B javalayer@javazoom.net
*
* 02/13/99 : Java Conversion by JavaZOOM , E.B javalayer@javazoom.net
*
* Declarations for MPEG header class
* A few layer III, MPEG-2 LSF, and seeking modifications made by Jeff Tsay.
* Last modified : 04/19/97
*
* @(#) header.h 1.7, last edit: 6/15/94 16:55:33
* @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
* @(#) Berlin University of Technology
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Class for extracting information from a frame header.
*/
public final class Header
{
public static final int[][] frequencies =
{{22050, 24000, 16000, 1},
{44100, 48000, 32000, 1},
{11025, 12000, 8000, 1}}; // SZD: MPEG25
/**
* Constant for MPEG-2 LSF version
*/
public static final int MPEG2_LSF = 0;
public static final int MPEG25_LSF = 2; // SZD
/**
* Constant for MPEG-1 version
*/
public static final int MPEG1 = 1;
public static final int STEREO = 0;
public static final int JOINT_STEREO = 1;
public static final int DUAL_CHANNEL = 2;
public static final int SINGLE_CHANNEL = 3;
public static final int FOURTYFOUR_POINT_ONE = 0;
public static final int FOURTYEIGHT=1;
public static final int THIRTYTWO=2;
private int h_layer, h_protection_bit, h_bitrate_index,
h_padding_bit, h_mode_extension;
private int h_version;
private int h_mode;
private int h_sample_frequency;
private int h_number_of_subbands, h_intensity_stereo_bound;
private boolean h_copyright, h_original;
// VBR support added by E.B
private double[] h_vbr_time_per_frame = {-1, 384, 1152, 1152};
private boolean h_vbr;
private int h_vbr_frames;
private int h_vbr_scale;
private int h_vbr_bytes;
private byte[] h_vbr_toc;
private byte syncmode = Bitstream.INITIAL_SYNC;
private Crc16 crc;
public short checksum;
public int framesize;
public int nSlots;
private int _headerstring = -1; // E.B
Header()
{
}
public String toString()
{
StringBuilder buffer = new StringBuilder(200);
buffer.append("Layer ");
buffer.append(layer_string());
buffer.append(" frame ");
buffer.append(mode_string());
buffer.append(' ');
buffer.append(version_string());
if (!checksums())
buffer.append(" no");
buffer.append(" checksums");
buffer.append(' ');
buffer.append(sample_frequency_string());
buffer.append(',');
buffer.append(' ');
buffer.append(bitrate_string());
String s = buffer.toString();
return s;
}
/**
* Read a 32-bit header from the bitstream.
*/
void read_header(Bitstream stream, Crc16[] crcp) throws BitstreamException
{
int headerstring;
int channel_bitrate;
boolean sync = false;
do
{
headerstring = stream.syncHeader(syncmode);
_headerstring = headerstring; // E.B
if (syncmode == Bitstream.INITIAL_SYNC)
{
h_version = ((headerstring >>> 19) & 1);
if (((headerstring >>> 20) & 1) == 0) // SZD: MPEG2.5 detection
if (h_version == MPEG2_LSF)
h_version = MPEG25_LSF;
else
throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);
if ((h_sample_frequency = ((headerstring >>> 10) & 3)) == 3)
{
throw stream.newBitstreamException(Bitstream.UNKNOWN_ERROR);
}
}
h_layer = 4 - (headerstring >>> 17) & 3;
h_protection_bit = (headerstring >>> 16) & 1;
h_bitrate_index = (headerstring >>> 12) & 0xF;
h_padding_bit = (headerstring >>> 9) & 1;
h_mode = ((headerstring >>> 6) & 3);
h_mode_extension = (headerstring >>> 4) & 3;
if (h_mode == JOINT_STEREO)
h_intensity_stereo_bound = (h_mode_extension << 2) + 4;
else
h_intensity_stereo_bound = 0; // should never be used
if (((headerstring >>> 3) & 1) == 1)
h_copyright = true;
if (((headerstring >>> 2) & 1) == 1)
h_original = true;
// calculate number of subbands:
if (h_layer == 1)
h_number_of_subbands = 32;
else
{
channel_bitrate = h_bitrate_index;
// calculate bitrate per channel:
if (h_mode != SINGLE_CHANNEL)
if (channel_bitrate == 4)
channel_bitrate = 1;
else
channel_bitrate -= 4;
if ((channel_bitrate == 1) || (channel_bitrate == 2))
if (h_sample_frequency == THIRTYTWO)
h_number_of_subbands = 12;
else
h_number_of_subbands = 8;
else if ((h_sample_frequency == FOURTYEIGHT) || ((channel_bitrate >= 3) && (channel_bitrate <= 5)))
h_number_of_subbands = 27;
else
h_number_of_subbands = 30;
}
if (h_intensity_stereo_bound > h_number_of_subbands)
h_intensity_stereo_bound = h_number_of_subbands;
// calculate framesize and nSlots
calculate_framesize();
// read framedata:
int framesizeloaded = stream.read_frame_data(framesize);
if ((framesize >=0) && (framesizeloaded != framesize))
{
// Data loaded does not match to expected framesize,
// it might be an ID3v1 TAG. (Fix 11/17/04).
throw stream.newBitstreamException(Bitstream.INVALIDFRAME);
}
if (stream.isSyncCurrentPosition(syncmode))
{
if (syncmode == Bitstream.INITIAL_SYNC)
{
syncmode = Bitstream.STRICT_SYNC;
stream.set_syncword(headerstring & 0xFFF80CC0);
}
sync = true;
}
else
{
stream.unreadFrame();
}
}
while (!sync);
stream.parse_frame();
if (h_protection_bit == 0)
{
// frame contains a crc checksum
checksum = (short) stream.get_bits(16);
if (crc == null)
crc = new Crc16();
crc.add_bits(headerstring, 16);
crcp[0] = crc;
}
else
crcp[0] = null;
if (h_sample_frequency == FOURTYFOUR_POINT_ONE)
{
/*
if (offset == null)
{
int max = max_number_of_frames(stream);
offset = new int[max];
for(int i=0; i<max; i++) offset[i] = 0;
}
// E.B : Investigate more
int cf = stream.current_frame();
int lf = stream.last_frame();
if ((cf > 0) && (cf == lf))
{
offset[cf] = offset[cf-1] + h_padding_bit;
}
else
{
offset[0] = h_padding_bit;
}
*/
}
}
/**
* Parse frame to extract optional VBR frame.
*
* @param firstframe
* @author E.B (javalayer@javazoom.net)
*/
void parseVBR(byte[] firstframe) throws BitstreamException
{
// Trying Xing header.
String xing = "Xing";
byte tmp[] = new byte[4];
int offset = 0;
// Compute "Xing" offset depending on MPEG version and channels.
if (h_version == MPEG1)
{
if (h_mode == SINGLE_CHANNEL) offset=21-4;
else offset=36-4;
}
else
{
if (h_mode == SINGLE_CHANNEL) offset=13-4;
else offset = 21-4;
}
try
{
System.arraycopy(firstframe, offset, tmp, 0, 4);
// Is "Xing" ?
if (xing.equals(new String(tmp)))
{
//Yes.
h_vbr = true;
h_vbr_frames = -1;
h_vbr_bytes = -1;
h_vbr_scale = -1;
h_vbr_toc = new byte[100];
int length = 4;
// Read flags.
byte flags[] = new byte[4];
System.arraycopy(firstframe, offset + length, flags, 0, flags.length);
length += flags.length;
// Read number of frames (if available).
if ((flags[3] & (byte) (1 << 0)) != 0)
{
System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;
length += 4;
}
// Read size (if available).
if ((flags[3] & (byte) (1 << 1)) != 0)
{
System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;
length += 4;
}
// Read TOC (if available).
if ((flags[3] & (byte) (1 << 2)) != 0)
{
System.arraycopy(firstframe, offset + length, h_vbr_toc, 0, h_vbr_toc.length);
length += h_vbr_toc.length;
}
// Read scale (if available).
if ((flags[3] & (byte) (1 << 3)) != 0)
{
System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
h_vbr_scale = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;
length += 4;
}
//System.out.println("VBR:"+xing+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes);
}
}
catch (ArrayIndexOutOfBoundsException e)
{
throw new BitstreamException("XingVBRHeader Corrupted",e);
}
// Trying VBRI header.
String vbri = "VBRI";
offset = 36-4;
try
{
System.arraycopy(firstframe, offset, tmp, 0, 4);
// Is "VBRI" ?
if (vbri.equals(new String(tmp)))
{
//Yes.
h_vbr = true;
h_vbr_frames = -1;
h_vbr_bytes = -1;
h_vbr_scale = -1;
h_vbr_toc = new byte[100];
// Bytes.
int length = 4 + 6;
System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
h_vbr_bytes = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;
length += 4;
// Frames.
System.arraycopy(firstframe, offset + length, tmp, 0, tmp.length);
h_vbr_frames = (tmp[0] << 24)&0xFF000000 | (tmp[1] << 16)&0x00FF0000 | (tmp[2] << 8)&0x0000FF00 | tmp[3]&0x000000FF;
length += 4;
//System.out.println("VBR:"+vbri+" Frames:"+ h_vbr_frames +" Size:"+h_vbr_bytes);
// TOC
// TODO
}
}
catch (ArrayIndexOutOfBoundsException e)
{
throw new BitstreamException("VBRIVBRHeader Corrupted",e);
}
}
// Functions to query header contents:
/**
* Returns version.
*/
public int version() { return h_version; }
/**
* Returns Layer ID.
*/
public int layer() { return h_layer; }
/**
* Returns bitrate index.
*/
public int bitrate_index() { return h_bitrate_index; }
/**
* Returns Sample Frequency.
*/
public int sample_frequency() { return h_sample_frequency; }
/**
* Returns Frequency.
*/
public int frequency() {return frequencies[h_version][h_sample_frequency];}
/**
* Returns Mode.
*/
public int mode() { return h_mode; }
/**
* Returns Protection bit.
*/
public boolean checksums()
{
if (h_protection_bit == 0) return true;
else return false;
}
/**
* Returns Copyright.
*/
public boolean copyright() { return h_copyright; }
/**
* Returns Original.
*/
public boolean original() { return h_original; }
/**
* Return VBR.
*
* @return true if VBR header is found
*/
public boolean vbr() { return h_vbr; }
/**
* Return VBR scale.
*
* @return scale of -1 if not available
*/
public int vbr_scale() { return h_vbr_scale; }
/**
* Return VBR TOC.
*
* @return vbr toc ot null if not available
*/
public byte[] vbr_toc() { return h_vbr_toc; }
/**
* Returns Checksum flag.
* Compares computed checksum with stream checksum.
*/
public boolean checksum_ok () { return (checksum == crc.checksum()); }
// Seeking and layer III stuff
/**
* Returns Layer III Padding bit.
*/
public boolean padding()
{
if (h_padding_bit == 0) return false;
else return true;
}
/**
* Returns Slots.
*/
public int slots() { return nSlots; }
/**
* Returns Mode Extension.
*/
public int mode_extension() { return h_mode_extension; }
// E.B -> private to public
public static final int bitrates[][][] = {
{{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,
112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0},
{0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,
56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0},
{0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,
56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}},
{{0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000,
224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0},
{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,
112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0},
{0 /*free format*/, 32000, 40000, 48000, 56000, 64000, 80000,
96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0}},
// SZD: MPEG2.5
{{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000,
112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0},
{0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,
56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0},
{0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000,
56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}},
};
// E.B -> private to public
/**
* Calculate Frame size.
*
* Calculates framesize in bytes excluding header size.
*/
public int calculate_framesize()
{
if (h_layer == 1)
{
framesize = (12 * bitrates[h_version][0][h_bitrate_index]) /
frequencies[h_version][h_sample_frequency];
if (h_padding_bit != 0 ) framesize++;
framesize <<= 2; // one slot is 4 bytes long
nSlots = 0;
}
else
{
framesize = (144 * bitrates[h_version][h_layer - 1][h_bitrate_index]) /
frequencies[h_version][h_sample_frequency];
if (h_version == MPEG2_LSF || h_version == MPEG25_LSF) framesize >>= 1; // SZD
if (h_padding_bit != 0) framesize++;
// Layer III slots
if (h_layer == 3)
{
if (h_version == MPEG1)
{
nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 17 : 32) // side info size
- ((h_protection_bit!=0) ? 0 : 2) // CRC size
- 4; // header size
}
else
{ // MPEG-2 LSF, SZD: MPEG-2.5 LSF
nSlots = framesize - ((h_mode == SINGLE_CHANNEL) ? 9 : 17) // side info size
- ((h_protection_bit!=0) ? 0 : 2) // CRC size
- 4; // header size
}
}
else
{
nSlots = 0;
}
}
framesize -= 4; // subtract header size
return framesize;
}
/**
* Returns the maximum number of frames in the stream.
*
* @param streamsize
* @return number of frames
*/
public int max_number_of_frames(int streamsize) // E.B
{
if (h_vbr == true) return h_vbr_frames;
else
{
if ((framesize + 4 - h_padding_bit) == 0) return 0;
else return(streamsize / (framesize + 4 - h_padding_bit));
}
}
/**
* Returns the maximum number of frames in the stream.
*
* @param streamsize
* @return number of frames
*/
public int min_number_of_frames(int streamsize) // E.B
{
if (h_vbr == true) return h_vbr_frames;
else
{
if ((framesize + 5 - h_padding_bit) == 0) return 0;
else return(streamsize / (framesize + 5 - h_padding_bit));
}
}
/**
* Returns ms/frame.
*
* @return milliseconds per frame
*/
public float ms_per_frame() // E.B
{
if (h_vbr == true)
{
double tpf = h_vbr_time_per_frame[layer()] / frequency();
if ((h_version == MPEG2_LSF) || (h_version == MPEG25_LSF)) tpf /= 2;
return ((float) (tpf * 1000));
}
else
{
float ms_per_frame_array[][] = {{8.707483f, 8.0f, 12.0f},
{26.12245f, 24.0f, 36.0f},
{26.12245f, 24.0f, 36.0f}};
return(ms_per_frame_array[h_layer-1][h_sample_frequency]);
}
}
/**
* Returns total ms.
*
* @param streamsize
* @return total milliseconds
*/
public float total_ms(int streamsize) // E.B
{
return(max_number_of_frames(streamsize) * ms_per_frame());
}
/**
* Returns synchronized header.
*/
public int getSyncHeader() // E.B
{
return _headerstring;
}
// functions which return header informations as strings:
/**
* Return Layer version.
*/
public String layer_string()
{
switch (h_layer)
{
case 1:
return "I";
case 2:
return "II";
case 3:
return "III";
}
return null;
}
// E.B -> private to public
public static final String bitrate_str[][][] = {
{{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",
"80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s",
"160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s",
"forbidden"},
{"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",
"40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
"96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",
"forbidden"},
{"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",
"40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
"96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",
"forbidden"}},
{{"free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s",
"160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s",
"320 kbit/s", "352 kbit/s", "384 kbit/s", "416 kbit/s", "448 kbit/s",
"forbidden"},
{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",
"80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s",
"192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", "384 kbit/s",
"forbidden"},
{"free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s",
"64 kbit/s", "80 kbit/s" , "96 kbit/s", "112 kbit/s", "128 kbit/s",
"160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s",
"forbidden"}},
// SZD: MPEG2.5
{{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s",
"80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s",
"160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s",
"forbidden"},
{"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",
"40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
"96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",
"forbidden"},
{"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s",
"40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s",
"96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s",
"forbidden"}},
};
/**
* Return Bitrate.
*
* @return bitrate in bps
*/
public String bitrate_string()
{
if (h_vbr == true)
{
return Integer.toString(bitrate()/1000)+" kb/s";
}
else return bitrate_str[h_version][h_layer - 1][h_bitrate_index];
}
/**
* Return Bitrate.
*
* @return bitrate in bps and average bitrate for VBR header
*/
public int bitrate()
{
if (h_vbr == true)
{
return ((int) ((h_vbr_bytes * 8) / (ms_per_frame() * h_vbr_frames)))*1000;
}
else return bitrates[h_version][h_layer - 1][h_bitrate_index];
}
/**
* Return Instant Bitrate.
* Bitrate for VBR is not constant.
*
* @return bitrate in bps
*/
public int bitrate_instant()
{
return bitrates[h_version][h_layer - 1][h_bitrate_index];
}
/**
* Returns Frequency
*
* @return frequency string in kHz
*/
public String sample_frequency_string()
{
switch (h_sample_frequency)
{
case THIRTYTWO:
if (h_version == MPEG1)
return "32 kHz";
else if (h_version == MPEG2_LSF)
return "16 kHz";
else // SZD
return "8 kHz";
case FOURTYFOUR_POINT_ONE:
if (h_version == MPEG1)
return "44.1 kHz";
else if (h_version == MPEG2_LSF)
return "22.05 kHz";
else // SZD
return "11.025 kHz";
case FOURTYEIGHT:
if (h_version == MPEG1)
return "48 kHz";
else if (h_version == MPEG2_LSF)
return "24 kHz";
else // SZD
return "12 kHz";
}
return(null);
}
/**
* Returns Mode.
*/
public String mode_string()
{
switch (h_mode)
{
case STEREO:
return "Stereo";
case JOINT_STEREO:
return "Joint stereo";
case DUAL_CHANNEL:
return "Dual channel";
case SINGLE_CHANNEL:
return "Single channel";
}
return null;
}
/**
* Returns Version.
*
* @return MPEG-1 or MPEG-2 LSF or MPEG-2.5 LSF
*/
public String version_string()
{
switch (h_version)
{
case MPEG1:
return "MPEG-1";
case MPEG2_LSF:
return "MPEG-2 LSF";
case MPEG25_LSF: // SZD
return "MPEG-2.5 LSF";
}
return(null);
}
/**
* Returns the number of subbands in the current frame.
*
* @return number of subbands
*/
public int number_of_subbands() {return h_number_of_subbands;}
/**
* Returns Intensity Stereo.
* (Layer II joint stereo only).
* Returns the number of subbands which are in stereo mode,
* subbands above that limit are in intensity stereo mode.
*
* @return intensity
*/
public int intensity_stereo_bound() {return h_intensity_stereo_bound;}
}

View File

@ -0,0 +1,80 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 12/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
import java.io.IOException;
import java.io.InputStream;
/**
* <i>Work In Progress.</i>
*
* An instance of <code>InputStreamSource</code> implements a
* <code>Source</code> that provides data from an <code>InputStream
* </code>. Seeking functionality is not supported.
*
* @author MDM
*/
public class InputStreamSource implements Source
{
private final InputStream in;
public InputStreamSource(InputStream in)
{
if (in==null)
throw new NullPointerException("in");
this.in = in;
}
public int read(byte[] b, int offs, int len)
throws IOException
{
int read = in.read(b, offs, len);
return read;
}
public boolean willReadBlock()
{
return true;
//boolean block = (in.available()==0);
//return block;
}
public boolean isSeekable()
{
return false;
}
public long tell()
{
return -1;
}
public long seek(long to)
{
return -1;
}
public long length()
{
return -1;
}
}

View File

@ -0,0 +1,31 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 12/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Work in progress.
*
* API usage errors may be handled by throwing an instance of this
* class, as per JMF 2.0.
*/
public class JavaLayerError extends Error
{
}

View File

@ -0,0 +1,40 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 12/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Exception error codes for components of the JavaLayer API.
*/
public interface JavaLayerErrors
{
/**
* The first bitstream error code. See the {@link DecoderErrors DecoderErrors}
* interface for other bitstream error codes.
*/
public static final int BITSTREAM_ERROR = 0x100;
/**
* The first decoder error code. See the {@link DecoderErrors DecoderErrors}
* interface for other decoder error codes.
*/
public static final int DECODER_ERROR = 0x200;
}

View File

@ -0,0 +1,78 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 12/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
import java.io.PrintStream;
/**
* The JavaLayerException is the base class for all API-level
* exceptions thrown by JavaLayer. To facilitate conversion and
* common handling of exceptions from other domains, the class
* can delegate some functionality to a contained Throwable instance.
* <p>
*
* @author MDM
*/
public class JavaLayerException extends Exception
{
private Throwable exception;
public JavaLayerException()
{
}
public JavaLayerException(String msg)
{
super(msg);
}
public JavaLayerException(String msg, Throwable t)
{
super(msg);
exception = t;
}
public Throwable getException()
{
return exception;
}
public void printStackTrace()
{
printStackTrace(System.err);
}
public void printStackTrace(PrintStream ps)
{
if (this.exception==null)
{
super.printStackTrace(ps);
}
else
{
exception.printStackTrace();
}
}
}

View File

@ -0,0 +1,36 @@
/*
* 11/19/04 1.0 moved to LGPL.
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
import java.io.InputStream;
/**
* The <code>JavaLayerHooks</code> class allows developers to change
* the way the JavaLayer library uses Resources.
*/
public interface JavaLayerHook
{
/**
* Retrieves the named resource. This allows resources to be
* obtained without specifying how they are retrieved.
*/
public InputStream getResourceAsStream(String name);
}

View File

@ -0,0 +1,208 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 12/12/99 Initial version. mdm@techie.com
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.lang.reflect.Array;
/**
* The JavaLayerUtils class is not strictly part of the JavaLayer API.
* It serves to provide useful methods and system-wide hooks.
*
* @author MDM
*/
public class JavaLayerUtils
{
private static JavaLayerHook hook = null;
/**
* Deserializes the object contained in the given input stream.
*
* @param in The input stream to deserialize an object from.
* @param cls The expected class of the deserialized object.
*/
public static Object deserialize(InputStream in, Class cls)
throws IOException
{
if (cls==null)
throw new NullPointerException("cls");
Object obj = deserialize(in, cls);
if (!cls.isInstance(obj))
{
throw new InvalidObjectException("type of deserialized instance not of required class.");
}
return obj;
}
/**
* Deserializes an object from the given <code>InputStream</code>.
* The deserialization is delegated to an <code>
* ObjectInputStream</code> instance.
*
* @param in The <code>InputStream</code> to deserialize an object
* from.
*
* @return The object deserialized from the stream.
* @exception IOException is thrown if there was a problem reading
* the underlying stream, or an object could not be deserialized
* from the stream.
*
* @see java.io.ObjectInputStream
*/
public static Object deserialize(InputStream in)
throws IOException
{
if (in==null)
throw new NullPointerException("in");
ObjectInputStream objIn = new ObjectInputStream(in);
Object obj;
try
{
obj = objIn.readObject();
}
catch (ClassNotFoundException ex)
{
throw new InvalidClassException(ex.toString());
}
return obj;
}
/**
* Deserializes an array from a given <code>InputStream</code>.
*
* @param in The <code>InputStream</code> to
* deserialize an object from.
*
* @param elemType The class denoting the type of the array
* elements.
* @param length The expected length of the array, or -1 if
* any length is expected.
*/
public static Object deserializeArray(InputStream in, Class elemType, int length)
throws IOException
{
if (elemType==null)
throw new NullPointerException("elemType");
if (length<-1)
throw new IllegalArgumentException("length");
Object obj = deserialize(in);
Class cls = obj.getClass();
if (!cls.isArray())
throw new InvalidObjectException("object is not an array");
Class arrayElemType = cls.getComponentType();
if (arrayElemType!=elemType)
throw new InvalidObjectException("unexpected array component type");
if (length != -1)
{
int arrayLength = Array.getLength(obj);
if (arrayLength!=length)
throw new InvalidObjectException("array length mismatch");
}
return obj;
}
public static Object deserializeArrayResource(String name, Class elemType, int length)
throws IOException
{
InputStream str = getResourceAsStream(name);
if (str==null)
throw new IOException("unable to load resource '"+name+"'");
Object obj = deserializeArray(str, elemType, length);
return obj;
}
public static void serialize(OutputStream out, Object obj)
throws IOException
{
if (out==null)
throw new NullPointerException("out");
if (obj==null)
throw new NullPointerException("obj");
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(obj);
}
/**
* Sets the system-wide JavaLayer hook.
*/
public static synchronized void setHook(JavaLayerHook hook0)
{
hook = hook0;
}
public static synchronized JavaLayerHook getHook()
{
return hook;
}
/**
* Retrieves an InputStream for a named resource.
*
* @param name The name of the resource. This must be a simple
* name, and not a qualified package name.
*
* @return The InputStream for the named resource, or null if
* the resource has not been found. If a hook has been
* provided, its getResourceAsStream() method is called
* to retrieve the resource.
*/
public static synchronized InputStream getResourceAsStream(String name)
{
InputStream is = null;
if (hook!=null)
{
is = hook.getResourceAsStream(name);
}
else
{
Class cls = JavaLayerUtils.class;
is = cls.getResourceAsStream(name);
}
return is;
}
}

View File

@ -0,0 +1,448 @@
/*
* 09/26/08 throw exception on subbband alloc error: Christopher G. Jennings (cjennings@acm.org)
*
* 11/19/04 1.0 moved to LGPL.
*
* 12/12/99 Initial version. Adapted from javalayer.java
* and Subband*.java. mdm@techie.com
*
* 02/28/99 Initial version : javalayer.java by E.B
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Implements decoding of MPEG Audio Layer I frames.
*/
class LayerIDecoder implements FrameDecoder
{
protected Bitstream stream;
protected Header header;
protected SynthesisFilter filter1, filter2;
protected Obuffer buffer;
protected int which_channels;
protected int mode;
protected int num_subbands;
protected Subband[] subbands;
protected Crc16 crc = null; // new Crc16[1] to enable CRC checking.
public LayerIDecoder()
{
crc = new Crc16();
}
public void create(Bitstream stream0, Header header0,
SynthesisFilter filtera, SynthesisFilter filterb,
Obuffer buffer0, int which_ch0)
{
stream = stream0;
header = header0;
filter1 = filtera;
filter2 = filterb;
buffer = buffer0;
which_channels = which_ch0;
}
public void decodeFrame() throws DecoderException
{
num_subbands = header.number_of_subbands();
subbands = new Subband[32];
mode = header.mode();
createSubbands();
readAllocation();
readScaleFactorSelection();
if ((crc != null) || header.checksum_ok())
{
readScaleFactors();
readSampleData();
}
}
protected void createSubbands()
{
int i;
if (mode == Header.SINGLE_CHANNEL)
for (i = 0; i < num_subbands; ++i)
subbands[i] = new SubbandLayer1(i);
else if (mode == Header.JOINT_STEREO)
{
for (i = 0; i < header.intensity_stereo_bound(); ++i)
subbands[i] = new SubbandLayer1Stereo(i);
for (; i < num_subbands; ++i)
subbands[i] = new SubbandLayer1IntensityStereo(i);
}
else
{
for (i = 0; i < num_subbands; ++i)
subbands[i] = new SubbandLayer1Stereo(i);
}
}
protected void readAllocation() throws DecoderException
{
// start to read audio data:
for (int i = 0; i < num_subbands; ++i)
subbands[i].read_allocation(stream, header, crc);
}
protected void readScaleFactorSelection()
{
// scale factor selection not present for layer I.
}
protected void readScaleFactors()
{
for (int i = 0; i < num_subbands; ++i)
subbands[i].read_scalefactor(stream, header);
}
protected void readSampleData()
{
boolean read_ready = false;
boolean write_ready = false;
int mode = header.mode();
int i;
do
{
for (i = 0; i < num_subbands; ++i)
read_ready = subbands[i].read_sampledata(stream);
do
{
for (i = 0; i < num_subbands; ++i)
write_ready = subbands[i].put_next_sample(which_channels,filter1, filter2);
filter1.calculate_pcm_samples(buffer);
if ((which_channels == OutputChannels.BOTH_CHANNELS) && (mode != Header.SINGLE_CHANNEL))
filter2.calculate_pcm_samples(buffer);
} while (!write_ready);
} while (!read_ready);
}
/**
* Abstract base class for subband classes of layer I and II
*/
abstract static class Subband
{
/*
* Changes from version 1.1 to 1.2:
* - array size increased by one, although a scalefactor with index 63
* is illegal (to prevent segmentation faults)
*/
// Scalefactors for layer I and II, Annex 3-B.1 in ISO/IEC DIS 11172:
public static final float scalefactors[] =
{
2.00000000000000f, 1.58740105196820f, 1.25992104989487f, 1.00000000000000f,
0.79370052598410f, 0.62996052494744f, 0.50000000000000f, 0.39685026299205f,
0.31498026247372f, 0.25000000000000f, 0.19842513149602f, 0.15749013123686f,
0.12500000000000f, 0.09921256574801f, 0.07874506561843f, 0.06250000000000f,
0.04960628287401f, 0.03937253280921f, 0.03125000000000f, 0.02480314143700f,
0.01968626640461f, 0.01562500000000f, 0.01240157071850f, 0.00984313320230f,
0.00781250000000f, 0.00620078535925f, 0.00492156660115f, 0.00390625000000f,
0.00310039267963f, 0.00246078330058f, 0.00195312500000f, 0.00155019633981f,
0.00123039165029f, 0.00097656250000f, 0.00077509816991f, 0.00061519582514f,
0.00048828125000f, 0.00038754908495f, 0.00030759791257f, 0.00024414062500f,
0.00019377454248f, 0.00015379895629f, 0.00012207031250f, 0.00009688727124f,
0.00007689947814f, 0.00006103515625f, 0.00004844363562f, 0.00003844973907f,
0.00003051757813f, 0.00002422181781f, 0.00001922486954f, 0.00001525878906f,
0.00001211090890f, 0.00000961243477f, 0.00000762939453f, 0.00000605545445f,
0.00000480621738f, 0.00000381469727f, 0.00000302772723f, 0.00000240310869f,
0.00000190734863f, 0.00000151386361f, 0.00000120155435f, 0.00000000000000f /* illegal scalefactor */
};
public abstract void read_allocation (Bitstream stream, Header header, Crc16 crc) throws DecoderException;
public abstract void read_scalefactor (Bitstream stream, Header header);
public abstract boolean read_sampledata (Bitstream stream);
public abstract boolean put_next_sample (int channels, SynthesisFilter filter1, SynthesisFilter filter2);
};
/**
* Class for layer I subbands in single channel mode.
* Used for single channel mode
* and in derived class for intensity stereo mode
*/
static class SubbandLayer1 extends Subband
{
// Factors and offsets for sample re-quantization
public static final float table_factor[] = {
0.0f, (1.0f/2.0f) * (4.0f/3.0f), (1.0f/4.0f) * (8.0f/7.0f), (1.0f/8.0f) * (16.0f/15.0f),
(1.0f/16.0f) * (32.0f/31.0f), (1.0f/32.0f) * (64.0f/63.0f), (1.0f/64.0f) * (128.0f/127.0f),
(1.0f/128.0f) * (256.0f/255.0f), (1.0f/256.0f) * (512.0f/511.0f),
(1.0f/512.0f) * (1024.0f/1023.0f), (1.0f/1024.0f) * (2048.0f/2047.0f),
(1.0f/2048.0f) * (4096.0f/4095.0f), (1.0f/4096.0f) * (8192.0f/8191.0f),
(1.0f/8192.0f) * (16384.0f/16383.0f), (1.0f/16384.0f) * (32768.0f/32767.0f)
};
public static final float table_offset[] = {
0.0f, ((1.0f/2.0f)-1.0f) * (4.0f/3.0f), ((1.0f/4.0f)-1.0f) * (8.0f/7.0f), ((1.0f/8.0f)-1.0f) * (16.0f/15.0f),
((1.0f/16.0f)-1.0f) * (32.0f/31.0f), ((1.0f/32.0f)-1.0f) * (64.0f/63.0f), ((1.0f/64.0f)-1.0f) * (128.0f/127.0f),
((1.0f/128.0f)-1.0f) * (256.0f/255.0f), ((1.0f/256.0f)-1.0f) * (512.0f/511.0f),
((1.0f/512.0f)-1.0f) * (1024.0f/1023.0f), ((1.0f/1024.0f)-1.0f) * (2048.0f/2047.0f),
((1.0f/2048.0f)-1.0f) * (4096.0f/4095.0f), ((1.0f/4096.0f)-1.0f) * (8192.0f/8191.0f),
((1.0f/8192.0f)-1.0f) * (16384.0f/16383.0f), ((1.0f/16384.0f)-1.0f) * (32768.0f/32767.0f)
};
protected int subbandnumber;
protected int samplenumber;
protected int allocation;
protected float scalefactor;
protected int samplelength;
protected float sample;
protected float factor, offset;
/**
* Constructor.
*/
public SubbandLayer1(int subbandnumber)
{
this.subbandnumber = subbandnumber;
samplenumber = 0;
}
/**
*
*/
public void read_allocation(Bitstream stream, Header header, Crc16 crc) throws DecoderException
{
if ((allocation = stream.get_bits (4)) == 15)
{
// CGJ: catch this condition and throw appropriate exception
throw new DecoderException(DecoderErrors.ILLEGAL_SUBBAND_ALLOCATION, null);
// cerr << "WARNING: stream contains an illegal allocation!\n";
// MPEG-stream is corrupted!
}
if (crc != null) crc.add_bits (allocation, 4);
if (allocation != 0)
{
samplelength = allocation + 1;
factor = table_factor[allocation];
offset = table_offset[allocation];
}
}
/**
*
*/
public void read_scalefactor(Bitstream stream, Header header)
{
if (allocation != 0) scalefactor = scalefactors[stream.get_bits(6)];
}
/**
*
*/
public boolean read_sampledata(Bitstream stream)
{
if (allocation != 0)
{
sample = (float) (stream.get_bits(samplelength));
}
if (++samplenumber == 12)
{
samplenumber = 0;
return true;
}
return false;
}
/**
*
*/
public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2)
{
if ((allocation !=0) && (channels != OutputChannels.RIGHT_CHANNEL))
{
float scaled_sample = (sample * factor + offset) * scalefactor;
filter1.input_sample (scaled_sample, subbandnumber);
}
return true;
}
};
/**
* Class for layer I subbands in joint stereo mode.
*/
static class SubbandLayer1IntensityStereo extends SubbandLayer1
{
protected float channel2_scalefactor;
/**
* Constructor
*/
public SubbandLayer1IntensityStereo(int subbandnumber)
{
super(subbandnumber);
}
/**
*
*/
public void read_allocation(Bitstream stream, Header header, Crc16 crc) throws DecoderException
{
super.read_allocation (stream, header, crc);
}
/**
*
*/
public void read_scalefactor (Bitstream stream, Header header)
{
if (allocation != 0)
{
scalefactor = scalefactors[stream.get_bits(6)];
channel2_scalefactor = scalefactors[stream.get_bits(6)];
}
}
/**
*
*/
public boolean read_sampledata(Bitstream stream)
{
return super.read_sampledata (stream);
}
/**
*
*/
public boolean put_next_sample (int channels, SynthesisFilter filter1, SynthesisFilter filter2)
{
if (allocation !=0 )
{
sample = sample * factor + offset; // re-quantization
if (channels == OutputChannels.BOTH_CHANNELS)
{
float sample1 = sample * scalefactor,
sample2 = sample * channel2_scalefactor;
filter1.input_sample(sample1, subbandnumber);
filter2.input_sample(sample2, subbandnumber);
}
else if (channels == OutputChannels.LEFT_CHANNEL)
{
float sample1 = sample * scalefactor;
filter1.input_sample(sample1, subbandnumber);
}
else
{
float sample2 = sample * channel2_scalefactor;
filter1.input_sample(sample2, subbandnumber);
}
}
return true;
}
};
/**
* Class for layer I subbands in stereo mode.
*/
static class SubbandLayer1Stereo extends SubbandLayer1
{
protected int channel2_allocation;
protected float channel2_scalefactor;
protected int channel2_samplelength;
protected float channel2_sample;
protected float channel2_factor, channel2_offset;
/**
* Constructor
*/
public SubbandLayer1Stereo(int subbandnumber)
{
super(subbandnumber);
}
/**
*
*/
public void read_allocation (Bitstream stream, Header header, Crc16 crc) throws DecoderException
{
allocation = stream.get_bits(4);
channel2_allocation = stream.get_bits(4);
if (crc != null)
{
crc.add_bits (allocation, 4);
crc.add_bits (channel2_allocation, 4);
}
if (allocation != 0)
{
samplelength = allocation + 1;
factor = table_factor[allocation];
offset = table_offset[allocation];
}
if (channel2_allocation != 0)
{
channel2_samplelength = channel2_allocation + 1;
channel2_factor = table_factor[channel2_allocation];
channel2_offset = table_offset[channel2_allocation];
}
}
/**
*
*/
public void read_scalefactor(Bitstream stream, Header header)
{
if (allocation != 0) scalefactor = scalefactors[stream.get_bits(6)];
if (channel2_allocation != 0) channel2_scalefactor = scalefactors[stream.get_bits(6)];
}
/**
*
*/
public boolean read_sampledata (Bitstream stream)
{
boolean returnvalue = super.read_sampledata(stream);
if (channel2_allocation != 0)
{
channel2_sample = (float) (stream.get_bits(channel2_samplelength));
}
return(returnvalue);
}
/**
*
*/
public boolean put_next_sample(int channels, SynthesisFilter filter1, SynthesisFilter filter2)
{
super.put_next_sample (channels, filter1, filter2);
if ((channel2_allocation != 0) && (channels != OutputChannels.LEFT_CHANNEL))
{
float sample2 = (channel2_sample * channel2_factor + channel2_offset) *
channel2_scalefactor;
if (channels == OutputChannels.BOTH_CHANNELS)
filter2.input_sample (sample2, subbandnumber);
else
filter1.input_sample (sample2, subbandnumber);
}
return true;
}
};
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
/*
* 11/19/04 1.0 moved to LGPL.
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Work in progress.
*
* Manages a number of controls.
*/
public class Manager //implements Control
{
public void addControl(Control c)
{
}
public void removeControl(Control c)
{
}
public void removeAll()
{
}
// control interface delegates to a managed control
}

View File

@ -0,0 +1,88 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 12/12/99 Added appendSamples() method for efficiency. MDM.
* 15/02/99 ,Java Conversion by E.B ,ebsp@iname.com, JavaLayer
*
* Declarations for output buffer, includes operating system
* implementation of the virtual Obuffer. Optional routines
* enabling seeks and stops added by Jeff Tsay.
*
* @(#) obuffer.h 1.8, last edit: 6/15/94 16:51:56
* @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
* @(#) Berlin University of Technology
*
* Idea and first implementation for u-law output with fast downsampling by
* Jim Boucher (jboucher@flash.bu.edu)
*
* LinuxObuffer class written by
* Louis P. Kruger (lpkruger@phoenix.princeton.edu)
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Base Class for audio output.
*/
public abstract class Obuffer
{
public static final int OBUFFERSIZE = 2 * 1152; // max. 2 * 1152 samples per frame
public static final int MAXCHANNELS = 2; // max. number of channels
/**
* Takes a 16 Bit PCM sample.
*/
public abstract void append(int channel, short value);
/**
* Accepts 32 new PCM samples.
*/
public void appendSamples(int channel, float[] f)
{
short s;
for (int i=0; i<32;)
{
s = clip(f[i++]);
append(channel, s);
}
}
/**
* Clip Sample to 16 Bits
*/
private final short clip(float sample)
{
return ((sample > 32767.0f) ? 32767 :
((sample < -32768.0f) ? -32768 :
(short) sample));
}
/**
* Write the samples to the file or directly to the audio hardware.
*/
public abstract void write_buffer(int val);
public abstract void close();
/**
* Clears all data in the buffer (for seeking).
*/
public abstract void clear_buffer();
/**
* Notify the buffer that the user has stopped the stream.
*/
public abstract void set_stop_flag();
}

View File

@ -0,0 +1,143 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 12/12/99 Initial implementation. mdm@techie.com.
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* A Type-safe representation of the the supported output channel
* constants.
*
* This class is immutable and, hence, is thread safe.
*
* @author Mat McGowan 12/12/99
* @since 0.0.7
*/
public class OutputChannels
{
/**
* Flag to indicate output should include both channels.
*/
public static final int BOTH_CHANNELS = 0;
/**
* Flag to indicate output should include the left channel only.
*/
public static final int LEFT_CHANNEL = 1;
/**
* Flag to indicate output should include the right channel only.
*/
public static final int RIGHT_CHANNEL = 2;
/**
* Flag to indicate output is mono.
*/
public static final int DOWNMIX_CHANNELS = 3;
public static final OutputChannels LEFT = new OutputChannels(LEFT_CHANNEL);
public static final OutputChannels RIGHT = new OutputChannels(RIGHT_CHANNEL);
public static final OutputChannels BOTH = new OutputChannels(BOTH_CHANNELS);
public static final OutputChannels DOWNMIX = new OutputChannels(DOWNMIX_CHANNELS);
private /*final*/ int outputChannels;
/**
* Creates an <code>OutputChannels</code> instance
* corresponding to the given channel code.
*
* @param code one of the OutputChannels channel code constants.
*
* @throws IllegalArgumentException if code is not a valid
* channel code.
*/
public static OutputChannels fromInt(int code)
{
switch (code)
{
case LEFT_CHANNEL:
return LEFT;
case RIGHT_CHANNEL:
return RIGHT;
case BOTH_CHANNELS:
return BOTH;
case DOWNMIX_CHANNELS:
return DOWNMIX;
default:
throw new IllegalArgumentException("Invalid channel code: "+code);
}
}
private OutputChannels(int channels)
{
outputChannels = channels;
if (channels<0 || channels>3)
throw new IllegalArgumentException("channels");
}
/**
* Retrieves the code representing the desired output channels.
* Will be one of LEFT_CHANNEL, RIGHT_CHANNEL, BOTH_CHANNELS
* or DOWNMIX_CHANNELS.
*
* @return the channel code represented by this instance.
*/
public int getChannelsOutputCode()
{
return outputChannels;
}
/**
* Retrieves the number of output channels represented
* by this channel output type.
*
* @return The number of output channels for this channel output
* type. This will be 2 for BOTH_CHANNELS only, and 1
* for all other types.
*/
public int getChannelCount()
{
int count = (outputChannels==BOTH_CHANNELS) ? 2 : 1;
return count;
}
public boolean equals(Object o)
{
boolean equals = false;
if (o instanceof OutputChannels)
{
OutputChannels oc = (OutputChannels)o;
equals = (oc.outputChannels == outputChannels);
}
return equals;
}
public int hashCode()
{
return outputChannels;
}
}

View File

@ -0,0 +1,132 @@
/*
* 11/19/04 1.0 moved to LGPL.
*
* 12/12/99 Initial Version based on FileObuffer. mdm@techie.com.
*
* FileObuffer:
* 15/02/99 Java Conversion by E.B ,javalayer@javazoom.net
*
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* The <code>SampleBuffer</code> class implements an output buffer
* that provides storage for a fixed size block of samples.
*/
public class SampleBuffer extends Obuffer
{
private short[] buffer;
private int[] bufferp;
private int channels;
private int frequency;
/**
* Constructor
*/
public SampleBuffer(int sample_frequency, int number_of_channels)
{
buffer = new short[OBUFFERSIZE];
bufferp = new int[MAXCHANNELS];
channels = number_of_channels;
frequency = sample_frequency;
for (int i = 0; i < number_of_channels; ++i)
bufferp[i] = (short)i;
}
public int getChannelCount()
{
return this.channels;
}
public int getSampleFrequency()
{
return this.frequency;
}
public short[] getBuffer()
{
return this.buffer;
}
public int getBufferLength()
{
return bufferp[0];
}
/**
* Takes a 16 Bit PCM sample.
*/
public void append(int channel, short value)
{
buffer[bufferp[channel]] = value;
bufferp[channel] += channels;
}
public void appendSamples(int channel, float[] f)
{
int pos = bufferp[channel];
short s;
float fs;
for (int i=0; i<32;)
{
fs = f[i++];
fs = (fs>32767.0f ? 32767.0f
: (fs < -32767.0f ? -32767.0f : fs));
s = (short)fs;
buffer[pos] = s;
pos += channels;
}
bufferp[channel] = pos;
}
/**
* Write the samples to the file (Random Access).
*/
public void write_buffer(int val)
{
//for (int i = 0; i < channels; ++i)
// bufferp[i] = (short)i;
}
public void close()
{}
/**
*
*/
public void clear_buffer()
{
for (int i = 0; i < channels; ++i)
bufferp[i] = (short)i;
}
/**
*
*/
public void set_stop_flag()
{}
}

View File

@ -0,0 +1,49 @@
/*
* 11/19/04 1.0 moved to LGPL.
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
import java.io.IOException;
/**
* Work in progress.
*
* Class to describe a seekable data source.
*
*/
public interface Source
{
public static final long LENGTH_UNKNOWN = -1;
public int read(byte[] b, int offs, int len)
throws IOException;
public boolean willReadBlock();
public boolean isSeekable();
public long length();
public long tell();
public long seek(long pos);
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,600 @@
/*
* 11/19/04 1.0 moved to LGPL.
* 16/11/99 Renamed class, added javadoc, and changed table
* name from String to 3 chars. mdm@techie.com
* 02/15/99 Java Conversion by E.B, javalayer@javazoom.net
*
* 04/19/97 : Adapted from the ISO MPEG Audio Subgroup Software Simulation
* Group's public c source for its MPEG audio decoder. Miscellaneous
* changes by Jeff Tsay (ctsay@pasteur.eecs.berkeley.edu).
*-----------------------------------------------------------------------
* Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved
* MPEG/audio coding/decoding software, work in progress
* NOT for public distribution until verified and approved by the
* MPEG/audio committee. For further information, please contact
* Davis Pan, 508-493-2241, e-mail: pan@3d.enet.dec.com
*
* VERSION 4.1
* changes made since last update:
* date programmers comment
* 27.2.92 F.O.Witte (ITT Intermetall)
* 8/24/93 M. Iwadare Changed for 1 pass decoding.
* 7/14/94 J. Koller useless 'typedef' before huffcodetab removed
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Class that implements a Huffman decoder.
*/
final class huffcodetab
{
private static final int MXOFF=250;
private static final int HTN=34;
private char tablename0 = ' '; /* string, containing table_description */
private char tablename1 = ' '; /* string, containing table_description */
private char tablename2 = ' '; /* string, containing table_description */
private int xlen; /* max. x-index+ */
private int ylen; /* max. y-index+ */
private int linbits; /* number of linbits */
private int linmax; /* max number to be stored in linbits */
private int ref; /* a positive value indicates a reference */
private int[] table=null; /* pointer to array[xlen][ylen] */
private int[] hlen=null; /* pointer to array[xlen][ylen] */
private int[][] val=null; /* decoder tree */
private int treelen; /* length of decoder tree */
private static int ValTab0[][] = {
{0,0} // dummy
};
private static int ValTab1[][] = {
{2,1},{0,0},{2,1},{0,16},{2,1},{0,1},{0,17},
};
private static int ValTab2[][] = {
{2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1},{2,1},
{0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34},
};
private static int ValTab3[][] = {
{4,1},{2,1},{0,0},{0,1},{2,1},{0,17},{2,1},{0,16},{4,1},{2,1},
{0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34},
};
private static int ValTab4[][] = {{0,0}}; // dummy
private static int ValTab5[][] = {
{2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{8,1},{4,1},
{2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{8,1},{4,1},{2,1},{0,34},
{0,48},{2,1},{0,3},{0,19},{2,1},{0,49},{2,1},{0,50},{2,1},{0,35},
{0,51},
};
private static int ValTab6[][] = {
{6,1},{4,1},{2,1},{0,0},{0,16},{0,17},{6,1},{2,1},{0,1},{2,1},
{0,32},{0,33},{6,1},{2,1},{0,18},{2,1},{0,2},{0,34},{4,1},{2,1},
{0,49},{0,19},{4,1},{2,1},{0,48},{0,50},{2,1},{0,35},{2,1},{0,3},
{0,51},
};
private static int ValTab7[][] = {
{2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{8,1},{2,1},{0,17},{4,1},
{2,1},{0,32},{0,2},{0,33},{18,1},{6,1},{2,1},{0,18},{2,1},{0,34},
{0,48},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1},{0,3},{0,50},{2,1},
{0,35},{0,4},{10,1},{4,1},{2,1},{0,64},{0,65},{2,1},{0,20},{2,1},
{0,66},{0,36},{12,1},{6,1},{4,1},{2,1},{0,51},{0,67},{0,80},{4,1},
{2,1},{0,52},{0,5},{0,81},{6,1},{2,1},{0,21},{2,1},{0,82},{0,37},
{4,1},{2,1},{0,68},{0,53},{4,1},{2,1},{0,83},{0,84},{2,1},{0,69},
{0,85},
};
private static int ValTab8[][] = {
{6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1},{2,1},
{0,33},{0,18},{14,1},{4,1},{2,1},{0,32},{0,2},{2,1},{0,34},{4,1},
{2,1},{0,48},{0,3},{2,1},{0,49},{0,19},{14,1},{8,1},{4,1},{2,1},
{0,50},{0,35},{2,1},{0,64},{0,4},{2,1},{0,65},{2,1},{0,20},{0,66},
{12,1},{6,1},{2,1},{0,36},{2,1},{0,51},{0,80},{4,1},{2,1},{0,67},
{0,52},{0,81},{6,1},{2,1},{0,21},{2,1},{0,5},{0,82},{6,1},{2,1},
{0,37},{2,1},{0,68},{0,53},{2,1},{0,83},{2,1},{0,69},{2,1},{0,84},
{0,85},
};
private static int ValTab9[][] = {
{8,1},{4,1},{2,1},{0,0},{0,16},{2,1},{0,1},{0,17},{10,1},{4,1},
{2,1},{0,32},{0,33},{2,1},{0,18},{2,1},{0,2},{0,34},{12,1},{6,1},
{4,1},{2,1},{0,48},{0,3},{0,49},{2,1},{0,19},{2,1},{0,50},{0,35},
{12,1},{4,1},{2,1},{0,65},{0,20},{4,1},{2,1},{0,64},{0,51},{2,1},
{0,66},{0,36},{10,1},{6,1},{4,1},{2,1},{0,4},{0,80},{0,67},{2,1},
{0,52},{0,81},{8,1},{4,1},{2,1},{0,21},{0,82},{2,1},{0,37},{0,68},
{6,1},{4,1},{2,1},{0,5},{0,84},{0,83},{2,1},{0,53},{2,1},{0,69},
{0,85},
};
private static int ValTab10[][] = {
{2,1},{0,0},{4,1},{2,1},{0,16},{0,1},{10,1},{2,1},{0,17},{4,1},
{2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{28,1},{8,1},{4,1},{2,1},
{0,34},{0,48},{2,1},{0,49},{0,19},{8,1},{4,1},{2,1},{0,3},{0,50},
{2,1},{0,35},{0,64},{4,1},{2,1},{0,65},{0,20},{4,1},{2,1},{0,4},
{0,51},{2,1},{0,66},{0,36},{28,1},{10,1},{6,1},{4,1},{2,1},{0,80},
{0,5},{0,96},{2,1},{0,97},{0,22},{12,1},{6,1},{4,1},{2,1},{0,67},
{0,52},{0,81},{2,1},{0,21},{2,1},{0,82},{0,37},{4,1},{2,1},{0,38},
{0,54},{0,113},{20,1},{8,1},{2,1},{0,23},{4,1},{2,1},{0,68},{0,83},
{0,6},{6,1},{4,1},{2,1},{0,53},{0,69},{0,98},{2,1},{0,112},{2,1},
{0,7},{0,100},{14,1},{4,1},{2,1},{0,114},{0,39},{6,1},{2,1},{0,99},
{2,1},{0,84},{0,85},{2,1},{0,70},{0,115},{8,1},{4,1},{2,1},{0,55},
{0,101},{2,1},{0,86},{0,116},{6,1},{2,1},{0,71},{2,1},{0,102},{0,117},
{4,1},{2,1},{0,87},{0,118},{2,1},{0,103},{0,119},
};
private static int ValTab11[][] = {
{6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{8,1},{2,1},{0,17},{4,1},
{2,1},{0,32},{0,2},{0,18},{24,1},{8,1},{2,1},{0,33},{2,1},{0,34},
{2,1},{0,48},{0,3},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1},{0,50},
{0,35},{4,1},{2,1},{0,64},{0,4},{2,1},{0,65},{0,20},{30,1},{16,1},
{10,1},{4,1},{2,1},{0,66},{0,36},{4,1},{2,1},{0,51},{0,67},{0,80},
{4,1},{2,1},{0,52},{0,81},{0,97},{6,1},{2,1},{0,22},{2,1},{0,6},
{0,38},{2,1},{0,98},{2,1},{0,21},{2,1},{0,5},{0,82},{16,1},{10,1},
{6,1},{4,1},{2,1},{0,37},{0,68},{0,96},{2,1},{0,99},{0,54},{4,1},
{2,1},{0,112},{0,23},{0,113},{16,1},{6,1},{4,1},{2,1},{0,7},{0,100},
{0,114},{2,1},{0,39},{4,1},{2,1},{0,83},{0,53},{2,1},{0,84},{0,69},
{10,1},{4,1},{2,1},{0,70},{0,115},{2,1},{0,55},{2,1},{0,101},{0,86},
{10,1},{6,1},{4,1},{2,1},{0,85},{0,87},{0,116},{2,1},{0,71},{0,102},
{4,1},{2,1},{0,117},{0,118},{2,1},{0,103},{0,119},
};
private static int ValTab12[][] = {
{12,1},{4,1},{2,1},{0,16},{0,1},{2,1},{0,17},{2,1},{0,0},{2,1},
{0,32},{0,2},{16,1},{4,1},{2,1},{0,33},{0,18},{4,1},{2,1},{0,34},
{0,49},{2,1},{0,19},{2,1},{0,48},{2,1},{0,3},{0,64},{26,1},{8,1},
{4,1},{2,1},{0,50},{0,35},{2,1},{0,65},{0,51},{10,1},{4,1},{2,1},
{0,20},{0,66},{2,1},{0,36},{2,1},{0,4},{0,80},{4,1},{2,1},{0,67},
{0,52},{2,1},{0,81},{0,21},{28,1},{14,1},{8,1},{4,1},{2,1},{0,82},
{0,37},{2,1},{0,83},{0,53},{4,1},{2,1},{0,96},{0,22},{0,97},{4,1},
{2,1},{0,98},{0,38},{6,1},{4,1},{2,1},{0,5},{0,6},{0,68},{2,1},
{0,84},{0,69},{18,1},{10,1},{4,1},{2,1},{0,99},{0,54},{4,1},{2,1},
{0,112},{0,7},{0,113},{4,1},{2,1},{0,23},{0,100},{2,1},{0,70},{0,114},
{10,1},{6,1},{2,1},{0,39},{2,1},{0,85},{0,115},{2,1},{0,55},{0,86},
{8,1},{4,1},{2,1},{0,101},{0,116},{2,1},{0,71},{0,102},{4,1},{2,1},
{0,117},{0,87},{2,1},{0,118},{2,1},{0,103},{0,119},
};
private static int ValTab13[][] = {
{2,1},{0,0},{6,1},{2,1},{0,16},{2,1},{0,1},{0,17},{28,1},{8,1},
{4,1},{2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{8,1},{4,1},{2,1},
{0,34},{0,48},{2,1},{0,3},{0,49},{6,1},{2,1},{0,19},{2,1},{0,50},
{0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{70,1},{28,1},{14,1},{6,1},
{2,1},{0,20},{2,1},{0,51},{0,66},{4,1},{2,1},{0,36},{0,80},{2,1},
{0,67},{0,52},{4,1},{2,1},{0,81},{0,21},{4,1},{2,1},{0,5},{0,82},
{2,1},{0,37},{2,1},{0,68},{0,83},{14,1},{8,1},{4,1},{2,1},{0,96},
{0,6},{2,1},{0,97},{0,22},{4,1},{2,1},{0,128},{0,8},{0,129},{16,1},
{8,1},{4,1},{2,1},{0,53},{0,98},{2,1},{0,38},{0,84},{4,1},{2,1},
{0,69},{0,99},{2,1},{0,54},{0,112},{6,1},{4,1},{2,1},{0,7},{0,85},
{0,113},{2,1},{0,23},{2,1},{0,39},{0,55},{72,1},{24,1},{12,1},{4,1},
{2,1},{0,24},{0,130},{2,1},{0,40},{4,1},{2,1},{0,100},{0,70},{0,114},
{8,1},{4,1},{2,1},{0,132},{0,72},{2,1},{0,144},{0,9},{2,1},{0,145},
{0,25},{24,1},{14,1},{8,1},{4,1},{2,1},{0,115},{0,101},{2,1},{0,86},
{0,116},{4,1},{2,1},{0,71},{0,102},{0,131},{6,1},{2,1},{0,56},{2,1},
{0,117},{0,87},{2,1},{0,146},{0,41},{14,1},{8,1},{4,1},{2,1},{0,103},
{0,133},{2,1},{0,88},{0,57},{2,1},{0,147},{2,1},{0,73},{0,134},{6,1},
{2,1},{0,160},{2,1},{0,104},{0,10},{2,1},{0,161},{0,26},{68,1},{24,1},
{12,1},{4,1},{2,1},{0,162},{0,42},{4,1},{2,1},{0,149},{0,89},{2,1},
{0,163},{0,58},{8,1},{4,1},{2,1},{0,74},{0,150},{2,1},{0,176},{0,11},
{2,1},{0,177},{0,27},{20,1},{8,1},{2,1},{0,178},{4,1},{2,1},{0,118},
{0,119},{0,148},{6,1},{4,1},{2,1},{0,135},{0,120},{0,164},{4,1},{2,1},
{0,105},{0,165},{0,43},{12,1},{6,1},{4,1},{2,1},{0,90},{0,136},{0,179},
{2,1},{0,59},{2,1},{0,121},{0,166},{6,1},{4,1},{2,1},{0,106},{0,180},
{0,192},{4,1},{2,1},{0,12},{0,152},{0,193},{60,1},{22,1},{10,1},{6,1},
{2,1},{0,28},{2,1},{0,137},{0,181},{2,1},{0,91},{0,194},{4,1},{2,1},
{0,44},{0,60},{4,1},{2,1},{0,182},{0,107},{2,1},{0,196},{0,76},{16,1},
{8,1},{4,1},{2,1},{0,168},{0,138},{2,1},{0,208},{0,13},{2,1},{0,209},
{2,1},{0,75},{2,1},{0,151},{0,167},{12,1},{6,1},{2,1},{0,195},{2,1},
{0,122},{0,153},{4,1},{2,1},{0,197},{0,92},{0,183},{4,1},{2,1},{0,29},
{0,210},{2,1},{0,45},{2,1},{0,123},{0,211},{52,1},{28,1},{12,1},{4,1},
{2,1},{0,61},{0,198},{4,1},{2,1},{0,108},{0,169},{2,1},{0,154},{0,212},
{8,1},{4,1},{2,1},{0,184},{0,139},{2,1},{0,77},{0,199},{4,1},{2,1},
{0,124},{0,213},{2,1},{0,93},{0,224},{10,1},{4,1},{2,1},{0,225},{0,30},
{4,1},{2,1},{0,14},{0,46},{0,226},{8,1},{4,1},{2,1},{0,227},{0,109},
{2,1},{0,140},{0,228},{4,1},{2,1},{0,229},{0,186},{0,240},{38,1},{16,1},
{4,1},{2,1},{0,241},{0,31},{6,1},{4,1},{2,1},{0,170},{0,155},{0,185},
{2,1},{0,62},{2,1},{0,214},{0,200},{12,1},{6,1},{2,1},{0,78},{2,1},
{0,215},{0,125},{2,1},{0,171},{2,1},{0,94},{0,201},{6,1},{2,1},{0,15},
{2,1},{0,156},{0,110},{2,1},{0,242},{0,47},{32,1},{16,1},{6,1},{4,1},
{2,1},{0,216},{0,141},{0,63},{6,1},{2,1},{0,243},{2,1},{0,230},{0,202},
{2,1},{0,244},{0,79},{8,1},{4,1},{2,1},{0,187},{0,172},{2,1},{0,231},
{0,245},{4,1},{2,1},{0,217},{0,157},{2,1},{0,95},{0,232},{30,1},{12,1},
{6,1},{2,1},{0,111},{2,1},{0,246},{0,203},{4,1},{2,1},{0,188},{0,173},
{0,218},{8,1},{2,1},{0,247},{4,1},{2,1},{0,126},{0,127},{0,142},{6,1},
{4,1},{2,1},{0,158},{0,174},{0,204},{2,1},{0,248},{0,143},{18,1},{8,1},
{4,1},{2,1},{0,219},{0,189},{2,1},{0,234},{0,249},{4,1},{2,1},{0,159},
{0,235},{2,1},{0,190},{2,1},{0,205},{0,250},{14,1},{4,1},{2,1},{0,221},
{0,236},{6,1},{4,1},{2,1},{0,233},{0,175},{0,220},{2,1},{0,206},{0,251},
{8,1},{4,1},{2,1},{0,191},{0,222},{2,1},{0,207},{0,238},{4,1},{2,1},
{0,223},{0,239},{2,1},{0,255},{2,1},{0,237},{2,1},{0,253},{2,1},{0,252},
{0,254},
};
private static int ValTab14[][] = {
{0,0} // dummy
};
private static int ValTab15[][] = {
{16,1},{6,1},{2,1},{0,0},{2,1},{0,16},{0,1},{2,1},{0,17},{4,1},
{2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{50,1},{16,1},{6,1},{2,1},
{0,34},{2,1},{0,48},{0,49},{6,1},{2,1},{0,19},{2,1},{0,3},{0,64},
{2,1},{0,50},{0,35},{14,1},{6,1},{4,1},{2,1},{0,4},{0,20},{0,65},
{4,1},{2,1},{0,51},{0,66},{2,1},{0,36},{0,67},{10,1},{6,1},{2,1},
{0,52},{2,1},{0,80},{0,5},{2,1},{0,81},{0,21},{4,1},{2,1},{0,82},
{0,37},{4,1},{2,1},{0,68},{0,83},{0,97},{90,1},{36,1},{18,1},{10,1},
{6,1},{2,1},{0,53},{2,1},{0,96},{0,6},{2,1},{0,22},{0,98},{4,1},
{2,1},{0,38},{0,84},{2,1},{0,69},{0,99},{10,1},{6,1},{2,1},{0,54},
{2,1},{0,112},{0,7},{2,1},{0,113},{0,85},{4,1},{2,1},{0,23},{0,100},
{2,1},{0,114},{0,39},{24,1},{16,1},{8,1},{4,1},{2,1},{0,70},{0,115},
{2,1},{0,55},{0,101},{4,1},{2,1},{0,86},{0,128},{2,1},{0,8},{0,116},
{4,1},{2,1},{0,129},{0,24},{2,1},{0,130},{0,40},{16,1},{8,1},{4,1},
{2,1},{0,71},{0,102},{2,1},{0,131},{0,56},{4,1},{2,1},{0,117},{0,87},
{2,1},{0,132},{0,72},{6,1},{4,1},{2,1},{0,144},{0,25},{0,145},{4,1},
{2,1},{0,146},{0,118},{2,1},{0,103},{0,41},{92,1},{36,1},{18,1},{10,1},
{4,1},{2,1},{0,133},{0,88},{4,1},{2,1},{0,9},{0,119},{0,147},{4,1},
{2,1},{0,57},{0,148},{2,1},{0,73},{0,134},{10,1},{6,1},{2,1},{0,104},
{2,1},{0,160},{0,10},{2,1},{0,161},{0,26},{4,1},{2,1},{0,162},{0,42},
{2,1},{0,149},{0,89},{26,1},{14,1},{6,1},{2,1},{0,163},{2,1},{0,58},
{0,135},{4,1},{2,1},{0,120},{0,164},{2,1},{0,74},{0,150},{6,1},{4,1},
{2,1},{0,105},{0,176},{0,177},{4,1},{2,1},{0,27},{0,165},{0,178},{14,1},
{8,1},{4,1},{2,1},{0,90},{0,43},{2,1},{0,136},{0,151},{2,1},{0,179},
{2,1},{0,121},{0,59},{8,1},{4,1},{2,1},{0,106},{0,180},{2,1},{0,75},
{0,193},{4,1},{2,1},{0,152},{0,137},{2,1},{0,28},{0,181},{80,1},{34,1},
{16,1},{6,1},{4,1},{2,1},{0,91},{0,44},{0,194},{6,1},{4,1},{2,1},
{0,11},{0,192},{0,166},{2,1},{0,167},{0,122},{10,1},{4,1},{2,1},{0,195},
{0,60},{4,1},{2,1},{0,12},{0,153},{0,182},{4,1},{2,1},{0,107},{0,196},
{2,1},{0,76},{0,168},{20,1},{10,1},{4,1},{2,1},{0,138},{0,197},{4,1},
{2,1},{0,208},{0,92},{0,209},{4,1},{2,1},{0,183},{0,123},{2,1},{0,29},
{2,1},{0,13},{0,45},{12,1},{4,1},{2,1},{0,210},{0,211},{4,1},{2,1},
{0,61},{0,198},{2,1},{0,108},{0,169},{6,1},{4,1},{2,1},{0,154},{0,184},
{0,212},{4,1},{2,1},{0,139},{0,77},{2,1},{0,199},{0,124},{68,1},{34,1},
{18,1},{10,1},{4,1},{2,1},{0,213},{0,93},{4,1},{2,1},{0,224},{0,14},
{0,225},{4,1},{2,1},{0,30},{0,226},{2,1},{0,170},{0,46},{8,1},{4,1},
{2,1},{0,185},{0,155},{2,1},{0,227},{0,214},{4,1},{2,1},{0,109},{0,62},
{2,1},{0,200},{0,140},{16,1},{8,1},{4,1},{2,1},{0,228},{0,78},{2,1},
{0,215},{0,125},{4,1},{2,1},{0,229},{0,186},{2,1},{0,171},{0,94},{8,1},
{4,1},{2,1},{0,201},{0,156},{2,1},{0,241},{0,31},{6,1},{4,1},{2,1},
{0,240},{0,110},{0,242},{2,1},{0,47},{0,230},{38,1},{18,1},{8,1},{4,1},
{2,1},{0,216},{0,243},{2,1},{0,63},{0,244},{6,1},{2,1},{0,79},{2,1},
{0,141},{0,217},{2,1},{0,187},{0,202},{8,1},{4,1},{2,1},{0,172},{0,231},
{2,1},{0,126},{0,245},{8,1},{4,1},{2,1},{0,157},{0,95},{2,1},{0,232},
{0,142},{2,1},{0,246},{0,203},{34,1},{18,1},{10,1},{6,1},{4,1},{2,1},
{0,15},{0,174},{0,111},{2,1},{0,188},{0,218},{4,1},{2,1},{0,173},{0,247},
{2,1},{0,127},{0,233},{8,1},{4,1},{2,1},{0,158},{0,204},{2,1},{0,248},
{0,143},{4,1},{2,1},{0,219},{0,189},{2,1},{0,234},{0,249},{16,1},{8,1},
{4,1},{2,1},{0,159},{0,220},{2,1},{0,205},{0,235},{4,1},{2,1},{0,190},
{0,250},{2,1},{0,175},{0,221},{14,1},{6,1},{4,1},{2,1},{0,236},{0,206},
{0,251},{4,1},{2,1},{0,191},{0,237},{2,1},{0,222},{0,252},{6,1},{4,1},
{2,1},{0,207},{0,253},{0,238},{4,1},{2,1},{0,223},{0,254},{2,1},{0,239},
{0,255},
};
private static int ValTab16[][] = {
{2,1},{0,0},{6,1},{2,1},{0,16},{2,1},{0,1},{0,17},{42,1},{8,1},
{4,1},{2,1},{0,32},{0,2},{2,1},{0,33},{0,18},{10,1},{6,1},{2,1},
{0,34},{2,1},{0,48},{0,3},{2,1},{0,49},{0,19},{10,1},{4,1},{2,1},
{0,50},{0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{6,1},{2,1},{0,20},
{2,1},{0,51},{0,66},{4,1},{2,1},{0,36},{0,80},{2,1},{0,67},{0,52},
{138,1},{40,1},{16,1},{6,1},{4,1},{2,1},{0,5},{0,21},{0,81},{4,1},
{2,1},{0,82},{0,37},{4,1},{2,1},{0,68},{0,53},{0,83},{10,1},{6,1},
{4,1},{2,1},{0,96},{0,6},{0,97},{2,1},{0,22},{0,98},{8,1},{4,1},
{2,1},{0,38},{0,84},{2,1},{0,69},{0,99},{4,1},{2,1},{0,54},{0,112},
{0,113},{40,1},{18,1},{8,1},{2,1},{0,23},{2,1},{0,7},{2,1},{0,85},
{0,100},{4,1},{2,1},{0,114},{0,39},{4,1},{2,1},{0,70},{0,101},{0,115},
{10,1},{6,1},{2,1},{0,55},{2,1},{0,86},{0,8},{2,1},{0,128},{0,129},
{6,1},{2,1},{0,24},{2,1},{0,116},{0,71},{2,1},{0,130},{2,1},{0,40},
{0,102},{24,1},{14,1},{8,1},{4,1},{2,1},{0,131},{0,56},{2,1},{0,117},
{0,132},{4,1},{2,1},{0,72},{0,144},{0,145},{6,1},{2,1},{0,25},{2,1},
{0,9},{0,118},{2,1},{0,146},{0,41},{14,1},{8,1},{4,1},{2,1},{0,133},
{0,88},{2,1},{0,147},{0,57},{4,1},{2,1},{0,160},{0,10},{0,26},{8,1},
{2,1},{0,162},{2,1},{0,103},{2,1},{0,87},{0,73},{6,1},{2,1},{0,148},
{2,1},{0,119},{0,134},{2,1},{0,161},{2,1},{0,104},{0,149},{220,1},{126,1},
{50,1},{26,1},{12,1},{6,1},{2,1},{0,42},{2,1},{0,89},{0,58},{2,1},
{0,163},{2,1},{0,135},{0,120},{8,1},{4,1},{2,1},{0,164},{0,74},{2,1},
{0,150},{0,105},{4,1},{2,1},{0,176},{0,11},{0,177},{10,1},{4,1},{2,1},
{0,27},{0,178},{2,1},{0,43},{2,1},{0,165},{0,90},{6,1},{2,1},{0,179},
{2,1},{0,166},{0,106},{4,1},{2,1},{0,180},{0,75},{2,1},{0,12},{0,193},
{30,1},{14,1},{6,1},{4,1},{2,1},{0,181},{0,194},{0,44},{4,1},{2,1},
{0,167},{0,195},{2,1},{0,107},{0,196},{8,1},{2,1},{0,29},{4,1},{2,1},
{0,136},{0,151},{0,59},{4,1},{2,1},{0,209},{0,210},{2,1},{0,45},{0,211},
{18,1},{6,1},{4,1},{2,1},{0,30},{0,46},{0,226},{6,1},{4,1},{2,1},
{0,121},{0,152},{0,192},{2,1},{0,28},{2,1},{0,137},{0,91},{14,1},{6,1},
{2,1},{0,60},{2,1},{0,122},{0,182},{4,1},{2,1},{0,76},{0,153},{2,1},
{0,168},{0,138},{6,1},{2,1},{0,13},{2,1},{0,197},{0,92},{4,1},{2,1},
{0,61},{0,198},{2,1},{0,108},{0,154},{88,1},{86,1},{36,1},{16,1},{8,1},
{4,1},{2,1},{0,139},{0,77},{2,1},{0,199},{0,124},{4,1},{2,1},{0,213},
{0,93},{2,1},{0,224},{0,14},{8,1},{2,1},{0,227},{4,1},{2,1},{0,208},
{0,183},{0,123},{6,1},{4,1},{2,1},{0,169},{0,184},{0,212},{2,1},{0,225},
{2,1},{0,170},{0,185},{24,1},{10,1},{6,1},{4,1},{2,1},{0,155},{0,214},
{0,109},{2,1},{0,62},{0,200},{6,1},{4,1},{2,1},{0,140},{0,228},{0,78},
{4,1},{2,1},{0,215},{0,229},{2,1},{0,186},{0,171},{12,1},{4,1},{2,1},
{0,156},{0,230},{4,1},{2,1},{0,110},{0,216},{2,1},{0,141},{0,187},{8,1},
{4,1},{2,1},{0,231},{0,157},{2,1},{0,232},{0,142},{4,1},{2,1},{0,203},
{0,188},{0,158},{0,241},{2,1},{0,31},{2,1},{0,15},{0,47},{66,1},{56,1},
{2,1},{0,242},{52,1},{50,1},{20,1},{8,1},{2,1},{0,189},{2,1},{0,94},
{2,1},{0,125},{0,201},{6,1},{2,1},{0,202},{2,1},{0,172},{0,126},{4,1},
{2,1},{0,218},{0,173},{0,204},{10,1},{6,1},{2,1},{0,174},{2,1},{0,219},
{0,220},{2,1},{0,205},{0,190},{6,1},{4,1},{2,1},{0,235},{0,237},{0,238},
{6,1},{4,1},{2,1},{0,217},{0,234},{0,233},{2,1},{0,222},{4,1},{2,1},
{0,221},{0,236},{0,206},{0,63},{0,240},{4,1},{2,1},{0,243},{0,244},{2,1},
{0,79},{2,1},{0,245},{0,95},{10,1},{2,1},{0,255},{4,1},{2,1},{0,246},
{0,111},{2,1},{0,247},{0,127},{12,1},{6,1},{2,1},{0,143},{2,1},{0,248},
{0,249},{4,1},{2,1},{0,159},{0,250},{0,175},{8,1},{4,1},{2,1},{0,251},
{0,191},{2,1},{0,252},{0,207},{4,1},{2,1},{0,253},{0,223},{2,1},{0,254},
{0,239},
};
private static int ValTab24[][] = {
{60,1},{8,1},{4,1},{2,1},{0,0},{0,16},{2,1},{0,1},{0,17},{14,1},
{6,1},{4,1},{2,1},{0,32},{0,2},{0,33},{2,1},{0,18},{2,1},{0,34},
{2,1},{0,48},{0,3},{14,1},{4,1},{2,1},{0,49},{0,19},{4,1},{2,1},
{0,50},{0,35},{4,1},{2,1},{0,64},{0,4},{0,65},{8,1},{4,1},{2,1},
{0,20},{0,51},{2,1},{0,66},{0,36},{6,1},{4,1},{2,1},{0,67},{0,52},
{0,81},{6,1},{4,1},{2,1},{0,80},{0,5},{0,21},{2,1},{0,82},{0,37},
{250,1},{98,1},{34,1},{18,1},{10,1},{4,1},{2,1},{0,68},{0,83},{2,1},
{0,53},{2,1},{0,96},{0,6},{4,1},{2,1},{0,97},{0,22},{2,1},{0,98},
{0,38},{8,1},{4,1},{2,1},{0,84},{0,69},{2,1},{0,99},{0,54},{4,1},
{2,1},{0,113},{0,85},{2,1},{0,100},{0,70},{32,1},{14,1},{6,1},{2,1},
{0,114},{2,1},{0,39},{0,55},{2,1},{0,115},{4,1},{2,1},{0,112},{0,7},
{0,23},{10,1},{4,1},{2,1},{0,101},{0,86},{4,1},{2,1},{0,128},{0,8},
{0,129},{4,1},{2,1},{0,116},{0,71},{2,1},{0,24},{0,130},{16,1},{8,1},
{4,1},{2,1},{0,40},{0,102},{2,1},{0,131},{0,56},{4,1},{2,1},{0,117},
{0,87},{2,1},{0,132},{0,72},{8,1},{4,1},{2,1},{0,145},{0,25},{2,1},
{0,146},{0,118},{4,1},{2,1},{0,103},{0,41},{2,1},{0,133},{0,88},{92,1},
{34,1},{16,1},{8,1},{4,1},{2,1},{0,147},{0,57},{2,1},{0,148},{0,73},
{4,1},{2,1},{0,119},{0,134},{2,1},{0,104},{0,161},{8,1},{4,1},{2,1},
{0,162},{0,42},{2,1},{0,149},{0,89},{4,1},{2,1},{0,163},{0,58},{2,1},
{0,135},{2,1},{0,120},{0,74},{22,1},{12,1},{4,1},{2,1},{0,164},{0,150},
{4,1},{2,1},{0,105},{0,177},{2,1},{0,27},{0,165},{6,1},{2,1},{0,178},
{2,1},{0,90},{0,43},{2,1},{0,136},{0,179},{16,1},{10,1},{6,1},{2,1},
{0,144},{2,1},{0,9},{0,160},{2,1},{0,151},{0,121},{4,1},{2,1},{0,166},
{0,106},{0,180},{12,1},{6,1},{2,1},{0,26},{2,1},{0,10},{0,176},{2,1},
{0,59},{2,1},{0,11},{0,192},{4,1},{2,1},{0,75},{0,193},{2,1},{0,152},
{0,137},{67,1},{34,1},{16,1},{8,1},{4,1},{2,1},{0,28},{0,181},{2,1},
{0,91},{0,194},{4,1},{2,1},{0,44},{0,167},{2,1},{0,122},{0,195},{10,1},
{6,1},{2,1},{0,60},{2,1},{0,12},{0,208},{2,1},{0,182},{0,107},{4,1},
{2,1},{0,196},{0,76},{2,1},{0,153},{0,168},{16,1},{8,1},{4,1},{2,1},
{0,138},{0,197},{2,1},{0,92},{0,209},{4,1},{2,1},{0,183},{0,123},{2,1},
{0,29},{0,210},{9,1},{4,1},{2,1},{0,45},{0,211},{2,1},{0,61},{0,198},
{85,250},{4,1},{2,1},{0,108},{0,169},{2,1},{0,154},{0,212},{32,1},{16,1},
{8,1},{4,1},{2,1},{0,184},{0,139},{2,1},{0,77},{0,199},{4,1},{2,1},
{0,124},{0,213},{2,1},{0,93},{0,225},{8,1},{4,1},{2,1},{0,30},{0,226},
{2,1},{0,170},{0,185},{4,1},{2,1},{0,155},{0,227},{2,1},{0,214},{0,109},
{20,1},{10,1},{6,1},{2,1},{0,62},{2,1},{0,46},{0,78},{2,1},{0,200},
{0,140},{4,1},{2,1},{0,228},{0,215},{4,1},{2,1},{0,125},{0,171},{0,229},
{10,1},{4,1},{2,1},{0,186},{0,94},{2,1},{0,201},{2,1},{0,156},{0,110},
{8,1},{2,1},{0,230},{2,1},{0,13},{2,1},{0,224},{0,14},{4,1},{2,1},
{0,216},{0,141},{2,1},{0,187},{0,202},{74,1},{2,1},{0,255},{64,1},{58,1},
{32,1},{16,1},{8,1},{4,1},{2,1},{0,172},{0,231},{2,1},{0,126},{0,217},
{4,1},{2,1},{0,157},{0,232},{2,1},{0,142},{0,203},{8,1},{4,1},{2,1},
{0,188},{0,218},{2,1},{0,173},{0,233},{4,1},{2,1},{0,158},{0,204},{2,1},
{0,219},{0,189},{16,1},{8,1},{4,1},{2,1},{0,234},{0,174},{2,1},{0,220},
{0,205},{4,1},{2,1},{0,235},{0,190},{2,1},{0,221},{0,236},{8,1},{4,1},
{2,1},{0,206},{0,237},{2,1},{0,222},{0,238},{0,15},{4,1},{2,1},{0,240},
{0,31},{0,241},{4,1},{2,1},{0,242},{0,47},{2,1},{0,243},{0,63},{18,1},
{8,1},{4,1},{2,1},{0,244},{0,79},{2,1},{0,245},{0,95},{4,1},{2,1},
{0,246},{0,111},{2,1},{0,247},{2,1},{0,127},{0,143},{10,1},{4,1},{2,1},
{0,248},{0,249},{4,1},{2,1},{0,159},{0,175},{0,250},{8,1},{4,1},{2,1},
{0,251},{0,191},{2,1},{0,252},{0,207},{4,1},{2,1},{0,253},{0,223},{2,1},
{0,254},{0,239},
};
private static int ValTab32[][] = {
{2,1},{0,0},{8,1},{4,1},{2,1},{0,8},{0,4},{2,1},{0,1},{0,2},
{8,1},{4,1},{2,1},{0,12},{0,10},{2,1},{0,3},{0,6},{6,1},{2,1},
{0,9},{2,1},{0,5},{0,7},{4,1},{2,1},{0,14},{0,13},{2,1},{0,15},
{0,11},
};
private static int ValTab33[][] = {
{16,1},{8,1},{4,1},{2,1},{0,0},{0,1},{2,1},{0,2},{0,3},{4,1},
{2,1},{0,4},{0,5},{2,1},{0,6},{0,7},{8,1},{4,1},{2,1},{0,8},
{0,9},{2,1},{0,10},{0,11},{4,1},{2,1},{0,12},{0,13},{2,1},{0,14},
{0,15},
};
public static huffcodetab[] ht = null; /* Simulate extern struct */
private static int[] bitbuf = new int[32];
/**
* Big Constructor : Computes all Huffman Tables.
*/
private huffcodetab(String S,int XLEN, int YLEN, int LINBITS, int LINMAX, int REF,
int[] TABLE, int[] HLEN, int[][] VAL, int TREELEN)
{
tablename0 = S.charAt(0);
tablename1 = S.charAt(1);
tablename2 = S.charAt(2);
xlen = XLEN;
ylen = YLEN;
linbits = LINBITS;
linmax = LINMAX;
ref = REF;
table = TABLE;
hlen = HLEN;
val = VAL;
treelen = TREELEN;
}
/**
* Do the Huffman decoding.
* note! for counta,countb -the 4 bit value is returned in y,
* discard x.
*/
public static int huffman_decoder(huffcodetab h, int[] x, int[] y, int[] v, int[] w, BitReserve br)
{
// array of all huffcodtable headers
// 0..31 Huffman code table 0..31
// 32,33 count1-tables
int dmask = 1 << ((4 * 8) - 1);
int hs = 4 * 8;
int level;
int point = 0;
int error = 1;
level = dmask;
if (h.val == null) return 2;
/* table 0 needs no bits */
if ( h.treelen == 0)
{
x[0] = y[0] = 0;
return 0;
}
/* Lookup in Huffman table. */
/*int bitsAvailable = 0;
int bitIndex = 0;
int bits[] = bitbuf;*/
do
{
if (h.val[point][0]==0)
{ /*end of tree*/
x[0] = h.val[point][1] >>> 4;
y[0] = h.val[point][1] & 0xf;
error = 0;
break;
}
// hget1bit() is called thousands of times, and so needs to be
// ultra fast.
/*
if (bitIndex==bitsAvailable)
{
bitsAvailable = br.readBits(bits, 32);
bitIndex = 0;
}
*/
//if (bits[bitIndex++]!=0)
if (br.hget1bit()!=0)
{
while (h.val[point][1] >= MXOFF) point += h.val[point][1];
point += h.val[point][1];
}
else
{
while (h.val[point][0] >= MXOFF) point += h.val[point][0];
point += h.val[point][0];
}
level >>>= 1;
// MDM: ht[0] is always 0;
} while ((level !=0 ) || (point < 0 /*ht[0].treelen*/) );
// put back any bits not consumed
/*
int unread = (bitsAvailable-bitIndex);
if (unread>0)
br.rewindNbits(unread);
*/
/* Process sign encodings for quadruples tables. */
// System.out.println(h.tablename);
if (h.tablename0 == '3' && (h.tablename1 == '2' || h.tablename1 == '3'))
{
v[0] = (y[0]>>3) & 1;
w[0] = (y[0]>>2) & 1;
x[0] = (y[0]>>1) & 1;
y[0] = y[0] & 1;
/* v, w, x and y are reversed in the bitstream.
switch them around to make test bistream work. */
if (v[0]!=0)
if (br.hget1bit() != 0) v[0] = -v[0];
if (w[0]!=0)
if (br.hget1bit() != 0) w[0] = -w[0];
if (x[0]!=0)
if (br.hget1bit() != 0) x[0] = -x[0];
if (y[0]!=0)
if (br.hget1bit() != 0) y[0] = -y[0];
}
else
{
// Process sign and escape encodings for dual tables.
// x and y are reversed in the test bitstream.
// Reverse x and y here to make test bitstream work.
if (h.linbits != 0)
if ((h.xlen-1) == x[0])
x[0] += br.hgetbits(h.linbits);
if (x[0] != 0)
if (br.hget1bit() != 0) x[0] = -x[0];
if (h.linbits != 0)
if ((h.ylen-1) == y[0])
y[0] += br.hgetbits(h.linbits);
if (y[0] != 0)
if (br.hget1bit() != 0) y[0] = -y[0];
}
return error;
}
public static void inithuff()
{
if (ht!=null)
return;
ht = new huffcodetab[HTN];
ht[0] = new huffcodetab("0 ",0,0,0,0,-1,null,null,ValTab0,0);
ht[1] = new huffcodetab("1 ",2,2,0,0,-1,null,null,ValTab1,7);
ht[2] = new huffcodetab("2 ",3,3,0,0,-1,null,null,ValTab2,17);
ht[3] = new huffcodetab("3 ",3,3,0,0,-1,null,null,ValTab3,17);
ht[4] = new huffcodetab("4 ",0,0,0,0,-1,null,null,ValTab4,0);
ht[5] = new huffcodetab("5 ",4,4,0,0,-1,null,null,ValTab5,31);
ht[6] = new huffcodetab("6 ",4,4,0,0,-1,null,null,ValTab6,31);
ht[7] = new huffcodetab("7 ",6,6,0,0,-1,null,null,ValTab7,71);
ht[8] = new huffcodetab("8 ",6,6,0,0,-1,null,null,ValTab8,71);
ht[9] = new huffcodetab("9 ",6,6,0,0,-1,null,null,ValTab9,71);
ht[10] = new huffcodetab("10 ",8,8,0,0,-1,null,null,ValTab10,127);
ht[11] = new huffcodetab("11 ",8,8,0,0,-1,null,null,ValTab11,127);
ht[12] = new huffcodetab("12 ",8,8,0,0,-1,null,null,ValTab12,127);
ht[13] = new huffcodetab("13 ",16,16,0,0,-1,null,null,ValTab13,511);
ht[14] = new huffcodetab("14 ",0,0,0,0,-1,null,null,ValTab14,0);
ht[15] = new huffcodetab("15 ",16,16,0,0,-1,null,null,ValTab15,511);
ht[16] = new huffcodetab("16 ",16,16,1,1,-1,null,null,ValTab16,511);
ht[17] = new huffcodetab("17 ",16,16,2,3,16,null,null,ValTab16,511);
ht[18] = new huffcodetab("18 ",16,16,3,7,16,null,null,ValTab16,511);
ht[19] = new huffcodetab("19 ",16,16,4,15,16,null,null,ValTab16,511);
ht[20] = new huffcodetab("20 ",16,16,6,63,16,null,null,ValTab16,511);
ht[21] = new huffcodetab("21 ",16,16,8,255,16,null,null,ValTab16,511);
ht[22] = new huffcodetab("22 ",16,16,10,1023,16,null,null,ValTab16,511);
ht[23] = new huffcodetab("23 ",16,16,13,8191,16,null,null,ValTab16,511);
ht[24] = new huffcodetab("24 ",16,16,4,15,-1,null,null,ValTab24,512);
ht[25] = new huffcodetab("25 ",16,16,5,31,24,null,null,ValTab24,512);
ht[26] = new huffcodetab("26 ",16,16,6,63,24,null,null,ValTab24,512);
ht[27] = new huffcodetab("27 ",16,16,7,127,24,null,null,ValTab24,512);
ht[28] = new huffcodetab("28 ",16,16,8,255,24,null,null,ValTab24,512);
ht[29] = new huffcodetab("29 ",16,16,9,511,24,null,null,ValTab24,512);
ht[30] = new huffcodetab("30 ",16,16,11,2047,24,null,null,ValTab24,512);
ht[31] = new huffcodetab("31 ",16,16,13,8191,24,null,null,ValTab24,512);
ht[32] = new huffcodetab("32 ",1,16,0,0,-1,null,null,ValTab32,31);
ht[33] = new huffcodetab("33 ",1,16,0,0,-1,null,null,ValTab33,31);
}
}

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,15 @@
TODO:
Implement high-level Player and Converter classes.
Add MP1 and MP2 support and test.
Add option to run each "stage" on own thread.
E.g. read & parse input, decode subbands, subband synthesis, audio output.
Retrofit seek support (temporarily removed when reworking classes.)
Document and give example code.

Binary file not shown.

View File

@ -0,0 +1,265 @@
/*
* DecodedMpegAudioInputStream.
*
* JavaZOOM : mp3spi@javazoom.net
* http://www.javazoom.net
*
* Copyright (c) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/)
*
*-----------------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*------------------------------------------------------------------------
*/
package javazoom.mp3spi;
import java.io.IOException;
import java.io.InputStream;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import tritonus.TAsynchronousFilteredAudioInputStream;
import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.BitstreamException;
import javazoom.jl.decoder.Decoder;
import javazoom.jl.decoder.DecoderException;
import javazoom.jl.decoder.Header;
import javazoom.jl.decoder.Obuffer;
/**
* Main decoder.
*/
public class DecodedMpegAudioInputStream extends TAsynchronousFilteredAudioInputStream
{
private InputStream m_encodedStream;
private Bitstream m_bitstream;
private Decoder m_decoder;
private Header m_header;
private DMAISObuffer m_oBuffer;
// Bytes info.
private long byteslength = -1;
private long currentByte = 0;
// Frame info.
private int frameslength = -1;
private long currentFrame = 0;
private int currentFramesize = 0;
public DecodedMpegAudioInputStream(AudioFormat outputFormat,
AudioInputStream bufferedInputStream)
{
super(outputFormat, -1);
try
{
// Try to find out inputstream length to allow skip.
byteslength = bufferedInputStream.available();
} catch (IOException e)
{
byteslength = -1;
}
m_encodedStream = bufferedInputStream;
m_bitstream = new Bitstream(bufferedInputStream);
m_decoder = new Decoder(null);
// m_equalizer = new Equalizer();
// m_equalizer_values = new float[32];
// for (int b=0;b<m_equalizer.getBandCount();b++)
// {
// m_equalizer_values[b] = m_equalizer.getBand(b);
// }
// m_decoder.setEqualizer(m_equalizer);
m_oBuffer = new DMAISObuffer(outputFormat.getChannels());
m_decoder.setOutputBuffer(m_oBuffer);
try
{
m_header = m_bitstream.readFrame();
if((m_header != null) && (frameslength == -1) && (byteslength > 0))
frameslength = m_header.max_number_of_frames((int) byteslength);
} catch (BitstreamException e)
{
byteslength = -1;
}
}
public void execute()// if( reverseBytes )
// reverseBytes( smallBuffer, 0, bytesRead );
{
try
{
// Following line hangs when FrameSize is available in AudioFormat.
Header header = null;
if(m_header == null)
header = m_bitstream.readFrame();
else header = m_header;
if(header == null)
{
getCircularBuffer().close();
return;
}
currentFrame++;
currentFramesize = header.calculate_framesize();
currentByte = currentByte + currentFramesize;
// Obuffer decoderOutput =
m_decoder.decodeFrame(header, m_bitstream);
m_bitstream.closeFrame();
getCircularBuffer().write(m_oBuffer.getBuffer(), 0, m_oBuffer.getCurrentBufferSize());
m_oBuffer.reset();
if(m_header != null)
m_header = null;
} catch (BitstreamException e)
{
} catch (DecoderException e)
{
}
}
public long skip(long bytes)
{
if((byteslength > 0) && (frameslength > 0))
{
float ratio = bytes * 1.0f / byteslength * 1.0f;
long bytesread = skipFrames((long) (ratio * frameslength));
currentByte = currentByte + bytesread;
m_header = null;
return bytesread;
} else return -1;
}
/**
* Skip frames. You don't need to call it severals times, it will exactly
* skip given frames number.
*
* @param frames
* @return bytes length skipped matching to frames skipped.
*/
public long skipFrames(long frames)
{
int framesRead = 0;
int bytesReads = 0;
try
{
for(int i = 0; i < frames; i++)
{
Header header = m_bitstream.readFrame();
if(header != null)
{
int fsize = header.calculate_framesize();
bytesReads = bytesReads + fsize;
}
m_bitstream.closeFrame();
framesRead++;
}
} catch (BitstreamException e)
{
}
currentFrame = currentFrame + framesRead;
return bytesReads;
}
private boolean isBigEndian()
{
return getFormat().isBigEndian();
}
public void close() throws IOException
{
super.close();
m_encodedStream.close();
}
private class DMAISObuffer extends Obuffer
{
private int m_nChannels;
private byte[] m_abBuffer;
private int[] m_anBufferPointers;
private boolean m_bIsBigEndian;
public DMAISObuffer(int nChannels)
{
m_nChannels = nChannels;
m_abBuffer = new byte[OBUFFERSIZE * nChannels];
m_anBufferPointers = new int[nChannels];
reset();
m_bIsBigEndian = DecodedMpegAudioInputStream.this.isBigEndian();
}
public void append(int nChannel, short sValue)
{
byte bFirstByte;
byte bSecondByte;
if(m_bIsBigEndian)
{
bFirstByte = (byte) ((sValue >>> 8) & 0xFF);
bSecondByte = (byte) (sValue & 0xFF);
} else
// little endian
{
bFirstByte = (byte) (sValue & 0xFF);
bSecondByte = (byte) ((sValue >>> 8) & 0xFF);
}
m_abBuffer[m_anBufferPointers[nChannel]] = bFirstByte;
m_abBuffer[m_anBufferPointers[nChannel] + 1] = bSecondByte;
m_anBufferPointers[nChannel] += m_nChannels * 2;
}
public void set_stop_flag()
{
}
public void close()
{
}
public void write_buffer(int nValue)
{
}
public void clear_buffer()
{
}
public byte[] getBuffer()
{
return m_abBuffer;
}
public int getCurrentBufferSize()
{
return m_anBufferPointers[0];
}
public void reset()
{
for(int i = 0; i < m_nChannels; i++)
{
/*
* Points to byte location, implicitely assuming 16 bit samples.
*/
m_anBufferPointers[i] = i * 2;
}
}
}
}

View File

@ -0,0 +1,126 @@
package net.PeytonPlayz585;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.CharBuffer;
import java.nio.DoubleBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.nio.LongBuffer;
import java.nio.ShortBuffer;
/**
* Some often-used Buffer code for creating native buffers of the appropriate size.
*
* @author $Author$
* @version $Revision$
* $Id$
*/
public final class BufferUtils {
/**
* Construct a direct native-ordered bytebuffer with the specified size.
* @param size The size, in bytes
* @return a ByteBuffer
*/
public static ByteBuffer createByteBuffer(int size) {
return ByteBuffer.allocateDirect(size).order(ByteOrder.nativeOrder());
}
/**
* Construct a direct native-order shortbuffer with the specified number
* of elements.
* @param size The size, in shorts
* @return a ShortBuffer
*/
public static ShortBuffer createShortBuffer(int size) {
return createByteBuffer(size << 1).asShortBuffer();
}
/**
* Construct a direct native-order charbuffer with the specified number
* of elements.
* @param size The size, in chars
* @return an CharBuffer
*/
public static CharBuffer createCharBuffer(int size) {
return createByteBuffer(size << 1).asCharBuffer();
}
/**
* Construct a direct native-order intbuffer with the specified number
* of elements.
* @param size The size, in ints
* @return an IntBuffer
*/
public static IntBuffer createIntBuffer(int size) {
return createByteBuffer(size << 2).asIntBuffer();
}
/**
* Construct a direct native-order longbuffer with the specified number
* of elements.
* @param size The size, in longs
* @return an LongBuffer
*/
public static LongBuffer createLongBuffer(int size) {
return createByteBuffer(size << 3).asLongBuffer();
}
/**
* Construct a direct native-order floatbuffer with the specified number
* of elements.
* @param size The size, in floats
* @return a FloatBuffer
*/
public static FloatBuffer createFloatBuffer(int size) {
return createByteBuffer(size << 2).asFloatBuffer();
}
/**
* Construct a direct native-order doublebuffer with the specified number
* of elements.
* @param size The size, in floats
* @return a FloatBuffer
*/
public static DoubleBuffer createDoubleBuffer(int size) {
return createByteBuffer(size << 3).asDoubleBuffer();
}
/**
* Construct a PointerBuffer with the specified number
* of elements.
* @param size The size, in memory addresses
* @return a PointerBuffer
*/
public static PointerBuffer createPointerBuffer(int size) {
return (PointerBuffer) PointerBuffer.allocateDirect(size);
}
/**
* @return n, where buffer_element_size=2^n.
*/
public static int getElementSizeExponent(Buffer buf) {
if (buf instanceof ByteBuffer)
return 0;
else if (buf instanceof ShortBuffer || buf instanceof CharBuffer)
return 1;
else if (buf instanceof FloatBuffer || buf instanceof IntBuffer)
return 2;
else if (buf instanceof LongBuffer || buf instanceof DoubleBuffer)
return 3;
else
throw new IllegalStateException("Unsupported buffer type: " + buf);
}
/**
* A helper function which is used to get the byte offset in an arbitrary buffer
* based on its position
* @return the position of the buffer, in BYTES
*/
public static int getOffset(Buffer buffer) {
return buffer.position() << getElementSizeExponent(buffer);
}
}

View File

@ -0,0 +1,18 @@
package net.PeytonPlayz585;
import net.PeytonPlayz585.opengl.GL11;
import net.minecraft.client.Minecraft;
import net.minecraft.src.Session;
public class Client {
public static void main(String[] par0ArrayOfStr) {
GL11.EaglerAdapterImpl2.initializeContext();
Minecraft mc = new Minecraft();
mc.session = new Session("Player094", "mcpass");
mc.run();
}
}

View File

@ -0,0 +1,20 @@
package net.PeytonPlayz585;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import org.lwjgl.opengl.Display;
import net.PeytonPlayz585.opengl.GL11;
import net.minecraft.client.Minecraft;
public final class GameWindowListener extends WindowAdapter {
public void windowClosing(WindowEvent par1WindowEvent) {
if(Minecraft.getMinecraft() != null) {
Minecraft.getMinecraft().shutdownMinecraftApplet();
Minecraft.getMinecraft().shutdown();
} else {
GL11.EaglerAdapterImpl2.exit();
}
}
}

View File

@ -0,0 +1,10 @@
package net.PeytonPlayz585;
public class LWJGLException extends org.lwjgl.LWJGLException {
/**
*
*/
private static final long serialVersionUID = 1L;
}

View File

@ -0,0 +1,13 @@
package net.PeytonPlayz585;
import java.nio.ByteBuffer;
public class PointerBuffer extends org.lwjgl.PointerBuffer {
public PointerBuffer(ByteBuffer buf) {
super(buf);
}
public PointerBuffer(int capacity) {
super(capacity);
}
}

View File

@ -0,0 +1,5 @@
package net.PeytonPlayz585;
public interface PointerWrapper extends org.lwjgl.PointerWrapper {
}

View File

@ -0,0 +1,199 @@
package net.PeytonPlayz585.fileutils;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
public class File {
private static final java.io.File filesystemBaseDirectory = new java.io.File("filesystem");
static {
filesystemBaseDirectory.mkdirs();
}
// ======== Virtual Filesystem Functions =============
public static final boolean exists(String path) {
return (new java.io.File(filesystemBaseDirectory, stripPath(path))).exists();
}
public static final boolean fileExists(String path) {
return (new java.io.File(filesystemBaseDirectory, stripPath(path))).isFile();
}
public static final boolean directoryExists(String path) {
return (new java.io.File(filesystemBaseDirectory, stripPath(path))).isDirectory();
}
public static final boolean pathExists(String path) {
return (new java.io.File(filesystemBaseDirectory, stripPath(path))).exists();
}
public static final void writeFile(String path, byte[] data) {
try {
java.io.File f = new java.io.File(filesystemBaseDirectory, stripPath(path));
java.io.File p = f.getParentFile();
if(p != null) {
p.mkdirs();
}
FileOutputStream os = new FileOutputStream(f);
os.write(data);
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public static final byte[] readFile(String path) {
java.io.File f = new java.io.File(filesystemBaseDirectory, stripPath(path));
if(!f.isFile()) {
return null;
}
try {
byte[] ret = new byte[(int)f.length()];
FileInputStream in = new FileInputStream(f);
in.read(ret);
in.close();
return ret;
}catch(IOException ex) {
ex.printStackTrace();
return null;
}
}
public static final long getLastModified(String path) {
return (new java.io.File(filesystemBaseDirectory, stripPath(path))).lastModified();
}
public static final int getFileSize(String path) {
return (int)(new java.io.File(filesystemBaseDirectory, stripPath(path))).length();
}
public static final void renameFile(String oldPath, String newPath) {
java.io.File f1 = new java.io.File(filesystemBaseDirectory, stripPath(oldPath));
java.io.File f2 = new java.io.File(filesystemBaseDirectory, stripPath(newPath));
if(f1.exists()) {
if(f2.exists()) {
try {
FileInputStream fs1 = new FileInputStream(f1);
FileOutputStream fs2 = new FileOutputStream(f2);
byte[] buffer = new byte[1024 * 64];
int a;
while((a = fs1.read(buffer)) > 0) {
fs2.write(buffer, 0, a);
}
fs1.close();
fs2.close();
f1.delete();
} catch (IOException e) {
System.err.println("Copy from '" + oldPath + "' to '" + newPath + "' failed");
e.printStackTrace();
}
}else {
java.io.File p = f2.getParentFile();
if(p != null) {
p.mkdirs();
}
f1.renameTo(f2);
}
}
}
public static final void copyFile(String oldPath, String newPath) {
try {
java.io.File ff2 = new java.io.File(filesystemBaseDirectory, stripPath(newPath));
java.io.File p = ff2.getParentFile();
if(p != null) {
p.mkdirs();
}
FileInputStream f1 = new FileInputStream(new java.io.File(filesystemBaseDirectory, stripPath(oldPath)));
FileOutputStream f2 = new FileOutputStream(ff2);
byte[] buffer = new byte[1024 * 64];
int a;
while((a = f1.read(buffer)) > 0) {
f2.write(buffer, 0, a);
}
f1.close();
f2.close();
} catch (IOException e) {
System.err.println("Copy from '" + oldPath + "' to '" + newPath + "' failed");
e.printStackTrace();
}
}
public static final void deleteFile(String path) {
(new java.io.File(filesystemBaseDirectory, stripPath(path))).delete();
}
public static final Collection<FileEntry> listFiles(String path, boolean listDirs, boolean recursiveDirs) {
path = stripPath(path);
ArrayList<FileEntry> ret = new ArrayList<>();
java.io.File f = new java.io.File(filesystemBaseDirectory, path);
if(f.isFile()) {
ret.add(new FileEntry(path, false, f.lastModified()));
}else if(f.isDirectory()) {
for(java.io.File ff : f.listFiles()) {
if(ff.isDirectory()) {
if(listDirs && !recursiveDirs) {
ret.add(new FileEntry(path + "/" + ff.getName(), true, -1l));
}
if(recursiveDirs) {
recursiveListing(path + "/" + ff.getName(), ff, ret, listDirs, recursiveDirs);
}
}else {
ret.add(new FileEntry(path + "/" + ff.getName(), false, ff.lastModified()));
}
}
}
return ret;
}
private static void recursiveListing(String path, java.io.File f, Collection<FileEntry> lst, boolean listDirs, boolean recursiveDirs) {
if(f.isFile()) {
lst.add(new FileEntry(path, false, f.lastModified()));
}else if(f.isDirectory()) {
if(listDirs) {
lst.add(new FileEntry(path, true, -1l));
}
if(recursiveDirs) {
for(java.io.File ff : f.listFiles()) {
recursiveListing(path + "/" + ff.getName(), ff, lst, listDirs, recursiveDirs);
}
}
}
}
public static final Collection<FileEntry> listFilesAndDirectories(String path) {
return listFiles(path, true, false);
}
public static final Collection<FileEntry> listFilesRecursive(String path) {
return listFiles(path, false, true);
}
public static final FileEntry[] listFiles(String path) {
Collection<FileEntry> entries = listFilesAndDirectories(path);
FileEntry[] entryArray = new FileEntry[entries.size()];
int i = 0;
for(FileEntry entry : entries) {
entryArray[i] = entry;
i = i + 1;
}
return entryArray;
}
private static String stripPath(String str) {
if(str.startsWith("/")) {
str = str.substring(1);
}
if(str.endsWith("/")) {
str = str.substring(0, str.length() - 1);
}
return str;
}
}

View File

@ -1,6 +1,6 @@
package org.lwjgl.input;
package net.PeytonPlayz585.input;
import org.lwjgl.opengl.GL11;
import net.PeytonPlayz585.opengl.GL11;
public class Keyboard {

View File

@ -1,6 +1,6 @@
package org.lwjgl.input;
package net.PeytonPlayz585.input;
import org.lwjgl.opengl.GL11;
import net.PeytonPlayz585.opengl.GL11;
public class Mouse {

View File

@ -0,0 +1,58 @@
package net.PeytonPlayz585.opengl;
public class Display {
static Display display = new Display();
//Can NOT be null!
private static String title = "Minecraft";
public Display() {
}
public static boolean isActive() {
return GL11.EaglerAdapterImpl2.isFocused();
}
public static int getWidth() {
return GL11.EaglerAdapterImpl2.getCanvasWidth();
}
public static int getHeight() {
return GL11.EaglerAdapterImpl2.getCanvasHeight();
}
public static void setFullscreen(boolean b) {
GL11.EaglerAdapterImpl2.setFullscreen(b);
}
public static void setTitle(String newTitle) {
if(newTitle == null) {
throw new IllegalArgumentException("title CAN NOT be null");
}
title = newTitle;
}
public static void update() {
//GL11.EaglerAdapterImpl2.doc.setTitle(title);
GL11.EaglerAdapterImpl2.updateDisplay();
}
public static Display getDisplayMode() {
return display;
}
public static void swapBuffers() {
GL11.glFlush();
GL11.EaglerAdapterImpl2.updateDisplay();
}
public static void destroy() {
}
public static boolean isFocused() {
return GL11.EaglerAdapterImpl2.isFocused();
}
}

View File

@ -0,0 +1,9 @@
package net.PeytonPlayz585.opengl;
public class GL11 extends GL11_1 {
public static class EaglerAdapterImpl2 extends GL11_1.EaglerAdapterImpl2 {
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
package org.lwjgl.opengl;
package net.PeytonPlayz585.opengl;
public class GL12 extends GL11 {

View File

@ -1,4 +1,4 @@
package org.lwjgl.opengl;
package net.PeytonPlayz585.opengl;
public class GL13 extends GL12 {

View File

@ -1,9 +1,9 @@
package org.lwjgl.util.glu;
package net.PeytonPlayz585.util.glu;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.opengl.GL11;
import net.PeytonPlayz585.opengl.GL11;
public class GLU {

View File

@ -1,4 +1,4 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
import java.io.Serializable;
import java.nio.FloatBuffer;

View File

@ -1,4 +1,4 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
import java.io.Serializable;
import java.nio.FloatBuffer;

View File

@ -1,4 +1,4 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
import java.nio.FloatBuffer;

View File

@ -1,4 +1,4 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
public interface ReadableVector2f extends ReadableVector {
float getX();

View File

@ -1,4 +1,4 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
public interface ReadableVector3f extends ReadableVector2f {
float getZ();

View File

@ -1,4 +1,4 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
public interface ReadableVector4f extends ReadableVector3f {

View File

@ -1,4 +1,4 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
import java.io.Serializable;
import java.nio.FloatBuffer;

View File

@ -1,10 +1,8 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
import java.io.Serializable;
import java.nio.FloatBuffer;
import org.lwjgl.util.vector.Vector2f;
public class Vector2f extends Vector implements Serializable, ReadableVector2f, WritableVector2f {
private static final long serialVersionUID = 1L;

View File

@ -1,4 +1,4 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
import java.io.Serializable;
import java.nio.FloatBuffer;

View File

@ -1,10 +1,8 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
import java.io.Serializable;
import java.nio.FloatBuffer;
import org.lwjgl.util.vector.Vector4f;
public class Vector4f extends Vector implements Serializable, ReadableVector4f, WritableVector4f {
private static final long serialVersionUID = 1L;

View File

@ -1,4 +1,4 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
public interface WritableVector2f {

View File

@ -1,4 +1,4 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
public interface WritableVector3f extends WritableVector2f {

View File

@ -1,4 +1,4 @@
package org.lwjgl.util.vector;
package net.PeytonPlayz585.util.vector;
public interface WritableVector4f extends WritableVector3f {

View File

@ -0,0 +1,248 @@
package net.minecraft.src;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import net.PeytonPlayz585.opengl.GL11;
public class Tessellator {
private ByteBuffer byteBuffer;
private IntBuffer intBuffer;
private int[] rawBuffer;
private int vertexCount = 0;
private double textureU;
private double textureV;
private int color;
private boolean hasColor = false;
private boolean hasTexture = false;
private boolean hasNormals = false;
private int rawBufferIndex = 0;
private int addedVertices = 0;
private boolean isColorDisabled = false;
private int drawMode;
private double xOffset;
private double yOffset;
private double zOffset;
private int normal;
public static final Tessellator instance = new Tessellator(2097152);
private boolean isDrawing = false;
private IntBuffer vertexBuffers;
private int vboIndex = 0;
private int vboCount = 10;
private int bufferSize;
private Tessellator(int var1) {
this.bufferSize = var1;
this.byteBuffer = GLAllocation.createDirectByteBuffer(var1 * 4);
this.intBuffer = this.byteBuffer.asIntBuffer();
this.rawBuffer = new int[var1];
}
public void draw() {
if(!this.isDrawing) {
throw new IllegalStateException("Not tesselating!");
} else {
this.isDrawing = false;
if(this.vertexCount > 0) {
IntBuffer upload = null;
this.intBuffer.clear();
this.intBuffer.put(rawBuffer, 0, this.rawBufferIndex);
this.intBuffer.flip();
upload = this.intBuffer;
if(this.hasTexture) {
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
}
if(this.hasColor) {
GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
}
if(this.hasNormals) {
GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
}
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glDrawArrays(this.drawMode, GL11.GL_POINTS, this.vertexCount, upload);
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
if(this.hasTexture) {
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
}
if(this.hasColor) {
GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
}
if(this.hasNormals) {
GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
}
}
this.reset();
}
}
private void reset() {
this.vertexCount = 0;
this.rawBufferIndex = 0;
this.addedVertices = 0;
}
public void startDrawingQuads() {
this.startDrawing(7);
}
public void startDrawing(int var1) {
if(this.isDrawing) {
throw new IllegalStateException("Already tesselating!");
} else {
this.isDrawing = true;
this.reset();
this.drawMode = var1;
this.hasNormals = false;
this.hasColor = false;
this.hasTexture = false;
this.isColorDisabled = false;
}
}
public void setTextureUV(double var1, double var3) {
this.hasTexture = true;
this.textureU = (float) var1;
this.textureV = (float) var3;
}
public void setColorOpaque_F(float var1, float var2, float var3) {
this.setColorOpaque((int)(var1 * 255.0F), (int)(var2 * 255.0F), (int)(var3 * 255.0F));
}
public void setColorRGBA_F(float var1, float var2, float var3, float var4) {
this.setColorRGBA((int)(var1 * 255.0F), (int)(var2 * 255.0F), (int)(var3 * 255.0F), (int)(var4 * 255.0F));
}
public void setColorOpaque(int var1, int var2, int var3) {
this.setColorRGBA(var1, var2, var3, 255);
}
public void setColorRGBA(int var1, int var2, int var3, int var4) {
if(!this.isColorDisabled) {
if(var1 > 255) {
var1 = 255;
}
if(var2 > 255) {
var2 = 255;
}
if(var3 > 255) {
var3 = 255;
}
if(var4 > 255) {
var4 = 255;
}
if(var1 < 0) {
var1 = 0;
}
if(var2 < 0) {
var2 = 0;
}
if(var3 < 0) {
var3 = 0;
}
if(var4 < 0) {
var4 = 0;
}
this.hasColor = true;
if(ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
this.color = var4 << 24 | var3 << 16 | var2 << 8 | var1;
} else {
this.color = var1 << 24 | var2 << 16 | var3 << 8 | var4;
}
}
}
public void addVertexWithUV(double var1, double var3, double var5, double var7, double var9) {
this.setTextureUV(var7, var9);
this.addVertex(var1, var3, var5);
}
public void addVertex(double var1, double var3, double var5) {
if(this.addedVertices > 65534) return;
++this.addedVertices;
this.rawBuffer[this.rawBufferIndex + 0] = Float.floatToRawIntBits((float) (var1 + this.xOffset));
this.rawBuffer[this.rawBufferIndex + 1] = Float.floatToRawIntBits((float) (var3 + this.yOffset));
this.rawBuffer[this.rawBufferIndex + 2] = Float.floatToRawIntBits((float) (var5 + this.zOffset));
if (this.hasTexture) {
this.rawBuffer[this.rawBufferIndex + 3] = Float.floatToRawIntBits((float) this.textureU);
this.rawBuffer[this.rawBufferIndex + 4] = Float.floatToRawIntBits((float) this.textureV);
}
if (this.hasColor) {
this.rawBuffer[this.rawBufferIndex + 5] = this.color;
}
if (this.hasNormals) {
this.rawBuffer[this.rawBufferIndex + 6] = this.normal;
}
this.rawBufferIndex += 8;
++this.vertexCount;
if(this.vertexCount % 4 == 0 && this.rawBufferIndex >= this.bufferSize - 32) {
this.draw();
this.isDrawing = true;
}
}
public void setColorOpaque_I(int var1) {
int var2 = var1 >>> 16 & 255;
int var3 = var1 >>> 8 & 255;
int var4 = var1 & 255;
this.setColorOpaque(var2, var3, var4);
}
public void setColorRGBA_I(int var1, int var2) {
int var3 = var1 >>> 16 & 255;
int var4 = var1 >>> 8 & 255;
int var5 = var1 & 255;
this.setColorRGBA(var3, var4, var5, var2);
}
public void disableColor() {
this.isColorDisabled = true;
}
public void setNormal(float var1, float var2, float var3) {
if(!this.isDrawing) {
System.out.println("But..");
}
this.hasNormals = true;
int var4 = (int)((var1) * 127.0F) + 127;
int var5 = (int)((var2) * 127.0F) + 127;
int var6 = (int)((var3) * 127.0F) + 127;
this.normal = var4 & 255 | (var5 & 255) << 8 | (var6 & 255) << 16;
}
public void setTranslationD(double var1, double var3, double var5) {
this.xOffset = var1;
this.yOffset = var3;
this.zOffset = var5;
}
public void setTranslationF(float var1, float var2, float var3) {
this.xOffset += (double)var1;
this.yOffset += (double)var2;
this.zOffset += (double)var3;
}
}

View File

@ -0,0 +1,270 @@
package paulscode.sound;
import java.util.LinkedList;
import javax.sound.sampled.AudioFormat;
/**
* The Channel class is the base class which can be extended for
* library-specific channels. It is also used in the "no-sound" library.
* A channel is a reserved sound-card voice through which sources are played
* back. Channels can be either streaming channels or normal (non-streaming)
* ones. For consistant naming conventions, each sub-class should have the
* name prefix "Channel".
*<br><br>
*<b><i> SoundSystem License:</b></i><br><b><br>
* You are free to use this library for any purpose, commercial or otherwise.
* You may modify this library or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this library or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this library or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this library in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this library or any part
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this library or any
* part of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
* </b>
*/
public class Channel
{
/**
* The library class associated with this type of channel.
*/
protected Class libraryType = Library.class;
/**
* Global identifier for the type of channel (normal or streaming). Possible
* values for this varriable can be found in the
* {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class.
*/
public int channelType;
/**
* Processes status messages, warnings, and error messages.
*/
private SoundSystemLogger logger;
/**
* Whatever source is attached to this channel.
*/
public Source attachedSource = null;
/**
* Cumulative counter of the buffers played then unqued.
*/
public int buffersUnqueued = 0;
/**
* Constructor: Takes channelType identifier as a paramater. Possible values
* for channel type can be found in the
* {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} class.
* @param type Type of channel (normal or streaming).
*/
public Channel( int type )
{
// grab a handle to the message logger:
logger = SoundSystemConfig.getLogger();
channelType = type;
}
/**
* Shuts the channel down and removes references to all instantiated objects.
*/
public void cleanup()
{
logger = null;
}
/**
* Queues up the initial byte[] buffers of data to be streamed.
* @param bufferList List of the first buffers to be played for a streaming source.
* @return False if an error occurred or if end of stream was reached.
*/
public boolean preLoadBuffers( LinkedList<byte[]> bufferList )
{
return true;
}
/**
* Queues up a byte[] buffer of data to be streamed.
* @param buffer The next buffer to be played for a streaming source.
* @return False if an error occurred or if the channel is shutting down.
*/
public boolean queueBuffer( byte[] buffer )
{
return false;
}
/**
* Feeds raw data to the stream.
* @param buffer Buffer containing raw audio data to stream.
* @return Number of prior buffers that have been processed.
*/
public int feedRawAudioData( byte[] buffer )
{
return 1;
}
/**
* Returns the number of queued byte[] buffers that have finished playing.
* @return Number of buffers processed.
*/
public int buffersProcessed()
{
return 0;
}
/**
* Calculates the number of milliseconds since the channel began playing.
* @return Milliseconds, or -1 if unable to calculate.
*/
public float millisecondsPlayed()
{
return -1;
}
/**
* Plays the next queued byte[] buffer. This method is run from the seperate
* {@link paulscode.sound.StreamThread StreamThread}.
* @return False when no more buffers are left to process.
*/
public boolean processBuffer()
{
return false;
}
/**
* Sets the channel up to receive the specified audio format.
*/
public void setAudioFormat( AudioFormat audioFormat )
{}
/**
* Dequeues all previously queued data.
*/
public void flush()
{}
/**
* Stops the channel, dequeues any queued data, and closes the channel.
*/
public void close()
{}
/**
* Plays the currently attached normal source, opens this channel up for
* streaming, or resumes playback if this channel was paused.
*/
public void play()
{}
/**
* Temporarily stops playback for this channel.
*/
public void pause()
{}
/**
* Stops playback for this channel and rewinds the attached source to the
* beginning.
*/
public void stop()
{}
/**
* Rewinds the attached source to the beginning. Stops the source if it was
* paused.
*/
public void rewind()
{}
/**
* Used to determine if a channel is actively playing a source. This method
* will return false if the channel is paused or stopped and when no data is
* queued to be streamed.
* @return True if this channel is playing a source.
*/
public boolean playing()
{
return false;
}
/**
* Returns the name of the class.
* @return "Channel" + library title.
*/
public String getClassName()
{
String libTitle = SoundSystemConfig.getLibraryTitle( libraryType );
if( libTitle.equals( "No Sound" ) )
return "Channel";
else
return "Channel" + libTitle;
}
/**
* Prints a message.
* @param message Message to print.
*/
protected void message( String message )
{
logger.message( message, 0 );
}
/**
* Prints an important message.
* @param message Message to print.
*/
protected void importantMessage( String message )
{
logger.importantMessage( message, 0 );
}
/**
* Prints the specified message if error is true.
* @param error True or False.
* @param message Message to print if error is true.
* @return True if error is true.
*/
protected boolean errorCheck( boolean error, String message )
{
return logger.errorCheck( error, getClassName(), message, 0 );
}
/**
* Prints an error message.
* @param message Message to print.
*/
protected void errorMessage( String message )
{
logger.errorMessage( getClassName(), message, 0 );
}
/**
* Prints an exception's error message followed by the stack trace.
* @param e Exception containing the information to print.
*/
protected void printStackTrace( Exception e )
{
logger.printStackTrace( e, 1 );
}
}

View File

@ -0,0 +1,603 @@
package paulscode.sound;
/**
* The CommandObject class is used to store arguments in the SoundSystem's
* Command Queue. Queued CommandObjects are then processed by the
* {@link paulscode.sound.CommandThread CommandThread}. Commands are queued
* and executed in the background, so it is unlikely that the user will ever
* need to use this class.
*<br><br>
*<b><i> SoundSystem License:</b></i><br><b><br>
* You are free to use this library for any purpose, commercial or otherwise.
* You may modify this library or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this library or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this library or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this library in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this library or any part
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this library or any
* part of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
* </b>
*/
public class CommandObject
{
/**
* Global identifier for the command to initialize the current sound library.
*/
public static final int INITIALIZE = 1;
/**
* Global identifier for the command to pre-load a sound file.
*/
public static final int LOAD_SOUND = 2;
/**
* Global identifier for the command to pre-load a sound file.
*/
public static final int LOAD_DATA = 3;
/**
* Global identifier for the command to remove a sound file from memory.
*/
public static final int UNLOAD_SOUND = 4;
/**
* Global identifier for the command to queue a sound file.
*/
public static final int QUEUE_SOUND = 5;
/**
* Global identifier for the command to dequeue a sound file.
*/
public static final int DEQUEUE_SOUND = 6;
/**
* Global identifier for the command to fade-out transition a source.
*/
public static final int FADE_OUT = 7;
/**
* Global identifier for the command to fade-out/in transition a source.
*/
public static final int FADE_OUT_IN = 8;
/**
* Global identifier for the command to check volume levels of fading sources.
*/
public static final int CHECK_FADE_VOLUMES = 9;
/**
* Global identifier for the command to create a new source.
*/
public static final int NEW_SOURCE = 10;
/**
* Global identifier for the command to create a new raw data stream.
*/
public static final int RAW_DATA_STREAM = 11;
/**
* Global identifier for the command to create a source and immediately play it.
*/
public static final int QUICK_PLAY = 12;
/**
* Global identifier for the command to set a source's position in 3D space.
*/
public static final int SET_POSITION = 13;
/**
* Global identifier for the command to change a source's volume.
*/
public static final int SET_VOLUME = 14;
/**
* Global identifier for the command to change a source's pitch.
*/
public static final int SET_PITCH = 15;
/**
* Global identifier for the command to change a source's priority.
*/
public static final int SET_PRIORITY = 16;
/**
* Global identifier for the command to tell a source whether or not to loop.
*/
public static final int SET_LOOPING = 17;
/**
* Global identifier for the command to set a source's attenuation model.
*/
public static final int SET_ATTENUATION = 18;
/**
* Global identifier for the command to set a source's fade distance or rolloff
* factor.
*/
public static final int SET_DIST_OR_ROLL = 19;
/**
* Global identifier for the command to change the Doppler factor.
*/
public static final int CHANGE_DOPPLER_FACTOR = 20;
/**
* Global identifier for the command to change the Doppler velocity.
*/
public static final int CHANGE_DOPPLER_VELOCITY = 21;
/**
* Global identifier for the command to set a source's velocity.
*/
public static final int SET_VELOCITY = 22;
/**
* Global identifier for the command to set a source's velocity.
*/
public static final int SET_LISTENER_VELOCITY = 23;
/**
* Global identifier for the command to play a source.
*/
public static final int PLAY = 24;
/**
* Global identifier for the command to play a source.
*/
public static final int FEED_RAW_AUDIO_DATA = 25;
/**
* Global identifier for the command to pause a source.
*/
public static final int PAUSE = 26;
/**
* Global identifier for the command to stop a source.
*/
public static final int STOP = 27;
/**
* Global identifier for the command to rewind a source.
*/
public static final int REWIND = 28;
/**
* Global identifier for the command to flush all queued data.
*/
public static final int FLUSH = 29;
/**
* Global identifier for the command to cull a source.
*/
public static final int CULL = 30;
/**
* Global identifier for the command to activate a source.
*/
public static final int ACTIVATE = 31;
/**
* Global identifier for the command to set a source as permanant or temporary.
*/
public static final int SET_TEMPORARY = 32;
/**
* Global identifier for the command to delete a source.
*/
public static final int REMOVE_SOURCE = 33;
/**
* Global identifier for the command to move the listner.
*/
public static final int MOVE_LISTENER = 34;
/**
* Global identifier for the command to set the listener's position.
*/
public static final int SET_LISTENER_POSITION = 35;
/**
* Global identifier for the command to turn the listener.
*/
public static final int TURN_LISTENER = 36;
/**
* Global identifier for the command to set the listener's turn angle.
*/
public static final int SET_LISTENER_ANGLE = 37;
/**
* Global identifier for the command to change the listener's orientation.
*/
public static final int SET_LISTENER_ORIENTATION = 38;
/**
* Global identifier for the command to change the master volume.
*/
public static final int SET_MASTER_VOLUME = 39;
/**
* Global identifier for the command to create a new library.
*/
public static final int NEW_LIBRARY = 40;
/**
* Any buffer required for a command.
*/
public byte[] buffer;
/**
* Any int arguments required for a command.
*/
public int[] intArgs;
/**
* Any float arguments required for a command.
*/
public float[] floatArgs;
/**
* Any long arguments required for a command.
*/
public long[] longArgs;
/**
* Any boolean arguments required for a command.
*/
public boolean[] boolArgs;
/**
* Any String arguments required for a command.
*/
public String[] stringArgs;
/**
* Any Class arguments required for a command.
*/
public Class[] classArgs;
/**
* Any Object arguments required for a command.
*/
public Object[] objectArgs;
/**
* Which command to execute.
*/
public int Command;
/**
* Constructor used to create a command which doesn't require any arguments.
* @param cmd Which command to execute.
*/
public CommandObject( int cmd )
{
Command = cmd;
}
/**
* Constructor used to create a command which requires one integer argument.
* @param cmd Which command to execute.
* @param i The integer argument needed to execute this command.
*/
public CommandObject( int cmd, int i )
{
Command = cmd;
intArgs = new int[1];
intArgs[0] = i;
}
/**
* Constructor used to create a command which requires one Library Class
* argument.
* @param cmd Which command to execute.
* @param c The Library Class argument needed to execute this command.
*/
public CommandObject( int cmd, Class c )
{
Command = cmd;
classArgs = new Class[1];
classArgs[0] = c;
}
/**
* Constructor used to create a command which requires one float argument.
* @param cmd Which command to execute.
* @param f The float argument needed to execute this command.
*/
public CommandObject( int cmd, float f )
{
Command = cmd;
floatArgs = new float[1];
floatArgs[0] = f;
}
/**
* Constructor used to create a command which requires one String argument.
* @param cmd Which command to execute.
* @param s The String argument needed to execute this command.
*/
public CommandObject( int cmd, String s )
{
Command = cmd;
stringArgs = new String[1];
stringArgs[0] = s;
}
/**
* Constructor used to create a command which requires one Object argument.
* @param cmd Which command to execute.
* @param o The Object argument needed to execute this command.
*/
public CommandObject( int cmd, Object o )
{
Command = cmd;
objectArgs = new Object[1];
objectArgs[0] = o;
}
/**
* Constructor used to create a command which requires one String argument and
* one Object argument.
* @param cmd Which command to execute.
* @param s The String argument needed to execute this command.
* @param o The Object argument needed to execute this command.
*/
public CommandObject( int cmd, String s, Object o )
{
Command = cmd;
stringArgs = new String[1];
stringArgs[0] = s;
objectArgs = new Object[1];
objectArgs[0] = o;
}
/**
* Constructor used to create a command which requires one String argument and
* one byte buffer argument.
* @param cmd Which command to execute.
* @param s The String argument needed to execute this command.
* @param buff The byte buffer argument needed to execute this command.
*/
public CommandObject( int cmd, String s, byte[] buff )
{
Command = cmd;
stringArgs = new String[1];
stringArgs[0] = s;
buffer = buff;
}
/**
* Constructor used to create a command which requires one String argument, one
* Object argument, and one long argument.
* @param cmd Which command to execute.
* @param s The String argument needed to execute this command.
* @param o The Object argument needed to execute this command.
* @param l The long argument needed to execute this command.
*/
public CommandObject( int cmd, String s, Object o, long l )
{
Command = cmd;
stringArgs = new String[1];
stringArgs[0] = s;
objectArgs = new Object[1];
objectArgs[0] = o;
longArgs = new long[1];
longArgs[0] = l;
}
/**
* Constructor used to create a command which requires one String argument, one
* Object argument, and two long arguments.
* @param cmd Which command to execute.
* @param s The String argument needed to execute this command.
* @param o The Object argument needed to execute this command.
* @param l1 The first long argument needed to execute this command.
* @param l2 The second long argument needed to execute this command.
*/
public CommandObject( int cmd, String s, Object o, long l1, long l2 )
{
Command = cmd;
stringArgs = new String[1];
stringArgs[0] = s;
objectArgs = new Object[1];
objectArgs[0] = o;
longArgs = new long[2];
longArgs[0] = l1;
longArgs[1] = l2;
}
/**
* Constructor used to create a command which requires two String arguments.
* @param cmd Which command to execute.
* @param s1 The first String argument needed to execute this command.
* @param s2 The second String argument needed to execute this command.
*/
public CommandObject( int cmd, String s1, String s2 )
{
Command = cmd;
stringArgs = new String[2];
stringArgs[0] = s1;
stringArgs[1] = s2;
}
/**
* Constructor used to create a command which requires a String and an int as
* arguments.
* @param cmd Which command to execute.
* @param s The String argument needed to execute this command.
* @param i The integer argument needed to execute this command.
*/
public CommandObject( int cmd, String s, int i )
{
Command = cmd;
intArgs = new int[1];
stringArgs = new String[1];
intArgs[0] = i;
stringArgs[0] = s;
}
/**
* Constructor used to create a command which requires a String and a float as
* arguments.
* @param cmd Which command to execute.
* @param s The String argument needed to execute this command.
* @param f The float argument needed to execute this command.
*/
public CommandObject( int cmd, String s, float f )
{
Command = cmd;
floatArgs = new float[1];
stringArgs = new String[1];
floatArgs[0] = f;
stringArgs[0] = s;
}
/**
* Constructor used to create a command which requires a String and a boolean
* as arguments.
* @param cmd Which command to execute.
* @param s The String argument needed to execute this command.
* @param b The boolean argument needed to execute this command.
*/
public CommandObject( int cmd, String s, boolean b )
{
Command = cmd;
boolArgs = new boolean[1];
stringArgs = new String[1];
boolArgs[0] = b;
stringArgs[0] = s;
}
/**
* Constructor used to create a command which requires three float arguments.
* @param cmd Which command to execute.
* @param f1 The first float argument needed to execute this command.
* @param f2 The second float argument needed to execute this command.
* @param f3 The third float argument needed to execute this command.
*/
public CommandObject( int cmd, float f1, float f2, float f3 )
{
Command = cmd;
floatArgs = new float[3];
floatArgs[0] = f1;
floatArgs[1] = f2;
floatArgs[2] = f3;
}
/**
* Constructor used to create a command which a String and three float
* arguments.
* @param cmd Which command to execute.
* @param s The String argument needed to execute this command.
* @param f1 The first float argument needed to execute this command.
* @param f2 The second float argument needed to execute this command.
* @param f3 The third float argument needed to execute this command.
*/
public CommandObject( int cmd, String s, float f1, float f2, float f3 )
{
Command = cmd;
floatArgs = new float[3];
stringArgs = new String[1];
floatArgs[0] = f1;
floatArgs[1] = f2;
floatArgs[2] = f3;
stringArgs[0] = s;
}
/**
* Constructor used to create a command which requires six float arguments.
* @param cmd Which command to execute.
* @param f1 The first float argument needed to execute this command.
* @param f2 The second float argument needed to execute this command.
* @param f3 The third float argument needed to execute this command.
* @param f4 The fourth float argument needed to execute this command.
* @param f5 The fifth float argument needed to execute this command.
* @param f6 The sixth float argument needed to execute this command.
*/
public CommandObject( int cmd, float f1, float f2, float f3, float f4,
float f5, float f6 )
{
Command = cmd;
floatArgs = new float[6];
floatArgs[0] = f1;
floatArgs[1] = f2;
floatArgs[2] = f3;
floatArgs[3] = f4;
floatArgs[4] = f5;
floatArgs[5] = f6;
}
/**
* Constructor used to create a command which requires several arguments.
* @param cmd Which command to execute.
* @param b1 The first boolean argument needed to execute this command.
* @param b2 The second boolean argument needed to execute this command.
* @param b3 The third boolean argument needed to execute this command.
* @param s The String argument needed to execute this command.
* @param o The Object argument needed to execute this command.
* @param f1 The first float argument needed to execute this command.
* @param f2 The second float argument needed to execute this command.
* @param f3 The third float argument needed to execute this command.
* @param i The integer argument needed to execute this command.
* @param f4 The fourth float argument needed to execute this command.
*/
public CommandObject( int cmd,
boolean b1, boolean b2, boolean b3,
String s, Object o,
float f1, float f2, float f3,
int i, float f4 )
{
Command = cmd;
intArgs = new int[1];
floatArgs = new float[4];
boolArgs = new boolean[3];
stringArgs = new String[1];
objectArgs = new Object[1];
intArgs[0] = i;
floatArgs[0] = f1;
floatArgs[1] = f2;
floatArgs[2] = f3;
floatArgs[3] = f4;
boolArgs[0] = b1;
boolArgs[1] = b2;
boolArgs[2] = b3;
stringArgs[0] = s;
objectArgs[0] = o;
}
/**
* Constructor used to create a command which requires several arguments.
* @param cmd Which command to execute.
* @param b1 The first boolean argument needed to execute this command.
* @param b2 The second boolean argument needed to execute this command.
* @param b3 The third boolean argument needed to execute this command.
* @param s The String argument needed to execute this command.
* @param o The Object argument needed to execute this command.
* @param f1 The first float argument needed to execute this command.
* @param f2 The second float argument needed to execute this command.
* @param f3 The third float argument needed to execute this command.
* @param i The integer argument needed to execute this command.
* @param f4 The fourth float argument needed to execute this command.
* @param b4 The fourth boolean argument needed to execute this command.
*/
public CommandObject( int cmd,
boolean b1, boolean b2, boolean b3,
String s,
Object o,
float f1, float f2, float f3,
int i, float f4, boolean b4 )
{
Command = cmd;
intArgs = new int[1];
floatArgs = new float[4];
boolArgs = new boolean[4];
stringArgs = new String[1];
objectArgs = new Object[1];
intArgs[0] = i;
floatArgs[0] = f1;
floatArgs[1] = f2;
floatArgs[2] = f3;
floatArgs[3] = f4;
boolArgs[0] = b1;
boolArgs[1] = b2;
boolArgs[2] = b3;
boolArgs[3] = b4;
stringArgs[0] = s;
objectArgs[0] = o;
}
/**
* Constructor used to create a command which requires several arguments.
* @param cmd Which command to execute.
* @param o The Object argument needed to execute this command.
* @param b The first boolean argument needed to execute this command.
* @param s The String argument needed to execute this command.
* @param f1 The first float argument needed to execute this command.
* @param f2 The second float argument needed to execute this command.
* @param f3 The third float argument needed to execute this command.
* @param i The integer argument needed to execute this command.
* @param f4 The fourth float argument needed to execute this command.
*/
public CommandObject( int cmd,
Object o,
boolean b,
String s,
float f1, float f2, float f3,
int i,
float f4 )
{
Command = cmd;
intArgs = new int[1];
floatArgs = new float[4];
boolArgs = new boolean[1];
stringArgs = new String[1];
objectArgs = new Object[1];
intArgs[0] = i;
floatArgs[0] = f1;
floatArgs[1] = f2;
floatArgs[2] = f3;
floatArgs[3] = f4;
boolArgs[0] = b;
stringArgs[0] = s;
objectArgs[0] = o;
}
}

View File

@ -0,0 +1,176 @@
package paulscode.sound;
/**
* The CommandThread class is designed to move all command processing into a
* single thread to be run in the background and avoid conflicts between
* threads. Commands are processed in the order that they were queued. The
* arguements for each command are stored in a
* {@link paulscode.sound.CommandObject CommandObject}. The Command Queue is
* located in the {@link paulscode.sound.SoundSystem SoundSystem} class.
* Calling kill() stops the thread, and this should be immediatly followed
* by a call to interrupt() to wake up the thread so it may end. This class
* also checks for temporary sources that are finished playing, and removes
* them.
*
* NOTE: The command thread is created automatically by the sound system, so it
* is unlikely that the user would ever need to use this class.
*<br><br>
*<b><i> SoundSystem License:</b></i><br><b><br>
* You are free to use this library for any purpose, commercial or otherwise.
* You may modify this library or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this library or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this library or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this library in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this library or any part
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this library or any
* part of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
* </b>
*/
public class CommandThread extends SimpleThread
{
/**
* Processes status messages, warnings, and error messages.
*/
protected SoundSystemLogger logger;
/**
* Handle to the Sound System. This is where the Command Queue is located.
*/
private SoundSystem soundSystem;
/**
* Name of this class.
*/
protected String className = "CommandThread";
/**
* Constructor: Takes a handle to the SoundSystem object as a parameter.
* @param s Handle to the SoundSystem.
*/
public CommandThread( SoundSystem s )
{
// grab a handle to the message logger:
logger = SoundSystemConfig.getLogger();
soundSystem = s;
}
/**
* Shuts the thread down and removes references to all instantiated objects.
* NOTE: Method alive() will return false when cleanup() has finished.
*/
@Override
protected void cleanup()
{
kill();
logger = null;
soundSystem = null;
super.cleanup(); // Important!
}
/**
* The main loop for processing commands. The Command Thread starts out
* asleep, and it sleeps again after it finishes processing commands, so it
* must be interrupted when commands are queued for processing.
*/
@Override
public void run()
{
long previousTime = System.currentTimeMillis();
long currentTime = previousTime;
if( soundSystem == null )
{
errorMessage( "SoundSystem was null in method run().", 0 );
cleanup();
return;
}
// Start out asleep:
snooze( 3600000 );
while( !dying() )
{
// Perform user-specific source management:
soundSystem.ManageSources();
// Process all queued commands:
soundSystem.CommandQueue( null );
// Remove temporary sources every ten seconds:
currentTime = System.currentTimeMillis();
if( (!dying()) && ((currentTime - previousTime) > 10000) )
{
previousTime = currentTime;
soundSystem.removeTemporarySources();
}
// Wait for more commands:
if( !dying() )
snooze( 3600000 );
}
cleanup(); // Important!
}
/**
* Prints a message.
* @param message Message to print.
*/
protected void message( String message, int indent )
{
logger.message( message, indent );
}
/**
* Prints an important message.
* @param message Message to print.
*/
protected void importantMessage( String message, int indent )
{
logger.importantMessage( message, indent );
}
/**
* Prints the specified message if error is true.
* @param error True or False.
* @param message Message to print if error is true.
* @return True if error is true.
*/
protected boolean errorCheck( boolean error, String message )
{
return logger.errorCheck( error, className, message, 0 );
}
/**
* Prints an error message.
* @param message Message to print.
*/
protected void errorMessage( String message, int indent )
{
logger.errorMessage( className, message, indent );
}
}

View File

@ -0,0 +1,153 @@
package paulscode.sound;
import java.net.URL;
/**
* The FilenameURL class is designed to associate a String filename/identifier
* with a URL. Handles either case where user supplies a String path or user
* supplies a URL instance.
*<br><br>
*<b><i> SoundSystem License:</b></i><br><b><br>
* You are free to use this library for any purpose, commercial or otherwise.
* You may modify this library or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this library or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this library or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this library in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this library or any part
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this library or any
* part of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
* </b>
*/
public class FilenameURL
{
/**
* Processes status messages, warnings, and error messages.
*/
private SoundSystemLogger logger;
/**
* Filename or identifier for the file.
*/
private String filename = null;
/**
* URL interface to the file.
*/
private URL url = null;
/**
* Constructor: Saves handles to the url and identifier. The identifier should
* look like a filename, and it must have the correct extension so SoundSystem
* knows what format to use for the file referenced by the URL instance.
* @param url URL interface to a file.
* @param identifier Identifier (filename) for the file.
*/
public FilenameURL( URL url, String identifier )
{
// grab a handle to the message logger:
logger = SoundSystemConfig.getLogger();
filename = identifier;
this.url = url;
}
/**
* Constructor: Saves a handle to the filename (used later to generate a URL
* instance). The file may either be located within the
* JAR or at an online location. If the file is online, filename must begin
* with "http://", since that is how SoundSystem recognizes URL names.
* @param filename Name of the file.
*/
public FilenameURL( String filename )
{
// grab a handle to the message logger:
logger = SoundSystemConfig.getLogger();
this.filename = filename;
url = null;
}
/**
* Returns the filename/identifier.
* @return Filename or identifier for the file.
*/
public String getFilename()
{
return filename;
}
/**
* Returns the URL interface to the file. If a URL was not originally specified
* in the constructor, then the first time this method is called it creates a
* URL instance using the previously specified filename.
* @return URL interface to the file.
*/
public URL getURL()
{
if( url == null )
{
// Check if the file is online or inside the JAR:
if( filename.matches( SoundSystemConfig.PREFIX_URL ) )
{
// Online
try
{
url = new URL( filename );
}
catch( Exception e )
{
errorMessage( "Unable to access online URL in " +
"method 'getURL'" );
printStackTrace( e );
return null;
}
}
else
{
// Inside the JAR
url = getClass().getClassLoader().getResource(
SoundSystemConfig.getSoundFilesPackage() + filename );
}
}
return url;
}
/**
* Prints an error message.
* @param message Message to print.
*/
private void errorMessage( String message )
{
logger.errorMessage( "MidiChannel", message, 0 );
}
/**
* Prints an exception's error message followed by the stack trace.
* @param e Exception containing the information to print.
*/
private void printStackTrace( Exception e )
{
logger.printStackTrace( e, 1 );
}
}

View File

@ -0,0 +1,119 @@
package paulscode.sound;
import java.net.URL;
import javax.sound.sampled.AudioFormat;
/**
* The ICodec interface provides a common interface for SoundSystem to use
* for accessing external codec libraries.
*<br><br>
*<b><i> SoundSystem License:</b></i><br><b><br>
* You are free to use this library for any purpose, commercial or otherwise.
* You may modify this library or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this library or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this library or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this library in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this library or any part
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this library or any
* part of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
* </b>
*/
public interface ICodec
{
/**
* Should tell derived classes when they may need to reverse the byte order of
* the data before returning it in the read() and readAll() methods. The
* reason for the reversBytOrder method is because some external codec
* libraries produce audio data in a format that some external audio libraries
* require to be reversed. Derivatives of the Library and Source classes for
* audio libraries which require this type of data to be reversed should call
* the reverseByteOrder() method for all instances of ICodec that they use.
* Derivatives of the ICodec interface for codec libraries which which produce
* this type of data should use the reverseByteOrder() method to know when the
* data needs to be reversed before returning it in the read() and readAll()
* methods. If a particular codec library does not produce this type of data,
* its derived ICodec class may disregard any calls to the reverseByteOrder()
* method.
* @param b True if the calling audio library requires byte-reversal by some codec libraries.
*/
public void reverseByteOrder( boolean b );
/**
* Should make any preperations required before reading from the audio stream.
* If another stream is already opened, it should be closed and a new audio
* stream opened in its place. This method is used internally by SoundSystem
* not only to initialize a stream, but also to rewind streams and to switch
* stream sources on the fly.
* @return False if an error occurred or if end of stream was reached.
*/
public boolean initialize( URL url );
/**
* Should return false if the stream is busy initializing. To prevent bad
* data from being returned by this method, derived classes should internally
* synchronize with any elements used by both the initialized() and initialize()
* methods.
* @return True if steam is initialized.
*/
public boolean initialized();
/**
* Should read in one stream buffer worth of audio data. See
* {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more
* information about accessing and changing default settings.
* @return The audio data wrapped into a SoundBuffer context.
*/
public SoundBuffer read();
/**
* Should read in all the audio data from the stream (up to the default
* "maximum file size". See
* {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more
* information about accessing and changing default settings.
* @return the audio data wrapped into a SoundBuffer context.
*/
public SoundBuffer readAll();
/**
* Should return false if there is still more data available to be read in. To
* prevent bad data from being returned by this method, derived classes should
* internally synchronize with any elements used in both the endOfStream() and
* the read() or readAll() methods.
* @return True if end of stream was reached.
*/
public boolean endOfStream();
/**
* Should close any open streams and remove references to all instantiated
* objects.
*/
public void cleanup();
/**
* Should return the audio format of the data being returned by the read() and
* readAll() methods.
* @return Information wrapped into an AudioFormat context.
*/
public AudioFormat getAudioFormat();
}

View File

@ -0,0 +1,11 @@
package paulscode.sound;
public interface IStreamListener
{
/**
* Notifies implementation that an End Of Stream was reached.
* @param sourcename String identifier of the source which reached the EOS.
* @param queueSize Number of items left the the stream's play queue, or zero if none.
*/
public void endOfStream( String sourcename, int queueSize );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,282 @@
package paulscode.sound;
/**
* The listenerData class is used to store information about the
* listener's position and orientation. A ListenerData object can be obtained
* using SoundSystem's getListenerData() method. See
* {@link paulscode.sound.Vector3D Vector3D} for more information about 3D
* coordinates and vectors.
*<br><br>
*<b><i> SoundSystem License:</b></i><br><b><br>
* You are free to use this library for any purpose, commercial or otherwise.
* You may modify this library or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this library or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this library or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this library in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this library or any part
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this library or any
* part of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
* </b>
*/
public class ListenerData
{
/**
* Listener's position in 3D space
*/
public Vector3D position;
/**
* A normalized vector indicating the direction the listener is facing
*/
public Vector3D lookAt;
/**
* A normalized vector indicating the up direction
*/
public Vector3D up;
/**
* Listener's velocity in world-space
*/
public Vector3D velocity;
/**
* Used for easy rotation along the x/z plane (for use in a first-person
* shooter type of application).
*/
public float angle = 0.0f;
/**
* Constructor: Set this listener data to the origin facing along the z-axis
*/
public ListenerData()
{
position = new Vector3D( 0.0f, 0.0f, 0.0f );
lookAt = new Vector3D( 0.0f, 0.0f, -1.0f );
up = new Vector3D( 0.0f, 1.0f, 0.0f );
velocity = new Vector3D( 0.0f, 0.0f, 0.0f );
angle = 0.0f;
}
/**
* Constructor: Set this listener data to the specified values for position and
* orientation.
* @param pX Listener's X coordinate.
* @param pY Listener's Y coordinate.
* @param pZ Listener's Z coordinate.
* @param lX X element of the look-at direction.
* @param lY Y element of the look-at direction.
* @param lZ Z element of the look-at direction.
* @param uX X element of the up direction.
* @param uY Y element of the up direction.
* @param uZ Z element of the up direction.
* @param a Angle in radians that the listener is turned counterclockwise around the y-axis.
*/
public ListenerData( float pX, float pY, float pZ, float lX, float lY,
float lZ, float uX, float uY, float uZ, float a )
{
position = new Vector3D( pX, pY, pZ );
lookAt = new Vector3D( lX, lY, lZ );
up = new Vector3D( uX, uY, uZ );
velocity = new Vector3D( 0.0f, 0.0f, 0.0f );
angle = a;
}
/**
* Constructor: Set this listener data to the specified values for position and
* orientation.
* @param p Position of the listener in 3D space.
* @param l Normalized vector indicating the direction which the listener is facing.
* @param u Normalized vector indicating the up direction.
* @param a Angle in radians that the listener is turned counterclockwise around the y-axis.
*/
public ListenerData( Vector3D p, Vector3D l, Vector3D u, float a )
{
position = p.clone();
lookAt = l.clone();
up = u.clone();
velocity = new Vector3D( 0.0f, 0.0f, 0.0f );
angle = a;
}
/**
* Change this listener data using the specified coordinates for position and
* orientation.
* @param pX Listener's X coordinate.
* @param pY Listener's Y coordinate.
* @param pZ Listener's Z coordinate.
* @param lX X element of the look-at direction.
* @param lY Y element of the look-at direction.
* @param lZ Z element of the look-at direction.
* @param uX X element of the up direction.
* @param uY Y element of the up direction.
* @param uZ Z element of the up direction.
* @param a Angle in radians that the listener is turned counterclockwise around the y-axis.
*/
public void setData( float pX, float pY, float pZ, float lX, float lY,
float lZ, float uX, float uY, float uZ, float a )
{
position.x = pX;
position.y = pY;
position.z = pZ;
lookAt.x = lX;
lookAt.y = lY;
lookAt.z = lZ;
up.x = uX;
up.y = uY;
up.z = uZ;
angle = a;
}
/**
* Change this listener data using the specified 3D vectors for position and
* orientation.
* @param p Position of the listener in 3D space.
* @param l Normalized vector indicating the direction which the listener is facing.
* @param u Normalized vector indicating the up direction.
* @param a Angle in radians that the listener is turned counterclockwise around the y-axis.
*/
public void setData( Vector3D p, Vector3D l, Vector3D u, float a )
{
position.x = p.x;
position.y = p.y;
position.z = p.z;
lookAt.x = l.x;
lookAt.y = l.y;
lookAt.z = l.z;
up.x = u.x;
up.y = u.y;
up.z = u.z;
angle = a;
}
/**
* Change this listener data to match the specified listener data.
* @param l Listener data to use.
*/
public void setData( ListenerData l )
{
position.x = l.position.x;
position.y = l.position.y;
position.z = l.position.z;
lookAt.x = l.lookAt.x;
lookAt.y = l.lookAt.y;
lookAt.z = l.lookAt.z;
up.x = l.up.x;
up.y = l.up.y;
up.z = l.up.z;
angle = l.angle;
}
/**
* Change this listener's position using the specified coordinates.
* @param x Listener's X coordinate.
* @param y Listener's Y coordinate.
* @param z Listener's Z coordinate.
*/
public void setPosition( float x, float y, float z )
{
position.x = x;
position.y = y;
position.z = z;
}
/**
* Change this listener's position using the specified vector.
* @param p New position.
*/
public void setPosition( Vector3D p )
{
position.x = p.x;
position.y = p.y;
position.z = p.z;
}
/**
* Changes the listeners orientation using the specified coordinates.
* @param lX X element of the look-at direction.
* @param lY Y element of the look-at direction.
* @param lZ Z element of the look-at direction.
* @param uX X element of the up direction.
* @param uY Y element of the up direction.
* @param uZ Z element of the up direction.
*/
public void setOrientation( float lX, float lY, float lZ,
float uX, float uY, float uZ )
{
lookAt.x = lX;
lookAt.y = lY;
lookAt.z = lZ;
up.x = uX;
up.y = uY;
up.z = uZ;
}
/**
* Changes the listeners orientation using the specified vectors.
* @param l Normalized vector representing the look-at direction.
* @param u Normalized vector representing the up direction.
*/
public void setOrientation( Vector3D l, Vector3D u )
{
lookAt.x = l.x;
lookAt.y = l.y;
lookAt.z = l.z;
up.x = u.x;
up.y = u.y;
up.z = u.z;
}
/**
* Change this listener's velocity in world-space.
* @param v New velocity.
*/
public void setVelocity( Vector3D v )
{
velocity.x = v.x;
velocity.y = v.y;
velocity.z = v.z;
}
/**
* Change this listener's velocity in world-space.
* @param x New velocity along world x-axis.
* @param y New velocity along world y-axis.
* @param z New velocity along world z-axis.
*/
public void setVelocity( float x, float y, float z )
{
velocity.x = x;
velocity.y = y;
velocity.z = z;
}
/**
* Sets the listener's angle counterclockwise around the y-axis.
* @param a Angle in radians.
*/
public void setAngle( float a )
{
angle = a;
lookAt.x = -1.0f * (float) Math.sin( angle );
lookAt.z = -1.0f * (float) Math.cos( angle );
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,200 @@
package paulscode.sound;
/**
* The SimpleThread class is the template used to create all thread classes
* used by in the SoundSystem library. It provides methods for common actions
* like sleeping, killing, and checking liveness. NOTE: super.cleanup() must
* be called at the bottom of overriden cleanup() methods, and cleanup()
* must be called at the bottom of the run() method for all extended classes.
*<br><br>
*<b><i> SoundSystem License:</b></i><br><b><br>
* You are free to use this library for any purpose, commercial or otherwise.
* You may modify this library or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this library or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this library or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this library in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this library or any part
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this library or any
* part of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
* </b>
*/
public class SimpleThread extends Thread
{
/**
* Used to return a current value from one of the synchronized
* boolean-interface methods.
*/
private static final boolean GET = false;
/**
* Used to set the value in one of the synchronized boolean-interface methods.
*/
private static final boolean SET = true;
/**
* Used when a parameter for one of the synchronized boolean-interface methods
* is not aplicable.
*/
private static final boolean XXX = false;
/**
* True when thread is running.
*/
private boolean alive = true;
/**
* True when thread should end.
*/
private boolean kill = false;
/**
* Removes all references to instantiated objects, and changes the thread's
* state to "not alive". Method alive() returns false when this method has
* completed. NOTE: super.cleanup() must be called at the bottom of overriden
* cleanup() methods, and cleanup() must be called at the bottom of the run()
* method for all extended classes.
*/
protected void cleanup()
{
kill( SET, true ); // tread needs to shut down
alive( SET, false ); // thread has ended
}
/**
* Executes the thread's main loop. NOTES: Extended classes should check
* method dying() often to know when the user wants the thread to shut down.
* Method cleanup() must be called at the bottom of the run() method for all
* extended classes.
*/
@Override
public void run()
{
/* How the run() method should be set up: */
// Do your stuff here. Remember to check dying() often to know when
// the user wants the thread to shut down.
// MUST call cleanup() at the bottom of Overridden run() method!!!!!
cleanup(); // clears memory and sets status to dead.
}
/**
* Calls the rerun() method on a seperate thread, which calls run() when the
* previous thread finishes.
*/
public void restart()
{
new Thread()
{
@Override
public void run()
{
rerun();
}
}.start();
}
/**
* Kills the previous thread, waits for it to die, then calls run().
*/
private void rerun()
{
kill( SET, true );
while( alive( GET, XXX ) )
{
snooze( 100 );
}
alive( SET, true );
kill( SET, false );
run();
}
/**
* Returns false when the cleanup() method has finished. This method should be
* used to know when the thread has been safely shut down.
* @return True while the thread is alive.
*/
public boolean alive()
{
return alive( GET, XXX );
}
/**
* Causes method dying() to return true, letting the thread know it needs to
* shut down.
*/
public void kill()
{
kill( SET, true );
}
/**
* Returns true when the thread is supposed to shut down.
* @return True if the thread should die.
*/
protected boolean dying()
{
return kill( GET, XXX );
}
/**
* Sets or returns the value of boolean 'alive'.
* @param action GET or SET.
* @param value New value if action == SET, or XXX if action == GET.
* @return True while the thread is alive.
*/
private synchronized boolean alive( boolean action, boolean value )
{
if( action == SET )
alive = value;
return alive;
}
/**
* Sets or returns the value of boolean 'kill'.
* @param action GET or SET.
* @param value New value if action == SET, or XXX if action == GET.
* @return True if the thread should die.
*/
private synchronized boolean kill( boolean action, boolean value )
{
if( action == SET )
kill = value;
return kill;
}
/**
* Sleeps for the specified number of milliseconds.
*/
protected void snooze( long milliseconds )
{
try
{
Thread.sleep( milliseconds );
}
catch( InterruptedException e ){}
}
}

View File

@ -0,0 +1,91 @@
package paulscode.sound;
import javax.sound.sampled.AudioFormat;
/**
* The SoundBuffer class is used to wrap audio data along with the format in
* which the data is stored.
*<br><br>
*<b><i> SoundSystem License:</b></i><br><b><br>
* You are free to use this library for any purpose, commercial or otherwise.
* You may modify this library or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this library or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this library or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this library in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this library or any part
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this library or any
* part of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
* </b>
*/
public class SoundBuffer
{
/**
* The actual audio data.
*/
public byte[] audioData;
/**
* The audio format in which the data is stored.
*/
public AudioFormat audioFormat;
/**
* Constructor: Wraps the specified data with the specified audio format.
*
* @param audioData The actual audio data.
* @param audioFormat The audio format in which the data is stored.
*/
public SoundBuffer( byte[] audioData, AudioFormat audioFormat )
{
this.audioData = audioData;
this.audioFormat = audioFormat;
}
/**
* Removes handles to all instantiated objects.
*/
public void cleanup()
{
audioData = null;
audioFormat = null;
}
/**
* Trims down the size of the audio data if it is larger than the specified
* maximum length.
*
* @param maxLength Maximum size this buffer may be.
*/
public void trimData( int maxLength )
{
if( audioData == null || maxLength == 0 )
audioData = null;
else if( audioData.length > maxLength )
{
byte[] trimmedArray = new byte[maxLength];
System.arraycopy( audioData, 0, trimmedArray, 0,
maxLength );
audioData = trimmedArray;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
package paulscode.sound;
/**
* The SoundSystemException class is used to provide information about serious
* errors.
*<br><br>
*<b><i> SoundSystem License:</b></i><br><b><br>
* You are free to use this library for any purpose, commercial or otherwise.
* You may modify this library or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this library or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this library or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this library in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this library or any part
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this library or any
* part of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
* </b>
*/
public class SoundSystemException extends Exception
{
/**
* Global identifier for no problem.
*/
public static final int ERROR_NONE = 0;
/**
* Global identifier for a generic exception.
*/
public static final int UNKNOWN_ERROR = 1;
/**
* Global identifier for a null parameter.
*/
public static final int NULL_PARAMETER = 2;
/**
* Global identifier for a class type mismatch.
*/
public static final int CLASS_TYPE_MISMATCH = 3;
/**
* Global identifier for the sound library does not exist.
*/
public static final int LIBRARY_NULL = 4;
/**
* Global identifier for the sound library does not exist.
*/
public static final int LIBRARY_TYPE = 5;
/**
* Holds a global identifier indicating the type of exception.
*/
private int myType = UNKNOWN_ERROR;
/**
* Constructor: Generic exception. Specify the error message.
*/
public SoundSystemException( String message )
{
super( message );
}
/**
* Constructor: Specify the error message and type of exception.
* @param message Description of the problem.
* @param type Global identifier for type of exception.
*/
public SoundSystemException( String message, int type )
{
super( message );
myType = type;
}
public int getType()
{
return myType;
}
}

View File

@ -0,0 +1,173 @@
package paulscode.sound;
/**
* The SoundSystemLogger class handles all status messages, warnings, and error
* messages for the SoundSystem library. This class can be extended and
* methods overriden to change how messages are handled. To do this, the
* overridden class should be instantiated, and a call should be made to method
* SoundSystemConfig.setLogger() BEFORE creating the SoundSystem object. If
* the setLogger() method is called after the SoundSystem has been created,
* there will be handles floating around to two different message loggers, and
* the results will be undesirable.
* See {@link paulscode.sound.SoundSystemConfig SoundSystemConfig} for more
* information about changing default settings. If an alternate logger is not
* set by the user, then an instance of this base class will be automatically
* created by default when the SoundSystem class is instantiated.
*<br><br>
*<b><i> SoundSystem License:</b></i><br><b><br>
* You are free to use this library for any purpose, commercial or otherwise.
* You may modify this library or source code, and distribute it any way you
* like, provided the following conditions are met:
*<br>
* 1) You may not falsely claim to be the author of this library or any
* unmodified portion of it.
*<br>
* 2) You may not copyright this library or a modified version of it and then
* sue me for copyright infringement.
*<br>
* 3) If you modify the source code, you must clearly document the changes
* made before redistributing the modified source code, so other users know
* it is not the original code.
*<br>
* 4) You are not required to give me credit for this library in any derived
* work, but if you do, you must also mention my website:
* http://www.paulscode.com
*<br>
* 5) I the author will not be responsible for any damages (physical,
* financial, or otherwise) caused by the use if this library or any part
* of it.
*<br>
* 6) I the author do not guarantee, warrant, or make any representations,
* either expressed or implied, regarding the use of this library or any
* part of it.
* <br><br>
* Author: Paul Lamb
* <br>
* http://www.paulscode.com
* </b>
*/
public class SoundSystemLogger
{
/**
* Prints a message.
* @param message Message to print.
* @param indent Number of tabs to indent the message.
*/
public void message( String message, int indent )
{
String messageText;
// Determine how many spaces to indent:
String spacer = "";
for( int x = 0; x < indent; x++ )
{
spacer += " ";
}
// indent the message:
messageText = spacer + message;
// Print the message:
System.out.println( messageText );
}
/**
* Prints an important message.
* @param message Message to print.
* @param indent Number of tabs to indent the message.
*/
public void importantMessage( String message, int indent )
{
String messageText;
// Determine how many spaces to indent:
String spacer = "";
for( int x = 0; x < indent; x++ )
{
spacer += " ";
}
// indent the message:
messageText = spacer + message;
// Print the message:
System.out.println( messageText );
}
/**
* Prints the specified message if error is true.
* @param error True or False.
* @param classname Name of the class checking for an error.
* @param message Message to print if error is true.
* @param indent Number of tabs to indent the message.
* @return True if error is true.
*/
public boolean errorCheck( boolean error, String classname, String message,
int indent )
{
if( error )
errorMessage( classname, message, indent );
return error;
}
/**
* Prints the classname which generated the error, followed by the error
* message.
* @param classname Name of the class which generated the error.
* @param message The actual error message.
* @param indent Number of tabs to indent the message.
*/
public void errorMessage( String classname, String message, int indent )
{
String headerLine, messageText;
// Determine how many spaces to indent:
String spacer = "";
for( int x = 0; x < indent; x++ )
{
spacer += " ";
}
// indent the header:
headerLine = spacer + "Error in class '" + classname + "'";
// indent the message one more than the header:
messageText = " " + spacer + message;
// Print the error message:
System.out.println( headerLine );
System.out.println( messageText );
}
/**
* Prints an exception's error message followed by the stack trace.
* @param e Exception containing the information to print.
* @param indent Number of tabs to indent the message and stack trace.
*/
public void printStackTrace( Exception e, int indent )
{
printExceptionMessage( e, indent );
importantMessage( "STACK TRACE:", indent );
if( e == null )
return;
StackTraceElement[] stack = e.getStackTrace();
if( stack == null )
return;
StackTraceElement line;
for( int x = 0; x < stack.length; x++ )
{
line = stack[x];
if( line != null )
message( line.toString(), indent + 1 );
}
}
/**
* Prints an exception's error message.
* @param e Exception containing the message to print.
* @param indent Number of tabs to indent the message.
*/
public void printExceptionMessage( Exception e, int indent )
{
importantMessage( "ERROR MESSAGE:", indent );
if( e.getMessage() == null )
message( "(none)", indent + 1 );
else
message( e.getMessage(), indent + 1 );
}
}

Some files were not shown because too many files have changed in this diff Show More