alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (AudioDevice.java)

This example Java source code file (AudioDevice.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

audio, audiodevice, audioformat, audioinputstream, datapusher, debug, exception, hashtable, info, inputstream, invalidmididataexception, lineunavailableexception, midi, sequencer, sound, unsupportedaudiofileexception, util, vector

The AudioDevice.java Java example source code

/*
 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.audio;

import java.util.Hashtable;
import java.util.Vector;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedInputStream;

import javax.sound.sampled.*;
import javax.sound.midi.*;
import com.sun.media.sound.DataPusher;
import com.sun.media.sound.Toolkit;

/**
 * This class provides an interface to the Headspace Audio engine through
 * the Java Sound API.
 *
 * This class emulates systems with multiple audio channels, mixing
 * multiple streams for the workstation's single-channel device.
 *
 * @see AudioData
 * @see AudioDataStream
 * @see AudioStream
 * @see AudioStreamSequence
 * @see ContinuousAudioDataStream
 * @author David Rivas
 * @author Kara Kytle
 * @author Jan Borgersen
 * @author Florian Bomers
 */

public final class AudioDevice {

    private boolean DEBUG = false  /*true*/ ;

    /** Hashtable of audio clips / input streams. */
    private Hashtable clipStreams;

    private Vector infos;

    /** Are we currently playing audio? */
    private boolean playing = false;

    /** Handle to the JS audio mixer. */
    private Mixer mixer = null;



    /**
     * The default audio player. This audio player is initialized
     * automatically.
     */
    public static final AudioDevice device = new AudioDevice();

    /**
     * Create an AudioDevice instance.
     */
    private AudioDevice() {

        clipStreams = new Hashtable();
        infos = new Vector();
    }


    private synchronized void startSampled( AudioInputStream as,
                                            InputStream in ) throws UnsupportedAudioFileException,
                                  LineUnavailableException {

        Info info = null;
        DataPusher datapusher = null;
        DataLine.Info lineinfo = null;
        SourceDataLine sourcedataline = null;

        // if ALAW or ULAW, we must convert....
        as = Toolkit.getPCMConvertedAudioInputStream(as);

        if( as==null ) {
            // could not convert
            return;
        }

        lineinfo = new DataLine.Info(SourceDataLine.class,
                                     as.getFormat());
        if( !(AudioSystem.isLineSupported(lineinfo))) {
            return;
        }
        sourcedataline = (SourceDataLine)AudioSystem.getLine(lineinfo);
        datapusher = new DataPusher(sourcedataline, as);

        info = new Info( null, in, datapusher );
        infos.addElement( info );

        datapusher.start();
    }

    private synchronized void startMidi( InputStream bis,
                                         InputStream in ) throws InvalidMidiDataException,
                                  MidiUnavailableException  {

        Sequencer sequencer = null;
        Info info = null;

        sequencer = MidiSystem.getSequencer( );
        sequencer.open();
        try {
            sequencer.setSequence( bis );
        } catch( IOException e ) {
            throw new InvalidMidiDataException( e.getMessage() );
        }

        info = new Info( sequencer, in, null );

        infos.addElement( info );

        // fix for bug 4302884: Audio device is not released when AudioClip stops
        sequencer.addMetaEventListener(info);

        sequencer.start();

    }



    /**
     *  Open an audio channel.
     */
    public synchronized void openChannel(InputStream in) {


        if(DEBUG) {
            System.out.println("AudioDevice: openChannel");
            System.out.println("input stream =" + in);
        }

        Info info = null;

        // is this already playing?  if so, then just return
        for(int i=0; i<infos.size(); i++) {
            info = (AudioDevice.Info)infos.elementAt(i);
            if( info.in == in ) {

                return;
            }
        }


        AudioInputStream as = null;

        if( in instanceof AudioStream ) {

            if ( ((AudioStream)in).midiformat != null ) {

                // it's a midi file
                try {
                    startMidi( ((AudioStream)in).stream, in );
                } catch (Exception e) {
                    return;
                }


            } else if( ((AudioStream)in).ais != null ) {

                // it's sampled audio
                try {
                    startSampled( ((AudioStream)in).ais, in );
                } catch (Exception e) {
                    return;
                }

            }
        } else if (in instanceof AudioDataStream ) {
            if (in instanceof ContinuousAudioDataStream) {
                try {
                    AudioInputStream ais = new AudioInputStream(in,
                                                                ((AudioDataStream)in).getAudioData().format,
                                                                AudioSystem.NOT_SPECIFIED);
                    startSampled(ais, in );
                } catch (Exception e) {
                    return;
                }
            }
            else {
                try {
                    AudioInputStream ais = new AudioInputStream(in,
                                                                ((AudioDataStream)in).getAudioData().format,
                                                                ((AudioDataStream)in).getAudioData().buffer.length);
                    startSampled(ais, in );
                } catch (Exception e) {
                    return;
                }
            }
        } else {
            BufferedInputStream bis = new BufferedInputStream( in, 1024 );

            try {

                try {
                    as = AudioSystem.getAudioInputStream(bis);
                } catch(IOException ioe) {
                    return;
                }

                startSampled( as, in );

            } catch( UnsupportedAudioFileException e ) {

                try {
                    try {
                        MidiFileFormat mff =
                            MidiSystem.getMidiFileFormat( bis );
                    } catch(IOException ioe1) {
                        return;
                    }

                    startMidi( bis, in );


                } catch( InvalidMidiDataException e1 ) {

                    // $$jb:08.01.99: adding this section to make some of our other
                    // legacy classes work.....
                    // not MIDI either, special case handling for all others

                    AudioFormat defformat = new AudioFormat( AudioFormat.Encoding.ULAW,
                                                             8000, 8, 1, 1, 8000, true );
                    try {
                        AudioInputStream defaif = new AudioInputStream( bis,
                                                                        defformat, AudioSystem.NOT_SPECIFIED);
                        startSampled( defaif, in );
                    } catch (UnsupportedAudioFileException es) {
                        return;
                    } catch (LineUnavailableException es2) {
                        return;
                    }

                } catch( MidiUnavailableException e2 ) {

                    // could not open sequence
                    return;
                }

            } catch( LineUnavailableException e ) {

                return;
            }
        }

        // don't forget adjust for a new stream.
        notify();
    }


    /**
     *  Close an audio channel.
     */
    public synchronized void closeChannel(InputStream in) {

        if(DEBUG) {
            System.out.println("AudioDevice.closeChannel");
        }

        if (in == null) return;         // can't go anywhere here!

        Info info;

        for(int i=0; i<infos.size(); i++) {

            info = (AudioDevice.Info)infos.elementAt(i);

            if( info.in == in ) {

                if( info.sequencer != null ) {

                    info.sequencer.stop();
                    //info.sequencer.close();
                    infos.removeElement( info );

                } else if( info.datapusher != null ) {

                    info.datapusher.stop();
                    infos.removeElement( info );
                }
            }
        }
        notify();
    }


    /**
     * Open the device (done automatically)
     */
    public synchronized void open() {

        // $$jb: 06.24.99: This is done on a per-stream
        // basis using the new JS API now.
    }


    /**
     * Close the device (done automatically)
     */
    public synchronized void close() {

        // $$jb: 06.24.99: This is done on a per-stream
        // basis using the new JS API now.

    }


    /**
     * Play open audio stream(s)
     */
    public void play() {

        // $$jb: 06.24.99:  Holdover from old architechture ...
        // we now open/close the devices as needed on a per-stream
        // basis using the JavaSound API.

        if (DEBUG) {
            System.out.println("exiting play()");
        }
    }

    /**
     * Close streams
     */
    public synchronized void closeStreams() {

        Info info;

        for(int i=0; i<infos.size(); i++) {

            info = (AudioDevice.Info)infos.elementAt(i);

            if( info.sequencer != null ) {

                info.sequencer.stop();
                info.sequencer.close();
                infos.removeElement( info );

            } else if( info.datapusher != null ) {

                info.datapusher.stop();
                infos.removeElement( info );
            }
        }


        if (DEBUG) {
            System.err.println("Audio Device: Streams all closed.");
        }
        // Empty the hash table.
        clipStreams = new Hashtable();
        infos = new Vector();
    }

    /**
     * Number of channels currently open.
     */
    public int openChannels() {
        return infos.size();
    }

    /**
     * Make the debug info print out.
     */
    void setVerbose(boolean v) {
        DEBUG = v;
    }






    // INFO CLASS

    final class Info implements MetaEventListener {

        final Sequencer   sequencer;
        final InputStream in;
        final DataPusher  datapusher;

        Info( Sequencer sequencer, InputStream in, DataPusher datapusher ) {

            this.sequencer  = sequencer;
            this.in         = in;
            this.datapusher = datapusher;
        }

        public void meta(MetaMessage event) {
            if (event.getType() == 47 && sequencer != null) {
                sequencer.close();
            }
        }
    }



}

Other Java examples (source code examples)

Here is a short list of links related to this Java AudioDevice.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.