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
00150
00151
00152
00153
00154
00155
00156
00157 return 0;
00158 }
00159
00160
00161
00162 if (mod->src1 > 0) {
00163 if (mod->flags1 & FLUID_MOD_CC) {
00164 v1 = fluid_channel_get_cc(chan, mod->src1);
00165 } else {
00166 switch (mod->src1) {
00167 case FLUID_MOD_NONE:
00168 v1 = range1;
00169 break;
00170 case FLUID_MOD_VELOCITY:
00171 v1 = voice->vel;
00172 break;
00173 case FLUID_MOD_KEY:
00174 v1 = voice->key;
00175 break;
00176 case FLUID_MOD_KEYPRESSURE:
00177 v1 = chan->key_pressure;
00178 break;
00179 case FLUID_MOD_CHANNELPRESSURE:
00180 v1 = chan->channel_pressure;
00181 break;
00182 case FLUID_MOD_PITCHWHEEL:
00183 v1 = chan->pitch_bend;
00184 range1 = 0x4000;
00185 break;
00186 case FLUID_MOD_PITCHWHEELSENS:
00187 v1 = chan->pitch_wheel_sensitivity;
00188 break;
00189 default:
00190 v1 = 0.0;
00191 }
00192 }
00193
00194
00195 switch (mod->flags1 & 0x0f) {
00196 case 0:
00197 v1 /= range1;
00198 break;
00199 case 1:
00200 v1 = 1.0f - v1 / range1;
00201 break;
00202 case 2:
00203 v1 = -1.0f + 2.0f * v1 / range1;
00204 break;
00205 case 3:
00206 v1 = 1.0f - 2.0f * v1 / range1;
00207 break;
00208 case 4:
00209 v1 = fluid_concave(v1);
00210 break;
00211 case 5:
00212 v1 = fluid_concave(127 - v1);
00213 break;
00214 case 6:
00215 v1 = (v1 > 64)? fluid_concave(2 * (v1 - 64)) : -fluid_concave(2 * (64 - v1));
00216 break;
00217 case 7:
00218 v1 = (v1 > 64)? -fluid_concave(2 * (v1 - 64)) : fluid_concave(2 * (64 - v1));
00219 break;
00220 case 8:
00221 v1 = fluid_convex(v1);
00222 break;
00223 case 9:
00224 v1 = fluid_convex(127 - v1);
00225 break;
00226 case 10:
00227 v1 = (v1 > 64)? fluid_convex(2 * (v1 - 64)) : -fluid_convex(2 * (64 - v1));
00228 break;
00229 case 11:
00230 v1 = (v1 > 64)? -fluid_convex(2 * (v1 - 64)) : fluid_convex(2 * (64 - v1));
00231 break;
00232 case 12:
00233 v1 = (v1 >= 64)? 1.0f : 0.0f;
00234 break;
00235 case 13:
00236 v1 = (v1 >= 64)? 0.0f : 1.0f;
00237 break;
00238 case 14:
00239 v1 = (v1 >= 64)? 1.0f : -1.0f;
00240 break;
00241 case 15:
00242 v1 = (v1 >= 64)? -1.0f : 1.0f;
00243 break;
00244 }
00245 } else {
00246 return 0.0;
00247 }
00248
00249
00250 if (v1 == 0.0f) {
00251 return 0.0f;
00252 }
00253
00254
00255 if (mod->src2 > 0) {
00256 if (mod->flags2 & FLUID_MOD_CC) {
00257 v2 = fluid_channel_get_cc(chan, mod->src2);
00258 } else {
00259 switch (mod->src2) {
00260 case FLUID_MOD_NONE:
00261 v2 = range2;
00262 break;
00263 case FLUID_MOD_VELOCITY:
00264 v2 = voice->vel;
00265 break;
00266 case FLUID_MOD_KEY:
00267 v2 = voice->key;
00268 break;
00269 case FLUID_MOD_KEYPRESSURE:
00270 v2 = chan->key_pressure;
00271 break;
00272 case FLUID_MOD_CHANNELPRESSURE:
00273 v2 = chan->channel_pressure;
00274 break;
00275 case FLUID_MOD_PITCHWHEEL:
00276 v2 = chan->pitch_bend;
00277 break;
00278 case FLUID_MOD_PITCHWHEELSENS:
00279 v2 = chan->pitch_wheel_sensitivity;
00280 break;
00281 default:
00282 v1 = 0.0f;
00283 }
00284 }
00285
00286
00287 switch (mod->flags2 & 0x0f) {
00288 case 0:
00289 v2 /= range2;
00290 break;
00291 case 1:
00292 v2 = 1.0f - v2 / range2;
00293 break;
00294 case 2:
00295 v2 = -1.0f + 2.0f * v2 / range2;
00296 break;
00297 case 3:
00298 v2 = -1.0f + 2.0f * v2 / range2;
00299 break;
00300 case 4:
00301 v2 = fluid_concave(v2);
00302 break;
00303 case 5:
00304 v2 = fluid_concave(127 - v2);
00305 break;
00306 case 6:
00307 v2 = (v2 > 64)? fluid_concave(2 * (v2 - 64)) : -fluid_concave(2 * (64 - v2));
00308 break;
00309 case 7:
00310 v2 = (v2 > 64)? -fluid_concave(2 * (v2 - 64)) : fluid_concave(2 * (64 - v2));
00311 break;
00312 case 8:
00313 v2 = fluid_convex(v2);
00314 break;
00315 case 9:
00316 v2 = 1.0f - fluid_convex(v2);
00317 break;
00318 case 10:
00319 v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2));
00320 break;
00321 case 11:
00322 v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2));
00323 break;
00324 case 12:
00325 v2 = (v2 >= 64)? 1.0f : 0.0f;
00326 break;
00327 case 13:
00328 v2 = (v2 >= 64)? 0.0f : 1.0f;
00329 break;
00330 case 14:
00331 v2 = (v2 >= 64)? 1.0f : -1.0f;
00332 break;
00333 case 15:
00334 v2 = (v2 >= 64)? -1.0f : 1.0f;
00335 break;
00336 }
00337 } else {
00338 v2 = 1.0f;
00339 }
00340
00341
00342 return (fluid_real_t) mod->amount * v1 * v2;
00343 }
00344
00345
00346
00347
00348 fluid_mod_t*
00349 fluid_mod_new()
00350 {
00351 fluid_mod_t* mod = FLUID_NEW(fluid_mod_t);
00352 if (mod == NULL) {
00353 FLUID_LOG(FLUID_ERR, "Out of memory");
00354 return NULL;
00355 }
00356 return mod;
00357 };
00358
00359
00360
00361
00362 void
00363 fluid_mod_delete(fluid_mod_t * mod)
00364 {
00365 FLUID_FREE(mod);
00366 };
00367
00368
00369
00370
00371
00372
00373
00374
00375 int fluid_mod_test_identity(fluid_mod_t * mod1, fluid_mod_t * mod2){
00376 if (mod1->dest != mod2->dest){return 0;};
00377 if (mod1->src1 != mod2->src1){return 0;};
00378 if (mod1->src2 != mod2->src2){return 0;};
00379 if (mod1->flags1 != mod2->flags1){return 0;}
00380 if (mod1->flags2 != mod2->flags2){return 0;}
00381 return 1;
00382 };
00383
00384
00385 void fluid_dump_modulator(fluid_mod_t * mod){
00386 int src1=mod->src1;
00387 int dest=mod->dest;
00388 int src2=mod->src2;
00389 int flags1=mod->flags1;
00390 int flags2=mod->flags2;
00391 fluid_real_t amount=(fluid_real_t)mod->amount;
00392
00393 printf("Src: ");
00394 if (flags1 & FLUID_MOD_CC){
00395 printf("MIDI CC=%i",src1);
00396 } else {
00397 switch(src1){
00398 case FLUID_MOD_NONE:
00399 printf("None"); break;
00400 case FLUID_MOD_VELOCITY:
00401 printf("note-on velocity"); break;
00402 case FLUID_MOD_KEY:
00403 printf("Key nr"); break;
00404 case FLUID_MOD_KEYPRESSURE:
00405 printf("Poly pressure"); break;
00406 case FLUID_MOD_CHANNELPRESSURE:
00407 printf("Chan pressure"); break;
00408 case FLUID_MOD_PITCHWHEEL:
00409 printf("Pitch Wheel"); break;
00410 case FLUID_MOD_PITCHWHEELSENS:
00411 printf("Pitch Wheel sens"); break;
00412 default:
00413 printf("(unknown: %i)", src1);
00414 };
00415 };
00416 if (flags1 & FLUID_MOD_NEGATIVE){printf("- ");} else {printf("+ ");};
00417 if (flags1 & FLUID_MOD_BIPOLAR){printf("bip ");} else {printf("unip ");};
00418 printf("-> ");
00419 switch(dest){
00420 case GEN_FILTERQ: printf("Q"); break;
00421 case GEN_FILTERFC: printf("fc"); break;
00422 case GEN_VIBLFOTOPITCH: printf("VibLFO-to-pitch"); break;
00423 case GEN_MODENVTOPITCH: printf("ModEnv-to-pitch"); break;
00424 case GEN_MODLFOTOPITCH: printf("ModLFO-to-pitch"); break;
00425 case GEN_CHORUSSEND: printf("Chorus send"); break;
00426 case GEN_REVERBSEND: printf("Reverb send"); break;
00427 case GEN_PAN: printf("pan"); break;
00428 case GEN_ATTENUATION: printf("att"); break;
00429 default: printf("dest %i",dest);
00430 };
00431 printf(", amount %f flags %i src2 %i flags2 %i\n",amount, flags1, src2, flags2);
00432 };
00433
00434