📄 soundscheduleratom.java
字号:
/* * $RCSfile: SoundSchedulerAtom.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision: 1.7 $ * $Date: 2007/04/12 17:34:06 $ * $State: Exp $ */package javax.media.j3d;import java.util.ArrayList;/** * 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");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -