Package org.tools.sound

Source Code of org.tools.sound.JukeBox

/*
* Copyright (C) 2013 Trilarion
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.tools.sound;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;
import org.tools.io.Resource;

/**
* A jukebox device controlling a stream player and being able to play a number
* of pieces in a consecutive way. It listens to the stream player and whenever
* it is finished with a piece, we tell it to play another one.
*
* Internally the jukebox listens to the stream player, so it knows when a song
* is over.
*
* For controlling the volume, the stream player is also given to the outside
* world.
*/
public class JukeBox implements PlayEventListener {

    /* The logger */
    private static final Logger LOG = Logger.getLogger(JukeBox.class.getName());
    /* After playing all pieces in the list, should we rewind and continue playing? */
    private volatile boolean autoRewind = false;
    /* After finishing one piece, should the next be played? */
    private volatile boolean autoContinue = true;
    /* A list of resources we might be played (album) */
    private volatile List<Resource> list = new ArrayList<>(0);
    /* Current index of the next to be played piece in the list */
    private volatile int nextItem = 0;
    /* The underlying stream player */
    private final StreamPlayer player;
    /* One can listen to the work of this juke box. */
    private volatile PlayEventListener listener;

    /**
     * Private access, call the static create method instead.
     *
     * @param player The player to be used.
     */
    private JukeBox(StreamPlayer player) {
        this.player = player;
    }

    /**
     * Initializes a new jukebox, given a player.
     *
     * @param player The player to be used.
     * @return A new jukebox.
     */
    public static JukeBox create(StreamPlayer player) {
        JukeBox jukebox = new JukeBox(player);
        player.setSongOverListener(jukebox);
        return jukebox;
    }

    /**
     * @return Returns the player for player specific adjustments (volume, ...).
     */
    public StreamPlayer getPlayer() {
        return player;
    }

    /**
     * @param l A new listener to be set.
     */
    public void setSongBeginListener(PlayEventListener l) {
        listener = l;
    }

    /**
     * Sets a new playlist, definitely stopping current play and reset the next
     * item counter to the first entry in the new list.
     *
     * You can only change the list completely so far.
     *
     * @param list The new play list.
     */
    public void setSongList(List<Resource> list) {
        if (list == null || list.isEmpty()) {
            throw new IllegalArgumentException("Expect non-null, non-empty list.");
        }
        stop();
        this.list = Collections.unmodifiableList(list);
    }

    /**
     * @return Number of songs in the current playlist
     */
    public int getListSize() {
        return list.size();
    }

    /**
     * @param value If true playing will continue at the beginning of the
     * playlist after reaching the end.
     */
    public void setAutoRewind(boolean value) {
        autoRewind = value;
    }

    /**
     * @return True if auto rewind is set.
     */
    public boolean isAutoRewind() {
        return autoRewind;
    }

    /**
     * @param value If true, playing continues with the next song after a song
     * has finished.
     */
    public void setAutoContinue(boolean value) {
        autoContinue = value;
    }

    /**
     * @return True if auto continue is set.
     */
    public boolean isAutoContinue() {
        return autoContinue;
    }

    /**
     * The player signals the jukebox that a song is over.
     *
     * @param event Description of the event.
     */
    @Override
    public void newEvent(String event) {
        // if we continue to play
        if (autoContinue) {
            if (nextItem < list.size() - 1) {
                // still unplayed songs in the play list, play them
                nextItem++;
                play();
            } else if (autoRewind) {
                // at the end of the playlist, but auto rewind is set, rewind and play
                nextItem = 0;
                play();
            }
        }
    }

    /**
     * Plays the next song in the list. If we have stopped or at the beginning,
     * the first song will be played.
     */
    public void play() {
        play(nextItem);
    }

    /**
     * Immediately jumps to certain song in the playlist and plays it.
     *
     * @param index The index of the new song to play.
     */
    public void play(int index) {
        // check for index within bounds
        if (index < 0 || index >= list.size()) {
            throw new IllegalArgumentException("index out of bounds.");
        }

        // store in the counter
        nextItem = index;

        // if player was playing, stop it immediately
        if (player.isPlaying()) {
            player.stop();
        }

        // get and AudioInputStream from the resource
        AudioFileFormat fmt = null;
        try {
            fmt = AudioSystem.getAudioFileFormat(list.get(index).getInputStream());
        } catch (UnsupportedAudioFileException | IOException ex) {
            LOG.log(Level.SEVERE, null, ex);
        }
        AudioInputStream is = SoundSystem.getAudioInputStream(list.get(index));

        // if we have a listener, tell about it
        if (listener != null) {
            String title = (String) fmt.properties().get("title");
            listener.newEvent("Audio: \"" + title + "\" now playing.");
        }

        // start playing this piece
        player.play(is);
    }

    /**
     * Stops playing.
     */
    public void stop() {
        player.stop();
        nextItem = 0;
    }
}
TOP

Related Classes of org.tools.sound.JukeBox

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.