0001: /*
0002: * $RCSfile: Sound.java,v $
0003: *
0004: * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0006: *
0007: * This code is free software; you can redistribute it and/or modify it
0008: * under the terms of the GNU General Public License version 2 only, as
0009: * published by the Free Software Foundation. Sun designates this
0010: * particular file as subject to the "Classpath" exception as provided
0011: * by Sun in the LICENSE file that accompanied this code.
0012: *
0013: * This code is distributed in the hope that it will be useful, but WITHOUT
0014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0016: * version 2 for more details (a copy is included in the LICENSE file that
0017: * accompanied this code).
0018: *
0019: * You should have received a copy of the GNU General Public License version
0020: * 2 along with this work; if not, write to the Free Software Foundation,
0021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0022: *
0023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0024: * CA 95054 USA or visit www.sun.com if you need additional information or
0025: * have any questions.
0026: *
0027: * $Revision: 1.6 $
0028: * $Date: 2008/02/28 20:17:30 $
0029: * $State: Exp $
0030: */
0031:
0032: package javax.media.j3d;
0033:
0034: /**
0035: * Sound node is an abstract class that defines the properties common to all
0036: * sound sources. A scene graph can contain multiple sounds. Associated with each
0037: * sound source are: a reference to sound data, an amplitude scale factor, a release
0038: * flag denoting that the sound associated with this node is to play to end when
0039: * it is disabled, the number of times sound is to be repeated, the sound's state
0040: * (on or off), a scheduling region, and a flag denoting if the sound is to
0041: * continue playing "silently" even while it is inactive. Whenever the listener
0042: * is within a sound node's scheduling bounds this sound is potentially audible.
0043: *<P>
0044: * Sound Data
0045: *
0046: * <UL>Associated with each Sound node is a MediaContainer
0047: * which includes audio data and information about this data.
0048: * This data can be cached (buffered) or non-cached (unbuffered or streaming).
0049: * If an AudioDevice has been attached to the PhysicalEnvironment, the sound
0050: * data is made ready to begin playing.
0051: * Certain functionality can not be applied to true streaming sound data:<p>
0052: * 1) querying the sound's duration (Sound.DURATION_UNKNOWN will be returned),<br>
0053: * 2) looping over a range of the streaming data; and<br>
0054: * 3) restart a previously played portion of the data.<p>
0055: * Depending on the implementation of the AudioDevice used, streamed, non-
0056: * cached data may not be fully spatialized.</UL>
0057: *<P>
0058: * Initial Gain
0059: *
0060: * <UL>This gain is a scale factor applied to the sound data associated
0061: * with this sound source to increase or decrease its overall amplitude.</UL>
0062: *<P>
0063: * Loop
0064: *
0065: * <UL>Data for non-streaming sound (such as a sound sample) can contain two
0066: * loop points marking a section of the data that is to be looped a specific
0067: * number of times. Thus sound data can be divided into three segments:
0068: * the attack (before the begin loop point), the sustain (between the begin
0069: * and end loop points), and the release (after the end loop point). If
0070: * there are no loop begin and end points defined as part of the sound data,
0071: * the begin loop point is set at the beginning of the sound data,
0072: * and the end loop point at the end of the sound data.
0073: * If this is the case, looping the sound would mean repeating the whole
0074: * sound. However, these allow a portion in the middle of the sound to
0075: * be looped.
0076: *<P>
0077: * A sound can be looped a specified number of times after it is activated
0078: * before it is completed. The loop count value explicitly sets the number
0079: * of times the sound is looped. Any non-negative number is a valid value.
0080: * A value of zero denotes that the looped section is not repeated, but is
0081: * played only once. A value of -1 denotes that the loop is repeated
0082: * indefinitely.
0083: *<P>
0084: * Changing loop count of a sound after the sound has been started will not
0085: * dynamically affect the loop count currently used by the sound playing.
0086: * The new loop count will be used the next time the sound is enabled.</UL>
0087: * <P>
0088: * Release Flag
0089: *
0090: * <UL>When a sound is disabled, its playback would normally stop immediately
0091: * no matter what part of the sound data was currently being played. By
0092: * setting the Release Flag to true for nodes with non-streaming sound data,
0093: * the sound is allowed to play from its current position in the sound data
0094: * to the end of the data (without repeats), thus playing the release portion
0095: * of the sound before stopping.</UL>
0096: *<P>
0097: * Continuous Flag
0098: *
0099: * <UL>For some applications, it's useful to turn a sound source "off" but to
0100: * continue "silently" playing the sound so that when it is turned back "on"
0101: * the sound picks up playing in the same location (over time) as it would
0102: * have been if the sound had never been disabled (turned off). Setting the
0103: * Continuous flag true causes the sound renderer to keep track of where
0104: * (over time) the sound would be playing even when the sound is disabled.</UL>
0105: *<P>
0106: * Enable Sound
0107: *
0108: * <UL>When enabled, the sound source is started
0109: * playing and thus can potentially be heard, depending on its activation
0110: * state, gain control parameters, continuation state, and spatialization
0111: * parameters. If the continuous state is true, even if the sound is not
0112: * active, enabling the sound starts the sound silently "playing," so that
0113: * when the sound is activated, the sound is (potentially) heard from
0114: * somewhere in the middle of the sound data. Activation state can change
0115: * from active to inactive any number of times without stopping or starting
0116: * the sound. To re-start a sound at the beginning of its data, re-enable
0117: * the sound by calling setEnable with true.
0118: *<P>
0119: * Setting the enable flag to true during construction acts as a request
0120: * to start the sound playing "as soon as it can" be started.
0121: * This could be close to immediately in limited cases, but several conditions,
0122: * detailed below, must be met for a sound to be ready to be played.</UL>
0123: *<P>
0124: * Mute Sound
0125: *
0126: * <UL>When the mute state is set true, a playing sound is made to play silently.
0127: *</UL><P>
0128: * Pause Sound
0129: *
0130: * <UL>When the pause state is set true, a playing sound is paused.
0131: *<P>
0132: * Setting the enable flag to true during construction acts as a request
0133: * to start the sound playing "as soon as it can" be started.
0134: * This could be close to immediately in limited cases, but several conditions,
0135: * detailed below, must be met for a sound to be ready to be played.</UL>
0136: * <P>
0137: * Scheduling Bounds
0138: *
0139: * <UL>
0140: * A Sound is scheduled for activation when its scheduling region intersects
0141: * the ViewPlatform's activation volume. This is used when the scheduling
0142: * bounding leaf is set to null.</UL>
0143: *<P>
0144: * Scheduling Bounding Leaf
0145: *
0146: * <UL>When set to a value other than null, the scheduling bounding leaf
0147: * region overrides the scheduling bounds
0148: * object.</UL>
0149: *<P>
0150: * Prioritize Sound
0151: *
0152: * <UL>Sound Priority is used
0153: * to rank concurrently playing sounds in order of importance during playback.
0154: * When more sounds are started than the AudioDevice
0155: * can handle, the sound node with the lowest priority ranking is
0156: * deactivated (but continues playing silently). If a sound is deactivated
0157: * (due to a sound with a higher
0158: * priority being started), it is automatically re-activated when
0159: * resources become available (e.g., when a sound with a higher priority
0160: * finishes playing), or when the ordering of sound nodes are changed due to
0161: * a change in a sound node's priority.
0162: * <P>
0163: * Sounds with a lower priority than sound that can
0164: * not be played due to lack of channels will be played.
0165: * For example, assume we have eight channels available for playing sounds.
0166: * After ordering four sounds, we begin playing them in order, checking if
0167: * the number of channels required to play a given sound are actually available
0168: * before the sound is played. Furthermore, say the first sound needs three
0169: * channels
0170: * to play, the second sound needs four channels, the third sound needs three
0171: * channels
0172: * and the fourth sound needs only one channel. The first and second sounds
0173: * can be started because they require seven of the eight available channels. The
0174: * third sound can not be audibly started because it requires three channels and
0175: * only one is still available. Consequently, the third sound starts playing
0176: * 'silently.' The fourth sound can and will be started since it only requires
0177: * one channel. The third sound will be made audible when three channels become
0178: * available (i.e., when the first or second sound finishes playing).
0179: * <P>
0180: * Sounds given the same priority are ordered randomly. If the application
0181: * wants a specific ordering, it must assign unique priorities to each sound.
0182: * <P>
0183: * Methods to determine what audio output resources are required for playing
0184: * a Sound node on a particular AudioDevice and to determine the currently
0185: * available audio output resources are described in the AudioDevice class.</UL>
0186: * <P>
0187: * Duration
0188: *
0189: * <UL>Each sound has a length of time in milliseconds that it
0190: * can run (including repeating loop section)
0191: * if it plays to completion. If the sound
0192: * media type is streaming, or if the sound is looped indefinitely, then a
0193: * value of -1 (implying infinite length) is returned.</UL>
0194: *<P>
0195: * Number of Channels used on Audio Device to Play Sound
0196: *
0197: * <UL>When a sound is started, it could use more than one channel on the
0198: * selected AudioDevice it is to be played on. The number of Audio Device
0199: * channels currently used for a sound can be queried using
0200: * getNumberOfChannelsUsed().</UL>
0201: *<P>
0202: * Preparing a Sound to be Played
0203: *
0204: * <UL>Sound data associated with a Sound node, either during construction
0205: * (when the MediaContainer is passed into the constructor as a parameter)
0206: * or by calling setSoundData(), it can be prepared to begin playing
0207: * only after the following conditions are satisfied:<p>
0208: * 1) the Sound node has non-null sound data associated with it<br>
0209: * 2) the Sound node is live<br>
0210: * 3) there is an active View in the Universe and<br>
0211: * 4) there is an initialized AudioDevice associated with the
0212: * PhysicalEnvironment.<p>
0213: * Depending on the type of MediaContainer the sound data is and on the
0214: * implementation of the AudioDevice used, sound data preparation could consist
0215: * of opening, attaching, loading, or copying into memory the associated sound data.
0216: * The query method, isReady() returns true when the sound is fully preprocessed
0217: * so that it is playable (audibly if active, silently if not active).</UL>
0218: *<P>
0219: * Playing Status
0220: *
0221: * <UL>A sound source will not be heard unless it is:<p>
0222: * 1) enabled/started<br>
0223: * 2) activated<br>
0224: * 3) not muted<br>
0225: * 4) not paused<p>
0226: * While these conditions are meet, the sound is potentially audible
0227: * and the method isPlaying() will return a status of true.
0228: *<P>
0229: * isPlaying returns false but isPlayingSilently returns true if a sound:<p>
0230: * 1) is enabled before it is activated; it is begun playing silently.<br>
0231: * 2) is enabled then deactivated while playing; it continues playing silently<br>
0232: * 3) is enabled while it mute state is true
0233: *<P>
0234: * When the sound finishes playing it's sound data (including all loops), it
0235: * is implicitly disabled.</UL>
0236: *<P>
0237: * @see AudioDevice
0238: */
0239:
0240: public abstract class Sound extends Leaf {
0241: // Constants for Sound object.
0242: //
0243: // These flags, when enabled using the setCapability method, allow an
0244: // application to invoke methods that respectively read and write the
0245: // sound fields.
0246: // These capability flags are enforced only when the node is part of
0247: // a live or compiled scene graph.
0248:
0249: /**
0250: * Specifies that this node allows access to its object's sound data
0251: * information.
0252: */
0253: public static final int ALLOW_SOUND_DATA_READ = CapabilityBits.SOUND_ALLOW_SOUND_DATA_READ;
0254:
0255: /**
0256: * Specifies that this node allows writing to its object's sound data
0257: * information.
0258: */
0259: public static final int ALLOW_SOUND_DATA_WRITE = CapabilityBits.SOUND_ALLOW_SOUND_DATA_WRITE;
0260:
0261: /**
0262: * Specifies that this node allows access to its object's initial gain
0263: * information.
0264: */
0265: public static final int ALLOW_INITIAL_GAIN_READ = CapabilityBits.SOUND_ALLOW_INITIAL_GAIN_READ;
0266:
0267: /**
0268: * Specifies that this node allows writing to its object's initial gain
0269: * information.
0270: */
0271: public static final int ALLOW_INITIAL_GAIN_WRITE = CapabilityBits.SOUND_ALLOW_INITIAL_GAIN_WRITE;
0272:
0273: /**
0274: * Specifies that this node allows access to its object's loop
0275: * information.
0276: */
0277: public static final int ALLOW_LOOP_READ = CapabilityBits.SOUND_ALLOW_LOOP_READ;
0278:
0279: /**
0280: * Specifies that this node allows writing to its object's loop
0281: * information.
0282: */
0283: public static final int ALLOW_LOOP_WRITE = CapabilityBits.SOUND_ALLOW_LOOP_WRITE;
0284:
0285: /**
0286: * Specifies that this node allows access to its object's release flag
0287: * information.
0288: */
0289: public static final int ALLOW_RELEASE_READ = CapabilityBits.SOUND_ALLOW_RELEASE_READ;
0290:
0291: /**
0292: * Specifies that this node allows writing to its object's release flag
0293: * information.
0294: */
0295: public static final int ALLOW_RELEASE_WRITE = CapabilityBits.SOUND_ALLOW_RELEASE_WRITE;
0296:
0297: /**
0298: * Specifies that this node allows access to its object's continuous
0299: * play information.
0300: */
0301: public static final int ALLOW_CONT_PLAY_READ = CapabilityBits.SOUND_ALLOW_CONT_PLAY_READ;
0302:
0303: /**
0304: * Specifies that this node allows writing to its object's continuous
0305: * play information.
0306: */
0307: public static final int ALLOW_CONT_PLAY_WRITE = CapabilityBits.SOUND_ALLOW_CONT_PLAY_WRITE;
0308:
0309: /**
0310: * Specifies that this node allows access to its object's sound on
0311: * information.
0312: */
0313: public static final int ALLOW_ENABLE_READ = CapabilityBits.SOUND_ALLOW_ENABLE_READ;
0314:
0315: /**
0316: * Specifies that this node allows writing to its object's sound on
0317: * information.
0318: */
0319: public static final int ALLOW_ENABLE_WRITE = CapabilityBits.SOUND_ALLOW_ENABLE_WRITE;
0320:
0321: /**
0322: * Specifies that this node allows read access to its scheduling bounds
0323: * information.
0324: */
0325: public static final int ALLOW_SCHEDULING_BOUNDS_READ = CapabilityBits.SOUND_ALLOW_SCHEDULING_BOUNDS_READ;
0326:
0327: /**
0328: * Specifies that this node allows write access to its scheduling bounds
0329: * information.
0330: */
0331: public static final int ALLOW_SCHEDULING_BOUNDS_WRITE = CapabilityBits.SOUND_ALLOW_SCHEDULING_BOUNDS_WRITE;
0332:
0333: /**
0334: * Specifies that this node allows read access to its priority order
0335: * value.
0336: */
0337: public static final int ALLOW_PRIORITY_READ = CapabilityBits.SOUND_ALLOW_PRIORITY_READ;
0338:
0339: /**
0340: * Specifies that this node allows write access to its priority order
0341: * value.
0342: */
0343: public static final int ALLOW_PRIORITY_WRITE = CapabilityBits.SOUND_ALLOW_PRIORITY_WRITE;
0344:
0345: /**
0346: * Specifies that this node allows access to its object's sound duration
0347: * information.
0348: */
0349: public static final int ALLOW_DURATION_READ = CapabilityBits.SOUND_ALLOW_DURATION_READ;
0350:
0351: /**
0352: * Specifies that this node allows access to its object's sound status
0353: * denoting if it is ready to be played 'immediately'.
0354: */
0355: public static final int ALLOW_IS_READY_READ = CapabilityBits.SOUND_ALLOW_IS_READY_READ;
0356:
0357: /**
0358: * Specifies that this node allows access to its object's sound audibly
0359: * playing or playing silently status.
0360: */
0361: public static final int ALLOW_IS_PLAYING_READ = CapabilityBits.SOUND_ALLOW_IS_PLAYING_READ;
0362:
0363: /**
0364: * Specifies that this node allows access to its number of channels
0365: * used by this sound.
0366: */
0367: public static final int ALLOW_CHANNELS_USED_READ = CapabilityBits.SOUND_ALLOW_CHANNELS_USED_READ;
0368:
0369: /**
0370: * Specifies that this node allows access to its object's mute flag
0371: * information.
0372: *
0373: * @since Java 3D 1.3
0374: */
0375: public static final int ALLOW_MUTE_READ = CapabilityBits.SOUND_ALLOW_MUTE_READ;
0376:
0377: /**
0378: * Specifies that this node allows writing to its object's mute flag
0379: * information.
0380: *
0381: * @since Java 3D 1.3
0382: */
0383: public static final int ALLOW_MUTE_WRITE = CapabilityBits.SOUND_ALLOW_MUTE_WRITE;
0384:
0385: /**
0386: * Specifies that this node allows access to its object's pause flag
0387: * information.
0388: *
0389: * @since Java 3D 1.3
0390: */
0391: public static final int ALLOW_PAUSE_READ = CapabilityBits.SOUND_ALLOW_PAUSE_READ;
0392:
0393: /**
0394: * Specifies that this node allows writing to its object's pause flag
0395: * information.
0396: *
0397: * @since Java 3D 1.3
0398: */
0399: public static final int ALLOW_PAUSE_WRITE = CapabilityBits.SOUND_ALLOW_PAUSE_WRITE;
0400:
0401: /**
0402: * Specifies that this node allows access to its object's sample rate scale
0403: * factor information.
0404: *
0405: * @since Java 3D 1.3
0406: */
0407: public static final int ALLOW_RATE_SCALE_FACTOR_READ = CapabilityBits.SOUND_ALLOW_RATE_SCALE_FACTOR_READ;
0408:
0409: /**
0410: * Specifies that this node allows writing to its object's sample rate scale
0411: * factor information.
0412: *
0413: * @since Java 3D 1.3
0414: */
0415: public static final int ALLOW_RATE_SCALE_FACTOR_WRITE = CapabilityBits.SOUND_ALLOW_RATE_SCALE_FACTOR_WRITE;
0416:
0417: /**
0418: * Denotes that there is no filter value associated with object's distance
0419: * or angular attenuation array.
0420: */
0421: public static final float NO_FILTER = -1.0f;
0422:
0423: /**
0424: * Denotes that the sound's duration could not be calculated.
0425: * A fall back for getDuration of a non-cached sound.
0426: */
0427: public static final int DURATION_UNKNOWN = -1;
0428:
0429: /**
0430: * When used as a loop count sound will loop an infinite number of time
0431: * until explicitly stopped (setEnabled(false)).
0432: */
0433: public static final int INFINITE_LOOPS = -1;
0434:
0435: // Array for setting default read capabilities
0436: private static final int[] readCapabilities = {
0437: ALLOW_CHANNELS_USED_READ, ALLOW_CONT_PLAY_READ,
0438: ALLOW_DURATION_READ, ALLOW_ENABLE_READ,
0439: ALLOW_INITIAL_GAIN_READ, ALLOW_IS_PLAYING_READ,
0440: ALLOW_IS_READY_READ, ALLOW_LOOP_READ, ALLOW_MUTE_READ,
0441: ALLOW_PAUSE_READ, ALLOW_PRIORITY_READ,
0442: ALLOW_RATE_SCALE_FACTOR_READ, ALLOW_RELEASE_READ,
0443: ALLOW_SCHEDULING_BOUNDS_READ, ALLOW_SOUND_DATA_READ };
0444:
0445: /**
0446: * Constructs and initializes a new Sound node using default
0447: * parameters. The following defaults values are used:
0448: * <ul>
0449: * sound data: null<br>
0450: * initial gain: 1.0<br>
0451: * loop: 0<br>
0452: * release flag: false<br>
0453: * continuous flag: false<br>
0454: * enable flag: false<br>
0455: * scheduling bounds : null<br>
0456: * scheduling bounding leaf : null<br>
0457: * priority: 1.0<br>
0458: * rate scale factor: 1.0<br>
0459: * mute state: false<br>
0460: * pause state: false<br>
0461: * </ul>
0462: */
0463: public Sound() {
0464: // set default read capabilities
0465: setDefaultReadCapabilities(readCapabilities);
0466: }
0467:
0468: /**
0469: * Constructs and initializes a new Sound node object using the provided
0470: * data and gain parameter values, and defaults for all other fields. This
0471: * constructor implicitly loads the sound data associated with this node if
0472: * the implementation uses sound caching.
0473: * @param soundData description of JMF source data used by this sound source
0474: * @param initialGain overall amplitude scale factor applied to sound source
0475: */
0476: public Sound(MediaContainer soundData, float initialGain) {
0477: // set default read capabilities
0478: setDefaultReadCapabilities(readCapabilities);
0479:
0480: ((SoundRetained) this .retained).setSoundData(soundData);
0481: ((SoundRetained) this .retained).setInitialGain(initialGain);
0482: }
0483:
0484: /**
0485: * Constructs and initializes a new Sound node using provided parameter
0486: * values.
0487: * @param soundData description of JMF source data used by this sound source
0488: * @param initialGain overall amplitude scale factor applied to sound source
0489: * @param loopCount number of times sound is looped when played
0490: * @param release flag specifying whether the sound is to be played
0491: * to end when stopped
0492: * @param continuous flag specifying whether the sound silently plays
0493: * when disabled
0494: * @param enable flag specifying whether the sound is enabled
0495: * @param region scheduling bounds
0496: * @param priority defines playback priority if too many sounds started
0497: */
0498: public Sound(MediaContainer soundData, float initialGain,
0499: int loopCount, boolean release, boolean continuous,
0500: boolean enable, Bounds region, float priority) {
0501: // set default read capabilities
0502: setDefaultReadCapabilities(readCapabilities);
0503:
0504: ((SoundRetained) this .retained).setSoundData(soundData);
0505: ((SoundRetained) this .retained).setInitialGain(initialGain);
0506: ((SoundRetained) this .retained).setLoop(loopCount);
0507: ((SoundRetained) this .retained).setReleaseEnable(release);
0508: ((SoundRetained) this .retained).setContinuousEnable(continuous);
0509: ((SoundRetained) this .retained).setEnable(enable);
0510: ((SoundRetained) this .retained).setSchedulingBounds(region);
0511: ((SoundRetained) this .retained).setPriority(priority);
0512: }
0513:
0514: /**
0515: * Constructs and initializes a new Sound node using provided parameter
0516: * values.
0517: * @param soundData description of JMF source data used by this sound source
0518: * @param initialGain overall amplitude scale factor applied to sound source
0519: * @param loopCount number of times sound is looped when played
0520: * @param release flag specifying whether the sound is to be played
0521: * to end when stopped
0522: * @param continuous flag specifying whether the sound silently plays
0523: * when disabled
0524: * @param enable flag specifying whether the sound is enabled
0525: * @param region scheduling bounds
0526: * @param priority defines playback priority if too many sounds started
0527: * @param rateFactor defines playback sample rate scale factor
0528: * @since Java 3D 1.3
0529: */
0530: public Sound(MediaContainer soundData, float initialGain,
0531: int loopCount, boolean release, boolean continuous,
0532: boolean enable, Bounds region, float priority,
0533: float rateFactor) {
0534: // set default read capabilities
0535: setDefaultReadCapabilities(readCapabilities);
0536:
0537: ((SoundRetained) this .retained).setSoundData(soundData);
0538: ((SoundRetained) this .retained).setInitialGain(initialGain);
0539: ((SoundRetained) this .retained).setLoop(loopCount);
0540: ((SoundRetained) this .retained).setReleaseEnable(release);
0541: ((SoundRetained) this .retained).setContinuousEnable(continuous);
0542: ((SoundRetained) this .retained).setEnable(enable);
0543: ((SoundRetained) this .retained).setSchedulingBounds(region);
0544: ((SoundRetained) this .retained).setPriority(priority);
0545: ((SoundRetained) this .retained).setRateScaleFactor(rateFactor);
0546: }
0547:
0548: /**
0549: * Sets fields that define the sound source data of this node.
0550: * @param soundData description of JMF source data used by this sound source
0551: * @exception CapabilityNotSetException if appropriate capability is
0552: * not set and this object is part of live or compiled scene graph
0553: */
0554: public void setSoundData(MediaContainer soundData) {
0555: if (isLiveOrCompiled())
0556: if (!this .getCapability(ALLOW_SOUND_DATA_WRITE))
0557: throw new CapabilityNotSetException(J3dI18N
0558: .getString("Sound0"));
0559:
0560: if (this instanceof BackgroundSound)
0561: ((SoundRetained) this .retained).setSoundData(soundData);
0562: else
0563: // instanceof PointSound or ConeSound
0564: ((PointSoundRetained) this .retained)
0565: .setSoundData(soundData);
0566: }
0567:
0568: /**
0569: * Retrieves description/data associated with this sound source.
0570: * @return soundData description of JMF source data used by this sound source
0571: * @exception CapabilityNotSetException if appropriate capability is
0572: * not set and this object is part of live or compiled scene graph
0573: */
0574: public MediaContainer getSoundData() {
0575: if (isLiveOrCompiled())
0576: if (!this .getCapability(ALLOW_SOUND_DATA_READ))
0577: throw new CapabilityNotSetException(J3dI18N
0578: .getString("Sound1"));
0579:
0580: return ((SoundRetained) this .retained).getSoundData();
0581: }
0582:
0583: /**
0584: * Set the overall gain scale factor applied to data associated with this
0585: * source to increase or decrease its overall amplitude.
0586: * @param amplitude (gain) scale factor
0587: * @exception CapabilityNotSetException if appropriate capability is
0588: * not set and this object is part of live or compiled scene graph
0589: */
0590: public void setInitialGain(float amplitude) {
0591: if (isLiveOrCompiled())
0592: if (!this .getCapability(ALLOW_INITIAL_GAIN_WRITE))
0593: throw new CapabilityNotSetException(J3dI18N
0594: .getString("Sound2"));
0595:
0596: ((SoundRetained) this .retained).setInitialGain(amplitude);
0597: }
0598:
0599: /**
0600: * Get the overall gain applied to the sound data associated with source.
0601: * @return overall gain scale factor applied to sound source data.
0602: * @exception CapabilityNotSetException if appropriate capability is
0603: * not set and this object is part of live or compiled scene graph
0604: */
0605: public float getInitialGain() {
0606: if (isLiveOrCompiled())
0607: if (!this .getCapability(ALLOW_INITIAL_GAIN_READ))
0608: throw new CapabilityNotSetException(J3dI18N
0609: .getString("Sound3"));
0610:
0611: return ((SoundRetained) this .retained).getInitialGain();
0612: }
0613:
0614: /**
0615: * Sets a sound's loop count.
0616: * @param loopCount number of times sound is looped during play
0617: * @exception CapabilityNotSetException if appropriate capability is
0618: * not set and this object is part of live or compiled scene graph
0619: */
0620: public void setLoop(int loopCount) {
0621: if (isLiveOrCompiled())
0622: if (!this .getCapability(ALLOW_LOOP_WRITE))
0623: throw new CapabilityNotSetException(J3dI18N
0624: .getString("Sound4"));
0625:
0626: ((SoundRetained) this .retained).setLoop(loopCount);
0627: }
0628:
0629: /**
0630: * Retrieves loop count for this sound
0631: * @return loop count
0632: * @exception CapabilityNotSetException if appropriate capability is
0633: * not set and this object is part of live or compiled scene graph
0634: */
0635: public int getLoop() {
0636: if (isLiveOrCompiled())
0637: if (!this .getCapability(ALLOW_LOOP_READ))
0638: throw new CapabilityNotSetException(J3dI18N
0639: .getString("Sound5"));
0640:
0641: return ((SoundRetained) this .retained).getLoop();
0642: }
0643:
0644: /**
0645: * Enables or disables the release flag for the sound associated with
0646: * this sound.
0647: * @param state release flag
0648: * @exception CapabilityNotSetException if appropriate capability is
0649: * not set and this object is part of live or compiled scene graph
0650: */
0651: public void setReleaseEnable(boolean state) {
0652: if (isLiveOrCompiled())
0653: if (!this .getCapability(ALLOW_RELEASE_WRITE))
0654: throw new CapabilityNotSetException(J3dI18N
0655: .getString("Sound6"));
0656:
0657: ((SoundRetained) this .retained).setReleaseEnable(state);
0658: }
0659:
0660: /**
0661: * Retrieves the release flag for sound associated with sound.
0662: * @return sound's release flag
0663: * @exception CapabilityNotSetException if appropriate capability is
0664: * not set and this object is part of live or compiled scene graph
0665: */
0666: public boolean getReleaseEnable() {
0667: if (isLiveOrCompiled())
0668: if (!this .getCapability(ALLOW_RELEASE_READ))
0669: throw new CapabilityNotSetException(J3dI18N
0670: .getString("Sound7"));
0671:
0672: return ((SoundRetained) this .retained).getReleaseEnable();
0673: }
0674:
0675: /**
0676: * Enables or disables continuous play flag.
0677: * @param state denotes if deactivated sound silently continues playing
0678: * @exception CapabilityNotSetException if appropriate capability is
0679: * not set and this object is part of live or compiled scene graph
0680: */
0681: public void setContinuousEnable(boolean state) {
0682: if (isLiveOrCompiled())
0683: if (!this .getCapability(ALLOW_CONT_PLAY_WRITE))
0684: throw new CapabilityNotSetException(J3dI18N
0685: .getString("Sound8"));
0686:
0687: ((SoundRetained) this .retained).setContinuousEnable(state);
0688: }
0689:
0690: /**
0691: * Retrieves sound's continuous play flag.
0692: * @return flag denoting if deactivated sound silently continues playing
0693: * @exception CapabilityNotSetException if appropriate capability is
0694: * not set and this object is part of live or compiled scene graph
0695: */
0696: public boolean getContinuousEnable() {
0697: if (isLiveOrCompiled())
0698: if (!this .getCapability(ALLOW_CONT_PLAY_READ))
0699: throw new CapabilityNotSetException(J3dI18N
0700: .getString("Sound9"));
0701:
0702: return ((SoundRetained) this .retained).getContinuousEnable();
0703: }
0704:
0705: /**
0706: * Enable or disable sound.
0707: * @param state enable (on/off) flag denotes if active sound is heard
0708: * @exception CapabilityNotSetException if appropriate capability is
0709: * not set and this object is part of live or compiled scene graph
0710: */
0711: public void setEnable(boolean state) {
0712: if (isLiveOrCompiled())
0713: if (!this .getCapability(ALLOW_ENABLE_WRITE))
0714: throw new CapabilityNotSetException(J3dI18N
0715: .getString("Sound10"));
0716:
0717: if (this instanceof BackgroundSound)
0718: ((SoundRetained) this .retained).setEnable(state);
0719: else
0720: // instanceof PointSound or ConeSound
0721: ((PointSoundRetained) this .retained).setEnable(state);
0722: }
0723:
0724: /**
0725: * Retrieves sound's enabled flag.
0726: * @return sound enabled flag
0727: * @exception CapabilityNotSetException if appropriate capability is
0728: * not set and this object is part of live or compiled scene graph
0729: */
0730: public boolean getEnable() {
0731: if (isLiveOrCompiled())
0732: if (!this .getCapability(ALLOW_ENABLE_READ))
0733: throw new CapabilityNotSetException(J3dI18N
0734: .getString("Sound21"));
0735:
0736: return ((SoundRetained) this .retained).getEnable();
0737: }
0738:
0739: /**
0740: * Set the Sound's scheduling region to the specified bounds.
0741: * This is used when the scheduling bounding leaf is set to null.
0742: * @param region the bounds that contains the Sound's new scheduling
0743: * region.
0744: * @exception CapabilityNotSetException if appropriate capability is
0745: * not set and this object is part of live or compiled scene graph
0746: */
0747: public void setSchedulingBounds(Bounds region) {
0748: if (isLiveOrCompiled())
0749: if (!this .getCapability(ALLOW_SCHEDULING_BOUNDS_WRITE))
0750: throw new CapabilityNotSetException(J3dI18N
0751: .getString("Sound11"));
0752:
0753: ((SoundRetained) this .retained).setSchedulingBounds(region);
0754: }
0755:
0756: /**
0757: * Retrieves the Sound node's scheduling bounds.
0758: * @return this Sound's scheduling bounds information
0759: * @exception CapabilityNotSetException if appropriate capability is
0760: * not set and this object is part of live or compiled scene graph
0761: */
0762: public Bounds getSchedulingBounds() {
0763: if (isLiveOrCompiled())
0764: if (!this .getCapability(ALLOW_SCHEDULING_BOUNDS_READ))
0765: throw new CapabilityNotSetException(J3dI18N
0766: .getString("Sound12"));
0767:
0768: return ((SoundRetained) this .retained).getSchedulingBounds();
0769: }
0770:
0771: /**
0772: * Set the Sound's scheduling region to the specified bounding leaf.
0773: * When set to a value other than null, this overrides the scheduling
0774: * bounds object.
0775: * @param region the bounding leaf node used to specify the Sound
0776: * node's new scheduling region.
0777: * @exception CapabilityNotSetException if appropriate capability is
0778: * not set and this object is part of live or compiled scene graph
0779: */
0780: public void setSchedulingBoundingLeaf(BoundingLeaf region) {
0781: if (isLiveOrCompiled())
0782: if (!this .getCapability(ALLOW_SCHEDULING_BOUNDS_WRITE))
0783: throw new CapabilityNotSetException(J3dI18N
0784: .getString("Sound11"));
0785:
0786: ((SoundRetained) this .retained)
0787: .setSchedulingBoundingLeaf(region);
0788: }
0789:
0790: /**
0791: * Retrieves the Sound node's scheduling bounding leaf.
0792: * @return this Sound's scheduling bounding leaf information
0793: * @exception CapabilityNotSetException if appropriate capability is
0794: * not set and this object is part of live or compiled scene graph
0795: */
0796: public BoundingLeaf getSchedulingBoundingLeaf() {
0797: if (isLiveOrCompiled())
0798: if (!this .getCapability(ALLOW_SCHEDULING_BOUNDS_READ))
0799: throw new CapabilityNotSetException(J3dI18N
0800: .getString("Sound12"));
0801:
0802: return ((SoundRetained) this .retained)
0803: .getSchedulingBoundingLeaf();
0804: }
0805:
0806: /**
0807: * Set sound's priority value.
0808: * @param priority value used to order sound's importance for playback.
0809: * @exception CapabilityNotSetException if appropriate capability is
0810: * not set and this object is part of live or compiled scene graph
0811: */
0812: public void setPriority(float priority) {
0813: if (isLiveOrCompiled())
0814: if (!this .getCapability(ALLOW_PRIORITY_WRITE))
0815: throw new CapabilityNotSetException(J3dI18N
0816: .getString("Sound15"));
0817:
0818: ((SoundRetained) this .retained).setPriority(priority);
0819: }
0820:
0821: /**
0822: * Retrieves sound's priority value.
0823: * @return sound priority value
0824: * @exception CapabilityNotSetException if appropriate capability is
0825: * not set and this object is part of live or compiled scene graph
0826: */
0827: public float getPriority() {
0828: if (isLiveOrCompiled())
0829: if (!this .getCapability(ALLOW_PRIORITY_READ))
0830: throw new CapabilityNotSetException(J3dI18N
0831: .getString("Sound16"));
0832:
0833: return ((SoundRetained) this .retained).getPriority();
0834: }
0835:
0836: /**
0837: * Get the Sound's duration
0838: * @return this Sound's duration in milliseconds including repeated
0839: * loops
0840: * @exception CapabilityNotSetException if appropriate capability is
0841: * not set and this object is part of live or compiled scene graph
0842: */
0843: public long getDuration() {
0844: if (isLiveOrCompiled())
0845: if (!this .getCapability(ALLOW_DURATION_READ))
0846: throw new CapabilityNotSetException(J3dI18N
0847: .getString("Sound17"));
0848:
0849: return ((SoundRetained) this .retained).getDuration();
0850: }
0851:
0852: /**
0853: * Retrieves sound's 'ready' status. If this sound is fully
0854: * prepared to begin playing (audibly or silently) on all
0855: * initialized audio devices, this method returns true.
0856: * @return flag denoting if sound is immediate playable or not
0857: * @exception CapabilityNotSetException if appropriate capability is
0858: * not set and this object is part of live or compiled scene graph
0859: */
0860: public boolean isReady() {
0861: if (isLiveOrCompiled())
0862: if (!this .getCapability(ALLOW_IS_READY_READ))
0863: throw new CapabilityNotSetException(J3dI18N
0864: .getString("Sound22"));
0865:
0866: return ((SoundRetained) this .retained).isReady();
0867: }
0868:
0869: /**
0870: * Retrieves sound's 'ready' status. If this sound is fully
0871: * prepared to begin playing (audibly or silently) on the audio
0872: * device associated with this view, this method returns true.
0873: * @param view the view on which to query the ready status.
0874: * @return flag denoting if sound is immediate playable or not
0875: * @exception CapabilityNotSetException if appropriate capability is
0876: * not set and this object is part of live or compiled scene graph
0877: * @since Java 3D 1.3
0878: */
0879: public boolean isReady(View view) {
0880: if (isLiveOrCompiled())
0881: if (!this .getCapability(ALLOW_IS_READY_READ))
0882: throw new CapabilityNotSetException(J3dI18N
0883: .getString("Sound22"));
0884:
0885: return ((SoundRetained) this .retained).isReady(view);
0886: }
0887:
0888: /**
0889: * Retrieves sound's play status. If this sound is audibly playing on any
0890: * initialized audio device, this method returns true.
0891: * @return flag denoting if sound is playing (potentially audible) or not
0892: * @exception CapabilityNotSetException if appropriate capability is
0893: * not set and this object is part of live or compiled scene graph
0894: */
0895: public boolean isPlaying() {
0896: if (isLiveOrCompiled())
0897: if (!this .getCapability(ALLOW_IS_PLAYING_READ))
0898: throw new CapabilityNotSetException(J3dI18N
0899: .getString("Sound18"));
0900:
0901: return ((SoundRetained) this .retained).isPlaying();
0902: }
0903:
0904: /**
0905: * Retrieves sound's play status. If this sound is audibly playing on the
0906: * audio device associated with the given view, this method returns
0907: * true.
0908: * @param view the view on which to query the isPlaying status.
0909: * @return flag denoting if sound is playing (potentially audible) or not
0910: * @exception CapabilityNotSetException if appropriate capability is
0911: * not set and this object is part of live or compiled scene graph
0912: * @since Java 3D 1.3
0913: */
0914: public boolean isPlaying(View view) {
0915: if (isLiveOrCompiled())
0916: if (!this .getCapability(ALLOW_IS_PLAYING_READ))
0917: throw new CapabilityNotSetException(J3dI18N
0918: .getString("Sound18"));
0919:
0920: return ((SoundRetained) this .retained).isPlaying(view);
0921: }
0922:
0923: /**
0924: * Retrieves sound's silent status. If this sound is silently playing on
0925: * any initialized audio device, this method returns true.
0926: * @return flag denoting if sound is silently playing (enabled but not active)
0927: * @exception CapabilityNotSetException if appropriate capability is
0928: * not set and this object is part of live or compiled scene graph
0929: */
0930: public boolean isPlayingSilently() {
0931: if (isLiveOrCompiled())
0932: if (!this .getCapability(ALLOW_IS_PLAYING_READ))
0933: throw new CapabilityNotSetException(J3dI18N
0934: .getString("Sound18"));
0935:
0936: return ((SoundRetained) this .retained).isPlayingSilently();
0937: }
0938:
0939: /**
0940: * Retrieves sound's silent status. If this sound is silently playing on
0941: * the audio device associated with the given view, this method returns
0942: * true.
0943: * The isPlayingSilently state is affected by enable, mute, and continuous
0944: * states as well as active status of sound.
0945: * @param view the view on which to query the isPlayingSilently status.
0946: * @return flag denoting if sound is silently playing (enabled but not active)
0947: * @exception CapabilityNotSetException if appropriate capability is
0948: * not set and this object is part of live or compiled scene graph
0949: * @since Java 3D 1.3
0950: */
0951: public boolean isPlayingSilently(View view) {
0952: if (isLiveOrCompiled())
0953: if (!this .getCapability(ALLOW_IS_PLAYING_READ))
0954: throw new CapabilityNotSetException(J3dI18N
0955: .getString("Sound18"));
0956:
0957: return ((SoundRetained) this .retained).isPlayingSilently(view);
0958: }
0959:
0960: /**
0961: * Retrieves number of channels that are being used to render this sound
0962: * on the audio device associated with the Virtual Universe's primary view.
0963: * @return number of channels used by sound; returns 0 if not playing
0964: * @exception CapabilityNotSetException if appropriate capability is
0965: * not set and this object is part of live or compiled scene graph
0966: */
0967: public int getNumberOfChannelsUsed() {
0968: if (isLiveOrCompiled())
0969: if (!this .getCapability(ALLOW_CHANNELS_USED_READ))
0970: throw new CapabilityNotSetException(J3dI18N
0971: .getString("Sound20"));
0972:
0973: return ((SoundRetained) this .retained)
0974: .getNumberOfChannelsUsed();
0975: }
0976:
0977: /**
0978: * Retrieves number of channels that are being used to render this sound
0979: * on the audio device associated with given view.
0980: * @param view the view on which to query the number of channels used.
0981: * @return number of channels used by sound; returns 0 if not playing
0982: * @exception CapabilityNotSetException if appropriate capability is
0983: * @since Java 3D 1.3
0984: * not set and this object is part of live or compiled scene graph
0985: */
0986: public int getNumberOfChannelsUsed(View view) {
0987: if (isLiveOrCompiled())
0988: if (!this .getCapability(ALLOW_CHANNELS_USED_READ))
0989: throw new CapabilityNotSetException(J3dI18N
0990: .getString("Sound20"));
0991:
0992: return ((SoundRetained) this .retained)
0993: .getNumberOfChannelsUsed(view);
0994: }
0995:
0996: /**
0997: * Set mute state flag. If the sound is playing it will be set to
0998: * play silently
0999: * @param state flag
1000: * @exception CapabilityNotSetException if appropriate capability is
1001: * not set and this object is part of live or compiled scene graph
1002: * @since Java 3D 1.3
1003: */
1004: public void setMute(boolean state) {
1005: if (isLiveOrCompiled())
1006: if (!this .getCapability(ALLOW_MUTE_WRITE))
1007: throw new CapabilityNotSetException(J3dI18N
1008: .getString("Sound23"));
1009:
1010: ((SoundRetained) this .retained).setMute(state);
1011: }
1012:
1013: /**
1014: * Retrieves sound Mute state.
1015: * A return value of true does not imply that the sound has
1016: * been started playing or is still playing silently.
1017: * @return mute state flag
1018: * @exception CapabilityNotSetException if appropriate capability is
1019: * not set and this object is part of live or compiled scene graph
1020: * @since Java 3D 1.3
1021: */
1022: public boolean getMute() {
1023: if (isLiveOrCompiled())
1024: if (!this .getCapability(ALLOW_MUTE_READ))
1025: throw new CapabilityNotSetException(J3dI18N
1026: .getString("Sound24"));
1027:
1028: return ((SoundRetained) this .retained).getMute();
1029: }
1030:
1031: /**
1032: * Pauses or resumes (paused) playing sound.
1033: * @param state pause flag
1034: * @exception CapabilityNotSetException if appropriate capability is
1035: * not set and this object is part of live or compiled scene graph
1036: * @since Java 3D 1.3
1037: */
1038: public void setPause(boolean state) {
1039: if (isLiveOrCompiled())
1040: if (!this .getCapability(ALLOW_PAUSE_WRITE))
1041: throw new CapabilityNotSetException(J3dI18N
1042: .getString("Sound25"));
1043:
1044: ((SoundRetained) this .retained).setPause(state);
1045: }
1046:
1047: /**
1048: * Retrieves the value of the Pause state flag.
1049: * A return value of true does not imply that the sound was
1050: * started playing and then paused.
1051: * @return pause state
1052: * @exception CapabilityNotSetException if appropriate capability is
1053: * not set and this object is part of live or compiled scene graph
1054: * @since Java 3D 1.3
1055: */
1056: public boolean getPause() {
1057: if (isLiveOrCompiled())
1058: if (!this .getCapability(ALLOW_PAUSE_READ))
1059: throw new CapabilityNotSetException(J3dI18N
1060: .getString("Sound26"));
1061:
1062: return ((SoundRetained) this .retained).getPause();
1063: }
1064:
1065: /**
1066: * Sets Sample Rate.
1067: * Changes (scales) the playback rate of a sound independent of
1068: * Doppler rate changes - applied to ALL sound types.
1069: * Affects device sample rate playback and thus affects both pitch and speed
1070: * @param scaleFactor %%% describe this.
1071: * @exception CapabilityNotSetException if appropriate capability is
1072: * not set and this object is part of live or compiled scene graph
1073: * @since Java 3D 1.3
1074: */
1075: public void setRateScaleFactor(float scaleFactor) {
1076: if (isLiveOrCompiled())
1077: if (!this .getCapability(ALLOW_RATE_SCALE_FACTOR_WRITE))
1078: throw new CapabilityNotSetException(J3dI18N
1079: .getString("Sound27"));
1080:
1081: ((SoundRetained) this .retained).setRateScaleFactor(scaleFactor);
1082: }
1083:
1084: /**
1085: * Retrieves Sample Rate.
1086: * @return sample rate scale factor
1087: * @exception CapabilityNotSetException if appropriate capability is
1088: * not set and this object is part of live or compiled scene graph
1089: * @since Java 3D 1.3
1090: */
1091: public float getRateScaleFactor() {
1092: if (isLiveOrCompiled())
1093: if (!this .getCapability(ALLOW_RATE_SCALE_FACTOR_READ))
1094: throw new CapabilityNotSetException(J3dI18N
1095: .getString("Sound28"));
1096:
1097: return ((SoundRetained) this .retained).getRateScaleFactor();
1098: }
1099:
1100: /**
1101: * Copies all Sound information from
1102: * <code>originalNode</code> into
1103: * the current node. This method is called from the
1104: * <code>cloneNode</code> method which is, in turn, called by the
1105: * <code>cloneTree</code> method.<P>
1106: *
1107: * @param originalNode the original node to duplicate.
1108: * @param forceDuplicate when set to <code>true</code>, causes the
1109: * <code>duplicateOnCloneTree</code> flag to be ignored. When
1110: * <code>false</code>, the value of each node's
1111: * <code>duplicateOnCloneTree</code> variable determines whether
1112: * NodeComponent data is duplicated or copied.
1113: *
1114: * @exception RestrictedAccessException if this object is part of a live
1115: * or compiled scenegraph.
1116: *
1117: * @see Node#duplicateNode
1118: * @see Node#cloneTree
1119: * @see NodeComponent#setDuplicateOnCloneTree
1120: */
1121: void duplicateAttributes(Node originalNode, boolean forceDuplicate) {
1122: super .duplicateAttributes(originalNode, forceDuplicate);
1123:
1124: SoundRetained orgRetained = (SoundRetained) originalNode.retained;
1125:
1126: SoundRetained this Retained = (SoundRetained) this .retained;
1127:
1128: this Retained.setSoundData((MediaContainer) getNodeComponent(
1129: orgRetained.getSoundData(), forceDuplicate,
1130: originalNode.nodeHashtable));
1131: this Retained.setInitialGain(orgRetained.getInitialGain());
1132: this Retained.setLoop(orgRetained.getLoop());
1133: this Retained.setReleaseEnable(orgRetained.getReleaseEnable());
1134: this Retained.setContinuousEnable(orgRetained
1135: .getContinuousEnable());
1136: this Retained.setSchedulingBounds(orgRetained
1137: .getSchedulingBounds());
1138: this Retained.setPriority(orgRetained.getPriority());
1139: this Retained.setEnable(orgRetained.getEnable());
1140:
1141: // updateNodeReferences will set the following correctly
1142: this Retained.setSchedulingBoundingLeaf(orgRetained
1143: .getSchedulingBoundingLeaf());
1144: }
1145:
1146: /**
1147: * Callback used to allow a node to check if any scene graph objects
1148: * referenced
1149: * by that node have been duplicated via a call to <code>cloneTree</code>.
1150: * This method is called by <code>cloneTree</code> after all nodes in
1151: * the sub-graph have been duplicated. The cloned Leaf node's method
1152: * will be called and the Leaf node can then look up any object references
1153: * by using the <code>getNewObjectReference</code> method found in the
1154: * <code>NodeReferenceTable</code> object. If a match is found, a
1155: * reference to the corresponding object in the newly cloned sub-graph
1156: * is returned. If no corresponding reference is found, either a
1157: * DanglingReferenceException is thrown or a reference to the original
1158: * object is returned depending on the value of the
1159: * <code>allowDanglingReferences</code> parameter passed in the
1160: * <code>cloneTree</code> call.
1161: * <p>
1162: * NOTE: Applications should <i>not</i> call this method directly.
1163: * It should only be called by the cloneTree method.
1164: *
1165: * @param referenceTable a NodeReferenceTableObject that contains the
1166: * <code>getNewObjectReference</code> method needed to search for
1167: * new object instances.
1168: * @see NodeReferenceTable
1169: * @see Node#cloneTree
1170: * @see DanglingReferenceException
1171: */
1172: public void updateNodeReferences(NodeReferenceTable referenceTable) {
1173: super .updateNodeReferences(referenceTable);
1174:
1175: SoundRetained rt = (SoundRetained) retained;
1176: BoundingLeaf bl = rt.getSchedulingBoundingLeaf();
1177:
1178: if (bl != null) {
1179: Object o = referenceTable.getNewObjectReference(bl);
1180: rt.setSchedulingBoundingLeaf((BoundingLeaf) o);
1181: }
1182: MediaContainer sd = rt.getSoundData();
1183: if (sd != null) {
1184: rt.setSoundData(sd);
1185: }
1186: }
1187: }
|