Beispiel #1
0
        /// <summary>
        ///  Set an array of generators to their initial value
        /// </summary>
        /// <param name="gens"></param>
        /// <param name="channel"></param>
        static public void fluid_gen_init(HiGen[] gens, fluid_channel channel)
        {
            fluid_gen_info.fluid_gen_set_default_values(gens);

            //for (int i = 0; i < gens.Length; i++)
            //{
            //    gens[i].nrpn = channel.gens[i];

            ///* This is an extension to the SoundFont standard. More
            // * documentation is available at the fluid_synth_set_gen2()
            // * function. */
            //if (fluid_channel_get_gen_abs(channel, i))
            //{
            //    gen[i].flags = GEN_ABS_NRPN;
            //}
            //}
        }
Beispiel #2
0
        public ushort SfTrans;      /* transform applied to source */

        public float fluid_mod_get_value(fluid_channel chan, int key, int vel)
        {
            float v1 = 0.0f, v2 = 1.0f;
            float range1 = 127.0f, range2 = 127.0f;

            if (chan == null)
            {
                return(0.0f);
            }

            /* 'special treatment' for default controller
             *
             *  Reference: SF2.01 section 8.4.2
             *
             * The GM default controller 'vel-to-filter cut off' is not clearly defined: If implemented according to the specs, the filter
             * frequency jumps between vel=63 and vel=64.  To maintain compatibility with existing sound fonts, the implementation is
             * 'hardcoded', it is impossible to implement using only one modulator otherwise.
             *
             * I assume here, that the 'intention' of the paragraph is one octave (1200 cents) filter frequency shift between vel=127 and
             * vel=64.  'amount' is (-2400), at least as long as the controller is set to default.
             *
             * Further, the 'appearance' of the modulator (source enumerator, destination enumerator, flags etc) is different from that
             * described in section 8.4.2, but it matches the definition used in several SF2.1 sound fonts (where it is used only to turn it off).
             * */
            if ((Dest == (byte)fluid_gen_type.GEN_FILTERFC) &&
                (Src2 == (int)fluid_mod_src.FLUID_MOD_VELOCITY) &&
                (Src1 == (int)fluid_mod_src.FLUID_MOD_VELOCITY) &&
                (Flags1 == ((byte)fluid_mod_flags.FLUID_MOD_GC | (byte)fluid_mod_flags.FLUID_MOD_UNIPOLAR | (byte)fluid_mod_flags.FLUID_MOD_NEGATIVE | (byte)fluid_mod_flags.FLUID_MOD_LINEAR)) &&
                (Flags2 == ((byte)fluid_mod_flags.FLUID_MOD_GC | (byte)fluid_mod_flags.FLUID_MOD_UNIPOLAR | (byte)fluid_mod_flags.FLUID_MOD_POSITIVE | (byte)fluid_mod_flags.FLUID_MOD_SWITCH)))

            {
                if (vel < 64)
                {
                    return(Amount / 2.0f);
                }
                else
                {
                    return(Amount * (127f - vel) / 127f);
                }
            }

            /* get the initial value of the first source */
            if (Src1 > 0)
            {
                if ((Flags1 & (byte)fluid_mod_flags.FLUID_MOD_CC) > 0)
                {
                    v1 = ((Src1 >= 0) && (Src1 < 128)) ? chan.cc[Src1] : 0;
                    //if (src1 == 10) Debug.Log("retreive pan " + v1);
                }
                else
                {
                    /* source 1 is one of the direct controllers */
                    switch (Src1)
                    {
                    case (int)fluid_mod_src.FLUID_MOD_NONE:             /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */
                        v1 = range1;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_VELOCITY:
                        v1 = vel;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_KEY:
                        v1 = key;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_KEYPRESSURE:
                        v1 = chan.key_pressure;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_CHANNELPRESSURE:
                        v1 = chan.channel_pressure;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_PITCHWHEEL:
                        v1     = chan.pitch_bend;
                        range1 = 0x4000;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_PITCHWHEELSENS:
                        v1 = chan.pitch_wheel_sensitivity;
                        break;

                    default:
                        v1 = 0.0f;
                        break;
                    }
                }

                /* transform the input value */
                switch (Flags1 & 0x0f)
                {
                case 0:     /* linear, unipolar, positive */
                    v1 /= range1;
                    break;

                case 1:     /* linear, unipolar, negative */
                    v1 = 1.0f - v1 / range1;
                    break;

                case 2:     /* linear, bipolar, positive */
                    v1 = -1.0f + 2.0f * v1 / range1;
                    break;

                case 3:     /* linear, bipolar, negative */
                    v1 = -1.0f + 2.0f * v1 / range1;
                    break;

                case 4:     /* concave, unipolar, positive */
                    v1 = fluid_conv.fluid_concave(v1);
                    break;

                case 5:     /* concave, unipolar, negative */
                    v1 = fluid_conv.fluid_concave(127 - v1);
                    break;

                case 6:     /* concave, bipolar, positive */
                    v1 = (v1 > 64) ? fluid_conv.fluid_concave(2 * (v1 - 64)) : -fluid_conv.fluid_concave(2 * (64 - v1));
                    break;

                case 7:     /* concave, bipolar, negative */
                    v1 = (v1 > 64) ? -fluid_conv.fluid_concave(2 * (v1 - 64)) : fluid_conv.fluid_concave(2 * (64 - v1));
                    break;

                case 8:     /* convex, unipolar, positive */
                    v1 = fluid_conv.fluid_convex(v1);
                    break;

                case 9:     /* convex, unipolar, negative */
                    v1 = fluid_conv.fluid_convex(127 - v1);
                    break;

                case 10:     /* convex, bipolar, positive */
                    v1 = (v1 > 64) ? -fluid_conv.fluid_convex(2 * (v1 - 64)) : fluid_conv.fluid_convex(2 * (64 - v1));
                    break;

                case 11:     /* convex, bipolar, negative */
                    v1 = (v1 > 64) ? -fluid_conv.fluid_convex(2 * (v1 - 64)) : fluid_conv.fluid_convex(2 * (64 - v1));
                    break;

                case 12:     /* switch, unipolar, positive */
                    v1 = (v1 >= 64) ? 1.0f : 0.0f;
                    break;

                case 13:     /* switch, unipolar, negative */
                    v1 = (v1 >= 64) ? 0.0f : 1.0f;
                    break;

                case 14:     /* switch, bipolar, positive */
                    v1 = (v1 >= 64) ? 1.0f : -1.0f;
                    break;

                case 15:     /* switch, bipolar, negative */
                    v1 = (v1 >= 64) ? -1.0f : 1.0f;
                    break;
                }
            }
            else
            {
                return(0.0f);
            }

            /* no need to go further */
            if (v1 == 0.0f)
            {
                return(0.0f);
            }

            /* get the second input source */
            if (Src2 > 0)
            {
                if ((Flags2 & (byte)fluid_mod_flags.FLUID_MOD_CC) > 0)
                {
                    v2 = ((Src2 >= 0) && (Src2 < 128)) ? chan.cc[Src2] : 0;
                }
                else
                {
                    switch (Src2)
                    {
                    case (int)fluid_mod_src.FLUID_MOD_NONE:             /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */
                        v2 = range2;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_VELOCITY:
                        v2 = vel;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_KEY:
                        v2 = key;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_KEYPRESSURE:
                        v2 = chan.key_pressure;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_CHANNELPRESSURE:
                        v2 = chan.channel_pressure;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_PITCHWHEEL:
                        v2 = chan.pitch_bend;
                        break;

                    case (int)fluid_mod_src.FLUID_MOD_PITCHWHEELSENS:
                        v2 = chan.pitch_wheel_sensitivity;
                        break;

                    default:
                        v1 = 0.0f;
                        break;
                    }
                }

                /* transform the second input value */
                switch (Flags2 & 0x0f)
                {
                case 0:     /* linear, unipolar, positive */
                    v2 /= range2;
                    break;

                case 1:     /* linear, unipolar, negative */
                    v2 = 1.0f - v2 / range2;
                    break;

                case 2:     /* linear, bipolar, positive */
                    v2 = -1.0f + 2.0f * v2 / range2;
                    break;

                case 3:     /* linear, bipolar, negative */
                    v2 = -1.0f + 2.0f * v2 / range2;
                    break;

                case 4:     /* concave, unipolar, positive */
                    v2 = fluid_conv.fluid_concave(v2);
                    break;

                case 5:     /* concave, unipolar, negative */
                    v2 = fluid_conv.fluid_concave(127 - v2);
                    break;

                case 6:     /* concave, bipolar, positive */
                    v2 = (v2 > 64) ? fluid_conv.fluid_concave(2 * (v2 - 64)) : -fluid_conv.fluid_concave(2 * (64 - v2));
                    break;

                case 7:     /* concave, bipolar, negative */
                    v2 = (v2 > 64) ? -fluid_conv.fluid_concave(2 * (v2 - 64)) : fluid_conv.fluid_concave(2 * (64 - v2));
                    break;

                case 8:     /* convex, unipolar, positive */
                    v2 = fluid_conv.fluid_convex(v2);
                    break;

                case 9:     /* convex, unipolar, negative */
                    v2 = 1.0f - fluid_conv.fluid_convex(v2);
                    break;

                case 10:     /* convex, bipolar, positive */
                    v2 = (v2 > 64) ? -fluid_conv.fluid_convex(2 * (v2 - 64)) : fluid_conv.fluid_convex(2 * (64 - v2));
                    break;

                case 11:     /* convex, bipolar, negative */
                    v2 = (v2 > 64) ? -fluid_conv.fluid_convex(2 * (v2 - 64)) : fluid_conv.fluid_convex(2 * (64 - v2));
                    break;

                case 12:     /* switch, unipolar, positive */
                    v2 = (v2 >= 64) ? 1.0f : 0.0f;
                    break;

                case 13:     /* switch, unipolar, negative */
                    v2 = (v2 >= 64) ? 0.0f : 1.0f;
                    break;

                case 14:     /* switch, bipolar, positive */
                    v2 = (v2 >= 64) ? 1.0f : -1.0f;
                    break;

                case 15:     /* switch, bipolar, negative */
                    v2 = (v2 >= 64) ? -1.0f : 1.0f;
                    break;
                }
            }
            else
            {
                v2 = 1.0f;
            }

            /* it's as simple as that: */
            return(Amount * v1 * v2);
        }