/// <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; //} //} }
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); }