Exemple #1
0
        public static void Update()
        {
            if (system == null)
            {
                return;
            }

            // Update sound
            if (channel != null)
            {
                FMOD.MODE mode = FMOD.MODE.DEFAULT;
                channel.getMode(ref mode);

                if ((mode & FMOD.MODE._3D) == FMOD.MODE._3D)
                {
                    FMOD.VECTOR pos; pos.x = 0.0f; pos.y = 0.0f; pos.z = 0.0f;
                    FMOD.VECTOR vel; vel.x = 0.0f; vel.y = 0.0f; vel.z = 0.0f;
                    channel.get3DAttributes(ref pos, ref vel);

                    float distance = (float)Math.Sqrt((double)(pos.x * pos.x + pos.y * pos.y));

                    float minDist = 0.0f, maxDist = 1000.0f;
                    channel.get3DMinMaxDistance(ref minDist, ref maxDist);

                    float distRatio = distance / maxDist;

                    if (ignorefod == false)
                    {
                        // Set direct and reverb occlusion
                        float direct = 1.0f - GetDistanceRatioValue(CONTROLTYPE.DIRECT, distRatio);
                        float reverb = 1.0f - GetDistanceRatioValue(CONTROLTYPE.REVERB, distRatio);
                        channel.set3DOcclusion(direct, reverb);

                        // Set lowpass
                        FMOD.DSP head = null;
                        channel.getDSPHead(ref head);
                        if (head != null)
                        {
                            int inputs = 0;
                            head.getNumInputs(ref inputs);
                            for (int i = 0; i < inputs; i++)
                            {
                                FMOD.DSP           dsp    = null;
                                FMOD.DSPConnection dspcon = null;
                                head.getInput(i, ref dsp, ref dspcon);
                                if (dsp == null)
                                {
                                    continue;
                                }

                                FMOD.DSP_TYPE type = FMOD.DSP_TYPE.UNKNOWN;
                                dsp.getType(ref type);
                                if (type == FMOD.DSP_TYPE.LOWPASS_SIMPLE)
                                {
                                    float hrtf = 1.0f;

                                    FMOD.VECTOR dir;
                                    dir.x = pos.x;
                                    dir.y = pos.y;
                                    dir.z = 0.0f;

                                    float length = (float)Math.Sqrt((double)(dir.x * dir.x + dir.y * dir.y));
                                    if (length > 0.0001f)
                                    {
                                        length = 1.0f / length;
                                        dir.x *= length;
                                        dir.y *= length;
                                        float _angle = (float)Math.Acos((double)dir.y);
                                        hrtf = 1.0f - HRTFDATA.Scale * Math.Min(1.0f, Math.Max(0.0f, (_angle - HRTFDATA.MinAngle) / (HRTFDATA.MaxAngle - HRTFDATA.MinAngle)));
                                    }

                                    float lowpass = 21990.0f * GetDistanceRatioValue(CONTROLTYPE.LOWPASS, distRatio) * hrtf + 10.0f;
                                    dsp.setParameter((int)FMOD.DSP_LOWPASS_SIMPLE.CUTOFF, lowpass);

                                    break;
                                }
                            }
                        }

                        // Set pan level
                        float panlevel = GetDistanceRatioValue(CONTROLTYPE.PANLEVEL, distRatio);
                        channel.set3DPanLevel(panlevel);
                    }

                    else
                    {
                        channel.set3DPanLevel(0.0f);
                    }
                }
            }

            system.update();
        }
