Source Code Cross Referenced for JavaSoundMixer.java in  » 6.0-JDK-Modules » java-3d » com » sun » j3d » audioengines » javasound » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » java 3d » com.sun.j3d.audioengines.javasound 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * $RCSfile: JavaSoundMixer.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.4 $
041:         * $Date: 2007/02/09 17:20:04 $
042:         * $State: Exp $
043:         */
044:
045:        /*
046:         * Audio device driver using Java Sound Mixer Engine.
047:         *
048:         * IMPLEMENTATION NOTE: The JavaSoundMixer is incomplete and really needs
049:         * to be rewritten.
050:         */
051:
052:        package com.sun.j3d.audioengines.javasound;
053:
054:        import java.net.URL;
055:        import java.io.InputStream;
056:        import javax.vecmath.*;
057:        import javax.media.j3d.*;
058:        import com.sun.j3d.audioengines.*;
059:        import java.util.ArrayList;
060:        import java.lang.Thread;
061:
062:        /**
063:         * The JavaSoundMixer Class defines an audio output device that accesses
064:         * JavaSound functionality stream data.
065:         */
066:        public class JavaSoundMixer extends AudioEngine3DL2 {
067:
068:            // Debug print flags and methods
069:            static final boolean debugFlag = false;
070:            static final boolean internalErrors = false;
071:
072:            void debugPrint(String message) {
073:                if (debugFlag)
074:                    System.out.println(message);
075:            }
076:
077:            void debugPrintln(String message) {
078:                if (debugFlag)
079:                    System.out.println(message);
080:            }
081:
082:            // Determines method to call for added or setting sound into ArrayList
083:            static final int ADD_TO_LIST = 1;
084:            static final int SET_INTO_LIST = 2;
085:
086:            // current Aural Parameters = Aural Attributes from core + JavaSound
087:            // specific fields, including reverberation parameters.
088:            JSAuralParameters auralParams = null;
089:
090:            // thread for dynamically changing audio parameters such as volume
091:            // and sample rate.
092:            JSThread thread = null;
093:
094:            /*
095:             * new fields in extended class
096:             */
097:            protected float deviceGain = 1.0f;
098:
099:            protected static final int NOT_PAUSED = 0;
100:            protected static final int PAUSE_PENDING = 1;
101:            protected static final int PAUSED = 2;
102:            protected static final int RESUME_PENDING = 3;
103:            protected int pause = NOT_PAUSED;
104:
105:            /*
106:             * Construct a new JavaSoundMixer with the specified P.E.
107:             * @param physicalEnvironment the physical environment object where we
108:             * want access to this device.
109:             */
110:            public JavaSoundMixer(PhysicalEnvironment physicalEnvironment) {
111:                super (physicalEnvironment);
112:                thread = new JSThread(Thread.currentThread().getThreadGroup(),
113:                        this );
114:            }
115:
116:            /**
117:             * Query total number of channels available for sound rendering
118:             * for this audio device.
119:             * Overridden method from AudioEngine.
120:             * @return number of maximum voices play simultaneously on JavaSound Mixer.
121:             */
122:            public int getTotalChannels() {
123:                if (thread != null)
124:                    return thread.getTotalChannels();
125:                else
126:                    return 32;
127:            }
128:
129:            /**
130:             * Code to initialize the device
131:             * New interface to mixer/engine specific methods 
132:             * @return flag: true is initialized sucessfully, false if error
133:             */
134:            public boolean initialize() {
135:                if (thread == null) {
136:                    return false;
137:                }
138:                // init JavaSound dynamic thread
139:                thread.initialize();
140:                auralParams = new JSAuralParameters();
141:                if (debugFlag)
142:                    debugPrintln("JavaSoundMixer: JSStream.initialize returned true");
143:                return true;
144:            }
145:
146:            /**
147:             * Code to close the device.
148:             * New interface to mixer/engine specific methods 
149:             * @return flag: true is closed sucessfully, false if error
150:             */
151:            public boolean close() {
152:                if (thread == null)
153:                    return false;
154:                if (thread.close()) {
155:                    if (debugFlag)
156:                        debugPrintln("JavaSoundMixer: JSStream.close returned true");
157:                    return true;
158:                } else {
159:                    if (debugFlag)
160:                        debugPrintln("JavaSoundMixer: JSStream.close returned false");
161:                    return false;
162:                }
163:            }
164:
165:            /**
166:             * Code to load sound data into a channel of device mixer.
167:             * Load sound as one or mores sample into the Java Sound Mixer:
168:             *   a) as either a STREAM or CLIP based on whether cached is enabled
169:             *   b) positional and directional sounds use three samples per
170:             *      sound
171:             * Overriden method from AudioEngine3D.
172:             *
173:             * Sound type determines if this is a Background, Point or Cone
174:             * sound source and thus the JSXxxxSample object type
175:             * Call JSXxxxxSample.loadSample()
176:             * If no error
177:             *     Get the next free index in the samples list.
178:             *     Store a reference to JSXxxxSample object in samples list.
179:             * @return index to the sample in samples list.
180:             */
181:            public int prepareSound(int soundType, MediaContainer soundData) {
182:                int index = JSSample.NULL_SAMPLE;
183:                int methodType = ADD_TO_LIST;
184:                if (soundData == null)
185:                    return JSSample.NULL_SAMPLE;
186:                synchronized (samples) {
187:                    // for now force to just add to end of samples list
188:                    int samplesSize = samples.size();
189:                    index = samplesSize;
190:                    samples.ensureCapacity(index + 1);
191:                    boolean error = false;
192:
193:                    if (soundType == AudioDevice3D.CONE_SOUND) {
194:                        if (debugFlag)
195:                            debugPrintln("JavaSoundMixer.prepareSound type=CONE");
196:                        JSDirectionalSample dirSample = new JSDirectionalSample();
197:                        error = dirSample.load(soundData);
198:                        if (error)
199:                            return JSSample.NULL_SAMPLE;
200:                        if (methodType == SET_INTO_LIST)
201:                            samples.set(index, dirSample);
202:                        else
203:                            samples.add(index, dirSample);
204:                        /*
205:                         * Since no error occurred while loading, save all the
206:                         * characterstics for the sound in the sample.
207:                         */
208:                        dirSample.setDirtyFlags(0xFFFF);
209:                        dirSample.setSoundType(soundType);
210:                        dirSample.setSoundData(soundData);
211:
212:                    } else if (soundType == AudioDevice3D.POINT_SOUND) {
213:                        if (debugFlag)
214:                            debugPrintln("JavaSoundMixer.prepareSound type=POINT");
215:                        JSPositionalSample posSample = new JSPositionalSample();
216:                        error = posSample.load(soundData);
217:                        if (error)
218:                            return JSSample.NULL_SAMPLE;
219:                        if (methodType == SET_INTO_LIST)
220:                            samples.set(index, posSample);
221:                        else
222:                            samples.add(index, posSample);
223:                        posSample.setDirtyFlags(0xFFFF);
224:                        posSample.setSoundType(soundType);
225:                        posSample.setSoundData(soundData);
226:                    } else { // soundType == AudioDevice3D.BACKGROUND_SOUND
227:                        if (debugFlag)
228:                            debugPrintln("JavaSoundMixer.prepareSound type=BACKGROUND");
229:                        JSSample sample = null;
230:                        sample = new JSSample();
231:                        error = sample.load(soundData);
232:                        if (error)
233:                            return JSSample.NULL_SAMPLE;
234:                        if (methodType == SET_INTO_LIST)
235:                            samples.set(index, sample);
236:                        else
237:                            samples.add(index, sample);
238:                        sample.setDirtyFlags(0xFFFF);
239:                        sample.setSoundType(soundType);
240:                        sample.setSoundData(soundData);
241:                    }
242:                }
243:
244:                if (debugFlag) {
245:                    debugPrint("               prepareSound type = "
246:                            + soundType);
247:                    debugPrintln("JavaSoundMixer.prepareSound returned "
248:                            + index);
249:                }
250:                return index;
251:            }
252:
253:            /**
254:             * Clears the fields associated with sample data for this sound.
255:             * Overriden method from AudioEngine3D.
256:             */
257:            public void clearSound(int index) {
258:                // TODO: call JSXXXX clear method
259:                JSSample sample = null;
260:                if ((sample = (JSSample) getSample(index)) == null)
261:                    return;
262:                sample.clear();
263:                synchronized (samples) {
264:                    samples.set(index, null);
265:                }
266:            }
267:
268:            /**
269:             * Save a reference to the local to virtual world coordinate space
270:             * Overriden method from AudioEngine3D.
271:             */
272:            public void setVworldXfrm(int index, Transform3D trans) {
273:                if (debugFlag)
274:                    debugPrintln("JavaSoundMixer: setVworldXfrm for index "
275:                            + index);
276:                super .setVworldXfrm(index, trans);
277:                if (debugFlag) {
278:                    double[] matrix = new double[16];
279:                    trans.get(matrix);
280:                    debugPrintln("JavaSoundMixer     column-major transform ");
281:                    debugPrintln("JavaSoundMixer         " + matrix[0] + ", "
282:                            + matrix[1] + ", " + matrix[2] + ", " + matrix[3]);
283:                    debugPrintln("JavaSoundMixer         " + matrix[4] + ", "
284:                            + matrix[5] + ", " + matrix[6] + ", " + matrix[7]);
285:                    debugPrintln("JavaSoundMixer         " + matrix[8] + ", "
286:                            + matrix[9] + ", " + matrix[10] + ", " + matrix[11]);
287:                    debugPrintln("JavaSoundMixer         " + matrix[12] + ", "
288:                            + matrix[13] + ", " + matrix[14] + ", "
289:                            + matrix[15]);
290:                }
291:                JSSample sample = null;
292:                if ((sample = (JSSample) getSample(index)) == null)
293:                    return;
294:                int soundType = sample.getSoundType();
295:
296:                if (soundType == AudioDevice3D.CONE_SOUND) {
297:                    JSDirectionalSample dirSample = null;
298:                    if ((dirSample = (JSDirectionalSample) getSample(index)) == null)
299:                        return;
300:                    dirSample.setXformedDirection();
301:                    dirSample.setXformedPosition();
302:                    // flag that VirtualWorld transform set
303:                    dirSample.setVWrldXfrmFlag(true);
304:                } else if (soundType == AudioDevice3D.POINT_SOUND) {
305:                    JSPositionalSample posSample = null;
306:                    if ((posSample = (JSPositionalSample) getSample(index)) == null)
307:                        return;
308:                    posSample.setXformedPosition();
309:                    // flag that VirtualWorld transform set
310:                    posSample.setVWrldXfrmFlag(true);
311:                }
312:                return;
313:            }
314:
315:            /*
316:             * Overriden method from AudioEngine3D.
317:             */
318:            public void setPosition(int index, Point3d position) {
319:                if (debugFlag)
320:                    debugPrintln("JavaSoundMixer: setPosition for index "
321:                            + index);
322:                super .setPosition(index, position);
323:                JSPositionalSample posSample = null;
324:                if ((posSample = (JSPositionalSample) getSample(index)) == null)
325:                    return;
326:                int soundType = posSample.getSoundType();
327:                if ((soundType == AudioDevice3D.POINT_SOUND)
328:                        || (soundType == AudioDevice3D.CONE_SOUND)) {
329:                    posSample.setXformedPosition();
330:                }
331:                return;
332:            }
333:
334:            /*     
335:             * Overriden method from AudioEngine3D.
336:             */
337:            public void setDirection(int index, Vector3d direction) {
338:                if (debugFlag)
339:                    debugPrintln("JavaSoundMixer: setDirection for index "
340:                            + index);
341:                super .setDirection(index, direction);
342:                JSDirectionalSample dirSample = null;
343:                if ((dirSample = (JSDirectionalSample) getSample(index)) == null)
344:                    return;
345:                int soundType = dirSample.getSoundType();
346:                if (soundType == AudioDevice3D.CONE_SOUND) {
347:                    dirSample.setXformedDirection();
348:                }
349:                return;
350:            }
351:
352:            /*     
353:             * Overriden method from AudioEngine3D.
354:             */
355:            public void setReflectionCoefficient(float coefficient) {
356:                super .setReflectionCoefficient(coefficient);
357:                auralParams.reverbDirty |= JSAuralParameters.REFLECTION_COEFF_CHANGED;
358:                return;
359:            }
360:
361:            /*     
362:             * Overriden method from AudioEngine3D.
363:             */
364:            public void setReverbDelay(float reverbDelay) {
365:                super .setReverbDelay(reverbDelay);
366:                auralParams.reverbDirty |= JSAuralParameters.REVERB_DELAY_CHANGED;
367:                return;
368:            }
369:
370:            /*     
371:             * Overriden method from AudioEngine3D.
372:             */
373:            public void setReverbOrder(int reverbOrder) {
374:                super .setReverbOrder(reverbOrder);
375:                auralParams.reverbDirty |= JSAuralParameters.REVERB_ORDER_CHANGED;
376:                return;
377:            }
378:
379:            /*
380:             * QUESTION: if this is used, for now, exclusively, to start a Background
381:             *    or any single sampled Sounds, why are there if-else cases to handle
382:             *    Point and Cone sounds??
383:             *
384:             * For now background sounds are not reverberated
385:             * 
386:             * Overriden method from AudioEngine3D.
387:             */
388:            public int startSample(int index) {
389:                // TODO: Rewrite this function
390:
391:                if (debugFlag)
392:                    debugPrintln("JavaSoundMixer: STARTSample for index "
393:                            + index);
394:
395:                JSSample sample = null;
396:                if (((sample = (JSSample) getSample(index)) == null)
397:                        || thread == null)
398:                    return JSSample.NULL_SAMPLE;
399:
400:                int soundType = sample.getSoundType();
401:                boolean muted = sample.getMuteFlag();
402:                if (muted) {
403:                    if (debugFlag)
404:                        debugPrintln("                            MUTEd start");
405:                    thread.muteSample(sample);
406:                    if (soundType != AudioDevice3D.BACKGROUND_SOUND)
407:                        setFilter(index, false, Sound.NO_FILTER);
408:                } else {
409:                    sample.render(sample.getDirtyFlags(), getView(),
410:                            auralParams);
411:                    this .scaleSampleRate(index, sample.rateRatio);
412:                    // filtering
413:                    if (soundType != AudioDevice3D.BACKGROUND_SOUND)
414:                        setFilter(index, sample.getFilterFlag(), sample
415:                                .getFilterFreq());
416:                }
417:
418:                boolean startSuccessful;
419:                startSuccessful = thread.startSample(sample);
420:
421:                sample.channel.startSample(sample.getLoopCount(), sample
422:                        .getGain(), 0);
423:
424:                if (!startSuccessful) {
425:                    if (internalErrors)
426:                        debugPrintln("JavaSoundMixer: Internal Error startSample for index "
427:                                + index + " failed");
428:                    return JSSample.NULL_SAMPLE;
429:                } else {
430:                    if (debugFlag)
431:                        debugPrintln("                startSample worked, "
432:                                + "returning " + startSuccessful);
433:                    // NOTE: Set AuralParameters AFTER sound started 
434:                    // Setting AuralParameters before you start sound doesn't work
435:                    if (!muted) {
436:                        if (auralParams.reverbDirty > 0) {
437:                            if (debugFlag) {
438:                                debugPrintln("startSample: reverb settings are:");
439:                                debugPrintln("    coeff = "
440:                                        + auralParams.reflectionCoefficient
441:                                        + ", delay = "
442:                                        + auralParams.reverbDelay
443:                                        + ", order = "
444:                                        + auralParams.reverbOrder);
445:                            }
446:                            float delayTime = auralParams.reverbDelay
447:                                    * auralParams.rolloff;
448:                            calcReverb(sample);
449:                        }
450:                        // NOTE: it apprears that reverb has to be reset in
451:                        // JavaSound engine when sound re-started??
452:                        // force reset of reverb parameters when sound is started
453:                        setReverb(sample);
454:                    }
455:                    return index;
456:                }
457:            }
458:
459:            /*     
460:             * Overriden method from AudioEngine3D.
461:             */
462:            public int stopSample(int index) {
463:                // TODO: Rewrite this function
464:
465:                if (debugFlag)
466:                    debugPrintln("JavaSoundMixer: STOPSample for index "
467:                            + index);
468:                JSSample sample = null;
469:                if ((sample = (JSSample) getSample(index)) == null)
470:                    return -1;
471:
472:                int dataType = sample.getDataType();
473:                int soundType = sample.getSoundType();
474:
475:                boolean stopSuccessful = true;
476:                stopSuccessful = thread.stopSample(sample);
477:
478:                sample.channel.stopSample();
479:
480:                if (!stopSuccessful) {
481:                    if (internalErrors)
482:                        debugPrintln("JavaSoundMixer: Internal Error stopSample(s) for index "
483:                                + index + " failed");
484:                    return -1;
485:                } else {
486:                    // set fields in sample to reset for future start
487:                    sample.reset();
488:                    if (debugFlag)
489:                        debugPrintln("JavaSoundMixer: stopSample for index "
490:                                + index + " worked, returning "
491:                                + stopSuccessful);
492:                    return 0;
493:                }
494:            }
495:
496:            /*     
497:             * Overriden method from AudioEngine3D.
498:             */
499:            public void pauseSample(int index) {
500:                if (debugFlag)
501:                    debugPrintln("JavaSoundMixer: PAUSESample for index "
502:                            + index);
503:                JSSample sample = null;
504:                if ((sample = (JSSample) getSample(index)) == null)
505:                    return;
506:                // check thread != null
507:                thread.pauseSample(sample);
508:            }
509:
510:            /*     
511:             * Overriden method from AudioEngine3D.
512:             */
513:            public void unpauseSample(int index) {
514:                if (debugFlag)
515:                    debugPrintln("JavaSoundMixer: UNPAUSESample for index "
516:                            + index);
517:                JSSample sample = null;
518:                if ((sample = (JSSample) getSample(index)) == null)
519:                    return;
520:                thread.unpauseSample(sample);
521:            }
522:
523:            /*     
524:             * Force thread to update sample.
525:             * Overriden method from AudioEngine3D.
526:             */
527:
528:            public void updateSample(int index) {
529:                if (debugFlag)
530:                    debugPrintln("JavaSoundMixer: UPDATESample for index "
531:                            + index);
532:                JSSample sample = null;
533:                if (((sample = (JSSample) getSample(index)) == null)
534:                        || thread == null)
535:                    return;
536:
537:                int soundType = sample.getSoundType();
538:                boolean muted = sample.getMuteFlag();
539:
540:                if (muted) {
541:                    if (soundType != AudioDevice3D.BACKGROUND_SOUND)
542:                        setFilter(index, false, Sound.NO_FILTER);
543:                    thread.muteSample(sample);
544:                    if (debugFlag)
545:                        debugPrintln("   Mute during update");
546:                } else {
547:                    // If reverb parameters changed resend to audio device
548:                    if (auralParams.reverbDirty > 0) {
549:                        if (debugFlag) {
550:                            debugPrintln("updateSample: reverb settings are:");
551:                            debugPrintln("    coeff = "
552:                                    + auralParams.reflectionCoefficient
553:                                    + ", delay = " + auralParams.reverbDelay
554:                                    + ", order = " + auralParams.reverbOrder);
555:                        }
556:                        float delayTime = auralParams.reverbDelay
557:                                * auralParams.rolloff;
558:                        calcReverb(sample);
559:                    }
560:                    // TODO: Only re-set reverb if values different
561:                    // For now force reset to ensure that reverb is currently correct
562:                    setReverb(sample); // ensure reverb is current/correct
563:
564:                    // TODO: For now sum left & rightGains for reverb gain
565:                    float reverbGain = 0.0f;
566:                    if (!muted && auralParams.reverbFlag) {
567:                        reverbGain = sample.getGain()
568:                                * auralParams.reflectionCoefficient;
569:                    }
570:
571:                    sample.render(sample.getDirtyFlags(), getView(),
572:                            auralParams);
573:
574:                    // filtering
575:                    if (soundType != AudioDevice3D.BACKGROUND_SOUND)
576:                        setFilter(index, sample.getFilterFlag(), sample
577:                                .getFilterFreq());
578:                    thread.setSampleGain(sample, auralParams);
579:                    thread.setSampleRate(sample, auralParams);
580:                    thread.setSampleDelay(sample, auralParams);
581:                }
582:                return;
583:            }
584:
585:            /*     
586:             * Overriden method from AudioEngine3D.
587:             */
588:            public void muteSample(int index) {
589:                JSSample sample = null;
590:                if ((sample = (JSSample) getSample(index)) == null)
591:                    return;
592:
593:                if (debugFlag)
594:                    debugPrintln("JavaSoundMixer: muteSample");
595:                sample.setMuteFlag(true);
596:                thread.muteSample(sample);
597:                return;
598:            }
599:
600:            /*     
601:             * Overriden method from AudioEngine3D.
602:             */
603:            public void unmuteSample(int index) {
604:                JSSample sample = null;
605:                if ((sample = (JSSample) getSample(index)) == null)
606:                    return;
607:
608:                if (debugFlag)
609:                    debugPrintln("JavaSoundMixer: unmuteSample");
610:                sample.setMuteFlag(false);
611:
612:                // since while mute the reverb type and state was not updated...
613:                // Reverb has to be recalculated when sound is unmuted .
614:                auralParams.reverbDirty = 0xFFFF; // force an update of reverb params
615:                sample.setDirtyFlags(0xFFFF); // heavy weight forcing of gain/delay update
616:
617:                // TODO: force an update of ALL parameters that could have changed
618:                // while muting disabled...
619:
620:                thread.unmuteSample(sample);
621:                return;
622:            }
623:
624:            /*     
625:             * Overriden method from AudioEngine3D.
626:             */
627:            public long getSampleDuration(int index) {
628:                JSSample sample = null;
629:                if ((sample = (JSSample) getSample(index)) == null)
630:                    return Sample.DURATION_UNKNOWN;
631:                long duration;
632:
633:                if (sample != null)
634:                    duration = sample.getDuration();
635:                else
636:                    duration = Sample.DURATION_UNKNOWN;
637:                if (debugFlag)
638:                    debugPrintln("                return duration " + duration);
639:                return duration;
640:            }
641:
642:            /*     
643:             * Overriden method from AudioEngine3D.
644:             */
645:            public int getNumberOfChannelsUsed(int index) {
646:                /*
647:                 * Calls same method with different signature containing the
648:                 * sample's mute flag passed as the 2nd parameter.
649:                 */
650:                JSSample sample = null;
651:                if ((sample = (JSSample) getSample(index)) == null)
652:                    return 0;
653:                else
654:                    return getNumberOfChannelsUsed(index, sample.getMuteFlag());
655:            }
656:
657:            /**
658:             * Overriden method from AudioEngine3D.
659:             */
660:            public int getNumberOfChannelsUsed(int index, boolean muted) {
661:                /*
662:                 * The JavaSoundMixer implementation uses THREE channels to render
663:                 * the stereo image of each Point and Cone Sounds:
664:                 *   Two for rendering the right and left portions of the rendered
665:                 *   spatialized sound image - panned hard right or left respectively.
666:                 * This implementation uses one channel to render Background sounds
667:                 * whether the sample is mono or stereo.
668:                 *
669:                 * TODO: When muted is implemented, that flag should be check
670:                 * so that zero is returned.
671:                 */
672:                JSSample sample = null;
673:                if ((sample = (JSSample) getSample(index)) == null)
674:                    return 0;
675:
676:                int soundType = sample.getSoundType();
677:                int dataType = sample.getDataType();
678:
679:                // TODO: for now positional Midi sound used only 1 sample
680:                if (dataType == JSSample.STREAMING_MIDI_DATA
681:                        || dataType == JSSample.BUFFERED_MIDI_DATA)
682:                    return 1;
683:
684:                if (soundType == BACKGROUND_SOUND)
685:                    return 1;
686:                else
687:                    // for Point and Cone sounds
688:                    return 3;
689:            }
690:
691:            /*     
692:             * Overriden method from AudioEngine3D.
693:             */
694:            public long getStartTime(int index) {
695:                JSSample sample = null;
696:                if ((sample = (JSSample) getSample(index)) == null)
697:                    return 0L;
698:                if (sample.channel == null)
699:                    return 0L;
700:                return (long) sample.channel.startTime;
701:            }
702:
703:            /*
704:             * Methods called during rendering
705:             */
706:            void scaleSampleRate(int index, float scaleFactor) {
707:                if (debugFlag)
708:                    debugPrintln("JavaSoundMixer: scaleSampleRate index "
709:                            + index + ", scale factor = " + scaleFactor);
710:                JSSample sample = null;
711:                if ((sample = (JSSample) getSample(index)) == null
712:                        || thread == null)
713:                    return;
714:                int dataType = sample.getDataType();
715:                if (debugFlag)
716:                    debugPrintln(" scaleSampleRate.dataType = " + dataType
717:                            + "using sample " + sample + " from samples["
718:                            + index + "]");
719:                int soundType = sample.getSoundType();
720:
721:                if (dataType == JSSample.STREAMING_AUDIO_DATA
722:                        || dataType == JSSample.BUFFERED_AUDIO_DATA) {
723:                    thread.setSampleRate(sample, scaleFactor);
724:                    /**********
725:                    // TODO:
726:                    if (soundType != AudioDevice3D.BACKGROUND_SOUND)  {
727:                        thread.setSampleRate( ((JSPositionalSample)sample).getSecondIndex(),
728:                              scaleFactor);
729:                        thread.setSampleRate(((JSPositionalSample)sample).getReverbIndex(),
730:                              scaleFactor);
731:                    }
732:                     **********/
733:                } else if (dataType == JSSample.STREAMING_MIDI_DATA
734:                        || dataType == JSSample.BUFFERED_MIDI_DATA) {
735:                    thread.setSampleRate(sample, scaleFactor);
736:                    /**********
737:                    if (soundType != AudioDevice3D.BACKGROUND_SOUND)  {
738:                        thread.setSampleRate(((JSPositionalSample)sample).getSecondIndex(),
739:                            scaleFactor);
740:                        thread.setSampleRate(((JSPositionalSample)sample).getReverbIndex(),
741:                            scaleFactor);
742:                    }
743:                     **********/
744:                } else {
745:                    if (internalErrors)
746:                        debugPrintln("JavaSoundMixer: Internal Error scaleSampleRate dataType "
747:                                + dataType + " invalid");
748:                }
749:            }
750:
751:            /*
752:             * Methods called during rendering
753:             */
754:            void calcReverb(JSSample sample) {
755:                /*
756:                 * Java Sound reverb parameters are a subset of Java 3D parameters
757:                 */
758:                int dataType = sample.getDataType();
759:                int soundType = sample.getSoundType();
760:                float decay = auralParams.decayTime;
761:                float delay = auralParams.reverbDelay * auralParams.rolloff;
762:                float reflection = auralParams.reflectionCoefficient;
763:                int order = auralParams.reverbOrder;
764:                /*
765:                 * Remember Coeff change is choosen over Order change if BOTH made
766:                 * otherwise the last one changed take precidence.
767:                 */
768:                if (auralParams.reflectionCoefficient == 0.0f
769:                        || auralParams.reverbCoefficient == 0.0f)
770:                    auralParams.reverbFlag = false;
771:                else {
772:                    auralParams.reverbFlag = true;
773:                    if (order > 0) {
774:                        // clamp reverb decay time to order*delay
775:                        float clampedTime = order * delay;
776:                        if (clampedTime < decay)
777:                            decay = clampedTime;
778:                    }
779:                    if (delay < 100.0f) {
780:                        // "small" reverberant space
781:                        if (decay <= 1500.0f)
782:                            auralParams.reverbType = 2;
783:                        else
784:                            auralParams.reverbType = 4;
785:                    } else if (delay < 500.0f) {
786:                        // "medium" reverberant space
787:                        if (decay <= 1500.0f)
788:                            auralParams.reverbType = 3;
789:                        else
790:                            auralParams.reverbType = 6;
791:                    } else { // delay >= 500.0f
792:                        // "large" reverberant space
793:                        if (decay <= 1500.0f)
794:                            auralParams.reverbType = 6;
795:                        else
796:                            auralParams.reverbType = 5;
797:                    }
798:                }
799:
800:                if (debugFlag)
801:                    debugPrintln("JavaSoundMixer: setReverb for " + sample
802:                            + ", type = " + auralParams.reverbType
803:                            + ", flag = " + auralParams.reverbFlag);
804:
805:                auralParams.reverbDirty = 0; // clear the attribute reverb dirty flags
806:            }
807:
808:            /*
809:             * Interal method for setting reverb parameters called during rendering.
810:             * This not called by SoundScheduler.
811:             */
812:            void setReverb(JSSample sample) {
813:                /*
814:                 * Only third sample of multisample sounds has reverb parameters set.
815:                 * For now, only positional and directional sounds are reverberated.
816:                 */
817:                int soundType = sample.getSoundType();
818:                int dataType = sample.getDataType();
819:
820:                // QUESTION: Should reverb be applied to background sounds?
821:                if ((soundType == AudioDevice3D.CONE_SOUND)
822:                        || (soundType == AudioDevice3D.POINT_SOUND)) {
823:                    if (debugFlag)
824:                        debugPrintln("setReverb called with type, on = "
825:                                + auralParams.reverbType + ", "
826:                                + auralParams.reverbFlag);
827:                    if (sample == null)
828:                        return;
829:                    JSPositionalSample posSample = (JSPositionalSample) sample;
830:                    if (posSample.channel == null)
831:                        return;
832:
833:                    /**********
834:                    // NOTE: no support for reverb channel yet...
835:                    int reverbIndex = posSample.getReverbIndex();
836:                     **********/
837:                    if (dataType == JSSample.STREAMING_AUDIO_DATA) {
838:                        JSStream stream = (JSStream) posSample.channel;
839:                        stream.setSampleReverb(auralParams.reverbType,
840:                                auralParams.reverbFlag);
841:                    } else if (dataType == JSSample.BUFFERED_AUDIO_DATA) {
842:                        JSClip clip = (JSClip) posSample.channel;
843:                        clip.setSampleReverb(auralParams.reverbType,
844:                                auralParams.reverbFlag);
845:                    }
846:                    /**********
847:                    // TODO:
848:                    else if (dataType == JSSample.STREAMING_MIDI_DATA ||             
849:                             dataType == JSSample.BUFFERED_MIDI_DATA) {
850:                        JSMidi.setSampleReverb(reverbIndex, 
851:                                 auralParams.reverbType, auralParams.reverbFlag);
852:                    }
853:                     **********/
854:                    else {
855:                        if (internalErrors)
856:                            debugPrintln("JavaSoundMixer: Internal Error setReverb "
857:                                    + "dataType " + dataType + " invalid");
858:                    }
859:                }
860:            }
861:
862:            // TEMPORARY: Override of method due to bug in Java Sound
863:            public void setLoop(int index, int count) {
864:                JSSample sample = null;
865:                if ((sample = (JSSample) getSample(index)) == null)
866:                    return;
867:                int dataType = sample.getDataType();
868:
869:                // WORKAROUND:
870:                //     Bug in Java Sound engine hangs when INFINITE_LOOP count
871:                //     for Audio Wave data.  Leave count unchanged for Midi data.
872:                if (dataType == JSSample.STREAMING_AUDIO_DATA
873:                        || dataType == JSSample.BUFFERED_AUDIO_DATA) {
874:                    if (count == Sound.INFINITE_LOOPS) {
875:                        // LoopCount of 'loop Infinitely' forced to largest positive int
876:                        count = 0x7FFFFFF;
877:                    }
878:                }
879:                super .setLoop(index, count);
880:                return;
881:            }
882:
883:            // Perform device specific filtering
884:            // Assumes that this is called for positional and directional sounds
885:            // not background sounds, so there are at lease two samples assigned
886:            // per sound.
887:            // TODO: remove assumption from method
888:            void setFilter(int index, boolean filterFlag, float filterFreq) {
889:                JSPositionalSample posSample = null;
890:                if ((posSample = (JSPositionalSample) getSample(index)) == null)
891:                    return;
892:                if (posSample.channel == null)
893:                    return;
894:                int dataType = posSample.getDataType();
895:
896:                // Filtering can NOT be performed on MIDI Songs
897:                if (dataType == JSSample.STREAMING_MIDI_DATA
898:                        || dataType == JSSample.BUFFERED_MIDI_DATA) {
899:                    return;
900:                }
901:
902:                /****
903:                // TODO: multiple clips per channel
904:                int secondIndex = posSample.getSecondIndex();
905:                 *****/
906:                if (dataType == JSSample.BUFFERED_AUDIO_DATA) {
907:                    JSClip clip = (JSClip) posSample.channel;
908:                    clip.setSampleFiltering(filterFlag, filterFreq);
909:                    /*****
910:                    JSClip.setSampleFiltering(econdIndex, filterFlag, filterFreq);
911:                     ******/
912:                } else { // dataType == JSSample.STREAMING_AUDIO_DATA
913:                    JSStream stream = (JSStream) posSample.channel;
914:                    stream.setSampleFiltering(filterFlag, filterFreq);
915:                    /*****
916:                    JSStream.setSampleFiltering(secondIndex, ilterFlag, filterFreq);
917:                     ******/
918:                }
919:                // QUESTION: should reverb channel be filtered???
920:
921:                if (debugFlag) {
922:                    debugPrintln("JavaSoundMixer:setFilter "
923:                            + "of non-backgroundSound by (" + filterFlag + ", "
924:                            + filterFreq + ")");
925:                }
926:            }
927:
928:            //
929:            // Set overall gain for device
930:            // @since Java 3D 1.3
931:            //
932:            public void setGain(float scaleFactor) {
933:                float oldDeviceGain = deviceGain;
934:                float gainFactor = scaleFactor / oldDeviceGain;
935:                // TODO:  for each sample, change gain by gainFactor
936:                deviceGain = scaleFactor; // set given scalefactor as new device gain
937:                return;
938:            }
939:
940:            /*
941:             * Set sample specific sample rate scale factor gain
942:             * @since Java 3D 1.3
943:             */
944:            public void setRateScaleFactor(int index, float rateScaleFactor) {
945:                JSSample sample = null;
946:                if ((sample = (JSSample) getSample(index)) == null)
947:                    return;
948:                sample.setRateScaleFactor(rateScaleFactor);
949:                this .scaleSampleRate(index, rateScaleFactor);
950:            }
951:
952:            /**
953:             * Pauses audio device engine without closing the device and associated
954:             * threads.
955:             * Causes all cached sounds to be paused and all streaming sounds to be
956:             * stopped.
957:             */
958:            public void pause() {
959:                pause = PAUSE_PENDING;
960:                // TODO: pause all sounds
961:                return;
962:            }
963:
964:            /**
965:             * Resumes audio device engine (if previously paused) without reinitializing     * the device.
966:             * Causes all paused cached sounds to be resumed and all streaming sounds
967:             * restarted.
968:             */
969:            public void resume() {
970:                pause = RESUME_PENDING;
971:                // TODO: unpause all sounds
972:                return;
973:            }
974:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.