📄 soundscheduler.java
字号:
//// until there's a difference in messages between detaching and deleting// a sound node, sound is stopped and atom enable state changed but atom// is NOT deleted from list.*/ SoundSchedulerAtom soundAtom = null; for (int arrIndx=1; ;arrIndx++) { soundAtom = findSoundAtom((SoundRetained)node, arrIndx); if (soundAtom == null) break; stopSound(soundAtom, false); } } else if (node instanceof SoundscapeRetained) { auralAttribsChanged = true; } } // Handle ViewScoped Nodes if (viewScopedNodes != null) { int size = viewScopedNodes.size(); int vlsize; for (int i = 0; i < size; i++) { node = (NodeRetained)viewScopedNodes.get(i); ArrayList vl = (ArrayList) scopedNodesViewList.get(i); // If the node object is scoped to this view, then .. if (vl.contains(view)) { if (node instanceof SoundRetained) { SoundSchedulerAtom soundAtom = null; for (int arrIndx=1; ;arrIndx++) { soundAtom = findSoundAtom((SoundRetained)node, arrIndx); if (soundAtom == null) break; stopSound(soundAtom, false); } } else if (node instanceof SoundscapeRetained) { auralAttribsChanged = true; } } } } } // deletes all instances of the sound nodes from the priority list void deleteSound(SoundRetained sound) { if (sound != null) return; if (debugFlag) debugPrint(".deleteSound()"); synchronized (prioritizedSounds) { if (!prioritizedSounds.isEmpty()) { // find sound in list and remove it int arrSize = prioritizedSounds.size(); for (int index=0; index<arrSize; index++) { SoundSchedulerAtom soundAtom = (SoundSchedulerAtom) prioritizedSounds.get(index); // QUESTION: which??? if (soundAtom.sound == sound || soundAtom.sound.sgSound == sound) { stopSound(soundAtom, false); prioritizedSounds.remove(index); } } } } } void changeNodeAttrib(J3dMessage m) { Object node = m.args[0]; Object value = m.args[1]; int attribDirty = ((Integer)value).intValue(); if (debugFlag) debugPrint(".changeNodeAttrib:"); if (node instanceof SoundRetained && universe.soundStructure.isSoundScopedToView(node, view)) { this.setAttribsDirtyFlag((SoundRetained)node, attribDirty); if (debugFlag) debugPrint(" Sound node dirty bit = " + attribDirty); if ((attribDirty & SoundRetained.PRIORITY_DIRTY_BIT) > 0) { shuffleSound((SoundRetained) node); } if ((attribDirty & SoundRetained.SOUND_DATA_DIRTY_BIT) >0) { if (debugFlag) debugPrint(".changeNodeAttrib " + "SOUND_DATA_DIRTY_BIT calls loadSound"); loadSound((SoundRetained) node, true); } if ((attribDirty & SoundRetained.MUTE_DIRTY_BIT) > 0) { if (debugFlag) debugPrint(" MuteDirtyBit is on"); muteSound((SoundRetained) node); } if ((attribDirty & SoundRetained.PAUSE_DIRTY_BIT) > 0) { if (debugFlag) debugPrint(" PauseDirtyBit is on"); pauseSound((SoundRetained) node); } } else if (node instanceof SoundscapeRetained && universe.soundStructure.isSoundscapeScopedToView(node, view)) { auralAttribsChanged = true; } else if (node instanceof AuralAttributesRetained) { auralAttribsChanged = true; } else if (node instanceof MediaContainerRetained) { int listSize = ((Integer)m.args[2]).intValue(); ArrayList userList = (ArrayList)m.args[3]; for (int i = 0; i < listSize; i++) { SoundRetained sound = (SoundRetained)userList.get(i); if (sound != null) { loadSound(sound, true); if (debugFlag) debugPrint(".changeNodeAttrib " + "MEDIA_CONTAINER_CHANGE calls loadSound"); } } } } void changeNodeState(J3dMessage m) { Object node = m.args[0]; Object value = m.args[1]; if (debugFlag) debugPrint(".changeNodeState:"); if (node instanceof SoundRetained && universe.soundStructure.isSoundScopedToView(node, view)) { int stateDirty = ((Integer)value).intValue(); setStateDirtyFlag((SoundRetained)node, stateDirty); if (debugFlag) debugPrint(" Sound node dirty bit = "+stateDirty); if ((stateDirty & SoundRetained.LIVE_DIRTY_BIT) > 0) { if (debugFlag) debugPrint(".changeNodeState LIVE_DIRTY_BIT " + "calls loadSound"); loadSound((SoundRetained) node, false); } if ((stateDirty & SoundRetained.ENABLE_DIRTY_BIT) > 0) { if (debugFlag) debugPrint(" EnableDirtyBit is on"); if (((Boolean) m.args[4]).booleanValue()) { enableSound((SoundRetained) node); } else { SoundSchedulerAtom soundAtom; SoundRetained soundRetained = (SoundRetained) node; for (int i=prioritizedSounds.size()-1; i >=0; i--) { soundAtom = ((SoundSchedulerAtom)prioritizedSounds.get(i)); if (soundAtom.sound.sgSound == soundRetained) { // ignore soundRetained.release // flag which is not implement turnOff(soundAtom); // Fix to Issue 431. soundAtom.enable(soundRetained.enable); } } } } } } void shuffleSound(SoundRetained sound) { // Find sound atom that references this sound node and // reinsert it into prioritized sound list by removing atom for // this sound from priority list, then re-add it. // Assumes priority has really changed since a message is not sent // to the scheduler if the 'new' priority value isn't different. deleteSound(sound); // remove atom for this sound addSound(sound); // then re-insert it back into list in new position } void loadSound(SoundRetained sound, boolean forceReload) { // find sound atom that references this sound node // QUESTION: "node" probably not mirror node? SoundSchedulerAtom soundAtom = null; for (int i=1; ;i++) { soundAtom = findSoundAtom(sound, i); if (soundAtom == null) break; MediaContainer mediaContainer = sound.getSoundData(); if (forceReload || soundAtom.loadStatus != SoundRetained.LOAD_COMPLETE) { if (debugFlag) debugPrint(": not LOAD_COMPLETE - try attaching"); attachSoundData(soundAtom, mediaContainer, forceReload); } } } void enableSound(SoundRetained sound) { if (debugFlag) debugPrint(".enableSound " + sound ); // find sound atom that references this sound node SoundSchedulerAtom soundAtom = null; for (int i=1; ;i++) { soundAtom = findSoundAtom(sound, i); if (soundAtom == null) break; // Set atom enabled field based on current Sound node // enable boolean flag soundAtom.enable(sound.enable); } } void muteSound(SoundRetained sound) { // make mute pending // mute -> MAKE-SILENT // unmute -> MAKE-AUDIBLE if (debugFlag) debugPrint(".muteSound " + sound ); // find sound atom that references this sound node SoundSchedulerAtom soundAtom = null; for (int i=1; ;i++) { soundAtom = findSoundAtom(sound, i); if (soundAtom == null) break; // Set atom mute field based on node current // mute boolean flag soundAtom.mute(sound.mute); } } void pauseSound(SoundRetained sound) { // make pause pending // Pause is a separate action // When resumed it has to reset its state // PAUSE_AUDIBLE // PAUSE_SILENT // RESUME_AUDIBLE // RESUME_SILENT // to whatever it was before if (debugFlag) debugPrint(".pauseSound " + sound ); // find sound atom that references this sound node SoundSchedulerAtom soundAtom = null; for (int i=1; ;i++) { soundAtom = findSoundAtom(sound, i); if (soundAtom == null) break; // Set atom pause field based on node's current // pause boolean flag soundAtom.pause(sound.pause); } } void processImmediateNodes(Object[] args, long referenceTime) { Object command = args[0]; Object newNode = args[1]; Object oldNode = args[2]; Sound oldSound = (Sound)oldNode; Sound newSound = (Sound)newNode; int action = ((Integer)command).intValue(); if (debugFlag) debugPrint(".processImmediateNodes() - action = " + action); switch (action) { case GraphicsContext3D.ADD_SOUND : case GraphicsContext3D.INSERT_SOUND : addSound((SoundRetained)newSound.retained); nImmedSounds++; break; case GraphicsContext3D.REMOVE_SOUND : deleteSound((SoundRetained)oldSound.retained); nImmedSounds--; break; case GraphicsContext3D.SET_SOUND : deleteSound((SoundRetained)oldSound.retained); addSound((SoundRetained)newSound.retained); break; } } void updateTransformChange(UpdateTargets targets, long referenceTime) { // node.updateTransformChange() called immediately rather than // waiting for updateObject to be called and process xformChangeList // which apprears to only happen when sound started... UnorderList arrList = targets.targetList[Targets.SND_TARGETS]; if (arrList != null) { int j,i; Object nodes[], nodesArr[]; int size = arrList.size(); nodesArr = arrList.toArray(false); for (j = 0; j<size; j++) { nodes = (Object[])nodesArr[j]; for (i = 0; i < nodes.length; i++) { if (nodes[i] instanceof ConeSoundRetained && universe.soundStructure.isSoundScopedToView(nodes[i], view)) { ConeSoundRetained cnSndNode = (ConeSoundRetained)nodes[i]; synchronized (cnSndNode) { cnSndNode.updateTransformChange(); } // set XFORM_DIRTY_BIT in corresponding atom setStateDirtyFlag((SoundRetained)nodes[i], SoundRetained.XFORM_DIRTY_BIT); } else if (nodes[i] instanceof PointSoundRetained && universe.soundStructure.isSoundScopedToView(nodes[i], view)) { PointSoundRetained ptSndNode = (PointSoundRetained)nodes[i]; synchronized (ptSndNode) { ptSndNode.updateTransformChange(); } // set XFORM_DIRTY_BIT in corresponding atom setStateDirtyFlag((SoundRetained)nodes[i], SoundRetained.XFORM_DIRTY_BIT); } else if (nodes[i] instanceof SoundscapeRetained && universe.soundStructure.isSoundscapeScopedToView(nodes[i], view)) { SoundscapeRetained sndScapeNode = (SoundscapeRetained)nodes[i]; synchronized (sndScapeNode) { sndScapeNode.updateTransformChange(); } } } } } } void updateTransformedFields(SoundRetained mirSound) { if (mirSound instanceof ConeSoundRetained && universe.soundStructure.isSoundScopedToView(mirSound, view)) { ConeSoundRetained cnSndNode = (ConeSoundRetained)mirSound; synchronized (cnSndNode) { cnSndNode.updateTransformChange(); } } else if (mirSound instanceof PointSoundRetained && universe.soundStructure.isSoundScopedToView(mirSound, view)) { PointSoundRetained ptSndNode = (PointSoundRetained)mirSound; synchronized (ptSndNode) { ptSndNode.updateTransformChange(); } } } void activate() { updateThread.active = true; if (debugFlag) debugPrint(".activate(): calls sendRunMessage for immediate processing"); VirtualUniverse.mc.sendRunMessage(universe, J3dThread.SOUND_SCHEDULER); // renderChanges() called indirectly thru processMessage now } // deactivate scheduler only if it state has such that it can not perform // sound processing void deactivate() { if (debugFlag) debugPrint(".deactivate()"); // // XXXX: The following code is clearly erroneous. // The indendation, along with the 2nd test of // "if (debugFlag)" in the else clause, suggests that // the intent was to make the else clause apply to // "if (checkState())". However, the else clause // actually applies to the first "if (debugFlag)". // This is a textbook example of why one should // *ALWAYS* enclose the target of an "if", "while", or // "else" in curly braces -- even when the target // consists of a single statement. // // The upshot of this, is that the else clause is // unconditionally executed, since "debugFlag" is a // static final constant that is set to false for // production builds. We won't fix it now, because // The SoundScheduler may actually be relying on the // fact that all sounds are unconditionally // deactivated when this method is called, and we // don't want to introduce a new bug. // if (checkState()) if (debugFlag) debugPrint(" checkState returns true"); else { if (debugFlag) debugPrint(" checkState returns false; deactive scheduler"); // Call deactivateAllSounds within try/catch so // errors won't kill the SoundScheduler. try { deactivateAllSounds(); } catch (RuntimeException e) { System.err.println("Exception occurred " + "during sound deactivation:"); e.printStackTrace(); } catch (Error e) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -