Desktop Runtime
This commit is contained in:
parent
97f389ae46
commit
9ec5c931a6
14
.classpath
14
.classpath
@ -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>
|
||||
|
2
.project
2
.project
@ -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>
|
||||
|
@ -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
19
debugRuntime.launch
Normal 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>
|
BIN
jars/Java-WebSocket-1.5.1-with-dependencies.jar
Normal file
BIN
jars/Java-WebSocket-1.5.1-with-dependencies.jar
Normal file
Binary file not shown.
BIN
jars/lwjgl.jar
Normal file
BIN
jars/lwjgl.jar
Normal file
Binary file not shown.
BIN
jars/lwjgl_util.jar
Normal file
BIN
jars/lwjgl_util.jar
Normal file
Binary file not shown.
BIN
jars/natives/OpenAL32.dll
Normal file
BIN
jars/natives/OpenAL32.dll
Normal file
Binary file not shown.
BIN
jars/natives/OpenAL64.dll
Normal file
BIN
jars/natives/OpenAL64.dll
Normal file
Binary file not shown.
BIN
jars/natives/liblwjgl.jnilib
Normal file
BIN
jars/natives/liblwjgl.jnilib
Normal file
Binary file not shown.
BIN
jars/natives/liblwjgl.so
Normal file
BIN
jars/natives/liblwjgl.so
Normal file
Binary file not shown.
BIN
jars/natives/liblwjgl64.so
Normal file
BIN
jars/natives/liblwjgl64.so
Normal file
Binary file not shown.
BIN
jars/natives/libopenal.so
Normal file
BIN
jars/natives/libopenal.so
Normal file
Binary file not shown.
BIN
jars/natives/libopenal64.so
Normal file
BIN
jars/natives/libopenal64.so
Normal file
Binary file not shown.
BIN
jars/natives/lwjgl.dll
Normal file
BIN
jars/natives/lwjgl.dll
Normal file
Binary file not shown.
BIN
jars/natives/lwjgl64.dll
Normal file
BIN
jars/natives/lwjgl64.dll
Normal file
Binary file not shown.
BIN
jars/natives/openal.dylib
Normal file
BIN
jars/natives/openal.dylib
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
586
src/lwjgl/java/de/cuina/fireandfuel/CodecJLayerMP3.java
Normal file
586
src/lwjgl/java/de/cuina/fireandfuel/CodecJLayerMP3.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
224
src/lwjgl/java/javazoom/jl/decoder/BitReserve.java
Normal file
224
src/lwjgl/java/javazoom/jl/decoder/BitReserve.java
Normal 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;
|
||||
}
|
||||
}
|
659
src/lwjgl/java/javazoom/jl/decoder/Bitstream.java
Normal file
659
src/lwjgl/java/javazoom/jl/decoder/Bitstream.java
Normal 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;
|
||||
}
|
||||
}
|
72
src/lwjgl/java/javazoom/jl/decoder/BitstreamErrors.java
Normal file
72
src/lwjgl/java/javazoom/jl/decoder/BitstreamErrors.java
Normal 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;
|
||||
|
||||
}
|
71
src/lwjgl/java/javazoom/jl/decoder/BitstreamException.java
Normal file
71
src/lwjgl/java/javazoom/jl/decoder/BitstreamException.java
Normal 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);
|
||||
}
|
||||
|
||||
|
||||
}
|
57
src/lwjgl/java/javazoom/jl/decoder/Control.java
Normal file
57
src/lwjgl/java/javazoom/jl/decoder/Control.java
Normal 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);
|
||||
|
||||
|
||||
}
|
70
src/lwjgl/java/javazoom/jl/decoder/Crc16.java
Normal file
70
src/lwjgl/java/javazoom/jl/decoder/Crc16.java
Normal 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;
|
||||
}
|
||||
}
|
356
src/lwjgl/java/javazoom/jl/decoder/Decoder.java
Normal file
356
src/lwjgl/java/javazoom/jl/decoder/Decoder.java
Normal 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;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
45
src/lwjgl/java/javazoom/jl/decoder/DecoderErrors.java
Normal file
45
src/lwjgl/java/javazoom/jl/decoder/DecoderErrors.java
Normal 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;
|
||||
|
||||
}
|
59
src/lwjgl/java/javazoom/jl/decoder/DecoderException.java
Normal file
59
src/lwjgl/java/javazoom/jl/decoder/DecoderException.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
227
src/lwjgl/java/javazoom/jl/decoder/Equalizer.java
Normal file
227
src/lwjgl/java/javazoom/jl/decoder/Equalizer.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
39
src/lwjgl/java/javazoom/jl/decoder/FrameDecoder.java
Normal file
39
src/lwjgl/java/javazoom/jl/decoder/FrameDecoder.java
Normal 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;
|
||||
|
||||
}
|
778
src/lwjgl/java/javazoom/jl/decoder/Header.java
Normal file
778
src/lwjgl/java/javazoom/jl/decoder/Header.java
Normal 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;}
|
||||
}
|
80
src/lwjgl/java/javazoom/jl/decoder/InputStreamSource.java
Normal file
80
src/lwjgl/java/javazoom/jl/decoder/InputStreamSource.java
Normal 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;
|
||||
}
|
||||
}
|
31
src/lwjgl/java/javazoom/jl/decoder/JavaLayerError.java
Normal file
31
src/lwjgl/java/javazoom/jl/decoder/JavaLayerError.java
Normal 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
|
||||
{
|
||||
}
|
40
src/lwjgl/java/javazoom/jl/decoder/JavaLayerErrors.java
Normal file
40
src/lwjgl/java/javazoom/jl/decoder/JavaLayerErrors.java
Normal 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;
|
||||
|
||||
}
|
78
src/lwjgl/java/javazoom/jl/decoder/JavaLayerException.java
Normal file
78
src/lwjgl/java/javazoom/jl/decoder/JavaLayerException.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
36
src/lwjgl/java/javazoom/jl/decoder/JavaLayerHook.java
Normal file
36
src/lwjgl/java/javazoom/jl/decoder/JavaLayerHook.java
Normal 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);
|
||||
}
|
208
src/lwjgl/java/javazoom/jl/decoder/JavaLayerUtils.java
Normal file
208
src/lwjgl/java/javazoom/jl/decoder/JavaLayerUtils.java
Normal 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;
|
||||
}
|
||||
}
|
448
src/lwjgl/java/javazoom/jl/decoder/LayerIDecoder.java
Normal file
448
src/lwjgl/java/javazoom/jl/decoder/LayerIDecoder.java
Normal 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;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
1064
src/lwjgl/java/javazoom/jl/decoder/LayerIIDecoder.java
Normal file
1064
src/lwjgl/java/javazoom/jl/decoder/LayerIIDecoder.java
Normal file
File diff suppressed because it is too large
Load Diff
2436
src/lwjgl/java/javazoom/jl/decoder/LayerIIIDecoder.java
Normal file
2436
src/lwjgl/java/javazoom/jl/decoder/LayerIIIDecoder.java
Normal file
File diff suppressed because it is too large
Load Diff
46
src/lwjgl/java/javazoom/jl/decoder/Manager.java
Normal file
46
src/lwjgl/java/javazoom/jl/decoder/Manager.java
Normal 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
|
||||
|
||||
}
|
88
src/lwjgl/java/javazoom/jl/decoder/Obuffer.java
Normal file
88
src/lwjgl/java/javazoom/jl/decoder/Obuffer.java
Normal 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();
|
||||
}
|
143
src/lwjgl/java/javazoom/jl/decoder/OutputChannels.java
Normal file
143
src/lwjgl/java/javazoom/jl/decoder/OutputChannels.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
132
src/lwjgl/java/javazoom/jl/decoder/SampleBuffer.java
Normal file
132
src/lwjgl/java/javazoom/jl/decoder/SampleBuffer.java
Normal 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()
|
||||
{}
|
||||
}
|
49
src/lwjgl/java/javazoom/jl/decoder/Source.java
Normal file
49
src/lwjgl/java/javazoom/jl/decoder/Source.java
Normal 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);
|
||||
|
||||
}
|
1815
src/lwjgl/java/javazoom/jl/decoder/SynthesisFilter.java
Normal file
1815
src/lwjgl/java/javazoom/jl/decoder/SynthesisFilter.java
Normal file
File diff suppressed because it is too large
Load Diff
BIN
src/lwjgl/java/javazoom/jl/decoder/au2lin.ser
Normal file
BIN
src/lwjgl/java/javazoom/jl/decoder/au2lin.ser
Normal file
Binary file not shown.
600
src/lwjgl/java/javazoom/jl/decoder/huffcodetab.java
Normal file
600
src/lwjgl/java/javazoom/jl/decoder/huffcodetab.java
Normal 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);
|
||||
}
|
||||
}
|
BIN
src/lwjgl/java/javazoom/jl/decoder/l3reorder.ser
Normal file
BIN
src/lwjgl/java/javazoom/jl/decoder/l3reorder.ser
Normal file
Binary file not shown.
BIN
src/lwjgl/java/javazoom/jl/decoder/lin2au.ser
Normal file
BIN
src/lwjgl/java/javazoom/jl/decoder/lin2au.ser
Normal file
Binary file not shown.
15
src/lwjgl/java/javazoom/jl/decoder/readme.txt
Normal file
15
src/lwjgl/java/javazoom/jl/decoder/readme.txt
Normal 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.
|
BIN
src/lwjgl/java/javazoom/jl/decoder/sfd.ser
Normal file
BIN
src/lwjgl/java/javazoom/jl/decoder/sfd.ser
Normal file
Binary file not shown.
265
src/lwjgl/java/javazoom/mp3spi/DecodedMpegAudioInputStream.java
Normal file
265
src/lwjgl/java/javazoom/mp3spi/DecodedMpegAudioInputStream.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
126
src/lwjgl/java/net/PeytonPlayz585/BufferUtils.java
Normal file
126
src/lwjgl/java/net/PeytonPlayz585/BufferUtils.java
Normal 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);
|
||||
}
|
||||
}
|
18
src/lwjgl/java/net/PeytonPlayz585/Client.java
Normal file
18
src/lwjgl/java/net/PeytonPlayz585/Client.java
Normal 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();
|
||||
|
||||
}
|
||||
|
||||
}
|
20
src/lwjgl/java/net/PeytonPlayz585/GameWindowListener.java
Normal file
20
src/lwjgl/java/net/PeytonPlayz585/GameWindowListener.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
10
src/lwjgl/java/net/PeytonPlayz585/LWJGLException.java
Normal file
10
src/lwjgl/java/net/PeytonPlayz585/LWJGLException.java
Normal file
@ -0,0 +1,10 @@
|
||||
package net.PeytonPlayz585;
|
||||
|
||||
public class LWJGLException extends org.lwjgl.LWJGLException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
13
src/lwjgl/java/net/PeytonPlayz585/PointerBuffer.java
Normal file
13
src/lwjgl/java/net/PeytonPlayz585/PointerBuffer.java
Normal 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);
|
||||
}
|
||||
}
|
5
src/lwjgl/java/net/PeytonPlayz585/PointerWrapper.java
Normal file
5
src/lwjgl/java/net/PeytonPlayz585/PointerWrapper.java
Normal file
@ -0,0 +1,5 @@
|
||||
package net.PeytonPlayz585;
|
||||
|
||||
public interface PointerWrapper extends org.lwjgl.PointerWrapper {
|
||||
|
||||
}
|
199
src/lwjgl/java/net/PeytonPlayz585/fileutils/File.java
Normal file
199
src/lwjgl/java/net/PeytonPlayz585/fileutils/File.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
58
src/lwjgl/java/net/PeytonPlayz585/opengl/Display.java
Normal file
58
src/lwjgl/java/net/PeytonPlayz585/opengl/Display.java
Normal 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;
|