📄 jssample.java
字号:
/* * $RCSfile: JSSample.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. * * $Revision: 1.4 $ * $Date: 2007/02/09 17:20:03 $ * $State: Exp $ *//* * Java Sound Sample object * * IMPLEMENTATION NOTE: The JavaSoundMixer is incomplete and really needs * to be rewritten. */package com.sun.j3d.audioengines.javasound;import java.net.URL;import java.io.InputStream;import javax.media.j3d.*;import javax.sound.sampled.*;import com.sun.j3d.audioengines.*;/** * The Sample Class extended for Java Sound Mixer specific audio device. */class JSSample extends com.sun.j3d.audioengines.Sample{ /* * NOTE: for this device type there is exactly one sample associated * with each sound. */ /** * Sound Data Types * * Samples can be processed as streaming or buffered data. * Fully spatializing sound sources may require data to be buffered. * * Sound data specified as Streaming is not copied by the AudioDevice * driver implementation. It is up the application to ensure that * this data is continuously accessible during sound rendering. * Futhermore, full sound spatialization may not be possible, for * all AudioDevice implementations on unbuffered sound data. */ static final int STREAMING_AUDIO_DATA = 1; /** * Sound data specified as Buffered is copied by the AudioDevice * driver implementation. */ static final int BUFFERED_AUDIO_DATA = 2; /** * MIDI data * TODO: differentiate between STREAMING and BUFFERED MIDI data * right now all MIDI data is buffered */ static final int STREAMING_MIDI_DATA = 3; static final int BUFFERED_MIDI_DATA = 3; static final int UNSUPPORTED_DATA_TYPE = -1; static final int NULL_SAMPLE = -1; /** * sound data types: BUFFERED (cached) or STREAMING (non-cached) */ int dataType = BUFFERED_AUDIO_DATA; JSChannel channel = null; /** * Offset pointer within currently playing sample data */ long dataOffset = 0; /* * Maintain continuously playing silent sound sources. */ long timeDeactivated = 0; long positionDeactivated = 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 float rateRatio = 1.0f; float currentRateRatio = -1.0f; // last actual rate ratio send to device float targetRateRatio = -1.0f; boolean rampRateFlag = false; public JSSample() { super(); if (debugFlag) debugPrintln("JSSample constructor"); } // the only public methods are those declared in the audioengines // package as public /* * This excutes code necessary to set current fields to their current * correct values before JavaSoundMixer either start or updates the * sample thru calls to JSThread. */ public void render(int dirtyFlags, View view, AuralParameters attribs) { if (debugFlag) debugPrint("JSSample.render "); // if this is starting set gain, delay (for Pos), freq rate ... // TODO: NOT SURE - leaving this in for now float freqScaleFactor = attribs.frequencyScaleFactor; if (attribs != null) { if (freqScaleFactor <= 0.0f) { // TODO: Pause Sample } else rateRatio = currentRateRatio * freqScaleFactor; } else rateRatio = currentRateRatio; } /** * Clears/re-initialize fields associated with sample data for * this sound, * and frees any device specific data associated with this sample. */ public void clear() { super.clear(); if (debugFlag) debugPrintln("JSSample.clear() entered"); // TODO: unload sound data at device// null out samples element that points to this?// would this cause samples list size to shrink?// if sample elements are never freed then does this mean// a have a memory leak? dataType = UNSUPPORTED_DATA_TYPE; dataOffset = 0; timeDeactivated = 0; positionDeactivated = 0; sampleLength = 0; loopStartOffset = 0; loopLength = 0; attackLength = 0; releaseLength = 0; rateRatio = 1.0f; channel = null; if (debugFlag) debugPrintln("JSSample.clear() exited"); } // @return error true if error occurred boolean load(MediaContainer soundData) { /** * Get the AudioInputStream first. * MediaContiner passed to method assumed to be a clone of the * application node with the query capability bits set on. */ String path = soundData.getURLString(); URL url = soundData.getURLObject(); InputStream inputStream = soundData.getInputStream(); boolean cacheFlag = soundData.getCacheEnable(); AudioInputStream ais = null; DataLine dataLine = null; // TODO: How do we determine if the file is a MIDI file??? // for now set dataType to BUFFERED_ or STREAMING_AUDIO_DATA // used to test for ais instanceof AudioMidiInputStream || // ais instanceof AudioRmfInputStream ) // then set dataType = JSSample.BUFFERED_MIDI_DATA; // QUESTION: can non-cached MIDI files ever be supported ? /**************** // TODO: when we have a way to determine data type use code below if (dataType==UNSUPPORTED_DATA_TYPE OR error_occurred) clearSound(index); if (debugFlag) debugPrintln("JavaSoundMixer.prepareSound get dataType failed"); return true; } *****************/ // ...for now just check cacheFlag if (cacheFlag) dataType = BUFFERED_AUDIO_DATA; else dataType = STREAMING_AUDIO_DATA; if ((url == null) && (inputStream == null) && (path == null)) { if (debugFlag) debugPrint("JavaSoundMixer.loadSound null data - return error"); return true; } // get ais if (path != null) { // generate url from string, and pass url to driver if (debugFlag) { debugPrint("JavaSoundMixer.loadSound with path = " + path); } try { url = new URL(path); } catch (Exception e) { // do not throw an exception while rendering return true; } } // get DataLine channel based on data type if (dataType == BUFFERED_AUDIO_DATA) { if (debugFlag) debugPrintln("JSSample.load dataType = BUFFERED "); channel = new JSClip(); if (debugFlag) debugPrintln(" calls JSClip.initAudioInputStream"); if (url != null) ais = channel.initAudioInputStream(url, cacheFlag); else if (inputStream != null) ais = channel.initAudioInputStream(inputStream, cacheFlag); if (ais == null) { if (debugFlag) debugPrintln("JavaSoundMixer.prepareSound " + "initAudioInputStream() failed"); return true; } if (debugFlag) debugPrintln(" calls JSClip.initDataLine"); dataLine = channel.initDataLine(ais); } else if (dataType == STREAMING_AUDIO_DATA) { if (debugFlag) debugPrintln("JSSample.load dataType = STREAMING "); channel = new JSStream(); if (debugFlag) debugPrintln(" calls JSStream.initAudioInputStream"); if (url != null) ais = channel.initAudioInputStream(url, cacheFlag); else if (inputStream != null) ais = channel.initAudioInputStream(inputStream, cacheFlag); if (ais == null) { if (debugFlag) debugPrintln("JavaSoundMixer.prepareSound " + "initAudioInputStream() failed"); return true; } if (debugFlag) debugPrintln(" calls JSStream.initDataLine"); dataLine = channel.initDataLine(ais); } else { if (debugFlag) debugPrintln("JSSample.load doesn't support MIDI yet"); } if (dataLine == null) { if (debugFlag) debugPrint("JSSample.load initDataLine failed "); channel = null; return true; } duration = channel.getDuration(); if (debugFlag) debugPrint("JSSample.load channel duration = " + duration); /* * Since no error occurred while loading, save all the characteristics * for the sound in the sample. */ setDirtyFlags(0xFFFF); setSoundType(soundType); setSoundData(soundData); if (debugFlag) debugPrintln("JSSample.load returned without error"); return false; } void reset() { if (debugFlag) debugPrint("JSSample.reset() exit"); rateRatio = 1.0f; }// TODO: NEED methods for any field accessed by both JSThread and // JavaSoundMixer so that we can make these MT safe?? /* * Process request for Filtering fields */ boolean getFilterFlag() { return false; } float getFilterFreq() { return -1.0f; } void setCurrentRateRatio(float ratio) { currentRateRatio = ratio; } float getCurrentRateRatio() { return currentRateRatio; } void setTargetRateRatio(float ratio) { targetRateRatio = ratio; } float getTargetRateRatio() { return targetRateRatio; } void setRampRateFlag(boolean flag) { rampRateFlag = flag; } boolean getRampRateFlag() { return rampRateFlag; } void setDataType(int type) { dataType = type; } int getDataType() { return dataType; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -