Class SoundCapture


  • public class SoundCapture
    extends java.lang.Object
    A buffer supporting the capturing of audio samples from a file or from the computer's audio input port.

    Overview

    A buffer supporting the capturing of audio samples from a file or from the computer's audio input port. This class supports the real-time capture of audio from the audio input port (mic or line-in) as well as the capture of audio from a sound file specified as a URL. Single channel (mono) and multichannel audio (stereo) are supported. This class, along with SoundPlayback, intends to provide an easy to use interface to Java Sound, Java's audio API. Java Sound supports the capture of audio data, but only at the byte level, which is audio format specific. This class, however, provides higher level support for the capture of double or integer valued samples from the computer's audio input port or any supported sound file type. This class is therefore useful when it one desires to capture audio samples in an audio format independent way.

    Depending on available audio system resources, it may be possible to run an instance of this class and an instance of SoundPlayback concurrently. This allows for the concurrent capture, signal processing, and playback of audio data.

    Usage

    Two constructors are provided. One constructor creates a sound capture object that captures from the line-in or microphone port. The operating system must be used to select between the microphone and line-in. This cannot be done using Java. If this constructor is used, there will be a small delay between the time that the audio enters the microphone or line-in and the time that the corresponding audio samples are available via getSamples() or getSamplesInt(). This latency can be adjusted by setting the bufferSize constructor parameter. Another constructor creates a sound capture object that captures audio from a sound file specified as a URL.

    After calling the appropriate constructor, startCapture() must be called to initialize the audio system for capture. The getSamples() or getSamplesInt() method should then be repeatedly invoked to obtain audio data in the form of a multidimensional array of audio sample values. getSamples() will return audio sample values in the range [-1, 1]. getSamplesInt() will return audio samples in the range (-2^(bits_per_sample/2), 2^(bits_per_sample/2)), where bits_per_sample is the number of bits per sample. For the case where audio is captured from the mic or line-in, it is important to invoke getSamples() or getSamplesInt() often enough to prevent overflow of the internal audio buffer. The size of the internal buffer is set in the constructor. Note that it is possible (but probably not useful) to interleave calls to getSamples() and getSamplesInt(). Finally, after no more audio data is desired, stopCapture() should be called to free up audio system resources.

    Security issues

    Applications have no restrictions on the capturing or playback of audio. Applets, however, may only capture audio from a file specified as a URL on the same machine as the one the applet was loaded from. Applet code is not allowed to read or write native files. The .java.policy file must be modified to grant applets more privileges.

    Since:
    Ptolemy II 1.0
    Version:
    $Id$
    Author:
    Brian K. Vogel
    See Also:
    SoundPlayback
    Pt.AcceptedRating:
    Yellow (cxh)
    Pt.ProposedRating:
    Yellow (vogel)
    • Constructor Summary

      Constructors 
      Constructor Description
      SoundCapture​(float sampleRate, int sampleSizeInBits, int channels, int bufferSize, int getSamplesSize)
      Construct a sound capture object that captures audio from a computer's audio input port.
      SoundCapture​(java.lang.String pathName, int getSamplesSize)
      Construct a sound capture object that captures audio from a sound file specified as a URL.
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      int getChannels()
      Return the number of audio channels.
      float getSampleRate()
      Return the sampling rate in Hz.
      double[][] getSamples()
      Return an array of captured audio samples.
      int[][] getSamplesInt()
      Return an array of captured audio samples.
      int getSampleSizeInBits()
      Return the number of bits per audio sample.
      void startCapture()
      Begin capturing audio.
      void stopCapture()
      Stop capturing audio.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • SoundCapture

        public SoundCapture​(float sampleRate,
                            int sampleSizeInBits,
                            int channels,
                            int bufferSize,
                            int getSamplesSize)
        Construct a sound capture object that captures audio from a computer's audio input port. If this constructor is used, then it is important that getSamples() be invoked often enough to prevent overflow of the internal audio input buffer. Note the startCapture() must be called before the first invocation of getSamples(), otherwise getSamples() will throw an exception.
        Parameters:
        sampleRate - Sample rate in Hz. Must be in the range: 8000 to 48000.
        sampleSizeInBits - Number of bits per sample. Choices are 8 or 16.
        channels - Number of audio channels. 1 for mono, 2 for stereo.
        bufferSize - Requested size of the internal audio input buffer in samples. This controls the latency. A lower bound on the latency is given by (bufferSize / sampleRate) seconds. Ideally, the smallest value that gives acceptable performance (no overflow) should be used. Typical values are about 1/10 th the sample rate. For example, at 44100 Hz sample rate, a typical buffer size value might be 4410.
        getSamplesSize - Size of the array returned by getSamples(). For performance reasons, the size should be chosen smaller than bufferSize. Typical values are 1/2 to 1/16th of bufferSize.
      • SoundCapture

        public SoundCapture​(java.lang.String pathName,
                            int getSamplesSize)
        Construct a sound capture object that captures audio from a sound file specified as a URL. Note that it is still possible to capture audio from a file on the local file system. For example, to capture from a sound file located at "C:\someDir\someFile.wave", pathName should be set to "file:///C:/someDir/someFile.wave".

        Note the startCapture() must be called before the first invocation of getSamples(), otherwise getSamples() will throw an exception.

        Parameters:
        pathName - The name of the file as a URL. Valid sound file formats are WAVE (.wav), AIFF (.aif, .aiff), AU (.au). The file format is automatically determined from the file extension. If there is a problem reading the sound file, an IOException will be thrown in startCapture().
        getSamplesSize - The number of samples per channel returned by getSamples().
    • Method Detail

      • getChannels

        public int getChannels()
                        throws java.lang.IllegalStateException
        Return the number of audio channels. This method will return the number of audio channels, regardless of which constructor was used. However, this method is really only useful when the constructor that causes audio to be captured from a file is used, since the number of channels is unknown until the file is opened.

        This method should be called while audio capture is active, i.e., after startCapture() is called and before stopCapture() is called.

        Returns:
        The number of audio channels. Return null if this method is called before startCapture().
        Throws:
        java.lang.IllegalStateException - If this method is called before startCapture() is called or after stopCapture() is called.
      • getSampleRate

        public float getSampleRate()
                            throws java.lang.IllegalStateException
        Return the sampling rate in Hz. This method will return the sampling rate, regardless of which constructor was used. However, this method is really only useful when the constructor that causes audio to be captured from a file is used, since the sampling rate is unknown until the file is opened.

        This method should be called while audio capture is active, i.e., after startCapture() is called and before stopCapture() is called.

        Returns:
        The sample rate in Hz. Return null if this method is called before startCapture().
        Throws:
        java.lang.IllegalStateException - If this method is called before startCapture() is called or after stopCapture() is called.
      • getSamples

        public double[][] getSamples()
                              throws java.io.IOException,
                                     java.lang.IllegalStateException
        Return an array of captured audio samples. This method should be repeatedly called to obtain audio data. The returned audio samples will have values in the range [-1, 1], regardless of the audio bit resolution (bits per sample). When capturing from the computer's audio input port (mic or line-in), this method should be called often enough to prevent overflow of the internal audio buffer. If overflow occurs, some audio data will be lost but no exception or other error condition will occur. If the audio data is not yet available, then this method will block until the data is available. When capturing from a sound file, it is not possible for overflow to occur.

        The array size is set by the getSamplesSize parameter in the constructor. For the case where audio is captured from the computer's audio-in port (mic or line-in), this method should be called often enough to prevent overflow of the internal audio buffer, the size of which is set in the constructor.

        Returns:
        Two dimensional array of captured audio samples. Return null if end of audio file is reached. A null return value is only possible when capturing from a sound file. The first index represents the channel number (0 for first channel, 1 for second channel, etc.). 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 getSamplesSize.
        Throws:
        java.io.IOException - If there is a problem capturing audio.
        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.
      • getSamplesInt

        public int[][] getSamplesInt()
                              throws java.io.IOException,
                                     java.lang.IllegalStateException
        Return an array of captured audio samples. This method should be repeatedly called to obtain audio data. This method requires less computation than getSamples(), since no conversion to doubles is performed. Therefore, the use of this method is recommended when integer valued audio samples are sufficient. The returned audio samples will have values in the range (-2^(bits_per_sample/2), 2^(bits_per_sample/2)). The range of sample values returned is therefore dependent on the bit resolution of the audio data. If this is not desired, then use getSamples() instead.

        When capturing from the computer's audio input port (mic or line-in), this method should be called often enough to prevent overflow of the internal audio buffer. If overflow occurs, some audio data will be lost but no exception or other error condition will occur. If the audio data is not yet available, then this method will block until the data is available. When capturing from a sound file, it is not possible for overflow to occur.

        The array size is set by the getSamplesSize parameter in the constructor. For the case where audio is captured from the computer's audio-in port (mic or line-in), this method should be called often enough to prevent overflow of the internal audio buffer, the size of which is set in the constructor.

        Returns:
        Two dimensional array of captured audio samples. Return null if end of audio file is reached A null return value is only possible when capturing from a sound file. The first index represents the channel number (0 for first channel, 1 for second channel, etc.). 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 getSamplesSize.
        Throws:
        java.io.IOException - If there is a problem capturing audio.
        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.
      • startCapture

        public void startCapture()
                          throws java.io.IOException,
                                 java.lang.IllegalStateException
        Begin capturing audio. This method must be invoked prior to the first invocation of getSamples(). If this is not done, then getSamples() will throw an exception when it is invoked. It is safe to call getSamples() immediately after this method returns. This method must not be called more than once between invocations of stopCapture(). Calling this method more than once between invocations of stopCapture() will cause this method to throw an exception.
        Throws:
        java.io.IOException - If there is a problem setting up the system for audio capture. This will occur if the a URL cannot be opened or if the audio in port cannot be accessed.
        java.lang.IllegalStateException - If this method is called more than once between invocations of stopCapture().
      • stopCapture

        public void stopCapture()
                         throws java.io.IOException
        Stop capturing audio. This method should be called when no more calls to getSamples(). are required, so that the system resources involved in the audio capture may be freed.
        Throws:
        java.io.IOException - If there is a problem closing the audio resources.
      • getSampleSizeInBits

        public int getSampleSizeInBits()
                                throws java.lang.IllegalStateException
        Return the number of bits per audio sample. This method will return the number of bits per audio sample, regardless of which constructor was used. However, this method is really only useful when the constructor that causes audio to be captured from a file is used, since the number of bits per audio sample is unknown until the file is opened.

        This method must be called while audio capture is active, i.e., after startCapture() is called and before stopCapture() is called, or else an exception will be thrown.

        Returns:
        The sample size in bits. Return null if this method is called before startCapture().
        Throws:
        java.lang.IllegalStateException - If this method is called before startCapture() is called or after stopCapture() is called.