All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.media.jfxmedia.AudioClip Maven / Gradle / Ivy

There is a newer version: 24-ea+15
Show newest version
/*
 * Copyright (c) 2010, 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 com.sun.media.jfxmedia;

import com.sun.media.jfxmediaimpl.AudioClipProvider;
import java.io.IOException;
import java.net.URI;
import java.io.FileNotFoundException;
import java.net.URISyntaxException;

/**
 * AudioClips are short segments of audio that can be
 * played quickly and on-demand. Though loading of compressed audio formats may
 * be supported, all AudioClip data is stored uncompressed internally to avoid
 * decoding latency. The system is currently capable of playing up to
 * 16 AudioClips simultaneously.
 *
 * 

Core AudioClip features: * *

  • Near-zero latency playback, playback begins as soon as it's called, decoding is done at load time
  • *
  • Play clips up to ten seconds, though clips of any length may be loaded
  • *
  • Quick and simple "one shot" playback interface, just load the effect and play, cleanup is automatic
  • *
  • Play/pause/stop playback of effect, each playback instance is unique and can be controlled individually
  • *
  • Each effect can be played multiple times simultaneously
  • *
  • Loop playback (to some maximum amount?)
  • *
  • Vary rate/pitch
  • *
  • Playback volume
  • *
  • Effect balance
  • *
  • Pan left/right
  • *
  • Mix N audio effects for simultaneous playback (N TBD, start with 32)
  • *
  • Audio effect priority, lower priority effects get dropped first when playback threshold is reached
  • *


    * * Loading sound effects *
    
     * SoundEffectBank soundBank = /* TBD */ ;
     * AudioClip ding = soundBank.effectNamed("ding");
     * AudioClip dong = soundBank.effectNamed("dong");
     * 
    * * OR
    * *
    
     * import javafx.scene.media.Media;
     * import javafx.scene.media.AudioClip;
     *
     * AudioClip ding = new AudioClip("http://somehost.com/sounds/ding.aiff");
     * AudioClip dong = new AudioClip("jar:http://host/path/some.jar!/resources/sounds/dong.aiff");
     *
     *      // Or you can use the ClassLoader to get a resource URI for resources bundled inside your application jar file
     * AudioClip bonk = new AudioClip(this.getClass().getClassLoader().getResource("sounds/bonk.wav"));
     *
     *      // You can also load from a Media object
     * Media whizMedia = new Media("http://somehost.com/sounds/whiz.aiff");
     * AudioClip whiz = new AudioClip(whizMedia);
     * 
    * *

    Playing sound effects *

    Single play (fire and forget method): *

     * ding.play();
     * dong.play(); // the two sounds play simultaneously, there is no further control over playback
     * 
    * *
    Chaining multiple effects: *
     * ding.append(dong).play(); // ding and dong play sequentially, when finished the player is automatically disposed of
     * ding.append(dong).append(ding).append(dong).append(ding).append(dong).play(); // really impatient person at the door :)
     * AudioClip dingDong = ding.append(dong).flatten(); // dingDong is completely independent of ding and dong
     * 
    * */ public abstract class AudioClip { // default playback parameters protected int clipPriority = 0; protected int loopCount = 0; protected double clipVolume = 1.0; protected double clipBalance = 0.0; protected double clipRate = 1.0; protected double clipPan = 0.0; /* * Supported LPCM sample formats, all formats here can be loaded, but the * underlying implementation may convert to an optimal format internally. */ public static final int SAMPLE_FORMAT_S8 = 0; /** Signed 8 bit LPCM */ public static final int SAMPLE_FORMAT_U8 = 1; /** Unsigned 8 bit LPCM */ public static final int SAMPLE_FORMAT_S16BE = 2; /** Signed 16 bit LPCM, big endian byte order */ public static final int SAMPLE_FORMAT_U16BE = 3; /** Unsigned 16 bit LPCM, big endian byte order */ public static final int SAMPLE_FORMAT_S16LE = 4; /** Signed 16 bit LPCM, little endian byte order */ public static final int SAMPLE_FORMAT_U16LE = 5; /** Unsigned 16 bit LPCM, little endian byte order */ public static final int SAMPLE_FORMAT_S24BE = 6; /** Signed 24 bit LPCM, big endian byte order */ public static final int SAMPLE_FORMAT_U24BE = 7; /** Unsigned 24 bit LPCM, big endian byte order */ public static final int SAMPLE_FORMAT_S24LE = 8; /** Signed 24 bit LPCM, little endian byte order */ public static final int SAMPLE_FORMAT_U24LE = 9; /** Unsigned 24 bit LPCM, little endian byte order */ // FIXME: float formats (F32LE, F32BE) // FIXME: add properties; sample size, sample playbackRate, duration, etc... /** * Load an audio clip from the specified source URI. Currently supported formats * are AIFF and WAV files. Audio data in the file must be raw PCM, loading * compressed files is not supported at this time. * * @param source URI to the desired clip. * @return AudioClip ready to play. * @throws IOException If an error occurred while loading the clip. * @throws IllegalArgumentException If an invalid URI is provided. */ public static AudioClip load(URI source) throws URISyntaxException, FileNotFoundException, IOException { return AudioClipProvider.getProvider().load(source); } /** * Generate a AudioClip from raw LPCM audio data. This can be used to * programmatically create sound effects, either generated mathematically * or loaded from some arbitrary source. Multiple channels must be * interleaved properly, for stereo audio left channel is always first. * * @param data Raw PCM samples stored in a byte array. * @param dataOffset Byte offset into data that the sample data starts. * @param sampleCount Number of LPCM samples stored in data. * @param sampleFormat Raw format that the LPCM data is being provided in. * This may not be the actual format stored internally. * @param channels The number of channels. Currently only two channel * audio is supported, channels beyond two are simply dropped. * @param sampleRate Audio sample playbackRate of the raw LPCM data. * * @return A new AudioClip that can play the given raw LPCM audio data. * @throws IllegalArgumentException If an AudioClip cannot be created with * the given arguments. */ public static AudioClip create(byte [] data, int dataOffset, int sampleCount, int sampleFormat, int channels, int sampleRate) throws IllegalArgumentException { return AudioClipProvider.getProvider().create(data, dataOffset, sampleCount, sampleFormat, channels, sampleRate); } /** * Stop all AudioClips that are currently playing. */ public static void stopAllClips() { AudioClipProvider.getProvider().stopAllClips(); } /** * Create a new AudioClip from a segment of an existing AudioClip. The new * clip may copy or simply reference this existing clip, so be aware that * this operation may have a severe memory usage impact for long segments. * The default parameters are copied to the new clip. This variant specifies * the start and end times of the segment. Specifying an end time beyond the * duration of the clip will crop the new AudioClip to the end of the source * clip. Specifying a start time less than zero or greater than end time is * undefined and will return null. * * @param startTime The start time for the segment * @param stopTime The end time of the segment or -1.0 for the remainder of * the source clip. * * @return A new AudioClip instance containing only the specified segment of * the source clip * @throws IllegalArgumentException If startTime or stopTime are not valid * for this AudioClip. */ public abstract AudioClip createSegment(double startTime, double stopTime) throws IllegalArgumentException; /** * Create a new AudioClip from a segment of an existing AudioClip. The new * clip may copy or simply reference this existing clip, so be aware that * this operation may have a severe memory usage impact for long segments. * The default parameters are copied to the new clip. This variant specifies * the exact sample offsets of the segment, starting at sample zero. If * endSample is greater than the number of samples in the source clip, it * will be cropped to the last sample. Specifying a start sample less than * zero or higher than endSample is undefined and will return null. * * @param startSample The starting audio sample for the segment * @param endSample The ending audio sample of the segment, or -1 for the * remainder of the source clip. * * @return A new AudioClip instance containing only the specified segment of * the source clip * @throws IllegalArgumentException If the given sample range is invalid for * this AudioClip. */ public abstract AudioClip createSegment(int startSample, int endSample) throws IllegalArgumentException; /** * Create a new AudioClip from an existing clip by resampling a segment of * the source clip to the specified sample playbackRate. * * @param startSample starting sample to begin resampling at. The first * sample is always zero, negative values are not allowed. * @param endSample The last sample to resample or -1 for the remainder of * the source clip. * @param newSampleRate The sample playbackRate to create the new AudioClip at. * * @return A new AudioClip that contains a copy of the source AudioClip * resampled to the new sample playbackRate. * @throws IllegalArgumentException If the sample range is invalid for this * AudioClip, or the new sample rate is not supported. * @throws IOException If an error occurred during rate conversion. */ public abstract AudioClip resample(int startSample, int endSample, int newSampleRate) throws IllegalArgumentException, IOException; /** * Create a new AudioClip by appending the given clip to the current clip. * The new clip is independent of the two source clips. If the sample rates * are mismatched, the new clip will contain at least one resampled copy of * a source clip. Which clip is resampled is implementation dependent. * * @param clip The clip to be appended to the current clip. * * @return A new AudioClip that contains the concatenation of the two source * clips. * @throws IOException If an error occurred during the concatenation, * generally during rate conversion if it's necessary. */ public abstract AudioClip append(AudioClip clip) throws IOException; /** * Creates a completely independent AudioClip. Any references contained * will be copied and the references removed. The result will be a single * AudioEffect containing all the audio data required to produce the effect. * If the effect is already independent, then this will simply return the * same AudioClip. * * @return A new AudioClip that is independent of all other clips. */ public abstract AudioClip flatten(); public int priority() { return this.clipPriority; } public void setPriority(int prio) { this.clipPriority = prio; } /** * Get the number of times the associated AudioClip will repeat when * played. Note that if you start a clip looping indefinitely the only way * to stop is to call AudioClip.stop() to stop all playback of a clip. * * @return The number of times a AudioClip will be repeated when played. */ public int loopCount() { return this.loopCount; } /** * Specify the number of times a AudioClip should be repeated when this * player is played. Note that if you start a clip looping indefinitely * the only way to stop is to call AudioClip.stop() to stop all playback of * a clip. * * @param loopCount How many times to repeat the AudioClip during normal * playback. If this is zero, then the AudioClip will play exactly once * and stop. Set this to -1 to repeat indefinitely, other negative values * are undefined. */ public void setLoopCount(int loopCount) { this.loopCount = loopCount; } /** * Returns playback volume. * * @return Volume level. */ public double volume() { return this.clipVolume; } /** * Set the volume level for playback. Volume control is by attenuation, * a volume of 1.0 is full volume where 0.0 is effectively muted. * * @param volume */ public void setVolume(double vol) { this.clipVolume = vol; } /** * Returns the left/right channel balance. * * @return */ public double balance() { return this.clipBalance; } /** * Set left/right balance or relative channel volumes for stereo effects. A * value of 0.0 is equal levels (both channels at full volume), -1.0 is full * left channel with muted right, 1.0 is full right channel with muted left. * @param balance Balance value. */ public void setBalance(double bal) { this.clipBalance = bal; } /** * Gets the audio sample rate multiplier that this player will use while * playing the associated AudioClip. * * @return Audio playback sample rate multiplier. * * @see #setPlaybackRate(double) */ public double playbackRate() { return this.clipRate; } /** * Set the audio sample rate multiplier. The player will use this multiplier * when mixing audio to effectively modify the playback rate. A value of 1.0 * plays the AudioClip at it's normal sample rate. For example, setting * the playback rate of a AudioClip that normally plays at 48 KHz to 0.5 * will cause the player to effectively play the AudioClip at 24 KHz. * * @param rate The new audio rate multiplier. Only positive values above * zero are allowed. Note that implementations may cap this value at some * undefined amount. * * @see #playbackRate() */ public void setPlaybackRate(double rate) { this.clipRate = rate; } /** * Pan (left/right spread) setting. * * @return Current pan value. */ public double pan() { return this.clipPan; } /** * Sets the audio pan (or left/right channel spread) value. Valid range is * -1.0 to 1.0 inclusively. A zero setting means normal playback, left and * right channels will be sent to their respective output channels. A -1.0 * value shifts the AudioClip so that all sound is output only on the left * output channel, likewise a 1.0 value shifts completely to the right * output channel. * * @param pan Audio pan setting */ public void setPan(double pan) { this.clipPan = pan; } /** * Test if any AudioClipPlayer has this AudioClip in its effect chain. * * @return true if at least one AudioClipPlayer is playing or * has this AudioClip enqueued. */ public abstract boolean isPlaying(); /** * Play this AudioClip with the default parameters. This is a fire and * forget method, the clip will play exactly once using the default * parameters. */ public abstract void play(); /** * Play this AudioClip at the given volume level. This is a fire and * forget method, the clip will play exactly once using the given volume and * default pitch and pan. * * @param volume Volume level to play this effect at. Valid volume range is * 0.0 to 1.0, where 0.0 is effectively muted and 1.0 is full volume. */ public abstract void play(double volume); /** * Play this AudioClip at the given volume level and relative pitch. This is * a fire and forget method, the clip will play exactly once using the given * parameters. * * @param volume Volume level to play this effect at. Valid volume range is * 0.0 to 1.0, where 0.0 is effectively muted and 1.0 is full volume. * @param balance Left/right balance or relative channel volumes for stereo * effects. * @param rate Playback rate multiplier. 1.0 will play back at the normal * rate while 2.0 will double the rate. * @param pan Left/right shift to be applied to the clip. A pan value of * -1.0 means full left channel, 1.0 means full right channel, 0.0 has no * effect. * @param loopCount The number of times to play this clip, specify -1 to * loop indefinitely * @param priority Audio effect priority. Lower priority effects will be * dropped first if too many effects are trying to play simultaneously. */ public abstract void play(double volume, double balance, double rate, double pan, int loopCount, int priority); /** * Stops all playback of this AudioClip. */ public abstract void stop(); }




    © 2015 - 2024 Weber Informatics LLC | Privacy Policy