00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "fluid_mod.h"
00022 #include "fluid_chan.h"
00023 #include "fluid_voice.h"
00024
00025
00026
00027
00028 void
00029 fluid_mod_clone(fluid_mod_t* mod, fluid_mod_t* src)
00030 {
00031 mod->dest = src->dest;
00032 mod->src1 = src->src1;
00033 mod->flags1 = src->flags1;
00034 mod->src2 = src->src2;
00035 mod->flags2 = src->flags2;
00036 mod->amount = src->amount;
00037 }
00038
00039
00040
00041
00042 void
00043 fluid_mod_set_source1(fluid_mod_t* mod, int src, int flags)
00044 {
00045 mod->src1 = src;
00046 mod->flags1 = flags;
00047 }
00048
00049
00050
00051
00052 void
00053 fluid_mod_set_source2(fluid_mod_t* mod, int src, int flags)
00054 {
00055 mod->src2 = src;
00056 mod->flags2 = flags;
00057 }
00058
00059
00060
00061
00062 void
00063 fluid_mod_set_dest(fluid_mod_t* mod, int dest)
00064 {
00065 mod->dest = dest;
00066 }
00067
00068
00069
00070
00071 void
00072 fluid_mod_set_amount(fluid_mod_t* mod, double amount)
00073 {
00074 mod->amount = (double) amount;
00075 }
00076
00077 int fluid_mod_get_source1(fluid_mod_t* mod)
00078 {
00079 return mod->src1;
00080 }
00081
00082 int fluid_mod_get_flags1(fluid_mod_t* mod)
00083 {
00084 return mod->flags1;
00085 }
00086
00087 int fluid_mod_get_source2(fluid_mod_t* mod)
00088 {
00089 return mod->src2;
00090 }
00091
00092 int fluid_mod_get_flags2(fluid_mod_t* mod)
00093 {
00094 return mod->flags2;
00095 }
00096
00097 int fluid_mod_get_dest(fluid_mod_t* mod)
00098 {
00099 return mod->dest;
00100 }
00101
00102 double fluid_mod_get_amount(fluid_mod_t* mod)
00103 {
00104 return (fluid_real_t) mod->amount;
00105 }
00106
00107
00108
00109
00110
00111 fluid_real_t
00112 fluid_mod_get_value(fluid_mod_t* mod, fluid_channel_t* chan, fluid_voice_t* voice)
00113 {
00114 fluid_real_t v1 = 0.0, v2 = 1.0;
00115 fluid_real_t range1 = 127.0, range2 = 127.0;
00116
00117 if (chan == NULL) {
00118 return 0.0f;
00119 }
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 if ((mod->src2 == FLUID_MOD_VELOCITY) &&
00143 (mod->src1 == FLUID_MOD_VELOCITY) &&
00144 (mod->flags1 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR
00145 | FLUID_MOD_NEGATIVE | FLUID_MOD_LINEAR)) &&
00146 (mod->flags2 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR
00147 | FLUID_MOD_POSITIVE | FLUID_MOD_SWITCH)) &&
00148 (mod->dest == GEN_FILTERFC)) {
00149 if (voice->vel < 64){
00150 return (fluid_real_t) mod->amount / 2.0;
00151 } else {
00152 return (fluid_real_t) mod->amount * (127 - voice->vel) / 127;
00153 }
00154 }
00155
00156
00157 if (mod->src1 > 0) {
00158 if (mod->flags1 & FLUID_MOD_CC) {
00159 v1 = fluid_channel_get_cc(chan, mod->src1);
00160 } else {
00161 switch (mod->src1) {
00162 case FLUID_MOD_NONE:
00163 v1 = range1;
00164 break;
00165 case FLUID_MOD_VELOCITY:
00166 v1 = voice->vel;
00167 break;
00168 case FLUID_MOD_KEY:
00169 v1 = voice->key;
00170 break;
00171 case FLUID_MOD_KEYPRESSURE:
00172 v1 = chan->key_pressure;
00173 break;
00174 case FLUID_MOD_CHANNELPRESSURE:
00175 v1 = chan->channel_pressure;
00176 break;
00177 case FLUID_MOD_PITCHWHEEL:
00178 v1 = chan->pitch_bend;
00179 range1 = 0x4000;
00180 break;
00181 case FLUID_MOD_PITCHWHEELSENS:
00182 v1 = chan->pitch_wheel_sensitivity;
00183 break;
00184 default:
00185 v1 = 0.0;
00186 }
00187 }
00188
00189
00190 switch (mod->flags1 & 0x0f) {
00191 case 0:
00192 v1 /= range1;
00193 break;
00194 case 1:
00195 v1 = 1.0f - v1 / range1;
00196 break;
00197 case 2:
00198 v1 = -1.0f + 2.0f * v1 / range1;
00199 break;
00200 case 3:
00201 v1 = -1.0f + 2.0f * v1 / range1;
00202 break;
00203 case 4:
00204 v1 = fluid_concave(v1);
00205 break;
00206 case 5:
00207 v1 = fluid_concave(127 - v1);
00208 break;
00209 case 6:
00210 v1 = (v1 > 64)? fluid_concave(2 * (v1 - 64)) : -fluid_concave(2 * (64 - v1));
00211 break;
00212 case 7:
00213 v1 = (v1 > 64)? -fluid_concave(2 * (v1 - 64)) : fluid_concave(2 * (64 - v1));
00214 break;
00215 case 8:
00216 v1 = fluid_convex(v1);
00217 break;
00218 case 9:
00219 v1 = fluid_convex(127 - v1);
00220 break;
00221 case 10:
00222 v1 = (v1 > 64)? -fluid_convex(2 * (v1 - 64)) : fluid_convex(2 * (64 - v1));
00223 break;
00224 case 11:
00225 v1 = (v1 > 64)? -fluid_convex(2 * (v1 - 64)) : fluid_convex(2 * (64 - v1));
00226 break;
00227 case 12:
00228 v1 = (v1 >= 64)? 1.0f : 0.0f;
00229 break;
00230 case 13:
00231 v1 = (v1 >= 64)? 0.0f : 1.0f;
00232 break;
00233 case 14:
00234 v1 = (v1 >= 64)? 1.0f : -1.0f;
00235 break;
00236 case 15:
00237 v1 = (v1 >= 64)? -1.0f : 1.0f;
00238 break;
00239 }
00240 } else {
00241 return 0.0;
00242 }
00243
00244
00245 if (v1 == 0.0f) {
00246 return 0.0f;
00247 }
00248
00249
00250 if (mod->src2 > 0) {
00251 if (mod->flags2 & FLUID_MOD_CC) {
00252 v2 = fluid_channel_get_cc(chan, mod->src2);
00253 } else {
00254 switch (mod->src2) {
00255 case FLUID_MOD_NONE:
00256 v2 = range2;
00257 break;
00258 case FLUID_MOD_VELOCITY:
00259 v2 = voice->vel;
00260 break;
00261 case FLUID_MOD_KEY:
00262 v2 = voice->key;
00263 break;
00264 case FLUID_MOD_KEYPRESSURE:
00265 v2 = chan->key_pressure;
00266 break;
00267 case FLUID_MOD_CHANNELPRESSURE:
00268 v2 = chan->channel_pressure;
00269 break;
00270 case FLUID_MOD_PITCHWHEEL:
00271 v2 = chan->pitch_bend;
00272 break;
00273 case FLUID_MOD_PITCHWHEELSENS:
00274 v2 = chan->pitch_wheel_sensitivity;
00275 break;
00276 default:
00277 v1 = 0.0f;
00278 }
00279 }
00280
00281
00282 switch (mod->flags2 & 0x0f) {
00283 case 0:
00284 v2 /= range2;
00285 break;
00286 case 1:
00287 v2 = 1.0f - v2 / range2;
00288 break;
00289 case 2:
00290 v2 = -1.0f + 2.0f * v2 / range2;
00291 break;
00292 case 3:
00293 v2 = -1.0f + 2.0f * v2 / range2;
00294 break;
00295 case 4:
00296 v2 = fluid_concave(v2);
00297 break;
00298 case 5:
00299 v2 = fluid_concave(127 - v2);
00300 break;
00301 case 6:
00302 v2 = (v2 > 64)? fluid_concave(2 * (v2 - 64)) : -fluid_concave(2 * (64 - v2));
00303 break;
00304 case 7:
00305 v2 = (v2 > 64)? -fluid_concave(2 * (v2 - 64)) : fluid_concave(2 * (64 - v2));
00306 break;
00307 case 8:
00308 v2 = fluid_convex(v2);
00309 break;
00310 case 9:
00311 v2 = 1.0f - fluid_convex(v2);
00312 break;
00313 case 10:
00314 v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2));
00315 break;
00316 case 11:
00317 v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2));
00318 break;
00319 case 12:
00320 v2 = (v2 >= 64)? 1.0f : 0.0f;
00321 break;
00322 case 13:
00323 v2 = (v2 >= 64)? 0.0f : 1.0f;
00324 break;
00325 case 14:
00326 v2 = (v2 >= 64)? 1.0f : -1.0f;
00327 break;
00328 case 15:
00329 v2 = (v2 >= 64)? -1.0f : 1.0f;
00330 break;
00331 }
00332 } else {
00333 v2 = 1.0f;
00334 }
00335
00336
00337 return (fluid_real_t) mod->amount * v1 * v2;
00338 }
00339
00340
00341
00342
00343 fluid_mod_t*
00344 fluid_mod_new()
00345 {
00346 fluid_mod_t* mod = FLUID_NEW(fluid_mod_t);
00347 if (mod == NULL) {
00348 FLUID_LOG(FLUID_ERR, "Out of memory");
00349 return NULL;
00350 }
00351 return mod;
00352 };
00353
00354
00355
00356
00357 void
00358 fluid_mod_delete(fluid_mod_t * mod)
00359 {
00360 FLUID_FREE(mod);
00361 };
00362
00363
00364
00365
00366
00367
00368
00369
00370 int fluid_mod_test_identity(fluid_mod_t * mod1, fluid_mod_t * mod2){
00371 if (mod1->dest != mod2->dest){return 0;};
00372 if (mod1->src1 != mod2->src1){return 0;};
00373 if (mod1->src2 != mod2->src2){return 0;};
00374 if (mod1->flags1 != mod2->flags1){return 0;}
00375 if (mod1->flags2 != mod2->flags2){return 0;}
00376 return 1;
00377 };
00378
00379
00380 void fluid_dump_modulator(fluid_mod_t * mod){
00381 int src1=mod->src1;
00382 int dest=mod->dest;
00383 int src2=mod->src2;
00384 int flags1=mod->flags1;
00385 int flags2=mod->flags2;
00386 fluid_real_t amount=(fluid_real_t)mod->amount;
00387
00388 printf("Src: ");
00389 if (flags1 & FLUID_MOD_CC){
00390 printf("MIDI CC=%i",src1);
00391 } else {
00392 switch(src1){
00393 case FLUID_MOD_NONE:
00394 printf("None"); break;
00395 case FLUID_MOD_VELOCITY:
00396 printf("note-on velocity"); break;
00397 case FLUID_MOD_KEY:
00398 printf("Key nr"); break;
00399 case FLUID_MOD_KEYPRESSURE:
00400 printf("Poly pressure"); break;
00401 case FLUID_MOD_CHANNELPRESSURE:
00402 printf("Chan pressure"); break;
00403 case FLUID_MOD_PITCHWHEEL:
00404 printf("Pitch Wheel"); break;
00405 case FLUID_MOD_PITCHWHEELSENS:
00406 printf("Pitch Wheel sens"); break;
00407 default:
00408 printf("(unknown: %i)", src1);
00409 };
00410 };
00411 if (flags1 & FLUID_MOD_NEGATIVE){printf("- ");} else {printf("+ ");};
00412 if (flags1 & FLUID_MOD_BIPOLAR){printf("bip ");} else {printf("unip ");};
00413 printf("-> ");
00414 switch(dest){
00415 case GEN_FILTERQ: printf("Q"); break;
00416 case GEN_FILTERFC: printf("fc"); break;
00417 case GEN_VIBLFOTOPITCH: printf("VibLFO-to-pitch"); break;
00418 case GEN_MODENVTOPITCH: printf("ModEnv-to-pitch"); break;
00419 case GEN_MODLFOTOPITCH: printf("ModLFO-to-pitch"); break;
00420 case GEN_CHORUSSEND: printf("Chorus send"); break;
00421 case GEN_REVERBSEND: printf("Reverb send"); break;
00422 case GEN_PAN: printf("pan"); break;
00423 case GEN_ATTENUATION: printf("att"); break;
00424 default: printf("dest %i",dest);
00425 };
00426 printf(", amount %f flags %i src2 %i flags2 %i\n",amount, flags1, src2, flags2);
00427 };
00428
00429