159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.audio;
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.asset.AssetManager;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.asset.AssetNotFoundException;
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.InputCapsule;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeExporter;
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.JmeImporter;
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.export.OutputCapsule;
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f;
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Node;
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.PlaceholderAssets;
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.io.IOException;
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Level;
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger;
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * An <code>AudioNode</code> is used in jME3 for playing audio files.
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <br/>
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * First, an {@link AudioNode} is loaded from file, and then assigned
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * to an audio node for playback. Once the audio node is attached to the
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * scene, its location will influence the position it is playing from relative
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * to the {@link Listener}.
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <br/>
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * An audio node can also play in "headspace", meaning its location
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * or velocity does not influence how it is played.
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The "positional" property of an AudioNode can be set via
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * {@link AudioNode#setPositional(boolean) }.
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author normenhansen
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Kirill Vainer
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class AudioNode extends Node {
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected boolean loop = false;
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float volume = 1;
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float pitch = 1;
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float timeOffset = 0;
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Filter dryFilter;
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected AudioKey audioKey;
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected transient AudioData data = null;
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected transient volatile Status status = Status.Stopped;
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected transient volatile int channel = -1;
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Vector3f velocity = new Vector3f();
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected boolean reverbEnabled = true;
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float maxDistance = 200; // 200 meters
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float refDistance = 10; // 10 meters
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Filter reverbFilter;
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private boolean directional = false;
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected Vector3f direction = new Vector3f(0, 0, 1);
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float innerAngle = 360;
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected float outerAngle = 360;
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected boolean positional = true;
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <code>Status</code> indicates the current status of the audio node.
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public enum Status {
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * The audio node is currently playing. This will be set if
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * {@link AudioNode#play() } is called.
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Playing,
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * The audio node is currently paused.
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Paused,
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        /**
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * The audio node is currently stopped.
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * This will be set if {@link AudioNode#stop() } is called
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         * or the audio has reached the end of the file.
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta         */
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Stopped,
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new <code>AudioNode</code> without any audio data set.
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioNode() {
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new <code>AudioNode</code> without any audio data set.
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param audioRenderer The audio renderer to use for playing. Cannot be null.
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @deprecated AudioRenderer parameter is ignored.
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioNode(AudioRenderer audioRenderer) {
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new <code>AudioNode</code> with the given data and key.
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param audioRenderer The audio renderer to use for playing. Cannot be null.
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param audioData The audio data contains the audio track to play.
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param audioKey The audio key that was used to load the AudioData
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @deprecated AudioRenderer parameter is ignored.
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioNode(AudioRenderer audioRenderer, AudioData audioData, AudioKey audioKey) {
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setAudioData(audioData, audioKey);
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new <code>AudioNode</code> with the given data and key.
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param audioData The audio data contains the audio track to play.
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param audioKey The audio key that was used to load the AudioData
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioNode(AudioData audioData, AudioKey audioKey) {
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setAudioData(audioData, audioKey);
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new <code>AudioNode</code> with the given audio file.
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param audioRenderer The audio renderer to use for playing. Cannot be null.
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param assetManager The asset manager to use to load the audio file
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param name The filename of the audio file
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param stream If true, the audio will be streamed gradually from disk,
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *               otherwise, it will be buffered.
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param streamCache If stream is also true, then this specifies if
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the stream cache is used. When enabled, the audio stream will
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * be read entirely but not decoded, allowing features such as
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * seeking, looping and determining duration.
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @deprecated AudioRenderer parameter is ignored.
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioNode(AudioRenderer audioRenderer, AssetManager assetManager, String name, boolean stream, boolean streamCache) {
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.audioKey = new AudioKey(name, stream, streamCache);
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.data = (AudioData) assetManager.loadAsset(audioKey);
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new <code>AudioNode</code> with the given audio file.
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param assetManager The asset manager to use to load the audio file
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param name The filename of the audio file
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param stream If true, the audio will be streamed gradually from disk,
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *               otherwise, it will be buffered.
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param streamCache If stream is also true, then this specifies if
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the stream cache is used. When enabled, the audio stream will
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * be read entirely but not decoded, allowing features such as
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * seeking, looping and determining duration.
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioNode(AssetManager assetManager, String name, boolean stream, boolean streamCache) {
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.audioKey = new AudioKey(name, stream, streamCache);
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.data = (AudioData) assetManager.loadAsset(audioKey);
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new <code>AudioNode</code> with the given audio file.
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param audioRenderer The audio renderer to use for playing. Cannot be null.
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param assetManager The asset manager to use to load the audio file
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param name The filename of the audio file
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param stream If true, the audio will be streamed gradually from disk,
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *               otherwise, it will be buffered.
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @deprecated AudioRenderer parameter is ignored.
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioNode(AudioRenderer audioRenderer, AssetManager assetManager, String name, boolean stream) {
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this(audioRenderer, assetManager, name, stream, false);
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new <code>AudioNode</code> with the given audio file.
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param assetManager The asset manager to use to load the audio file
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param name The filename of the audio file
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param stream If true, the audio will be streamed gradually from disk,
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *               otherwise, it will be buffered.
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioNode(AssetManager assetManager, String name, boolean stream) {
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this(assetManager, name, stream, false);
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new <code>AudioNode</code> with the given audio file.
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param audioRenderer The audio renderer to use for playing. Cannot be null.
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param assetManager The asset manager to use to load the audio file
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param name The filename of the audio file
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @deprecated AudioRenderer parameter is ignored.
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioNode(AudioRenderer audioRenderer, AssetManager assetManager, String name) {
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this(assetManager, name, false);
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Creates a new <code>AudioNode</code> with the given audio file.
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param assetManager The asset manager to use to load the audio file
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param name The filename of the audio file
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioNode(AssetManager assetManager, String name) {
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this(assetManager, name, false);
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    protected AudioRenderer getRenderer() {
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        AudioRenderer result = AudioContext.getAudioRenderer();
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if( result == null )
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalStateException( "No audio renderer available, make sure call is being performed on render thread." );
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return result;
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Start playing the audio.
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void play(){
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        getRenderer().playSource(this);
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Start playing an instance of this audio. This method can be used
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * to play the same <code>AudioNode</code> multiple times. Note
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * that changes to the parameters of this AudioNode will not effect the
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * instances already playing.
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void playInstance(){
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        getRenderer().playSourceInstance(this);
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Stop playing the audio that was started with {@link AudioNode#play() }.
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void stop(){
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        getRenderer().stopSource(this);
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Pause the audio that was started with {@link AudioNode#play() }.
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void pause(){
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        getRenderer().pauseSource(this);
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Do not use.
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public final void setChannel(int channel) {
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (status != Status.Stopped) {
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalStateException("Can only set source id when stopped");
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.channel = channel;
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Do not use.
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public int getChannel() {
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return channel;
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The {#link Filter dry filter} that is set.
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setDryFilter(com.jme3.audio.Filter)
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Filter getDryFilter() {
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return dryFilter;
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the dry filter to use for this audio node.
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * When {@link AudioNode#setReverbEnabled(boolean) reverb} is used,
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the dry filter will only influence the "dry" portion of the audio,
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * e.g. not the reverberated parts of the AudioNode playing.
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * See the relevent documentation for the {@link Filter} to determine
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * the effect.
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param dryFilter The filter to set, or null to disable dry filter.
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setDryFilter(Filter dryFilter) {
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.dryFilter = dryFilter;
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.DryFilter);
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the audio data to use for the audio. Note that this method
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * can only be called once, if for example the audio node was initialized
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * without an {@link AudioData}.
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param audioData The audio data contains the audio track to play.
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param audioKey The audio key that was used to load the AudioData
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setAudioData(AudioData audioData, AudioKey audioKey) {
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data != null) {
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalStateException("Cannot change data once its set");
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        data = audioData;
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.audioKey = audioKey;
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The {@link AudioData} set previously with
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * {@link AudioNode#setAudioData(com.jme3.audio.AudioData, com.jme3.audio.AudioKey) }
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * or any of the constructors that initialize the audio data.
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioData getAudioData() {
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return data;
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The {@link Status} of the audio node.
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The status will be changed when either the {@link AudioNode#play() }
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * or {@link AudioNode#stop() } methods are called.
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Status getStatus() {
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return status;
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Do not use.
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public final void setStatus(Status status) {
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.status = status;
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return True if the audio will keep looping after it is done playing,
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * otherwise, false.
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setLooping(boolean)
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
36459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean isLooping() {
36559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return loop;
36659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
36759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
36959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the looping mode for the audio node. The default is false.
37059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
37159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param loop True if the audio should keep looping after it is done playing.
37259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
37359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setLooping(boolean loop) {
37459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.loop = loop;
37559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
37659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.Looping);
37759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
37859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
37959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
38059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The pitch of the audio, also the speed of playback.
38159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
38259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setPitch(float)
38359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
38459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float getPitch() {
38559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return pitch;
38659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
38759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
38859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
38959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the pitch of the audio, also the speed of playback.
39059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The value must be between 0.5 and 2.0.
39159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
39259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param pitch The pitch to set.
39359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @throws IllegalArgumentException If pitch is not between 0.5 and 2.0.
39459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
39559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setPitch(float pitch) {
39659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (pitch < 0.5f || pitch > 2.0f) {
39759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Pitch must be between 0.5 and 2.0");
39859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
39959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.pitch = pitch;
40159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
40259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.Pitch);
40359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
40459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
40559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
40659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The volume of this audio node.
40759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
40859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setVolume(float)
40959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
41059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float getVolume() {
41159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return volume;
41259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
41359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
41459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
41559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the volume of this audio node.
41659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
41759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The volume is specified as gain. 1.0 is the default.
41859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
41959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param volume The volume to set.
42059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @throws IllegalArgumentException If volume is negative
42159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
42259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setVolume(float volume) {
42359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (volume < 0f) {
42459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Volume cannot be negative");
42559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
42659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
42759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.volume = volume;
42859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
42959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.Volume);
43059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
43159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
43359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The time offset in seconds when the sound will start playing.
43459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
43559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float getTimeOffset() {
43659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return timeOffset;
43759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
43859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
43959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
44059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the time offset in seconds when the sound will start playing.
44159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
44259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param timeOffset The time offset
44359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @throws IllegalArgumentException If timeOffset is negative
44459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
44559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setTimeOffset(float timeOffset) {
44659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (timeOffset < 0f) {
44759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Time offset cannot be negative");
44859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
44959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
45059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.timeOffset = timeOffset;
45159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (data instanceof AudioStream) {
45259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            System.out.println("request setTime");
45359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            ((AudioStream) data).setTime(timeOffset);
45459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else if(status == Status.Playing){
45559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            stop();
45659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            play();
45759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
45859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
45959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
46059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
46159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The velocity of the audio node.
46259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
46359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setVelocity(com.jme3.math.Vector3f)
46459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
46559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Vector3f getVelocity() {
46659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return velocity;
46759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
46859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
46959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
47059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the velocity of the audio node. The velocity is expected
47159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * to be in meters. Does nothing if the audio node is not positional.
47259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
47359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param velocity The velocity to set.
47459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setPositional(boolean)
47559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
47659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setVelocity(Vector3f velocity) {
47759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.velocity.set(velocity);
47859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
47959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.Velocity);
48059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
48159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
48259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
48359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return True if reverb is enabled, otherwise false.
48459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
48559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setReverbEnabled(boolean)
48659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
48759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean isReverbEnabled() {
48859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return reverbEnabled;
48959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
49059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
49159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
49259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set to true to enable reverberation effects for this audio node.
49359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Does nothing if the audio node is not positional.
49459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <br/>
49559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * When enabled, the audio environment set with
49659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * {@link AudioRenderer#setEnvironment(com.jme3.audio.Environment) }
49759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * will apply a reverb effect to the audio playing from this audio node.
49859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
49959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param reverbEnabled True to enable reverb.
50059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
50159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setReverbEnabled(boolean reverbEnabled) {
50259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.reverbEnabled = reverbEnabled;
50359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
50459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.ReverbEnabled);
50559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
50659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
50759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
50859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return Filter for the reverberations of this audio node.
50959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
51059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setReverbFilter(com.jme3.audio.Filter)
51159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
51259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Filter getReverbFilter() {
51359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return reverbFilter;
51459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
51559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
51659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
51759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the reverb filter for this audio node.
51859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <br/>
51959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The reverb filter will influence the reverberations
52059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * of the audio node playing. This only has an effect if
52159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * reverb is enabled.
52259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
52359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param reverbFilter The reverb filter to set.
52459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setDryFilter(com.jme3.audio.Filter)
52559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
52659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setReverbFilter(Filter reverbFilter) {
52759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.reverbFilter = reverbFilter;
52859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
52959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.ReverbFilter);
53059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
53159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
53259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
53359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return Max distance for this audio node.
53459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
53559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setMaxDistance(float)
53659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
53759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float getMaxDistance() {
53859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return maxDistance;
53959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
54059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
54159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
54259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the maximum distance for the attenuation of the audio node.
54359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Does nothing if the audio node is not positional.
54459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <br/>
54559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The maximum distance is the distance beyond which the audio
54659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * node will no longer be attenuated.  Normal attenuation is logarithmic
54759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * from refDistance (it reduces by half when the distance doubles).
54859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Max distance sets where this fall-off stops and the sound will never
54959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * get any quieter than at that distance.  If you want a sound to fall-off
55059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * very quickly then set ref distance very short and leave this distance
55159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * very long.
55259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
55359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param maxDistance The maximum playing distance.
55459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @throws IllegalArgumentException If maxDistance is negative
55559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
55659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setMaxDistance(float maxDistance) {
55759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (maxDistance < 0) {
55859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Max distance cannot be negative");
55959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
56059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
56159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.maxDistance = maxDistance;
56259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
56359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.MaxDistance);
56459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
56559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
56659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
56759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The reference playing distance for the audio node.
56859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
56959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setRefDistance(float)
57059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
57159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float getRefDistance() {
57259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return refDistance;
57359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
57459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
57559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
57659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the reference playing distance for the audio node.
57759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Does nothing if the audio node is not positional.
57859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <br/>
57959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The reference playing distance is the distance at which the
58059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * audio node will be exactly half of its volume.
58159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
58259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param refDistance The reference playing distance.
58359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @throws  IllegalArgumentException If refDistance is negative
58459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
58559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setRefDistance(float refDistance) {
58659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (refDistance < 0) {
58759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Reference distance cannot be negative");
58859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
58959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
59059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.refDistance = refDistance;
59159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
59259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.RefDistance);
59359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
59459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
59559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
59659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return True if the audio node is directional
59759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
59859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setDirectional(boolean)
59959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
60059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean isDirectional() {
60159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return directional;
60259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
60359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
60459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
60559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the audio node to be directional.
60659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Does nothing if the audio node is not positional.
60759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <br/>
60859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * After setting directional, you should call
60959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * {@link AudioNode#setDirection(com.jme3.math.Vector3f) }
61059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * to set the audio node's direction.
61159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
61259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param directional If the audio node is directional
61359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
61459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setDirectional(boolean directional) {
61559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.directional = directional;
61659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
61759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.IsDirectional);
61859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
61959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
62059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
62159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The direction of this audio node.
62259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
62359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setDirection(com.jme3.math.Vector3f)
62459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
62559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public Vector3f getDirection() {
62659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return direction;
62759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
62859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
62959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
63059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the direction of this audio node.
63159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Does nothing if the audio node is not directional.
63259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
63359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param direction
63459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setDirectional(boolean)
63559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
63659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setDirection(Vector3f direction) {
63759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.direction = direction;
63859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
63959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.Direction);
64059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
64159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
64259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
64359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The directional audio node, cone inner angle.
64459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
64559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setInnerAngle(float)
64659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
64759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float getInnerAngle() {
64859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return innerAngle;
64959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
65059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
65159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
65259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the directional audio node cone inner angle.
65359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Does nothing if the audio node is not directional.
65459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
65559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param innerAngle The cone inner angle.
65659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
65759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setInnerAngle(float innerAngle) {
65859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.innerAngle = innerAngle;
65959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
66059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.InnerAngle);
66159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
66259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
66359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
66459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The directional audio node, cone outer angle.
66559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
66659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setOuterAngle(float)
66759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
66859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float getOuterAngle() {
66959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return outerAngle;
67059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
67159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
67259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
67359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the directional audio node cone outer angle.
67459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Does nothing if the audio node is not directional.
67559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
67659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param outerAngle The cone outer angle.
67759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
67859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setOuterAngle(float outerAngle) {
67959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.outerAngle = outerAngle;
68059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
68159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.OuterAngle);
68259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
68359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
68459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
68559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return True if the audio node is positional.
68659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
68759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AudioNode#setPositional(boolean)
68859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
68959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public boolean isPositional() {
69059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return positional;
69159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
69259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
69359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
69459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the audio node as positional.
69559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The position, velocity, and distance parameters effect positional
69659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * audio nodes. Set to false if the audio node should play in "headspace".
69759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
69859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param positional True if the audio node should be positional, otherwise
69959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * false if it should be headspace.
70059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
70159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setPositional(boolean positional) {
70259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.positional = positional;
70359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (channel >= 0)
70459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.IsPositional);
70559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
70659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
70759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
70859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void updateGeometricState(){
70959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        boolean updatePos = false;
71059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if ((refreshFlags & RF_TRANSFORM) != 0){
71159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            updatePos = true;
71259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
71359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
71459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        super.updateGeometricState();
71559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
71659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (updatePos && channel >= 0)
71759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            getRenderer().updateSourceParam(this, AudioParam.Position);
71859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
71959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
72059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
72159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AudioNode clone(){
72259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        AudioNode clone = (AudioNode) super.clone();
72359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
72459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        clone.direction = direction.clone();
72559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        clone.velocity  = velocity.clone();
72659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
72759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return clone;
72859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
72959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
73059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
73159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void write(JmeExporter ex) throws IOException {
73259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        super.write(ex);
73359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        OutputCapsule oc = ex.getCapsule(this);
73459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(audioKey, "audio_key", null);
73559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(loop, "looping", false);
73659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(volume, "volume", 1);
73759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(pitch, "pitch", 1);
73859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(timeOffset, "time_offset", 0);
73959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(dryFilter, "dry_filter", null);
74059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
74159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(velocity, "velocity", null);
74259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(reverbEnabled, "reverb_enabled", false);
74359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(reverbFilter, "reverb_filter", null);
74459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(maxDistance, "max_distance", 20);
74559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(refDistance, "ref_distance", 10);
74659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
74759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(directional, "directional", false);
74859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(direction, "direction", null);
74959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(innerAngle, "inner_angle", 360);
75059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(outerAngle, "outer_angle", 360);
75159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
75259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        oc.write(positional, "positional", false);
75359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
75459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
75559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
75659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void read(JmeImporter im) throws IOException {
75759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        super.read(im);
75859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        InputCapsule ic = im.getCapsule(this);
75959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
76059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // NOTE: In previous versions of jME3, audioKey was actually
76159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // written with the name "key". This has been changed
76259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        // to "audio_key" in case Spatial's key will be written as "key".
76359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (ic.getSavableVersion(AudioNode.class) == 0){
76459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            audioKey = (AudioKey) ic.readSavable("key", null);
76559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else{
76659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            audioKey = (AudioKey) ic.readSavable("audio_key", null);
76759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
76859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
76959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        loop = ic.readBoolean("looping", false);
77059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        volume = ic.readFloat("volume", 1);
77159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        pitch = ic.readFloat("pitch", 1);
77259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        timeOffset = ic.readFloat("time_offset", 0);
77359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        dryFilter = (Filter) ic.readSavable("dry_filter", null);
77459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
77559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        velocity = (Vector3f) ic.readSavable("velocity", null);
77659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        reverbEnabled = ic.readBoolean("reverb_enabled", false);
77759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        reverbFilter = (Filter) ic.readSavable("reverb_filter", null);
77859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        maxDistance = ic.readFloat("max_distance", 20);
77959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        refDistance = ic.readFloat("ref_distance", 10);
78059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
78159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        directional = ic.readBoolean("directional", false);
78259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        direction = (Vector3f) ic.readSavable("direction", null);
78359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        innerAngle = ic.readFloat("inner_angle", 360);
78459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        outerAngle = ic.readFloat("outer_angle", 360);
78559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
78659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        positional = ic.readBoolean("positional", false);
78759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
78859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (audioKey != null) {
78959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            try {
79059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data = im.getAssetManager().loadAudio(audioKey);
79159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } catch (AssetNotFoundException ex){
79259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                Logger.getLogger(AudioNode.class.getName()).log(Level.FINE, "Cannot locate {0} for audio node {1}", new Object[]{audioKey, key});
79359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                data = PlaceholderAssets.getPlaceholderAudio();
79459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
79559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
79659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
79759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
79859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    @Override
79959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public String toString() {
80059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        String ret = getClass().getSimpleName()
80159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                + "[status=" + status;
80259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (volume != 1f) {
80359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            ret += ", vol=" + volume;
80459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
80559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (pitch != 1f) {
80659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            ret += ", pitch=" + pitch;
80759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
80859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return ret + "]";
80959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
81059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
811