001: /*
002: * $RCSfile: AudioEngine3D.java,v $
003: *
004: * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions
008: * are met:
009: *
010: * - Redistribution of source code must retain the above copyright
011: * notice, this list of conditions and the following disclaimer.
012: *
013: * - Redistribution in binary form must reproduce the above copyright
014: * notice, this list of conditions and the following disclaimer in
015: * the documentation and/or other materials provided with the
016: * distribution.
017: *
018: * Neither the name of Sun Microsystems, Inc. or the names of
019: * contributors may be used to endorse or promote products derived
020: * from this software without specific prior written permission.
021: *
022: * This software is provided "AS IS," without a warranty of any
023: * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
024: * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
025: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
026: * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL
027: * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF
028: * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
029: * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR
030: * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL,
031: * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND
032: * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR
033: * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
034: * POSSIBILITY OF SUCH DAMAGES.
035: *
036: * You acknowledge that this software is not designed, licensed or
037: * intended for use in the design, construction, operation or
038: * maintenance of any nuclear facility.
039: *
040: * $Revision: 1.5 $
041: * $Date: 2007/02/09 17:20:02 $
042: * $State: Exp $
043: */
044:
045: package com.sun.j3d.audioengines;
046:
047: import javax.media.j3d.*;
048: import javax.vecmath.*;
049: import java.util.ArrayList;
050:
051: /**
052: * The AudioEngine3D Class defines an audio output device that generates
053: * sound 'image' from high-level sound parameters passed to it during
054: * scene graph.
055: *
056: * <P>
057: * The methods in this class are meant to be optionally overridden by an
058: * extended class. This extended class would provice device specific code.
059: *
060: * <P>
061: * Error checking on all parameters passed to these methods is already
062: * explicitly being done by the Java 3D core code that calls these methods.
063: *
064: * <p>
065: * NOTE: AudioEngine developers should not subclass this class directly.
066: * Subclass AudioEngine3DL2 instead.
067: */
068:
069: public abstract class AudioEngine3D extends AudioEngine implements
070: AudioDevice3D {
071: /*
072: * Identifiers of sample associated with sound source
073: * This array grows as the AudioDevice3D implementation requires it larger.
074: */
075: protected ArrayList samples = new ArrayList(64);
076:
077: /**
078: * Current View sound is being rendered
079: */
080: protected View currentView = (View) null;
081:
082: /*
083: * current Aural attribute Parameters
084: */
085: protected AuralParameters attribs = new AuralParameters();
086:
087: /**
088: * Construct a new AudioEngine with the specified PhysicalEnvironment.
089: * @param physicalEnvironment the physical environment object where we
090: * want access to this device.
091: */
092: public AudioEngine3D(PhysicalEnvironment physicalEnvironment) {
093: super (physicalEnvironment);
094: }
095:
096: /*
097: *
098: * Methods that affect AudioEngine3D fields that are NOT associated
099: * with a specific sound sample
100: *
101: */
102:
103: /**
104: * Save a reference to the current View object.
105: * @param reference to current view object
106: */
107: public void setView(View reference) {
108: currentView = reference;
109: return;
110: }
111:
112: /**
113: * Get reference to the current View object.
114: * @return reference to current view object
115: */
116: public View getView() {
117: return (currentView);
118: }
119:
120: /*
121: *
122: * Methods explicitly affect sound rendering and that require
123: * audio device specific methods that override this class.
124: *
125: */
126:
127: /**
128: * Prepare Sound in device.
129: * Makes sound assessible to device - in this case attempts to load sound
130: * Stores sound type and data.
131: * @param soundType denotes type of sound: Background, Point or Cone
132: * @param soundData descrition of sound source data
133: * @return index into sample vector of Sample object for sound
134: */
135: public int prepareSound(int soundType, MediaContainer soundData) {
136: // This method must be overridden by device specific implementation
137: return Sample.NULL_SAMPLE;
138: }
139:
140: /**
141: * Clear Sound.
142: * Removes/clears associated sound data with this sound source node
143: * @param index device specific reference number to device driver sample
144: */
145: public abstract void clearSound(int index);
146:
147: /**
148: * Set the transform for local to virtual world coordinate space
149: * @param index device specific reference number to device driver sample
150: * @param trans is a reference to virtual world composite transform
151: */
152: public void setVworldXfrm(int index, Transform3D trans) {
153: Sample sample = (Sample) getSample(index);
154: if (sample != null)
155: sample.vworldXfrm.set(trans);
156: return;
157: }
158:
159: /**
160: * Start sample playing on audio device
161: * @param index device specific reference number to device driver sample
162: * @return status: < 0 denotes an error
163: */
164: public abstract int startSample(int index);
165:
166: /**
167: * Stop sample playing on audio device
168: * @param index device specific reference number to device driver sample
169: * @return status: < 0 denotes an error
170: */
171: public abstract int stopSample(int index);
172:
173: /**
174: * Update sample.
175: * Implies that some parameters affecting rendering have been modified.
176: * @param index device specific reference number to device driver sample
177: */
178: // TODO: The update method exists on a TEMPORARY basis.
179: public abstract void updateSample(int index);
180:
181: /**
182: * Mute sample.
183: * @param index device specific reference number to device driver sample
184: */
185: public abstract void muteSample(int index);
186:
187: /**
188: * Unmute sample.
189: * @param index device specific reference number to device driver sample
190: */
191: public abstract void unmuteSample(int index);
192:
193: /**
194: * Pause sample.
195: * @param index device specific reference number to device driver sample
196: */
197: public abstract void pauseSample(int index);
198:
199: /**
200: * Unpause sample.
201: * @param index device specific reference number to device driver sample
202: */
203: public abstract void unpauseSample(int index);
204:
205: /*
206: *
207: * Methods that affect fields associated with the sound sample
208: * and that may cause implicit rendering.
209: *
210: */
211: /**
212: * Set gain scale factor applied to sample.
213: * @param index device specific reference number to device driver sample
214: * @param scaleFactor floating point multiplier applied to sample amplitude
215: */
216: public void setSampleGain(int index, float scaleFactor) {
217: Sample sample = (Sample) getSample(index);
218: if (sample != null)
219: sample.setGain(scaleFactor);
220: return;
221: }
222:
223: /**
224: * Set number of times sample is looped.
225: * @param index device specific reference number to device driver sample
226: * @param count number of times sample is repeated
227: */
228: public void setLoop(int index, int count) {
229: Sample sample = (Sample) getSample(index);
230: if (sample != null)
231: sample.setLoopCount(count);
232: return;
233: }
234:
235: /**
236: * Set location of sample.
237: * @param index device specific reference number to device driver sample
238: * @param position point location in virtual world coordinate of sample
239: */
240: public void setPosition(int index, Point3d position) {
241: Sample sample = (Sample) getSample(index);
242: if (sample != null)
243: sample.setPosition(position);
244: return;
245: }
246:
247: /* Set elliptical distance attenuation arrays applied to sample amplitude.
248: * @param index device specific reference number to device driver sample
249: * @param frontDistance defines an array of distance along the position axis
250: * thru which ellipses pass
251: * @param frontAttenuationScaleFactor gain scale factors
252: * @param backDistance defines an array of distance along the negative axis
253: * thru which ellipses pass
254: * @param backAttenuationScaleFactor gain scale factors
255: */
256: public void setDistanceGain(int index, double[] frontDistance,
257: float[] frontAttenuationScaleFactor, double[] backDistance,
258: float[] backAttenuationScaleFactor) {
259: Sample sample = (Sample) getSample(index);
260: if (sample != null)
261: sample.setDistanceGain(frontDistance,
262: frontAttenuationScaleFactor, backDistance,
263: backAttenuationScaleFactor);
264: return;
265: }
266:
267: /**
268: * Set direction vector of sample.
269: * @param index device specific reference number to device driver sample
270: * @param direction vector in virtual world coordinate.
271: */
272: public void setDirection(int index, Vector3d direction) {
273: Sample sample = (Sample) getSample(index);
274: if (sample != null)
275: sample.setDirection(direction);
276: return;
277: }
278:
279: /**
280: * Set angular attenuation arrays affecting angular amplitude attenuation
281: * and angular distance filtering.
282: * @param index device specific reference number to device driver sample
283: * @param filterType denotes type of filtering (on no filtering) applied
284: * to sample.
285: * @param angle array containing angular distances from sound axis
286: * @param attenuationScaleFactor array containing gain scale factor
287: * @param filterCutoff array containing filter cutoff frequencies.
288: * The filter values for each tuples can be set to Sound.NO_FILTER.
289: */
290: public void setAngularAttenuation(int index, int filterType,
291: double[] angle, float[] attenuationScaleFactor,
292: float[] filterCutoff) {
293: Sample sample = (Sample) getSample(index);
294: if (sample != null)
295: sample.setAngularAttenuation(filterType, angle,
296: attenuationScaleFactor, filterCutoff);
297: return;
298: }
299:
300: /**
301: * Set rolloff value for current aural attribute applied to all samples.
302: * @param rolloff scale factor applied to standard speed of sound.
303: */
304: public void setRolloff(float rolloff) {
305: attribs.rolloff = rolloff;
306: return;
307: }
308:
309: /**
310: * Set reverberation surface reflection coefficient value for current aural
311: * attribute applied to all samples.
312: * @param coefficient applied to amplitude of reverbation added at each
313: * iteration of reverb processing.
314: */
315: public void setReflectionCoefficient(float coefficient) {
316: attribs.reflectionCoefficient = coefficient;
317: return;
318: }
319:
320: /**
321: * Set reverberation delay time for current aural attribute applied to
322: * all samples.
323: * @param reverbDelay amount of time in millisecond between each
324: * iteration of reverb processing.
325: */
326: public void setReverbDelay(float reverbDelay) {
327: attribs.reverbDelay = reverbDelay;
328: return;
329: }
330:
331: /**
332: * Set reverberation order for current aural attribute applied to all
333: * samples.
334: * @param reverbOrder number of times reverb process loop is iterated.
335: */
336: public void setReverbOrder(int reverbOrder) {
337: attribs.reverbOrder = reverbOrder;
338: return;
339: }
340:
341: /**
342: * Set distance filter for current aural attribute applied to all samples.
343: * @param filterType denotes type of filtering (on no filtering) applied
344: * to all sample based on distance between listener and sound.
345: * @param dist is an attenuation array of distance and low-pass filter values.
346: */
347: public void setDistanceFilter(int filterType, double[] dist,
348: float[] filterCutoff) {
349: attribs.setDistanceFilter(filterType, dist, filterCutoff);
350: return;
351: }
352:
353: /**
354: * Set frequency scale factor for current aural attribute applied to all
355: * samples.
356: * @param scaleFactor frequency scale factor applied to samples normal
357: * playback rate.
358: */
359: public void setFrequencyScaleFactor(float scaleFactor) {
360: attribs.frequencyScaleFactor = scaleFactor;
361: return;
362: }
363:
364: /**
365: * Set velocity scale factor for current aural attribute applied to all
366: * samples when Doppler is calculated.
367: * @param scaleFactor scale factor applied to postional samples'
368: * listener-to-soundSource velocity.
369: * playback rate.
370: */
371: public void setVelocityScaleFactor(float scaleFactor) {
372: attribs.velocityScaleFactor = scaleFactor;
373: return;
374: }
375:
376: /**
377: * Get number of channels used by a particular sample on the audio device.
378: * @param index device specific reference number to device driver sample
379: * @return number of channels currently being used by this sample.
380: */
381: public int getNumberOfChannelsUsed(int index) {
382: // This method must be overridden by device specific implementation
383: Sample sample = (Sample) getSample(index);
384: if (sample != null)
385: return (sample.getNumberOfChannelsUsed());
386: else
387: return 0;
388: }
389:
390: /**
391: * Get number of channels that would be used by a particular sample on
392: * the audio device given the mute flag passed in as a parameter.
393: * @param index device specific reference number to device driver sample
394: * @param muteFlag denotes the mute state to assume while executing this
395: * query. This mute value does not have to match the current mute state
396: * of the sample.
397: * @return number of channels that would be used by this sample if it
398: * were playing.
399: */
400: public int getNumberOfChannelsUsed(int index, boolean muteFlag) {
401: // This method must be overridden by device specific implementation
402: Sample sample = (Sample) getSample(index);
403: if (sample != null)
404: return (sample.getNumberOfChannelsUsed());
405: else
406: return 0;
407: }
408:
409: /**
410: * Get length of time a sample would play if allowed to play to completion.
411: * @param index device specific reference number to device driver sample
412: * @return length of sample in milliseconds
413: */
414: public long getSampleDuration(int index) {
415: Sample sample = (Sample) getSample(index);
416: if (sample != null)
417: return (sample.getDuration());
418: else
419: return 0L;
420: }
421:
422: /**
423: * Get time this sample begun playing on the audio device.
424: * @param index device specific reference number to device driver sample
425: * @return system clock time sample started
426: */
427: public long getStartTime(int index) {
428: Sample sample = (Sample) getSample(index);
429: if (sample != null)
430: return (sample.getStartTime());
431: else
432: return 0L;
433: }
434:
435: /**
436: * Get reference to the array list of samples
437: * @return reference to samples list
438: * @deprecated unsafe to get reference to samples list with this method.
439: * It's better to directly reference samples list within a synchronized
440: * block which also contains calls to .getSample(index).
441: */
442: protected ArrayList getSampleList() {
443: return (samples);
444: }
445:
446: public int getSampleListSize() {
447: return (samples.size());
448: }
449:
450: /**
451: * Get specific sample from indexed sample list
452: * Checks for valid index before attempting to get sample from list.
453: * @param index device specific reference number to device driver sample
454: * @return reference to sample; returns null if index out of range.
455: *
456: * @since Java 3D 1.2.1
457: */
458: public Sample getSample(int index) {
459: synchronized (samples) {
460: if ((index >= 0) && (index < samples.size())) {
461: Sample sample = (Sample) samples.get(index);
462: return (sample);
463: } else
464: return null;
465: }
466: }
467:
468: /*
469: * Get reference to current aural attribute parameters associated with
470: * this audio device.
471: * @return reference to current aural attribute parameters
472: */
473: public AuralParameters getAuralParameters() {
474: return (attribs);
475: }
476: }
|