Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
package org.scijava.java3d;
/**
* A SoundSchedulerAtom is the smallest object representing a Sound within
* SoundScheduler. This class contains View-Depedent fields. Some of these
* fields may appear to over lap fields in the Sound Node classes, but
* remember that the Sound Node fields are universal, user-defined fields
* and do not take into account specific Audio Device view-dependent
* conditions.
*/
class SoundSchedulerAtom extends Object {
/**
* The mirror sound node component of this sound scheduler atom
*/
SoundRetained sound = null;
/**
* MediaContainer currently loaded for this atom
*/
MediaContainer soundData = null;
// Maintain continuously playing silent sound sources.
long startTime = 0;
long endTime = 0;
long sampleLength = 0;
long loopStartOffset = 0; // for most this will be 0
long loopLength = 0; // for most this is end sample - sampleLength
long attackLength = 0; // portion of sample before loop section
long releaseLength = 0; // portion of sample after loop section
int loadStatus = SoundRetained.LOAD_NULL;
boolean playing = false;
int numberChannels = 0;
/**
* Is this sound in an active scheduling region
*/
boolean activated = false;
/**
* Switch for turning sound on or off while the sound is "active"
*/
static final int OFF = 0;
static final int ON = 1;
static final int PENDING_ON = 2;
static final int PENDING_OFF = 3;
int enabled = OFF;
/**
* Switch for muting and unmuting sound while it is playing
*/
static final int UNMUTED = 0;
static final int MUTED = 1;
static final int PENDING_UNMUTE = 2;
static final int PENDING_MUTE = 3;
int muted = UNMUTED;
/**
* Switch for pausing and unpausing sound while it is playing
*/
static final int UNPAUSED = 0; // or resumed
static final int PAUSED = 1;
static final int PENDING_UNPAUSE = 2; // or pending resume
static final int PENDING_PAUSE = 3;
int paused = UNPAUSED;
/**
* Pending action for this sound determined by the SoundScheduler
*/
static final int DO_NOTHING = 0;
static final int LEAVE_OFF = 1;
static final int LEAVE_SILENT = 2;
static final int LEAVE_AUDIBLE = 3;
static final int LEAVE_PAUSED = 4;
static final int RESTART_AUDIBLE = 5;
static final int START_AUDIBLE = 6;
static final int RESTART_SILENT = 7;
static final int START_SILENT = 8;
static final int MAKE_AUDIBLE = 11;
static final int MAKE_SILENT = 12;
static final int PAUSE_AUDIBLE = 13;
static final int PAUSE_SILENT = 14;
static final int RESUME_AUDIBLE = 15;
static final int RESUME_SILENT = 16;
static final int TURN_OFF = 17;
static final int UPDATE = 18;
static final int COMPLETE = 19;
int schedulingAction = DO_NOTHING;
/**
* This status flag is used for sound scheduling
*/
static final int SOUND_OFF = 0; // The sound is not playing
static final int SOUND_AUDIBLE = 1; // The sound is potentially audible
static final int SOUND_SILENT = 2; // The sound is playing silently
static final int SOUND_PAUSED = 3; // The sound is playing silently
static final int SOUND_COMPLETE = 4; // The sound is finished playing
int status = SOUND_OFF;
// Sound atoms have two dirty flags: attribsDirty for sound node fields
// and stateDirty for changes to sound state not reflected by sound fields.
// When the field/parameter associated with the dirty bit has been:
// passed to all SoundSchedulers to update sound rendering or 'run' state
// the bit for that field is cleared by the SoundStructure thread.
/**
* attribsDirty bit field
* This bitmask is set when sound node attribute is changed by the user.
*/
int attribsDirty = 0x0000;
/**
* stateDirty bit field
* This bitmask is set when scene graph state is changed.
*/
int stateDirty = 0x0000;
// Load Sound Data Status maintained in SoundRetained class
/**
* Identifiers of sample associated with sound source
*/
int sampleId = SoundRetained.NULL_SOUND;
/**
* reference to Sound Scheduler this atom is associated with
*/
SoundScheduler soundScheduler = null;
/**
* Calculate absolute time at which sample completes
* Checks playing flag denoting if sound is started already or not:
* false - calcalutes endTime in relation to startTime
* true - re-calculates endTime based on current position in
* loop portion of sample plus release length
*/
synchronized void calculateEndTime() {
SoundRetained sgSound = sound.sgSound;
int loops = sgSound.loopCount;
if (debugFlag)
debugPrint("calculateEndTime: loop count = " + loops);
// test lengths for <= 0; this includes DURATION_UNKNOWN
if ( (sampleLength <= 0 || loopLength <= 0 || loops < 0 )
// QUESTION: removed? but what was this trying to avoid
// changing endTime when that is already set?
// but what happens when user changes LoopCount AFTER
// sound is started - should be able to do this
// && (enabled == OFF || enabled == PENDING_OFF)
) {
endTime = -1;
if (debugFlag)
debugPrint("calculateEndTime: set to -1");
}
else {
// QUESTION: if "&& playing" is in above test; won't we have to test for
// length unknown and loop = -1??
if (playing && (startTime > 0)) {
endTime = startTime + attackLength +
(loopLength * (loops+1)) + releaseLength; if (debugFlag)
debugPrint("calculateEndTime: isPlaying so = " + endTime); }
else {
// Called when release flag is true
// Determine where within the loop portion sample the
// sound is currently playing, then set endTime to
// play remaining portion of loop portion plus the
// release portion.
long currentTime = J3dClock.currentTimeMillis();
endTime = currentTime + ( (loopLength -
((currentTime - startTime - attackLength) % loopLength)) +
releaseLength );
if (debugFlag)
debugPrint("calculateEndTime: NOT Playing so = " + endTime);
}
}
}
void enable(boolean enabled) {
if (enabled) {
setEnableState(PENDING_ON);
if (debugFlag)
debugPrint(" enableSound calls soundAtom " +
this + " setEnableState PENDING_ON");
}
else {
setEnableState(PENDING_OFF);
if (debugFlag)
debugPrint(" enableSound calls soundAtom " +
this + " setEnableState PENDING_OFF");
}
}
void mute(boolean muted) {
if (muted) {
setMuteState(PENDING_MUTE);
if (debugFlag)
debugPrint(" muteSound() calls soundAtom " +
this + " setMuteState PENDING_ON");
}
else {
setMuteState(PENDING_UNMUTE);
if (debugFlag)
debugPrint(" muteSound() calls soundAtom " +
this + " setMuteState PENDING_UNMUTE");
}
}
void pause(boolean paused) {
if (paused) {
setPauseState(PENDING_PAUSE);
if (debugFlag)
debugPrint(this + ".pause calls setPauseState(PENDING_PAUSE)");
}
else {
setPauseState(PENDING_UNPAUSE);
if (debugFlag)
debugPrint(this +".pause calls setPauseState(PENDING_UNPAUSE)");
}
}
// XXXX: remove this
// just set the state after debug no longer needed
void setEnableState(int state) {
enabled = state;
switch (state) {
case PENDING_ON:
if (debugFlag)
debugPrint("set enabled to PENDING_ON");
break;
case ON:
if (debugFlag)
debugPrint("set enabled to ON");
break;
case PENDING_OFF:
if (debugFlag)
debugPrint("set enabled to PENDING_OFF");
break;
case OFF:
if (debugFlag)
debugPrint("set enabled to OFF");
break;
default:
if (debugFlag)
debugPrint("state = " + state);
break;
}
}
// XXXX: remove this
// just set the state after debug no longer needed
void setMuteState(int state) {
muted = state;
switch (state) {
case PENDING_MUTE:
if (debugFlag)
debugPrint("set mute to PENDING_MUTE");
break;
case MUTED:
if (debugFlag)
debugPrint("set mute to MUTE");
break;
case PENDING_UNMUTE:
if (debugFlag)
debugPrint("set mute to PENDING_UNMUTE");
break;
case UNMUTED:
if (debugFlag)
debugPrint("set mute to UNMUTE");
break;
default:
if (debugFlag)
debugPrint("state = " + state);
break;
}
}
// XXXX: remove this
// just set the state after debug no longer needed
void setPauseState(int state) {
paused = state;
switch (state) {
case PENDING_PAUSE:
if (debugFlag)
debugPrint("set pause to PENDING_PAUSE");
break;
case PAUSED:
if (debugFlag)
debugPrint("set pause to PAUSE");
break;
case PENDING_UNPAUSE:
if (debugFlag)
debugPrint("set pause to PENDING_UNPAUSE");
break;
case UNPAUSED:
if (debugFlag)
debugPrint("set pause to UNPAUSE");
break;
default:
if (debugFlag)
debugPrint("state = " + state);
break;
}
}
/**
* calcActiveSchedAction()
* Calculate Sound Scheduler Action for Active sound (it's region
* intersects the viewPlatform).
*
* A big switch testing various SoundRetained fields to determine
* what SoundScheduler action to perform when sound is Active
* set sound active flag true
* switch on enable value, to set pending scheduling action
* depending on continuous and release flags and sound status
*/
synchronized int calcActiveSchedAction() {
SoundRetained sgSound = sound.sgSound;
int action = DO_NOTHING;
activated = true;
switch (enabled) {
case PENDING_ON:
setEnableState(ON);
if (debugFlag)
debugPrint(" calcActiveSchedAction: PENDING_ON");
if (status == SOUND_OFF ||
status == SOUND_PAUSED)
action = START_AUDIBLE;
else
action = RESTART_AUDIBLE;
break;
case ON:
if (debugFlag)
debugPrint(" calcActiveSchedAction: ON");
if (status == SOUND_OFF)
// should NOT see this, but if we do...
action = START_AUDIBLE;
else if (status == SOUND_SILENT)
action = MAKE_AUDIBLE;
else // status == SOUND_AUDIBLE
action = LEAVE_AUDIBLE;
break;
case PENDING_OFF:
setEnableState(OFF);
if (debugFlag)
debugPrint("enable = " + enabled +
"enabled set to OFF");
// fail thru
case OFF:
// QUESTION: Why would enable status ever be OFF yet
// status SOUND_AUDIBLE or _SILENT?
if (status == SOUND_AUDIBLE) {
if (sgSound.release) {
if (debugFlag)
debugPrint("enable = " + enabled +
", AUDIBLE, released, " +
"action <- LEAVE_AUDIBLE");
if (enabled == PENDING_OFF) {
// re-calculate EndTime
calculateEndTime();
}
action = LEAVE_AUDIBLE;
}
else {
if (debugFlag)
debugPrint("enable = " + enabled +
", AUDIBLE, not released, "+
"action <- TURN_OFF");
action = TURN_OFF;
}
}
else if (status == SOUND_SILENT) {
if (sgSound.release) {
if (debugFlag)
debugPrint("enable = " + enabled +
", SILENT, released, " +
"action <- MAKE_AUDIBLE");
// re-calculate EndTime
calculateEndTime();
action = MAKE_AUDIBLE;
}
else {
if (debugFlag)
debugPrint("enable = " + enabled +
", SILENT, not released, " +
"action <- TURN_OFF");
action = TURN_OFF;
}
}
else { // status == SOUND_OFF
action = LEAVE_OFF;
}
break;
} // switch on enabled flag
// if sounds pause state is PENDING_PAUSE modify action to perform.
if (paused == PENDING_PAUSE) {
// if this pause state is set to PAUSE then assume the sound is
// already paused, so any incoming action that leave the state
// as it already is, leaves the sound paused.
if (debugFlag)
debugPrint(" PENDING_PAUSE");
switch (action) {
case MAKE_AUDIBLE:
case LEAVE_AUDIBLE:
case RESUME_AUDIBLE:
action = PAUSE_AUDIBLE;
break;
case MAKE_SILENT:
case LEAVE_SILENT:
case RESUME_SILENT:
action = PAUSE_SILENT;
break;
default:
// don't change action for any other cases
break;
}
}
// if sounds pause state is PENDING_UNPAUSE modify action
else if (paused == PENDING_UNPAUSE) {
debugPrint(" PENDING_UNPAUSE");
switch (action) {
// When restart (audible or silent) pause flag is checked and
// explicitly set in SoundScheduler
case MAKE_AUDIBLE:
case LEAVE_AUDIBLE:
case PAUSE_AUDIBLE:
action = RESUME_AUDIBLE;
break;
case MAKE_SILENT:
case LEAVE_SILENT:
case PAUSE_SILENT:
action = RESUME_SILENT;
break;
default:
// don't change action for any other cases
break;
}
}
return(action);
} // end of calcActiveSchedAction
/**
* calcInactiveSchedAction()
* Calculate Sound Scheduler action for Inactive sound
*
* A big switch testing various SoundRetained fields to determine
* what SoundScheduler action to perform when sound is inactive.
* set sound active flag false
* switch on enable value, to set pending scheduling action
* depending on continuous and release flags and sound status
*/
synchronized int calcInactiveSchedAction() {
int action = DO_NOTHING;
SoundRetained sgSound = sound.sgSound;
// Sound is Inactive
// Generally, sound is OFF unless continuous flag true
// then sound is silently playing if on.
activated = false;
switch (enabled) {
case PENDING_ON:
if (debugFlag)
debugPrint(" calcInactiveSchedAction: PENDING_ON ");
setEnableState(ON);
if (sgSound.continuous) {
if (status == SOUND_OFF)
action = START_SILENT;
else // status == SOUND_AUDIBLE or SOUND_SILENT
action = RESTART_SILENT;
}
else { // sound is not continuous
if (status == SOUND_OFF)
action = LEAVE_OFF;
else // status == SOUND_SILENT || SOUND_AUDIBLE
action = TURN_OFF;
}
break;
case ON:
if (debugFlag)
debugPrint(" calcInactiveSchedActio: ON ");
if (sgSound.continuous) {
if (status == SOUND_AUDIBLE)
action = MAKE_SILENT;
else if (status == SOUND_OFF)
action = START_SILENT;
else // status == SOUND_SILENT
action = LEAVE_SILENT;
}
else { // sound is not continuous
// nothing to do if already off
if (status == SOUND_OFF)
action = LEAVE_OFF;
else // status == SOUND_SILENT or SOUND_AUDIBLE
action = TURN_OFF;
}
break;
case PENDING_OFF:
setEnableState(OFF);
if (debugFlag)
debugPrint("Enable = " + enabled +
"enabled set to OFF");
// fall thru
case OFF:
if (sgSound.release && sgSound.continuous) {
if (enabled == PENDING_OFF) {
// re-calculate EndTime
calculateEndTime();
}
if (status == SOUND_AUDIBLE) {
if (debugFlag)
debugPrint("Enable = " + enabled +
", AUDIBLE, released & continuous - " +
"action <- MAKE_SILENT");
action = MAKE_SILENT;
}
else if (status == SOUND_SILENT) {
if (debugFlag)
debugPrint("Enable = " + enabled +
", SILENT, released & continuous - " +
"action <- TURN_OFF");
action = LEAVE_SILENT;
}
else {
if (debugFlag)
debugPrint("Enable = " + enabled +
", already OFF, action <- LEAVE_OFF");
action = LEAVE_OFF;
}
}
else { // continuous and release flag not both true
if (status == SOUND_OFF) {
if (debugFlag)
debugPrint("Enable = " + enabled +
", already OFF, action <- LEAVE_OFF");
action = LEAVE_OFF;
}
else {
if (debugFlag)
debugPrint("Enable = " + enabled +
", not already OFF, action <- TURN_OFF");
action = TURN_OFF;
}
}
break;
default:
break;
} // switch
// if sounds pause state is PENDING_PAUSE modify action to perform.
if (paused == PENDING_PAUSE) {
// if this pause state is set to PAUSE then assume the sound is
// already paused, so any incoming action that leave the state
// as it already is, leaves the sound paused.
switch (action) {
case MAKE_SILENT:
case LEAVE_SILENT:
case RESUME_SILENT:
action = PAUSE_SILENT;
break;
default:
// don't change action for any other cases
break;
}
}
// if sounds pause state is PENDING_UNPAUSE modify action
else if (paused == PENDING_UNPAUSE) {
switch (action) {
case LEAVE_SILENT:
action = RESUME_SILENT;
break;
default:
// don't change action for any other cases
break;
}
}
return (action);
} // end of calcInactiveSchedAction
// XXXX: isPLaying
// XXXX: setLoadingState
// Debug print mechanism for Sound nodes
static final boolean debugFlag = false;
static final boolean internalErrors = false;
void debugPrint(String message) {
if (debugFlag) {
System.err.println(message);
}
}
/**
* Set bit(s) in soundDirty field
* @param binary flag denotes bits to set ON
*/
void setAttribsDirtyFlag(int bitFlag) {
attribsDirty |= bitFlag;
if (debugFlag)
debugPrint("setAttribsDirtyFlag = " + bitFlag);
return ;
}
void setStateDirtyFlag(int bitFlag) {
stateDirty |= bitFlag;
if (debugFlag)
debugPrint("setStateDirtyFlag = " + bitFlag);
return ;
}
/**
* Clear sound's dirty flag bit value.
* @param binary flag denotes bits to set OFF
*/
void clearAttribsDirtyFlag(int bitFlag) {
if (debugFlag)
debugPrint("clearAttribsDirtyFlag = " + bitFlag);
attribsDirty &= ~bitFlag;
return ;
}
void clearAttribsDirtyFlag() {
// clear all bits
if (debugFlag)
debugPrint("clearAttribsDirtyFlag = ALL");
attribsDirty = 0x0;
return ;
}
void clearStateDirtyFlag(int bitFlag) {
if (debugFlag)
debugPrint("clearStateDirtyFlag = " + bitFlag);
stateDirty &= ~bitFlag;
return ;
}
void clearStateDirtyFlag() {
if (debugFlag)
debugPrint("clearStateDirtyFlag = ALL");
stateDirty = 0x0;
return ;
}
/**
* Test sound's dirty flag bit(s)
* @param field denotes which bitmask to set into
* @param binary flag denotes bits to set Test
* @return true if bit(s) in bitFlag are set dirty (on)
*/
boolean testDirtyFlag(int field, int bitFlag) {
if ((field & bitFlag) > 0)
return true;
else
return false;
}
/**
* Test sound's dirty flags for ANY bits on
* @return true if any bit in bitFlag is flipped on
*/
boolean testDirtyFlags() {
if ((attribsDirty & 0xFFFF) > 0)
return true;
else if ((stateDirty & 0xFFFF) > 0)
return true;
else
return false;
}
}