Class JavaSound

java.lang.Object
  |
  +--JavaSound

public class JavaSound
extends java.lang.Object

The JavaSound class is an Implementation of the Java Sound API specifically designed for use with the Jython Environment for Students (JES).

This class allows for easy playback, and manipulation of AU, AIFF, and WAV files.

Note that EVERYTHING in this file is 0-indexed. (Since we want JES to use a 1-based indexing system for sounds, the media.py file contains wrappers for all of these functions that translate between the 0 and 1 based systems). Except error messages, they are 1-indexed so that JES can catch them and make sense of it all.


Nested Class Summary
 class JavaSound.Playback
          The nested class Playback extends from Thread and allows for playback of this sound.
 
Constructor Summary
JavaSound()
          Constructs a JavaSound of 3 seconds long.
JavaSound(int numSeconds)
          Constructs a JavaSound of the specified length.
JavaSound(int sampleSizeInBits, boolean isBigEndian)
           
JavaSound(java.lang.String fileName)
          Constructs a new JavaSound from the given file.
 
Method Summary
 byte[] asArray()
           
 void blockingPlay()
          Creates a new Playback thread, starts it, then waits for the entire sound to finish playing before it returns.
 void blockingPlayAtRateDur(double rate, double durInFrames)
          Calls playAtRateInRange((float)rate, 0, (int)durInFrames-1, true) .
 void blockingPlayAtRateInRange(float rate, int startFrame, int endFrame)
          Calls playAtRateInRange(rate, startFrame, endFrame, true) .
 javax.sound.sampled.AudioFileFormat getAudioFileFormat()
          Obtains the AudioFileFormat describing this sound.
 byte[] getBuffer()
          Obtains the byte array representation of this sound.
 int getChannels()
          Obtains the number of channels of this sound.
 java.lang.String getFileName()
          Obtains the name of the file this sound came from.
 byte[] getFrame(int frameNum)
          Returns an array containing all of the bytes in the specified frame.
 int getLeftSample(int frameNum)
          Obtains the left sample of the audio data contained at the specified frame.
 int getLength()
          Obtains the length of this sound in bytes.
 int getLengthInFrames()
          Obtains the length of the audio data contained in the file, expressed in sample frames.
 java.util.Vector getPlaybacks()
          Obtains the collection of playback threads currently active on this sound.
 int getRightSample(int frameNum)
          Obtains the right sample of the audio data contained at the specified frame.
 int getSample(int frameNum)
          If this is a mono sound, obtains the single sample contained within this frame, else obtains the first (left) sample contained in the specified frame.
static byte intToUnsignedByte(int sample)
           
static void intToUnsignedBytes16(int sample, byte[] buffer, int byteOffset, boolean bigEndian)
           
static void intToUnsignedBytes24(int sample, byte[] buffer, int byteOffset, boolean bigEndian)
           
static void intToUnsignedBytes32(int sample, byte[] buffer, int byteOffset, boolean bigEndian)
           
 boolean isStereo()
           
 java.lang.String justABufferTaste(byte[] b)
           
 java.lang.String justATaste()
           
static byte linear2alaw(short pcm_val)
           
static byte linear2ulaw(int sample)
          Converts a linear signed 16bit sample to a uLaw byte.
 void loadFromFile(java.lang.String inFileName)
          Resets the fields of this sound so that it now represents the sound in the specified file.
static void main(java.lang.String[] args)
           
 javax.sound.sampled.AudioInputStream makeAIS()
          Creates an AudioInputStream for this sound from the buffer and the audioFileFormat.
 void play()
          Creates a new Playback thread and starts it.
 void playAtRateDur(double rate, double durInFrames)
          Calls playAtRateInRange((float)rate, 0, (int)durInFrames-1, false) .
 void playAtRateInRange(float rate, int startFrame, int endFrame)
          Calls playAtRateInRange(rate, startFrame, endFrame, false) .
 void playAtRateInRange(float rate, int startFrame, int endFrame, boolean isBlocking)
          Plays the specified segment of this sound at the given sample rate.
 void printError(java.lang.String message)
          Invokes printError(message, null)
 void printError(java.lang.String message, java.lang.Exception e)
          Prints the given String to the "standard" error output stream, then prints a stack trace on the exception, and then exits the program.
 void setAudioFileFormat(javax.sound.sampled.AudioFileFormat newAudioFileFormat)
          Changes the AudioFileFormat of this sound.
 void setBuffer(byte[] newBuffer)
          Changes the byte array that represents this sound.
 void setFrame(int frameNum, byte[] theFrame)
          Changes the value of each byte of the specified frame.
 void setLeftSample(int frameNum, int sample)
           
 void setRightSample(int frameNum, int sample)
           
 void setSample(int frameNum, int sample)
          Changes the value of the sample found at the specified frame.
 void setSoundView(SoundView soundView)
          Changes the view of this object.
 java.lang.String toString()
          Obtains a string representation of this JavaSound.
static int unsignedByteToInt24(byte[] buffer, int offset, boolean isBigEndian)
           
static int unsignedByteToInt32(byte[] buffer, int offset, boolean isBigEndian)
           
 void writeToFile(java.lang.String outFileName)
          Creates an audioInputStream from this sound, and then writes this stream out to the file with the specified name.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

JavaSound

public JavaSound()
Constructs a JavaSound of 3 seconds long.

See Also:
JavaSound(int numSeconds)

JavaSound

public JavaSound(int numSeconds)
Constructs a JavaSound of the specified length. This sound will simply consist of an empty byte array, and an AudioFileFormat with the following values: Note that no new sound file is created, we only represent the sound with a buffer and the AudioFileFormat. If a file is desired, then the method writeToFile(String filename) must be called on this newly created sound.

Parameters:
numSeconds - The length, in seconds, for the new sound
See Also:
writeToFile(String filename)

JavaSound

public JavaSound(int sampleSizeInBits,
                 boolean isBigEndian)

JavaSound

public JavaSound(java.lang.String fileName)
          throws JavaSoundException
Constructs a new JavaSound from the given file.

Parameters:
fileName - The File from which to create this sound.
Throws:
JavaSoundException - if there are problems loading the file
See Also:
loadFromFile(String filename)
Method Detail

getBuffer

public byte[] getBuffer()
Obtains the byte array representation of this sound.

Returns:
the sound represented as a byte array

getAudioFileFormat

public javax.sound.sampled.AudioFileFormat getAudioFileFormat()
Obtains the AudioFileFormat describing this sound.

Returns:
the AudioFileFormat describing this sound
See Also:
AudioFileFormat

asArray

public byte[] asArray()
See Also:
getBuffer()

getPlaybacks

public java.util.Vector getPlaybacks()
Obtains the collection of playback threads currently active on this sound.


getFileName

public java.lang.String getFileName()
Obtains the name of the file this sound came from. If this sound did not orriginate with a file, this value will be null.

See Also:
loadFromFile(String fileName)

setBuffer

public void setBuffer(byte[] newBuffer)
Changes the byte array that represents this sound.

Parameters:
newBuffer - a byte array representation of the new sound we want this to represent.

setAudioFileFormat

public void setAudioFileFormat(javax.sound.sampled.AudioFileFormat newAudioFileFormat)
Changes the AudioFileFormat of this sound.

Parameters:
newAudioFileFormat - the new audioFileFormat that describes this sound.
See Also:
AudioFileFormat

setSoundView

public void setSoundView(SoundView soundView)
Changes the view of this object.

See Also:
#soundView

makeAIS

public javax.sound.sampled.AudioInputStream makeAIS()
Creates an AudioInputStream for this sound from the buffer and the audioFileFormat.

Returns:
an AudioInputStream representing this sound.
See Also:
AudioInputStream

printError

public void printError(java.lang.String message)
                throws JavaSoundException
Invokes printError(message, null)

Throws:
JavaSoundException - Will throw under every circumstance. This way we can catch the exception in JES.
See Also:
printError(String message, Exception e)

printError

public void printError(java.lang.String message,
                       java.lang.Exception e)
                throws JavaSoundException
Prints the given String to the "standard" error output stream, then prints a stack trace on the exception, and then exits the program. If the String is null, then nothing happens, the method just returns. If the Exception is null, then it prints the String and then exits the program.

Parameters:
message - A description of the error
e - The exception, if any, that was caught regarding the error
Throws:
JavaSoundException - Will throw under every circumstance. This way we can catch the exception in JES.

isStereo

public boolean isStereo()

writeToFile

public void writeToFile(java.lang.String outFileName)
                 throws JavaSoundException
Creates an audioInputStream from this sound, and then writes this stream out to the file with the specified name. If no file exists, one is created. If a file already exists, then it is overwritten. Does not check the extension of the fileName passed in to make sure it agrees with the AudioFileFormat.Type of this sound.

Parameters:
outFileName - The name of the file to write this sound to
Throws:
JavaSoundException - if any error is encountered while writing to the file.

loadFromFile

public void loadFromFile(java.lang.String inFileName)
                  throws JavaSoundException
Resets the fields of this sound so that it now represents the sound in the specified file. If successful, the fileName variable is updated such that it is equivalent to inFileName.

Parameters:
inFileName - the path and filename of the sound we want to represent.
Throws:
JavaSoundException - if any problem is encountered while reading in from the file.

play

public void play()
Creates a new Playback thread and starts it. The thread is guarranteed to finish playing the sound as long as the program doesn't exit before it is done. This method does not block, however. So, if you invoke play() multiple times in a row, sounds will simply play on top of eachother - "accidental mixing"

See Also:
JavaSound.Playback

blockingPlay

public void blockingPlay()
Creates a new Playback thread, starts it, then waits for the entire sound to finish playing before it returns. This method is guarranteed to play the entire sound, and does not allow for any "accidental mixing"

See Also:
JavaSound.Playback

playAtRateDur

public void playAtRateDur(double rate,
                          double durInFrames)
                   throws JavaSoundException
Calls playAtRateInRange((float)rate, 0, (int)durInFrames-1, false) . Checks the value of durInFrames to make sure that it is not larger than Integer.MAX_VALUE to guarrantee safe casting. Also checks the value of rate to make sure that it is not larger than Float.MAX_VALUE before casting.

Parameters:
rate - a double representing the change in sampleRate (==frameRate) for playing back this sound
durInFrames - a double representing how much of this sound we want to play.
Throws:
JavaSoundException - if there are problems playing the sound.
See Also:
playAtRateInRange(float rate, int startFrame, int endFrame, boolean isBlocking)

blockingPlayAtRateDur

public void blockingPlayAtRateDur(double rate,
                                  double durInFrames)
                           throws JavaSoundException
Calls playAtRateInRange((float)rate, 0, (int)durInFrames-1, true) . First, checks the value of durInFrames to make sure that it is not larger than Integer.MAX_VALUE to guarrantee safe casting. Simmilarly, checks the value of rate to make sure that it is not larger than FLoat.MAX_VALUE before casting.

Parameters:
rate - a double representing the change in sampleRate (==frameRate) for playing back this sound
durInFrames - a double representing how much of this sound we want to play
Throws:
JavaSoundException - if there are problems playing the sound.
See Also:
playAtRateInRange(float range, int startFrame, int endFrame, boolean isBlocking)

playAtRateInRange

public void playAtRateInRange(float rate,
                              int startFrame,
                              int endFrame)
                       throws JavaSoundException
Calls playAtRateInRange(rate, startFrame, endFrame, false) .

Parameters:
rate - a float representing the change in sampleRate (==frameRate) for playing back this sound
startFrame - an int representing the frame at which we want to begin playing the sound
endFrame - an int representing the frame at which want to stop playing the sound
Throws:
JavaSoundException - if there are problems playing the sound.
See Also:
playAtRateInRange(float range, int startFrame, int endFrame, boolean isBlocking)

blockingPlayAtRateInRange

public void blockingPlayAtRateInRange(float rate,
                                      int startFrame,
                                      int endFrame)
                               throws JavaSoundException
Calls playAtRateInRange(rate, startFrame, endFrame, true) .

Parameters:
rate - a float representing the change in sampleRate (==frameRate) for playing back this sound
startFrame - an int representing the frame at which we want to begin playing the sound
endFrame - an int representing the frame at which want to stop playing the sound
Throws:
JavaSoundException - if there are problems playing the sound.
See Also:
playAtRateInRange(float range, int startFrame, int endFrame, boolean isBlocking)

playAtRateInRange

public void playAtRateInRange(float rate,
                              int startFrame,
                              int endFrame,
                              boolean isBlocking)
                       throws JavaSoundException
Plays the specified segment of this sound at the given sample rate. Then it saves the old fields (buffer and audioFileFormat) of this sound into temporary variables, and setting the fields of this sound to modified values. Then it creates a Playback thread on this sound (with the modified values) and starts the thread. The values for buffer and audioFileFormat are restored to their original values before the method returns.

Parameters:
rate - The change in the sampleRate (==frameRate) for playing back this sound. The old SampleRate is multiplied by this value. So, if rate = 2, the sound will play twice as fast (half the length), and if rate = .5, the sound will play half as fast (twice the length).
startFrame - The index of the frame where we want to begin play
endFrame - The index of the frame where we want to end play
isBlocking - If true, this method waits until the thread is done playing the sound before returning. If false, it simply starts the thread and then returns.
Throws:
JavaSoundException - if there are any problems playing the sound.

