Class StdAudioStereo


  • public final class StdAudioStereo
    extends Object
    The StdAudioStereo class provides static methods for playing, reading, and saving stereo audio. It uses a simple audio model that allows you to send one pair of samples (left channel and right channel) to the sound card at a time. Each sample is a real number between –1.0 and +1.0. The samples are played in real time using a sampling rate of 44,100 Hz. In addition to playing individual pairs of samples, standard audio supports reading, writing, and playing audio files in a number of standard formats.

    See StdAudio for a version that supports monaural audio (one channel only).

    Getting started. To use this class, you must have StdAudioStereo in your Java classpath. Here are three possible ways to do this:

    • If you ran our autoinstaller, use the commands javac-introcs and java-introcs (or javac-algs4 and java-algs4) when compiling and executing. These commands add stdlib.jar (or algs4.jar) to the Java classpath, which provides access to StdAudioStereo.
    • Download stdlib.jar (or algs4.jar) and add it to the Java classpath.
    • Download StdAudioStereo.java and put it in the working directory.

    As a test, cut-and-paste the following short program into your editor:

       public class TestStdAudioStereo {
           public static void main(String[] args) {
               double freq1 = 440.0;
               double freq2 = 220.0;
               for (int i = 0; i < StdAudioStereo.SAMPLE_RATE; i++) {
                   double sampleLeft  = 0.5 * Math.sin(2 * Math.PI * freq1 * i / StdAudioStereo.SAMPLE_RATE);
                   double sampleRight = 0.5 * Math.sin(2 * Math.PI * freq2 * i / StdAudioStereo.SAMPLE_RATE);
                   StdAudioStereo.play(sampleLeft, sampleRight);
               }
               StdAudioStereo.drain();
           }
       }
      

    If you compile and execute the program, you should hear a pure tone whose frequency is concert A (440 Hz) in the left speaker and the pitch A3 (220 Hz) in the right speaker.

    Playing audio samples. You can use the following methods to play individual audio samples, either in monaural or stereo:

    Each method sends the specified sample (or samples) to the sound card. The individual samples are real numbers between –1.0 and +1.0. If a sample is outside this range, it will be clipped (rounded to –1.0 or +1.0). The samples are played in real time using a sampling rate of 44,100 Hz.

    Playing audio files. You can use the following method to play an audio file:

    It plays an audio file (in WAVE, AU, AIFF, or MIDI format) and does not return until the audio file is finished playing. This can produce particularly striking programs with minimal code. For example, the following code fragment plays a drum loop:

       while (true) {
           StdAudioStereo.play("BassDrum.wav");
           StdAudioStereo.play("SnareDrum.wav");
       }
      
    The individual audio files (such as BassDrum.wav and SnareDrum.wav) must be accessible to Java, typically by being in the same directory as the .class file.

    Reading and writing audio files. You can read and write audio files using the following methods:

    The first method reads audio samples from an audio file (in WAVE, AU, AIFF, or MIDI format) and returns them as a double array with values between –1.0 and +1.0. The second two method saves the audio samples in the specified double array to an audio file (in WAVE, AU, or AIFF format), either in monaural or stereo.

    Audio file formats. StdAudioStereo relies on the Java Media Framework for reading, writing, and playing audio files. You should be able to read or play files in WAVE, AU, AIFF, and MIDI formats and save them to WAVE, AU, and AIFF formats. The file extensions corresponding to WAVE, AU, AIFF, and MIDI files are .wav, .au, .aiff, and .midi, respectively. Some systems support additional audio file formats, but probably not MP3 or M4A.

    The Java Media Framework supports a variety of different audio data formats, which includes

    • the sampling rate (e.g., 44,100 Hz);
    • the number of bits per sample per channel (e.g., 8-bit or 16-bit);
    • the number of channels (e.g., monaural or stereo);
    • the byte ordering (e.g., little endian or big endian); and
    • the encoding scheme (typically linear PCM).

    When saving files, StdAudioStereo uses a sampling rate of 44,100 Hz, 16 bits per sample, stereo audio, little endian, and linear PCM encoding. When reading files, StdAudioStereo converts to a sammpling rate of 44,100 Hz, with 16 bits per sample.

    Recording audio. You can use the following methods to record audio samples that are played as a result of calls to play(double sample), play(double sampleLeft, double sampleRight), play(double[] samples), play(double[] samplesLeft, double[] samplesRight), or play(String filename):

    The method startRecording() begins recording audio. The method stopRecording() stops recording. After calling stopRecording(), you can access the recorded left and right channels using getRecordingLeft() and getRecordingRight().

    StdAudioStereo does not currently support recording audio that calls playInBackground().

    Playing audio files in a background thread. You can use the following methods to play an audio file in a background thread (e.g., as a background score in your program).

    Each call to the first method plays the specified sound in a separate background thread. Unlike with the play(double,double) methods, your program will not wait for the samples to finish playing before continuing. It supports playing an audio file in WAVE, AU, AIFF, or MIDI format. It is possible to play multiple audio files simultaneously (in separate background threads). The second method stops the playing of all audio in background threads.

    Draining standard audio. On some systems, your Java program may terminate before all of the samples have been sent to the sound card. To prevent this, it is recommend that you call the following method to indicate that you are done using standard audio:

    The method drains any samples queued to the sound card that have not yet been sent to the sound card.

    Reference. For additional documentation, see Section 1.5 of Computer Science: An Interdisciplinary Approach by Robert Sedgewick and Kevin Wayne.

    Author:
    Robert Sedgewick, Kevin Wayne
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static int SAMPLE_RATE
      The sample rate: 44,100 Hz for CD quality audio.
    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      static void drain()
      Sends any queued samples to the sound card.
      static double[] getRecordingLeft()
      Returns the array of samples that was recorded in the left channel in between the last calls to startRecording() and stopRecording().
      static double[] getRecordingMono()
      Returns the array of samples that was recorded in the right channel in between the last calls to startRecording() and stopRecording(), by taking the average of the samples in the left and right channels.
      static double[] getRecordingRight()
      Returns the array of samples that was recorded in the right channel in between the last calls to startRecording() and stopRecording().
      static void main​(String[] args)
      Test client - plays some sound files and concert A.
      static void play​(double sample)
      Writes one sample (between –1.0 and +1.0) to standard audio.
      static void play​(double[] samples)
      Writes the array of samples (between –1.0 and +1.0) to standard audio.
      static void play​(double[] samplesLeft, double[] samplesRight)
      Writes the array of stereo samples (between –1.0 and +1.0) to standard audio.
      static void play​(double sampleLeft, double sampleRight)
      Writes one stereo sample (between –1.0 and +1.0) to standard audio.
      static void play​(String filename)
      Plays an audio file (in WAVE, AU, AIFF, or MIDI format) and waits for it to finish.
      static void playInBackground​(String filename)
      Plays an audio file (in WAVE, AU, AIFF, or MIDI format) in its own background thread.
      static double[] read​(String filename)
      Reads the audio samples from a file (in WAVE, AU, AIFF, or MIDI format) and returns them as a double array with values between –1.0 and +1.0.
      static double[] readLeft​(String filename)
      Reads the audio samples (left channel) from an audio file (in WAVE, AU, AIFF, or MIDI format) and returns them as a double array with values between –1.0 and +1.0.
      static double[] readRight​(String filename)
      Reads the audio samples (right channel) from an audio file (in WAVE, AU, AIFF, or MIDI format) and returns them as a double array with values between –1.0 and +1.0.
      static void save​(String filename, double[] samples)
      Saves the audio samples as an monaural audio file (in WAV, AU, or AIFF format).
      static void save​(String filename, double[] samplesLeft, double[] samplesRight)
      Saves the stereo samples as a stereo audio file (in WAV, AU, or AIFF format).
      static void startRecording()
      Starts recording audio samples.
      static void stopInBackground()
      Stops the playing of all audio files in background threads.
      static void stopRecording()
      Stops recording audio samples.
    • Field Detail

      • SAMPLE_RATE

        public static final int SAMPLE_RATE
        The sample rate: 44,100 Hz for CD quality audio.
        See Also:
        Constant Field Values
    • Method Detail

      • drain

        public static void drain()
        Sends any queued samples to the sound card.
      • play

        public static void play​(double sampleLeft,
                                double sampleRight)
        Writes one stereo sample (between –1.0 and +1.0) to standard audio. If the sample is outside the range, it will be clipped (rounded to –1.0 or +1.0).
        Parameters:
        sampleLeft - the left sample to play
        sampleRight - the right sample to play
        Throws:
        IllegalArgumentException - if either sampleLeft or sampleRight is Double.NaN
      • play

        public static void play​(double sample)
        Writes one sample (between –1.0 and +1.0) to standard audio. If the sample is outside the range, it will be clipped (rounded to –1.0 or +1.0).
        Parameters:
        sample - the sample to play
        Throws:
        IllegalArgumentException - if sample is Double.NaN
      • play

        public static void play​(double[] samples)
        Writes the array of samples (between –1.0 and +1.0) to standard audio. If a sample is outside the range, it will be clipped.
        Parameters:
        samples - the array of samples to play
        Throws:
        IllegalArgumentException - if any sample is Double.NaN
        IllegalArgumentException - if samples is null
      • play

        public static void play​(double[] samplesLeft,
                                double[] samplesRight)
        Writes the array of stereo samples (between –1.0 and +1.0) to standard audio. If a sample is outside the range, it will be clipped.
        Parameters:
        samplesLeft - the array of samples for the left channel to play
        samplesRight - the array of samples for the right channel to play
        Throws:
        IllegalArgumentException - if any sample is Double.NaN
        IllegalArgumentException - if either samplesLeft or samplesRight is null
        IllegalArgumentException - if samplesLeft.length != samplesRight.length
      • play

        public static void play​(String filename)
        Plays an audio file (in WAVE, AU, AIFF, or MIDI format) and waits for it to finish.
        Parameters:
        filename - the name of the audio file
        Throws:
        IllegalArgumentException - if unable to play filename
        IllegalArgumentException - if filename is null
      • readLeft

        public static double[] readLeft​(String filename)
        Reads the audio samples (left channel) from an audio file (in WAVE, AU, AIFF, or MIDI format) and returns them as a double array with values between –1.0 and +1.0. The file can be any audio file supported by the Java Media Framework; if the audio data format is monaural, then readLeft(java.lang.String) and readRight(java.lang.String) will return the same sequence of values.
        Parameters:
        filename - the name of the audio file
        Returns:
        the array of samples
      • readRight

        public static double[] readRight​(String filename)
        Reads the audio samples (right channel) from an audio file (in WAVE, AU, AIFF, or MIDI format) and returns them as a double array with values between –1.0 and +1.0. The file can be any audio file supported by the Java Media Framework; if the audio data format is monaural, then readLeft(java.lang.String) and readRight(java.lang.String) will return the same sequence of values.
        Parameters:
        filename - the name of the audio file
        Returns:
        the array of samples
      • read

        public static double[] read​(String filename)
        Reads the audio samples from a file (in WAVE, AU, AIFF, or MIDI format) and returns them as a double array with values between –1.0 and +1.0. The samples returned use 16-bit audio data, a sampling rate of 44,100, and monaural audio. The file can be any audio file supported by the Java Media Framework; if the audio data format is stereo, it is first converted to monaural.
        Parameters:
        filename - the name of the audio file
        Returns:
        the array of samples
      • save

        public static void save​(String filename,
                                double[] samples)
        Saves the audio samples as an monaural audio file (in WAV, AU, or AIFF format). The file extension type must be either .wav, .au, or .aiff. The audio data format uses a sampling rate of 44,100 Hz, 16-bit audio, monaural, signed PCM, ands little endian.
        Parameters:
        filename - the name of the audio file
        samples - the array of samples to save
        Throws:
        IllegalArgumentException - if unable to save filename
        IllegalArgumentException - if samples is null
        IllegalArgumentException - if filename is null
        IllegalArgumentException - if filename extension is not .wav, .au, or .aiff.
      • save

        public static void save​(String filename,
                                double[] samplesLeft,
                                double[] samplesRight)
        Saves the stereo samples as a stereo audio file (in WAV, AU, or AIFF format). The file extension type must be either .wav, .au, or .aiff. The audio data format uses a sampling rate of 44,100 Hz, 16-bit audio, stereo, signed PCM, ands little endian.
        Parameters:
        filename - the name of the audio file
        samplesLeft - the array of samples in left channel to save
        samplesRight - the array of samples in right channel to save
        Throws:
        IllegalArgumentException - if unable to save filename
        IllegalArgumentException - if samplesLeft is null
        IllegalArgumentException - if samplesRight is null
        IllegalArgumentException - if samplesLeft.length != samplesRight.length
        IllegalArgumentException - if filename extension is not .wav, .au, or .aiff.
      • stopInBackground

        public static void stopInBackground()
        Stops the playing of all audio files in background threads.
      • playInBackground

        public static void playInBackground​(String filename)
        Plays an audio file (in WAVE, AU, AIFF, or MIDI format) in its own background thread. Multiple audio files can be played simultaneously.
        Parameters:
        filename - the name of the audio file
        Throws:
        IllegalArgumentException - if unable to play filename
        IllegalArgumentException - if filename is null
      • startRecording

        public static void startRecording()
        Starts recording audio samples. This includes all calls to play() that take samples as arguments, but not calls to play() that play audio files.
        Throws:
        IllegalArgumentException - if recording mode is already on
      • stopRecording

        public static void stopRecording()
        Stops recording audio samples.
        Throws:
        IllegalArgumentException - if recording mode is not currently on
      • getRecordingLeft

        public static double[] getRecordingLeft()
        Returns the array of samples that was recorded in the left channel in between the last calls to startRecording() and stopRecording().
        Returns:
        the array of samples
        Throws:
        IllegalArgumentException - unless startRecording and stopRecording were previously called in the appropriate order
      • getRecordingRight

        public static double[] getRecordingRight()
        Returns the array of samples that was recorded in the right channel in between the last calls to startRecording() and stopRecording().
        Returns:
        the array of samples
        Throws:
        IllegalArgumentException - unless startRecording and stopRecording were previously called in the appropriate order
      • getRecordingMono

        public static double[] getRecordingMono()
        Returns the array of samples that was recorded in the right channel in between the last calls to startRecording() and stopRecording(), by taking the average of the samples in the left and right channels.
        Returns:
        the array of samples
        Throws:
        IllegalArgumentException - unless startRecording and stopRecording were previously called in the appropriate order
      • main

        public static void main​(String[] args)
        Test client - plays some sound files and concert A.
        Parameters:
        args - the command-line arguments (none should be specified)