Exemple #2
0
        private void Form1_Load(object sender, System.EventArgs e)
        {
            uint version = 0;

            FMOD.RESULT        result;
            FMOD.DSPConnection dspconnectiontemp = null;

            /*
             *  Create a System object and initialize.
             */
            result = FMOD.Factory.System_Create(ref system);
            ERRCHECK(result);

            result = system.getVersion(ref version);
            ERRCHECK(result);
            if (version < FMOD.VERSION.number)
            {
                MessageBox.Show("Error!  You are using an old version of FMOD " + version.ToString("X") + ".  This program requires " + FMOD.VERSION.number.ToString("X") + ".");
                Application.Exit();
            }

            result = system.init(32, FMOD.INITFLAGS.NORMAL, (IntPtr)null);
            ERRCHECK(result);

            result = system.createSound("../../../../../examples/media/drumloop.wav", FMOD.MODE.SOFTWARE | FMOD.MODE.LOOP_NORMAL, ref sound);
            ERRCHECK(result);

            result = system.playSound(FMOD.CHANNELINDEX.FREE, sound, false, ref channel);
            ERRCHECK(result);

            /*
             *  Create the DSP effects.
             */
            result = system.createDSPByType(FMOD.DSP_TYPE.LOWPASS, ref dsplowpass);
            ERRCHECK(result);

            result = system.createDSPByType(FMOD.DSP_TYPE.CHORUS, ref dspchorus);
            ERRCHECK(result);

            /*
             *  Connect up the DSP network
             */

            /*
             *  When a sound is played, a subnetwork is set up in the DSP network which looks like this.
             *  Wavetable is the drumloop sound, and it feeds its data from right to left.
             *
             *  [DSPHEAD]<------------[DSPCHANNELMIXER]
             */
            result = system.getDSPHead(ref dsphead);
            ERRCHECK(result);

            result = dsphead.getInput(0, ref dspchannelmixer, ref dspconnectiontemp);
            ERRCHECK(result);

            /*
             *  Now disconnect channeldsp head from wavetable to look like this.
             *
             *  [DSPHEAD]             [DSPCHANNELMIXER]
             */
            result = dsphead.disconnectFrom(dspchannelmixer);
            ERRCHECK(result);

            /*
             *  Now connect the 2 effects to channeldsp head.
             *
             *            [DSPLOWPASS]
             *           /
             *  [DSPHEAD]             [DSPCHANNELMIXER]
             \
             \            [DSPCHORUS]
             */
            result = dsphead.addInput(dsplowpass, ref dsplowpassconnection);
            ERRCHECK(result);
            result = dsphead.addInput(dspchorus, ref dspchorusconnection);
            ERRCHECK(result);

            /*
             *  Now connect the wavetable to the 2 effects
             *
             *            [DSPLOWPASS]
             *           /           \
             *  [DSPHEAD]             [DSPCHANNELMIXER]
             \           /
             \            [DSPCHORUS]
             */
            result = dsplowpass.addInput(dspchannelmixer, ref dspconnectiontemp);
            ERRCHECK(result);
            result = dspchorus.addInput(dspchannelmixer, ref dspconnectiontemp);
            ERRCHECK(result);

            /*
             *  Now the drumloop will be twice as loud, because it is being split into 2, then recombined at the end.
             *  What we really want is to only feed the dspchannelmixer->dsplowpass through the left speaker, and
             *  dspchannelmixer->dspchorus to the right speaker.
             *  We can do that simply by setting the pan, or speaker levels of the connections.
             *
             *            [DSPLOWPASS]
             *           /1,0        \
             *  [DSPHEAD]             [DSPCHANNELMIXER]
             \0,1        /
             *            [DSPCHORUS]
             */
            {
                float[] leftinputon  = { 1.0f, 0.0f };
                float[] rightinputon = { 0.0f, 1.0f };
                float[] inputsoff    = { 0.0f, 0.0f };

                result = dsplowpassconnection.setLevels(FMOD.SPEAKER.FRONT_LEFT, leftinputon, 2);
                ERRCHECK(result);
                result = dsplowpassconnection.setLevels(FMOD.SPEAKER.FRONT_RIGHT, inputsoff, 2);
                ERRCHECK(result);

                result = dsplowpassconnection.setLevels(FMOD.SPEAKER.FRONT_LEFT, inputsoff, 2);
                ERRCHECK(result);
                result = dsplowpassconnection.setLevels(FMOD.SPEAKER.FRONT_RIGHT, rightinputon, 2);
                ERRCHECK(result);
            }

            result = dsplowpass.setBypass(true);
            result = dspchorus.setBypass(true);

            result = dsplowpass.setActive(true);
            result = dspchorus.setActive(true);
        }