getFrame

public byte[] getFrame(int frameNum)
                throws JavaSoundException
Returns an array containing all of the bytes in the specified frame.

Parameters:
frameNum - the index of the frame to access
Returns:
the array containing all of the bytes in frame frameNum
Throws:
JavaSoundException - if the frame number is invalid.

getLengthInFrames

public int getLengthInFrames()
Obtains the length of the audio data contained in the file, expressed in sample frames.

Returns:
the number of sample frames of audio data in the file

getSample

public int getSample(int frameNum)
              throws JavaSoundException
If this is a mono sound, obtains the single sample contained within this frame, else obtains the first (left) sample contained in the specified frame.

Parameters:
frameNum - the index of the frame to access
Returns:
an integer representation of the bytes contained within the specified frame
Throws:
JavaSoundException - if the frame number is invalid.

getLeftSample

public int getLeftSample(int frameNum)
                  throws JavaSoundException
Obtains the left sample of the audio data contained at the specified frame.

Parameters:
frameNum - the index of the frame to access
Returns:
an int representation of the bytes contained in the specified frame.
Throws:
JavaSoundException - if the frameNumber is invalid

getRightSample

public int getRightSample(int frameNum)
                   throws JavaSoundException
Obtains the right sample of the audio data contained at the specified frame.

Parameters:
frameNum - the index of the frame to access
Returns:
an int representation of the bytes contained in the specified frame.
Throws:
JavaSoundException - if the frameNumber is invalid, or the encoding isn't supported.

getLength

public int getLength()
Obtains the length of this sound in bytes. Note, that this number is not neccessarily the same as the length of this sound's file in bytes.

Returns:
the sound length in bytes

getChannels

public int getChannels()
Obtains the number of channels of this sound.

Returns:
the number of channels (1 for mono, 2 for stereo), or AudioSystem.NOT_SPECIFIED
See Also:
AudioSystem.NOT_SPECIFIED

setFrame

public void setFrame(int frameNum,
                     byte[] theFrame)
              throws JavaSoundException
Changes the value of each byte of the specified frame.

Parameters:
frameNum - the index of the frame to change
theFrame - the byte array that will be copied into this sound's buffer in place of the specified frame.
Throws:
JavaSoundException - if the frameNumber is invalid.

setSample

public void setSample(int frameNum,
                      int sample)
               throws JavaSoundException
Changes the value of the sample found at the specified frame. If this sound has more than one channel, then this defaults to setting only the first (left) sample.

Parameters:
frameNum - the index of the frame where the sample should be changed
sample - an int representation of the new sample to put in this sound's buffer at the specified frame
Throws:
JavaSoundException - if the frameNumber is invalid, or another problem is encountered

setLeftSample

public void setLeftSample(int frameNum,
                          int sample)
                   throws JavaSoundException
JavaSoundException

setRightSample

public void setRightSample(int frameNum,
                           int sample)
                    throws JavaSoundException
JavaSoundException

linear2ulaw

public static byte linear2ulaw(int sample)
Converts a linear signed 16bit sample to a uLaw byte. Ported to Java by fb.
Originally by:
Craig Reese: IDA/Supercomputing Research Center
Joe Campbell: Department of Defense
29 September 1989


linear2alaw

public static byte linear2alaw(short pcm_val)

unsignedByteToInt24

public static int unsignedByteToInt24(byte[] buffer,
                                      int offset,
                                      boolean isBigEndian)

unsignedByteToInt32

public static int unsignedByteToInt32(byte[] buffer,
                                      int offset,
                                      boolean isBigEndian)

intToUnsignedByte

public static byte intToUnsignedByte(int sample)

intToUnsignedBytes16

public static void intToUnsignedBytes16(int sample,
                                        byte[] buffer,
                                        int byteOffset,
                                        boolean bigEndian)

intToUnsignedBytes24

public static void intToUnsignedBytes24(int sample,
                                        byte[] buffer,
                                        int byteOffset,
                                        boolean bigEndian)

intToUnsignedBytes32

public static void intToUnsignedBytes32(int sample,
                                        byte[] buffer,
                                        int byteOffset,
                                        boolean bigEndian)

toString

public java.lang.String toString()
Obtains a string representation of this JavaSound.

Overrides:
toString in class java.lang.Object
Returns:
a String representation of this JavaSound.

justATaste

public java.lang.String justATaste()

justABufferTaste

public java.lang.String justABufferTaste(byte[] b)

main

public static void main(java.lang.String[] args)