📄 javasoundmixer.java
字号:
/** * Overriden method from AudioEngine3D. */ public int getNumberOfChannelsUsed(int index, boolean muted) { /* * The JavaSoundMixer implementation uses THREE channels to render * the stereo image of each Point and Cone Sounds: * Two for rendering the right and left portions of the rendered * spatialized sound image - panned hard right or left respectively. * This implementation uses one channel to render Background sounds * whether the sample is mono or stereo. * * TODO: When muted is implemented, that flag should be check * so that zero is returned. */ JSSample sample = null; if ((sample = (JSSample)getSample(index)) == null) return 0; int soundType = sample.getSoundType(); int dataType = sample.getDataType(); // TODO: for now positional Midi sound used only 1 sample if (dataType == JSSample.STREAMING_MIDI_DATA || dataType == JSSample.BUFFERED_MIDI_DATA) return 1; if (soundType == BACKGROUND_SOUND) return 1; else // for Point and Cone sounds return 3; } /* * Overriden method from AudioEngine3D. */ public long getStartTime(int index) { JSSample sample = null; if ((sample = (JSSample)getSample(index)) == null) return 0L; if (sample.channel == null) return 0L; return (long)sample.channel.startTime; } /* * Methods called during rendering */ void scaleSampleRate(int index, float scaleFactor) { if (debugFlag) debugPrintln("JavaSoundMixer: scaleSampleRate index " + index + ", scale factor = " + scaleFactor); JSSample sample = null; if ((sample = (JSSample)getSample(index)) == null || thread == null) return; int dataType = sample.getDataType(); if (debugFlag) debugPrintln(" scaleSampleRate.dataType = " + dataType + "using sample " + sample + " from samples[" + index +"]"); int soundType = sample.getSoundType(); if (dataType == JSSample.STREAMING_AUDIO_DATA || dataType == JSSample.BUFFERED_AUDIO_DATA) { thread.setSampleRate(sample, scaleFactor); /********** // TODO: if (soundType != AudioDevice3D.BACKGROUND_SOUND) { thread.setSampleRate( ((JSPositionalSample)sample).getSecondIndex(), scaleFactor); thread.setSampleRate(((JSPositionalSample)sample).getReverbIndex(), scaleFactor); } **********/ } else if (dataType == JSSample.STREAMING_MIDI_DATA || dataType == JSSample.BUFFERED_MIDI_DATA) { thread.setSampleRate(sample, scaleFactor); /********** if (soundType != AudioDevice3D.BACKGROUND_SOUND) { thread.setSampleRate(((JSPositionalSample)sample).getSecondIndex(), scaleFactor); thread.setSampleRate(((JSPositionalSample)sample).getReverbIndex(), scaleFactor); } **********/ } else { if (internalErrors) debugPrintln( "JavaSoundMixer: Internal Error scaleSampleRate dataType " + dataType + " invalid"); } } /* * Methods called during rendering */ void calcReverb(JSSample sample) { /* * Java Sound reverb parameters are a subset of Java 3D parameters */ int dataType = sample.getDataType(); int soundType = sample.getSoundType(); float decay = auralParams.decayTime; float delay = auralParams.reverbDelay * auralParams.rolloff; float reflection = auralParams.reflectionCoefficient; int order = auralParams.reverbOrder; /* * Remember Coeff change is choosen over Order change if BOTH made * otherwise the last one changed take precidence. */ if (auralParams.reflectionCoefficient == 0.0f || auralParams.reverbCoefficient == 0.0f) auralParams.reverbFlag = false; else { auralParams.reverbFlag = true; if (order > 0) { // clamp reverb decay time to order*delay float clampedTime = order * delay; if ( clampedTime < decay) decay = clampedTime; } if (delay < 100.0f) { // "small" reverberant space if (decay <= 1500.0f) auralParams.reverbType = 2; else auralParams.reverbType = 4; } else if (delay < 500.0f) { // "medium" reverberant space if (decay <= 1500.0f) auralParams.reverbType = 3; else auralParams.reverbType = 6; } else { // delay >= 500.0f // "large" reverberant space if (decay <= 1500.0f) auralParams.reverbType = 6; else auralParams.reverbType = 5; } } if (debugFlag) debugPrintln("JavaSoundMixer: setReverb for " + sample + ", type = " + auralParams.reverbType + ", flag = " + auralParams.reverbFlag); auralParams.reverbDirty = 0; // clear the attribute reverb dirty flags } /* * Interal method for setting reverb parameters called during rendering. * This not called by SoundScheduler. */ void setReverb(JSSample sample) { /* * Only third sample of multisample sounds has reverb parameters set. * For now, only positional and directional sounds are reverberated. */ int soundType = sample.getSoundType(); int dataType = sample.getDataType(); // QUESTION: Should reverb be applied to background sounds? if ( (soundType == AudioDevice3D.CONE_SOUND) || (soundType == AudioDevice3D.POINT_SOUND) ) { if (debugFlag) debugPrintln("setReverb called with type, on = " + auralParams.reverbType + ", " + auralParams.reverbFlag); if (sample == null) return; JSPositionalSample posSample = (JSPositionalSample)sample; if (posSample.channel == null) return; /********** // NOTE: no support for reverb channel yet... int reverbIndex = posSample.getReverbIndex(); **********/ if (dataType == JSSample.STREAMING_AUDIO_DATA) { JSStream stream = (JSStream)posSample.channel; stream.setSampleReverb(auralParams.reverbType, auralParams.reverbFlag); } else if (dataType == JSSample.BUFFERED_AUDIO_DATA) { JSClip clip = (JSClip)posSample.channel; clip.setSampleReverb(auralParams.reverbType, auralParams.reverbFlag); } /********** // TODO: else if (dataType == JSSample.STREAMING_MIDI_DATA || dataType == JSSample.BUFFERED_MIDI_DATA) { JSMidi.setSampleReverb(reverbIndex, auralParams.reverbType, auralParams.reverbFlag); } **********/ else { if (internalErrors) debugPrintln( "JavaSoundMixer: Internal Error setReverb " + "dataType " + dataType + " invalid"); } } } // TEMPORARY: Override of method due to bug in Java Sound public void setLoop(int index, int count) { JSSample sample = null; if ((sample = (JSSample)getSample(index)) == null) return; int dataType = sample.getDataType(); // WORKAROUND: // Bug in Java Sound engine hangs when INFINITE_LOOP count // for Audio Wave data. Leave count unchanged for Midi data. if (dataType==JSSample.STREAMING_AUDIO_DATA || dataType==JSSample.BUFFERED_AUDIO_DATA) { if (count == Sound.INFINITE_LOOPS) { // LoopCount of 'loop Infinitely' forced to largest positive int count = 0x7FFFFFF; } } super.setLoop(index, count); return; } // Perform device specific filtering // Assumes that this is called for positional and directional sounds // not background sounds, so there are at lease two samples assigned // per sound. // TODO: remove assumption from method void setFilter(int index, boolean filterFlag, float filterFreq) { JSPositionalSample posSample = null; if ((posSample = (JSPositionalSample)getSample(index)) == null) return; if (posSample.channel == null) return; int dataType = posSample.getDataType(); // Filtering can NOT be performed on MIDI Songs if (dataType == JSSample.STREAMING_MIDI_DATA || dataType == JSSample.BUFFERED_MIDI_DATA) { return; } /**** // TODO: multiple clips per channel int secondIndex = posSample.getSecondIndex(); *****/ if (dataType == JSSample.BUFFERED_AUDIO_DATA) { JSClip clip = (JSClip)posSample.channel; clip.setSampleFiltering(filterFlag,filterFreq); /***** JSClip.setSampleFiltering(econdIndex, filterFlag, filterFreq); ******/ } else { // dataType == JSSample.STREAMING_AUDIO_DATA JSStream stream = (JSStream)posSample.channel; stream.setSampleFiltering(filterFlag,filterFreq); /***** JSStream.setSampleFiltering(secondIndex, ilterFlag, filterFreq); ******/ } // QUESTION: should reverb channel be filtered??? if (debugFlag) { debugPrintln("JavaSoundMixer:setFilter " + "of non-backgroundSound by (" + filterFlag + ", " + filterFreq + ")"); } } // // Set overall gain for device // @since Java 3D 1.3 // public void setGain(float scaleFactor) { float oldDeviceGain = deviceGain; float gainFactor = scaleFactor/oldDeviceGain; // TODO: for each sample, change gain by gainFactor deviceGain = scaleFactor; // set given scalefactor as new device gain return; } /* * Set sample specific sample rate scale factor gain * @since Java 3D 1.3 */ public void setRateScaleFactor(int index, float rateScaleFactor) { JSSample sample = null; if ((sample = (JSSample)getSample(index)) == null) return; sample.setRateScaleFactor(rateScaleFactor); this.scaleSampleRate(index, rateScaleFactor); } /** * Pauses audio device engine without closing the device and associated * threads. * Causes all cached sounds to be paused and all streaming sounds to be * stopped. */ public void pause() { pause = PAUSE_PENDING; // TODO: pause all sounds return; } /** * Resumes audio device engine (if previously paused) without reinitializing * the device. * Causes all paused cached sounds to be resumed and all streaming sounds * restarted. */ public void resume() { pause = RESUME_PENDING; // TODO: unpause all sounds return; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -