|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES All Classes | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectptolemy.media.javasound.LiveSound
public class LiveSound
This class supports live capture and playback of audio samples. For audio capture, audio samples are captured from the audio input port of the computer. The audio input port is typically associated with the line-in port, microphone-in port, or cdrom audio-in port. For audio playback, audio samples are written to the audio output port. The audio output port is typically associated with the headphones jack or the internal speaker of the computer.
Format of audio samples
In this class, audio samples are double-valued and have a valid range of [-1.0, 1.0]. Thus when this class is used for audio capture, the returned samples will all range in value from -1.0 to 1.0. When this class is used for audio playback, the valid range of input samples is from -1.0 to 1.0. Any samples that are outside of this range will be hard-clipped to fall within this range.
Supported audio formats
This class supports the subset of the hardware supported audio formats that are also supported under Java. Provided that the computer has a sound card that was manufactured after 1998, the following formats are likely to be supported.
Input/output latency
When capturing audio samples, there will be some delay (latency) from the time the sound arrives at the input port to the time that the corresponding audio samples are available from this class. Likewise, there will be some delay from the time sample are written until the corresponding audio signal reaches the output port (e.g., the speaker). This is because an internal buffer is used to temporarily store audio samples when they are captured or played. The size of this internal buffer affects the latency in that a lower bound on the capture (playback) latency is given by (bufferSize / sampleRate) seconds. Here, bufferSize parameter is the size of the buffer in samples per channel. This class provides a method, setBufferSize(), to simultaneously set the size of internal capture buffer and the internal playback buffer. The method getBufferSize() may be used to read the buffer size. The default size of the internal buffer is 4096 samples.
Constraints
This class requires that the sample rate, number of channels, bit resolution, and internal buffer size be the same for both capture and playback. The motivation for this constraint is to simplify usage. Most audio hardware requires this anyway.
Usage: audio capture
First, call the appropriate methods to set the desired audio format parameters such as sample rate, channels, bit resolution if values other than the defaults are desired. The setTransferSize() method should also be invoked to set the size of the array (in samples per channel) that is returned when audio samples are captured. The default value is 128 samples per channel. Then invoke the startCapture(consumer) method to start the audio capture process. This class will be ready to capture audio immediately after startCapture() returns. Note that startCapture() takes an Object parameter, consumer. In addition to starting the audio capture process, startCapture() also grants an object permission to capture audio.
After calling startCapture(consumer), the consumer object can capture audio from the input port by calling getSamples(consumer). The getSamples() method returns an array of samples from the input port. The getSamples() blocks until the requested number of samples (which is set by the setTransferSize method) are available. Thus, it is not possible to call this method too frequently. Note that if getSamples() is not called frequently enough, the internal buffer will overflow and some audio data will be lost, which is generally undersirable. After the consumer object no longer wishes to capture audio, it should free up the audio system resources by calling the stopCapture(consumer) method. It should be noted that only one object may capture audio simultaneously from the audio input port. A future version of this class may support multiple objects capturing from the input port simultaneously.
Usage: audio Playback
First, call the appropriate methods to set the desired audio format parameters such as sample rate, channels, bit resolution if values other than the defaults are desired. The setTransferSize() method should also be invoked to set the size of the array (in samples per channel) that is supplied when audio samples are played. The default value is 128 samples per channel. Then invoke the startPlayback(producer) method to start the audio playback process. This class will be ready to playback audio immediately after startPlayback() returns. Note that startPlayback() takes an Object parameter, producer. In addition to starting the audio playback process, startPlayback() also grants an object permission to playback audio.
After calling startPlayback(producer), the producer object can playback audio to the output port by calling putSamples(producer). The putSamples() method takes an array of samples and sends the audio data to the output port. The putSamples() method blocks until the requested number of samples (which is set by the setTransferSize method) have been written to the output port. Thus, it is not possible to call this method too frequently. Note that if putSamples() is not called frequently enough, the internal buffer will underflow, causing audible artifacts in the output signal. After the producer object no longer wishes to playback audio, it should free up the audio system resources by calling the stopPlayback(producer) method. It should be noted that only one object may playback audio simultaneously to the audio output port. A future version of this class may support multiple objects playing to the output port simultaneously.
SoundReader
,
SoundWriter
Red (cxh) |
Yellow (net) |
Field Summary | |
---|---|
private static double[][] |
_audioInDoubleArray
Array of audio samples in double format. |
private static int |
_bitsPerSample
The number of bits per sample. |
private static int |
_bufferSize
The requested buffer size in samples per channel. |
private static int |
_bytesPerSample
The number of bytes per sample, default 2. |
private static byte[] |
_captureData
Array of audio samples in byte format. |
private static boolean |
_captureIsActive
true is audio capture is currently active. |
private static int |
_channels
The number of channels. |
private static java.util.List |
_liveSoundListeners
|
private static double |
_maxSample
|
private static double |
_maxSampleReciprocal
|
private static byte[] |
_playbackData
Byte buffer used for playback data. |
private static boolean |
_playbackIsActive
|
private static float |
_sampleRate
|
private static java.util.List |
_soundConsumers
|
private static javax.sound.sampled.SourceDataLine |
_sourceLine
Interface to the hardware for reading data. |
private static javax.sound.sampled.TargetDataLine |
_targetLine
Interface to the hardware for producing sound. |
private static int |
_transferSize
The number of audio samples to transfer per channel when getSamples() is invoked. |
Constructor Summary | |
---|---|
LiveSound()
|
Method Summary | |
---|---|
private static void |
_byteArrayToDoubleArray(double[][] doubleArray,
byte[] byteArray)
|
private static byte[] |
_doubleArrayToByteArray(double[][] doubleArray)
|
private static java.lang.String |
_encodings(javax.sound.sampled.AudioFormat format)
Return a string that describes the possible encodings for an AudioFormat. |
private static void |
_flushCaptureBuffer()
|
private static void |
_flushPlaybackBuffer()
|
private static void |
_notifyLiveSoundListeners(int parameter)
Notify the live sound listeners about a change in an audio parameter. |
private static void |
_startCapture()
Start audio capture. |
private static void |
_startPlayback()
Start audio playback. |
private static void |
_stopCapture()
Stop audio capture. |
private static void |
_stopPlayback()
Stop audio playback. |
static void |
addLiveSoundListener(LiveSoundListener listener)
Add a live sound listener. |
static void |
flushCaptureBuffer(java.lang.Object consumer)
Flush queued data from the capture buffer. |
static void |
flushPlaybackBuffer(java.lang.Object producer)
Flush queued data from the playback buffer. |
static int |
getBitsPerSample()
Return the number of bits per audio sample, which is set by the setBitsPerSample() method. |
static int |
getBufferSize()
Return the suggested size of the internal capture and playback audio buffers, in samples per channel. |
static int |
getBufferSizeCapture()
Return the size of the internal capture audio buffer, in samples per channel. |
static int |
getBufferSizePlayback()
Return the size of the internal playback audio buffer, in samples per channel. |
static int |
getChannels()
Return the number of audio channels, which is set by the setChannels() method. |
static int |
getSampleRate()
Return the current sampling rate in Hz, which is set by the setSampleRate() method. |
static double[][] |
getSamples(java.lang.Object consumer)
Return an array of captured audio samples. |
static int |
getTransferSize()
Get the array length (in samples per channel) to use for capturing and playing samples via the putSamples() and getSamples() methods. |
static boolean |
isCaptureActive()
Return true if audio capture is currently active. |
static boolean |
isPlaybackActive()
Return true if audio playback is currently active. |
static void |
putSamples(java.lang.Object producer,
double[][] samplesArray)
Play an array of audio samples. |
static void |
removeLiveSoundListener(LiveSoundListener listener)
Remove a live sound listener. |
static void |
resetCapture()
Stop audio capture. |
static void |
resetPlayback()
Stop audio playback. |
static void |
setBitsPerSample(int bitsPerSample)
Set the number of bits per sample to use for audio capture and playback and notify any registered listeners of the change. |
static void |
setBufferSize(int bufferSize)
Request that the internal capture and playback audio buffers have bufferSize samples per channel and notify the registered listeners of the change. |
static void |
setChannels(int channels)
Set the number of audio channels to use for capture and playback and notify any registered listeners of the change. |
static void |
setSampleRate(int sampleRate)
Set the sample rate to use for audio capture and playback and notify an registered listeners of the change. |
static void |
setTransferSize(int transferSize)
Set the array length (in samples per channel) to use for capturing and playing samples via the putSamples() and getSamples() methods. |
static void |
startCapture(java.lang.Object consumer)
Start audio capture. |
static void |
startPlayback(java.lang.Object producer)
Start audio playback. |
static void |
stopCapture(java.lang.Object consumer)
Stop audio capture. |
static void |
stopPlayback(java.lang.Object producer)
Stop audio playback. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
private static double[][] _audioInDoubleArray
private static int _bitsPerSample
private static int _bufferSize
private static int _bytesPerSample
private static boolean _captureIsActive
private static int _channels
private static byte[] _captureData
private static byte[] _playbackData
private static java.util.List _liveSoundListeners
private static double _maxSampleReciprocal
private static double _maxSample
private static boolean _playbackIsActive
private static float _sampleRate
private static java.util.List _soundConsumers
private static javax.sound.sampled.SourceDataLine _sourceLine
private static javax.sound.sampled.TargetDataLine _targetLine
private static int _transferSize
Constructor Detail |
---|
public LiveSound()
Method Detail |
---|
public static void addLiveSoundListener(LiveSoundListener listener)
listener
- The LiveSoundListener to add.removeLiveSoundListener(LiveSoundListener)
public static void flushCaptureBuffer(java.lang.Object consumer) throws java.io.IOException, java.lang.IllegalStateException
Note that only the object with the exclusive lock on the capture audio resources is allowed to invoke this method. An exception will occur if the specified object does not have the lock on the playback audio resources.
consumer
- The object that has an exclusive lock on
the capture audio resources.
java.lang.IllegalStateException
- If audio capture is currently
inactive. That is, if startCapture() has not yet been called
or if stopCapture() has already been called.
java.io.IOException
- If the calling program does not have permission
to access the audio capture resources.public static void flushPlaybackBuffer(java.lang.Object producer) throws java.io.IOException, java.lang.IllegalStateException
Note that only the object with the exclusive lock on the playback audio resources is allowed to invoke this method. An exception will occur if the specified object does not have the lock on the playback audio resources.
producer
- The object that has an exclusive lock on
the playback audio resources.
java.lang.IllegalStateException
- If audio playback is currently
inactive. That is, if startPlayback() has not yet been called
or if stopPlayback() has already been called.
java.io.IOException
- If the calling program does not have permission
to access the audio playback resources.public static int getBitsPerSample()
setBitsPerSample(int)
public static int getBufferSize()
setBufferSize(int)
public static int getBufferSizeCapture() throws java.lang.IllegalStateException
java.lang.IllegalStateException
- If audio capture is inactive.public static int getBufferSizePlayback()
java.lang.IllegalStateException
- If audio playback is inactive.public static int getChannels()
setChannels(int)
public static int getSampleRate()
setSampleRate(int)
public static double[][] getSamples(java.lang.Object consumer) throws java.io.IOException, java.lang.IllegalStateException
The first index of the returned array represents the channel number (0 for first channel, 1 for second channel). The number of channels is set by the setChannels() method. The second index represents the sample index within a channel. For example, returned array[n][m] contains the (m+1)th sample of the (n+1)th channel. For each channel, n, the length of returned array[n] is equal to the value returned by the getTransferSize() method. The size of the 2nd dimension of the returned array is set by the setTransferSize() method.
Note that only the object with the exclusive lock on the captured audio resources is allowed to invoked this method. An exception will occur if the specified object does not have the lock on the captured audio resources.
consumer
- The object that has an exclusive lock on
the capture audio resources.
java.lang.IllegalStateException
- If audio capture is currently
inactive. That is, if startCapture() has not yet been called or if
stopCapture() has already been called.
java.io.IOException
- If the calling program does not have permission
to access the audio capture resources.public static int getTransferSize()
setTransferSize(int)
public static boolean isCaptureActive()
public static boolean isPlaybackActive()
public static void putSamples(java.lang.Object producer, double[][] samplesArray) throws java.io.IOException, java.lang.IllegalStateException
The samples should be in the range (-1, 1). Samples that are outside this range will be hard-clipped so that they fall within this range.
The first index of the specified array represents the channel number (0 for first channel, 1 for second channel, etc.). The number of channels is set by the setChannels() method. The second index represents the sample index within a channel. For example, putSamplesArray[n][m] contains the (m+1)th sample of the (n+1)th channel.
Note that only the object with the exclusive lock on the playback audio resources is allowed to invoke this method. An exception will occur if the specified object does not have the lock on the playback audio resources.
producer
- The object that has an exclusive lock on
the playback audio resources.samplesArray
- A two dimensional array containing
the samples to play or write to a file.
java.io.IOException
- If the calling program does not have permission
to access the audio playback resources.
java.lang.IllegalStateException
- If audio playback is currently
inactive. That is, If startPlayback() has not yet been called
or if stopPlayback() has already been called.public static void removeLiveSoundListener(LiveSoundListener listener)
listener
- The LiveSoundListener to remove.addLiveSoundListener(LiveSoundListener)
public static void resetCapture()
public static void resetPlayback()
public static void setBitsPerSample(int bitsPerSample) throws java.io.IOException
bitsPerSample
- The number of bits per sample.
java.io.IOException
- If the specified bits per sample is
not supported by the audio hardware or by Java.getBitsPerSample()
public static void setBufferSize(int bufferSize) throws java.io.IOException
bufferSize
- The suggested size of the internal capture and
playback audio buffers, in samples per channel.
java.io.IOException
- If the specified number of channels is
not supported by the audio hardware or by Java.getBufferSize()
public static void setChannels(int channels) throws java.io.IOException
channels
- The number audio channels.
java.io.IOException
- If the specified number of channels is
not supported by the audio hardware or by Java.getChannels()
public static void setSampleRate(int sampleRate) throws java.io.IOException
sampleRate
- Sample rate in Hz.
java.io.IOException
- If the specified sample rate is
not supported by the audio hardware or by Java.getSampleRate()
public static void setTransferSize(int transferSize) throws java.lang.IllegalStateException
This method should only be called while audio capture and playback are inactive. Otherwise an exception will occur.
transferSize
- The size of the 2nd dimension of
the 2-dimensional array used by the putSamples() and
getSamples() methods
java.lang.IllegalStateException
- If this method is called
while audio capture or playback are active.getTransferSize()
public static void startCapture(java.lang.Object consumer) throws java.io.IOException, java.lang.IllegalStateException
If audio capture is already active, then an exception will occur.
consumer
- The object to be given exclusive access
to the captured audio resources.
java.io.IOException
- If another object currently has access
to the audio capture resources or if starting the capture or
playback throws it.
java.lang.IllegalStateException
- If this method is called
while audio capture is already active.public static void startPlayback(java.lang.Object producer) throws java.io.IOException, java.lang.IllegalStateException
If audio playback is already active, then an exception will occur.
producer
- The object to be given exclusive access
to the playback resources.
java.io.IOException
- If another object currently has access
to the audio capture resources or if starting the playback throws it.
java.lang.IllegalStateException
- If this method is called
while audio playback is already active.public static void stopCapture(java.lang.Object consumer) throws java.io.IOException, java.lang.IllegalStateException
consumer
- The object that held on exclusive
lock on the captured audio resources when this
method was invoked.
java.io.IOException
- If another object currently has access
to the audio capture resources or if stopping the capture throws it.
java.lang.IllegalStateException
- If the specified
object did not hold an exclusive lock on the
captured audio resources when this method was invoked.public static void stopPlayback(java.lang.Object producer) throws java.io.IOException, java.lang.IllegalStateException
producer
- The object that held on exclusive
lock on the playback audio resources when this
method was invoked.
java.io.IOException
- If another object currently has access
to the audio capture resources or if stopping the playback throws it.
java.lang.IllegalStateException
- If the specified
object did not hold an exclusive lock on the
playback audio resources when this method was invoked.private static void _byteArrayToDoubleArray(double[][] doubleArray, byte[] byteArray)
private static byte[] _doubleArrayToByteArray(double[][] doubleArray) throws java.lang.IllegalArgumentException
java.lang.IllegalArgumentException
private static java.lang.String _encodings(javax.sound.sampled.AudioFormat format)
format
- The audio format.
private static void _flushCaptureBuffer()
private static void _flushPlaybackBuffer()
private static void _notifyLiveSoundListeners(int parameter)
parameter
- The audio parameter of LiveSound that
has changed. The value of parameter should be one of
LiveSoundEvent.SAMPLE_RATE, LiveSoundEvent.CHANNELS,
LiveSoundEvent.BUFFER_SIZE, or
LiveSoundEvent.BITS_PER_SAMPLE.
java.lang.Exception
- If a listener has a problem responding
to the change.private static void _startCapture() throws java.io.IOException
java.io.IOException
private static void _startPlayback() throws java.io.IOException
java.io.IOException
private static void _stopPlayback()
private static void _stopCapture()
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES All Classes | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |