⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soundscheduler.java

📁 JAVA3D矩陈的相关类
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* * $RCSfile: SoundScheduler.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Use is subject to license terms. * * $Revision: 1.10 $ * $Date: 2007/04/12 17:34:06 $ * $State: Exp $ */package javax.media.j3d;import javax.vecmath.*;import java.lang.Math;import java.util.Vector;import java.util.ArrayList;import java.net.URL;import java.io.InputStream;import java.util.Enumeration;import java.util.Arrays;import java.awt.*;import java.awt.event.*;/** * This structure parallels the RenderBin structure and * is used for sounds */class SoundScheduler extends J3dStructure {    /**     * The View that owns this SoundScheduler     */    View view = null;    /**     * This boolean tells the thread to suspend itself.     * This is true ONLY when everythings ready to render using run loop     */    boolean ready = false;    /**     * The ViewPlatform that is associated with this SoundScheduler     */    ViewPlatformRetained viewPlatform = null;    /**     * The GraphicContext3D that we are currently unning in.     */    GraphicsContext3D graphicsCtx = null;    /**     * Maintain what reference to the last AuralAttributes found active     * was so that only if there was a change do we need to reset these     * parameters in the AudioDevice3D.     */    AuralAttributesRetained lastAA = null;    /**     * Since AuralAttribute gain scale factor is multipled with sound's     * initialGain scale factor, any change in AuralAttrib gain scale     * factor should force an update of all active sounds' gains     * Also, change in AuralAttributes should force a sound update     * even if no other sound field changes occurred.     */    boolean resetAA = true;    /**     * Audio Device     */    AudioDevice     audioDevice = null;    AudioDevice3D   audioDevice3D = null;    AudioDevice3DL2 audioDevice3DL2 = null;    int           totalChannels = 0;    /**     * Array of SoundScapeRetained nodes that intersect the viewPlatform     * This list is a subset of the soundscapes array, and is used when     * selecting the closest Soundscape.     * Maintained as an expandable array.     */    SoundscapeRetained[] intersectedSoundscapes = new SoundscapeRetained[32];    /**     * Array of Bounds nodes for the corresponding intersectedSoundscapes     * array.  This array is used when selecting the closest Soundscape.     * This list is used when selecting the closest Soundscape.     * Maintained as an expandable array.     */    Bounds[] intersectedRegions = new Bounds[32];    /**     * Reference to last processed region within run().     * Maintained to avoid re-transforming this bounds.     */    Bounds    region = null;    /**     * An array of prioritized sounds currently playing "live" sounds.     * This prioritized sound list is NO longer re-create instead sounds     * are insert, shuffled or removed as messages are processed.     */    // XXXX: (Enhancement) should have a seperate list for    //       background sound and a list for positional sounds    ArrayList prioritizedSounds = new ArrayList();    /**     * Current number of scene graph sound nodes in the universe     */    int  nRetainedSounds = -1;   // none calculated yet    /**     * Current number of immediate mode sound nodes in the universe     */    int  nImmedSounds = -1;      // none calculated yet    /**     * Current active (selected) attribute node in the sceneGraph     */    AuralAttributesRetained aaRetained = null;    // variables for processing transform messages    boolean transformMsg = false;    UpdateTargets targets = null;    /**     * Current active (selected) attribute node in the sceneGraph     */    AuralAttributesRetained aaImmed = null;    // Dirty flags for fields and parameters that are unique to the    // Sound Scheduler or the Audio Device    // Any listener (body) and/or view transform changes processed in    // CanvasViewCache force one of these flags to be set.    static final int EAR_POSITIONS_CHANGED         =  0x0001;    static final int EYE_POSITIONS_CHANGED         =  0x0002;    static final int IMAGE_PLATE_TO_VWORLD_CHANGED =  0x0004;    static final int HEAD_TO_VWORLD_CHANGED        =  0x0008;    static final int LISTENER_CHANGED              =  0x000F;// all of the above    private int        listenerUpdated = LISTENER_CHANGED;    /**     * Temporary flag that's denotes that a positional sound was processed     * in the current loop of renderChange().     */    private boolean    positionalSoundUpdated = false;    /**     * Temporary flag that's denotes that some field auralAttribute was changed     */    private boolean    auralAttribsChanged = true;  // force processing 1st x    private boolean     stallThread = false;    int lastEventReceived = WindowEvent.WINDOW_CLOSED;    /**     * Constructs a new SoundScheduler     */    SoundScheduler(VirtualUniverse u, View v) {	super(u, J3dThread.SOUND_SCHEDULER);	// Assertion check view & universe	if (v == null) {	    System.err.println("WARNING: SoundScheduler constructed with null view");	}	if (u == null) {	    System.err.println("WARNING: SoundScheduler constructed with null universe");	}	universe = u;	view = v;	reset();    }    // NOTE: processMessage only called with updatethread.active true    void processMessages(long referenceTime) {	J3dMessage[] messages = getMessages(referenceTime);	int nMsg = getNumMessage();	J3dMessage m;	int nSounds;	if (nMsg > 0) {	    for (int i=0; i < nMsg; i++) {		m = messages[i];		switch (m.type) {		case J3dMessage.INSERT_NODES:		    insertNodes(m);		    break;		case J3dMessage.REMOVE_NODES:		    removeNodes(m);		    break;		case J3dMessage.SOUND_ATTRIB_CHANGED:		    changeNodeAttrib(m);		    break;		case J3dMessage.SOUND_STATE_CHANGED:		    changeNodeState(m);		    break;		case J3dMessage.BOUNDINGLEAF_CHANGED:		    processBoundingLeafChanged(m);		    break;		case J3dMessage.SOUNDSCAPE_CHANGED:		    SoundscapeRetained ss = (SoundscapeRetained)m.args[0];		    if (universe.soundStructure.isSoundscapeScopedToView(ss, view)) {			auralAttribsChanged = true;			changeNodeAttrib(m);		    }		    break;		case J3dMessage.AURALATTRIBUTES_CHANGED:		    auralAttribsChanged = true;		    changeNodeAttrib(m);		    break;		case J3dMessage.MEDIA_CONTAINER_CHANGED:		    changeNodeAttrib(m);		    break;		case J3dMessage.TRANSFORM_CHANGED:		    transformMsg = true;		    auralAttribsChanged = true;		    break;		case J3dMessage.RENDER_IMMEDIATE:		    processImmediateNodes(m.args, referenceTime);		    break;		case J3dMessage.VIEWSPECIFICGROUP_CHANGED:		    processViewSpecificGroupChanged(m);		    break;		case J3dMessage.UPDATE_VIEW:		    if (debugFlag)			debugPrint(".processMessage() UPDATE_VIEW");		    // NOTE: can only rely on seeing UPDATE_VIEW when canvas [re]Created		    //      AND when view deactivated...		    // NOTE:		    //      temp work-around		    //      calling prioritizeSounds() wipes out old atom fields		    // QUESTION: prioritizedSound is NEVER empty - why if size is 0 can		    //      .isEmpty return anything but TRUE???		    //		    if (prioritizedSounds.isEmpty()) {			nSounds = prioritizeSounds();		    }		    break;		case J3dMessage.SWITCH_CHANGED:		    if (debugFlag)			debugPrint(".processMessage() " +				   "SWITCH_CHANGED ignored");		    break;		}  // switch		m.decRefcount();	    }  // for	    if (transformMsg) {		targets = universe.transformStructure.getTargetList();		updateTransformChange(targets, referenceTime);		transformMsg = false;		targets = null;	    }	    Arrays.fill(messages, 0, nMsg, null);	}	// Call renderChanges within try/catch so errors won't kill	// the SoundScheduler.	try {	    renderChanges();	}	catch (RuntimeException e) {	    System.err.println("Exception occurred " +			       "during Sound rendering:");	    e.printStackTrace();	}        catch (Error e) {            // Issue 264 - catch Error	    System.err.println("Error occurred " +			       "during Sound rendering:");	    e.printStackTrace();        }	// what if the user/app makes no change to scenegraph?	// must still re-render after retest for sound complete	// calculate which sound will finished first and set a	// wait time to this shortest time so that scheduler is	// re-entered to process sound complete.	long  waitTime = shortestTimeToFinish();	if (waitTime == 0L) {	    // come right back	    if (debugFlag)		debugPrint(".processMessage calls sendRunMessage " +			   "for immediate processing");	    VirtualUniverse.mc.sendRunMessage(universe,					      J3dThread.SOUND_SCHEDULER);	}	else if (waitTime > 0L) {	    // Use TimerThread to send message with sounds complete.	    // This uses waitForElapse time to sleep for at least the duration	    // returned by shortestTimeToFinish method.	    if (debugFlag)		debugPrint(".processMessage calls sendRunMessage " +			   "with wait time = " + waitTime );	    // QUESTION (ISSUE): even when this is set to a large time	    //     processMessage is reentered immediately.	    //     Why is timer thread not waiting??	    VirtualUniverse.mc.sendRunMessage(waitTime, view,					      J3dThread.SOUND_SCHEDULER);	}    }    void insertNodes(J3dMessage m) {	Object[] nodes = (Object[])m.args[0];	ArrayList viewScopedNodes = (ArrayList)m.args[3];	ArrayList scopedNodesViewList = (ArrayList)m.args[4];	Object node;	for (int i=0; i<nodes.length; i++) {	    node = (Object) nodes[i];	    if (node instanceof SoundRetained) {		nRetainedSounds++;		// insert sound node into sound scheduler's prioritized list		addSound((SoundRetained) node);	    }	    else if (node instanceof SoundscapeRetained) {		auralAttribsChanged = true;	    }	    else if (node instanceof AuralAttributesRetained) {		auralAttribsChanged = true;	    }	    else if (node instanceof ViewPlatformRetained) {		// XXXX: don't support multiple viewPlatforms per scheduler		/*		// useful for resetting VP ??		addViewPlatform((ViewPlatformRetained) node);		*/		if (debugFlag) {		    debugPrint(".insertNodes() viewPlatformRetained not supported yet");		}	    }	}	// 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) {			nRetainedSounds++;			// insert sound node into sound scheduler's prioritized list			addSound((SoundRetained) node);		    }		    else if (node instanceof SoundscapeRetained) {			auralAttribsChanged = true;		    }		}	    }	}    }    /**     * Add sound to sounds list.     */    void addSound(SoundRetained sound) {	if (sound == null)	    return;	if (debugFlag)	    debugPrint(".addSound()");	synchronized (prioritizedSounds) {	    addPrioritizedSound(sound);	}    } // end addSound    /**     * Node removed from tree     */    void removeNodes(J3dMessage m) {	Object[] nodes = (Object[])m.args[0];	ArrayList viewScopedNodes = (ArrayList)m.args[3];	ArrayList scopedNodesViewList = (ArrayList)m.args[4];	Object node;	for (int i=0; i<nodes.length; i++) {	    node = (Object) nodes[i];	    if (node instanceof SoundRetained) {		// sound is deactivated but NOT deleted		// incase sound is reattached// QUESTION: what's the difference in messages between really deleting//     a node and just deactivating it./*//// can't delete atom in case it's reactivitated//			nRetainedSounds--;			deleteSound((SoundRetained) node);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -