public class LiveSound
extends java.lang.Object
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 undesirable. 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
Constructor and Description |
---|
LiveSound() |
Modifier and Type | Method and Description |
---|---|
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.
|
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() methodsjava.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.