00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "fluidsynth_priv.h"
00022 #include "fluid_voice.h"
00023 #include "fluid_mod.h"
00024 #include "fluid_chan.h"
00025 #include "fluid_conv.h"
00026 #include "fluid_synth.h"
00027 #include "fluid_sys.h"
00028 #include "fluid_sfont.h"
00029
00030
00031
00032 #define FLUID_MAX_AUDIBLE_FILTER_FC 19000.0f
00033 #define FLUID_MIN_AUDIBLE_FILTER_Q 1.2f
00034
00035
00036
00037
00038
00039 #define FLUID_NOISE_FLOOR 0.00003
00040
00041
00042 #define FLUID_MIN_LOOP_SIZE 2
00043 #define FLUID_MIN_LOOP_PAD 0
00044
00045
00046 #define FLUID_MIN_VOLENVRELEASE -7200.0f
00047
00048
00049 static inline void fluid_voice_effects (fluid_voice_t *voice, int count,
00050 fluid_real_t* dsp_left_buf,
00051 fluid_real_t* dsp_right_buf,
00052 fluid_real_t* dsp_reverb_buf,
00053 fluid_real_t* dsp_chorus_buf);
00054
00055
00056
00057 fluid_voice_t*
00058 new_fluid_voice(fluid_real_t output_rate)
00059 {
00060 fluid_voice_t* voice;
00061 voice = FLUID_NEW(fluid_voice_t);
00062 if (voice == NULL) {
00063 FLUID_LOG(FLUID_ERR, "Out of memory");
00064 return NULL;
00065 }
00066 voice->status = FLUID_VOICE_CLEAN;
00067 voice->chan = NO_CHANNEL;
00068 voice->key = 0;
00069 voice->vel = 0;
00070 voice->channel = NULL;
00071 voice->sample = NULL;
00072 voice->output_rate = output_rate;
00073
00074
00075
00076
00077
00078
00079 voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].count = 0xffffffff;
00080 voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].coeff = 1.0f;
00081 voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].incr = 0.0f;
00082 voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].min = -1.0f;
00083 voice->volenv_data[FLUID_VOICE_ENVSUSTAIN].max = 2.0f;
00084
00085 voice->volenv_data[FLUID_VOICE_ENVFINISHED].count = 0xffffffff;
00086 voice->volenv_data[FLUID_VOICE_ENVFINISHED].coeff = 0.0f;
00087 voice->volenv_data[FLUID_VOICE_ENVFINISHED].incr = 0.0f;
00088 voice->volenv_data[FLUID_VOICE_ENVFINISHED].min = -1.0f;
00089 voice->volenv_data[FLUID_VOICE_ENVFINISHED].max = 1.0f;
00090
00091 voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].count = 0xffffffff;
00092 voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].coeff = 1.0f;
00093 voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].incr = 0.0f;
00094 voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].min = -1.0f;
00095 voice->modenv_data[FLUID_VOICE_ENVSUSTAIN].max = 2.0f;
00096
00097 voice->modenv_data[FLUID_VOICE_ENVFINISHED].count = 0xffffffff;
00098 voice->modenv_data[FLUID_VOICE_ENVFINISHED].coeff = 0.0f;
00099 voice->modenv_data[FLUID_VOICE_ENVFINISHED].incr = 0.0f;
00100 voice->modenv_data[FLUID_VOICE_ENVFINISHED].min = -1.0f;
00101 voice->modenv_data[FLUID_VOICE_ENVFINISHED].max = 1.0f;
00102
00103 return voice;
00104 }
00105
00106
00107
00108
00109 int
00110 delete_fluid_voice(fluid_voice_t* voice)
00111 {
00112 if (voice == NULL) {
00113 return FLUID_OK;
00114 }
00115 FLUID_FREE(voice);
00116 return FLUID_OK;
00117 }
00118
00119
00120
00121
00122
00123 int
00124 fluid_voice_init(fluid_voice_t* voice, fluid_sample_t* sample,
00125 fluid_channel_t* channel, int key, int vel, unsigned int id,
00126 unsigned int start_time, fluid_real_t gain)
00127 {
00128
00129
00130
00131
00132
00133
00134 voice->id = id;
00135 voice->chan = fluid_channel_get_num(channel);
00136 voice->key = (unsigned char) key;
00137 voice->vel = (unsigned char) vel;
00138 voice->channel = channel;
00139 voice->mod_count = 0;
00140 voice->sample = sample;
00141 voice->start_time = start_time;
00142 voice->ticks = 0;
00143 voice->debug = 0;
00144 voice->has_looped = 0;
00145 voice->last_fres = -1;
00146 voice->filter_startup = 1;
00147 voice->interp_method = fluid_channel_get_interp_method(voice->channel);
00148
00149
00150 voice->volenv_count = 0;
00151 voice->volenv_section = 0;
00152 voice->volenv_val = 0.0f;
00153 voice->amp = 0.0f;
00154
00155
00156
00157
00158 voice->modenv_count = 0;
00159 voice->modenv_section = 0;
00160 voice->modenv_val = 0.0f;
00161
00162
00163 voice->modlfo_val = 0.0;
00164
00165
00166
00167
00168 voice->viblfo_val = 0.0f;
00169
00170
00171 voice->hist1 = 0;
00172 voice->hist2 = 0;
00173
00174
00175
00176
00177
00178
00179
00180 fluid_gen_init(&voice->gen[0], channel);
00181
00182 voice->synth_gain = gain;
00183
00184 if (voice->synth_gain < 0.0000001){
00185 voice->synth_gain = 0.0000001;
00186 }
00187
00188
00189
00190
00191
00192
00193 voice->amplitude_that_reaches_noise_floor_nonloop = FLUID_NOISE_FLOOR / voice->synth_gain;
00194 voice->amplitude_that_reaches_noise_floor_loop = FLUID_NOISE_FLOOR / voice->synth_gain;
00195
00196
00197
00198 fluid_sample_incr_ref(voice->sample);
00199
00200 return FLUID_OK;
00201 }
00202
00203 void fluid_voice_gen_set(fluid_voice_t* voice, int i, float val)
00204 {
00205 voice->gen[i].val = val;
00206 voice->gen[i].flags = GEN_SET;
00207 }
00208
00209 void fluid_voice_gen_incr(fluid_voice_t* voice, int i, float val)
00210 {
00211 voice->gen[i].val += val;
00212 voice->gen[i].flags = GEN_SET;
00213 }
00214
00215 float fluid_voice_gen_get(fluid_voice_t* voice, int gen)
00216 {
00217 return voice->gen[gen].val;
00218 }
00219
00220 fluid_real_t fluid_voice_gen_value(fluid_voice_t* voice, int num)
00221 {
00222
00223
00224
00225 if (voice->gen[num].flags == GEN_ABS_NRPN) {
00226 return (fluid_real_t) voice->gen[num].nrpn;
00227 } else {
00228 return (fluid_real_t) (voice->gen[num].val + voice->gen[num].mod + voice->gen[num].nrpn);
00229 }
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244 int
00245 fluid_voice_write(fluid_voice_t* voice,
00246 fluid_real_t* dsp_left_buf, fluid_real_t* dsp_right_buf,
00247 fluid_real_t* dsp_reverb_buf, fluid_real_t* dsp_chorus_buf)
00248 {
00249 unsigned int i;
00250 fluid_real_t incr;
00251 fluid_real_t fres;
00252 fluid_real_t target_amp;
00253 int count;
00254
00255 int dsp_interp_method = voice->interp_method;
00256
00257 fluid_real_t dsp_buf[FLUID_BUFSIZE];
00258 fluid_env_data_t* env_data;
00259 fluid_real_t x;
00260
00261
00262
00263 if (!_PLAYING(voice)) return FLUID_OK;
00264
00265
00266
00267 if (voice->sample == NULL)
00268 {
00269 fluid_voice_off(voice);
00270 return FLUID_OK;
00271 }
00272
00273 fluid_check_fpe ("voice_write startup");
00274
00275
00276
00277 fluid_voice_check_sample_sanity (voice);
00278
00279
00280
00281 env_data = &voice->volenv_data[voice->volenv_section];
00282
00283
00284 while (voice->volenv_count >= env_data->count)
00285 {
00286 env_data = &voice->volenv_data[++voice->volenv_section];
00287 voice->volenv_count = 0;
00288 }
00289
00290
00291 x = env_data->coeff * voice->volenv_val + env_data->incr;
00292 if (x < env_data->min)
00293 {
00294 x = env_data->min;
00295 voice->volenv_section++;
00296 voice->volenv_count = 0;
00297 }
00298 else if (x > env_data->max)
00299 {
00300 x = env_data->max;
00301 voice->volenv_section++;
00302 voice->volenv_count = 0;
00303 }
00304
00305 voice->volenv_val = x;
00306 voice->volenv_count++;
00307
00308 if (voice->volenv_section == FLUID_VOICE_ENVFINISHED)
00309 {
00310 fluid_profile (FLUID_PROF_VOICE_RELEASE, voice->ref);
00311 fluid_voice_off (voice);
00312 return FLUID_OK;
00313 }
00314
00315 fluid_check_fpe ("voice_write vol env");
00316
00317
00318
00319 env_data = &voice->modenv_data[voice->modenv_section];
00320
00321
00322 while (voice->modenv_count >= env_data->count)
00323 {
00324 env_data = &voice->modenv_data[++voice->modenv_section];
00325 voice->modenv_count = 0;
00326 }
00327
00328
00329 x = env_data->coeff * voice->modenv_val + env_data->incr;
00330
00331 if (x < env_data->min)
00332 {
00333 x = env_data->min;
00334 voice->modenv_section++;
00335 voice->modenv_count = 0;
00336 }
00337 else if (x > env_data->max)
00338 {
00339 x = env_data->max;
00340 voice->modenv_section++;
00341 voice->modenv_count = 0;
00342 }
00343
00344 voice->modenv_val = x;
00345 voice->modenv_count++;
00346 fluid_check_fpe ("voice_write mod env");
00347
00348
00349
00350 if (voice->ticks >= voice->modlfo_delay)
00351 {
00352 voice->modlfo_val += voice->modlfo_incr;
00353
00354 if (voice->modlfo_val > 1.0)
00355 {
00356 voice->modlfo_incr = -voice->modlfo_incr;
00357 voice->modlfo_val = (fluid_real_t) 2.0 - voice->modlfo_val;
00358 }
00359 else if (voice->modlfo_val < -1.0)
00360 {
00361 voice->modlfo_incr = -voice->modlfo_incr;
00362 voice->modlfo_val = (fluid_real_t) -2.0 - voice->modlfo_val;
00363 }
00364 }
00365
00366 fluid_check_fpe ("voice_write mod LFO");
00367
00368
00369
00370 if (voice->ticks >= voice->viblfo_delay)
00371 {
00372 voice->viblfo_val += voice->viblfo_incr;
00373
00374 if (voice->viblfo_val > (fluid_real_t) 1.0)
00375 {
00376 voice->viblfo_incr = -voice->viblfo_incr;
00377 voice->viblfo_val = (fluid_real_t) 2.0 - voice->viblfo_val;
00378 }
00379 else if (voice->viblfo_val < -1.0)
00380 {
00381 voice->viblfo_incr = -voice->viblfo_incr;
00382 voice->viblfo_val = (fluid_real_t) -2.0 - voice->viblfo_val;
00383 }
00384 }
00385
00386 fluid_check_fpe ("voice_write Vib LFO");
00387
00388
00389
00390
00391
00392
00393
00394
00395 if (voice->volenv_section == FLUID_VOICE_ENVDELAY)
00396 goto post_process;
00397
00398 if (voice->volenv_section == FLUID_VOICE_ENVATTACK)
00399 {
00400
00401
00402
00403 target_amp = fluid_atten2amp (voice->attenuation)
00404 * fluid_cb2amp (voice->modlfo_val * -voice->modlfo_to_vol)
00405 * voice->volenv_val;
00406 }
00407 else
00408 {
00409 fluid_real_t amplitude_that_reaches_noise_floor;
00410 fluid_real_t amp_max;
00411
00412 target_amp = fluid_atten2amp (voice->attenuation)
00413 * fluid_cb2amp (960.0f * (1.0f - voice->volenv_val)
00414 + voice->modlfo_val * -voice->modlfo_to_vol);
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428 if (voice->has_looped)
00429 amplitude_that_reaches_noise_floor = voice->amplitude_that_reaches_noise_floor_loop;
00430 else
00431 amplitude_that_reaches_noise_floor = voice->amplitude_that_reaches_noise_floor_nonloop;
00432
00433
00434
00435
00436
00437
00438
00439 amp_max = fluid_atten2amp (voice->min_attenuation_cB) * voice->volenv_val;
00440
00441
00442
00443
00444 if (amp_max < amplitude_that_reaches_noise_floor)
00445 {
00446 fluid_profile (FLUID_PROF_VOICE_RELEASE, voice->ref);
00447 fluid_voice_off (voice);
00448 goto post_process;
00449 }
00450 }
00451
00452
00453 voice->amp_incr = (target_amp - voice->amp) / FLUID_BUFSIZE;
00454
00455 fluid_check_fpe ("voice_write amplitude calculation");
00456
00457
00458 if ((voice->amp == 0.0f) && (voice->amp_incr == 0.0f))
00459 goto post_process;
00460
00461
00462
00463
00464
00465 voice->phase_incr = fluid_ct2hz_real
00466 (voice->pitch + voice->modlfo_val * voice->modlfo_to_pitch
00467 + voice->viblfo_val * voice->viblfo_to_pitch
00468 + voice->modenv_val * voice->modenv_to_pitch) / voice->root_pitch;
00469
00470 fluid_check_fpe ("voice_write phase calculation");
00471
00472
00473 if (voice->phase_incr == 0) voice->phase_incr = 1;
00474
00475
00476
00477
00478 fres = fluid_ct2hz(voice->fres
00479 + voice->modlfo_val * voice->modlfo_to_fc
00480 + voice->modenv_val * voice->modenv_to_fc);
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 if (fres > 0.45f * voice->output_rate)
00496 fres = 0.45f * voice->output_rate;
00497 else if (fres < 5)
00498 fres = 5;
00499
00500
00501 if ((abs (fres - voice->last_fres) > 0.01))
00502 {
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 fluid_real_t omega = (fluid_real_t) (2.0 * M_PI * (fres / 44100.0f));
00519 fluid_real_t sin_coeff = (fluid_real_t) sin(omega);
00520 fluid_real_t cos_coeff = (fluid_real_t) cos(omega);
00521 fluid_real_t alpha_coeff = sin_coeff / (2.0f * voice->q_lin);
00522 fluid_real_t a0_inv = 1.0f / (1.0f + alpha_coeff);
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 fluid_real_t a1_temp = -2.0f * cos_coeff * a0_inv;
00534 fluid_real_t a2_temp = (1.0f - alpha_coeff) * a0_inv;
00535 fluid_real_t b1_temp = (1.0f - cos_coeff) * a0_inv * voice->filter_gain;
00536
00537 fluid_real_t b02_temp = b1_temp * 0.5f;
00538
00539 if (voice->filter_startup)
00540 {
00541
00542
00543
00544 voice->a1 = a1_temp;
00545 voice->a2 = a2_temp;
00546 voice->b02 = b02_temp;
00547 voice->b1 = b1_temp;
00548 voice->filter_coeff_incr_count = 0;
00549 voice->filter_startup = 0;
00550
00551 }
00552 else
00553 {
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564 #define FILTER_TRANSITION_SAMPLES (FLUID_BUFSIZE)
00565
00566 voice->a1_incr = (a1_temp - voice->a1) / FILTER_TRANSITION_SAMPLES;
00567 voice->a2_incr = (a2_temp - voice->a2) / FILTER_TRANSITION_SAMPLES;
00568 voice->b02_incr = (b02_temp - voice->b02) / FILTER_TRANSITION_SAMPLES;
00569 voice->b1_incr = (b1_temp - voice->b1) / FILTER_TRANSITION_SAMPLES;
00570
00571 voice->filter_coeff_incr_count = FILTER_TRANSITION_SAMPLES;
00572 }
00573 voice->last_fres = fres;
00574 fluid_check_fpe ("voice_write filter calculation");
00575 }
00576
00577
00578 fluid_check_fpe ("voice_write DSP coefficients");
00579
00580
00581
00582
00583
00584
00585
00586 voice->dsp_buf = dsp_buf;
00587
00588 switch (voice->interp_method)
00589 {
00590 case FLUID_INTERP_NONE:
00591 count = fluid_dsp_float_interpolate_none (voice);
00592 break;
00593 case FLUID_INTERP_LINEAR:
00594 count = fluid_dsp_float_interpolate_linear (voice);
00595 break;
00596 case FLUID_INTERP_4THORDER:
00597 default:
00598 count = fluid_dsp_float_interpolate_4th_order (voice);
00599 break;
00600 case FLUID_INTERP_7THORDER:
00601 count = fluid_dsp_float_interpolate_7th_order (voice);
00602 break;
00603 }
00604
00605 fluid_check_fpe ("voice_write interpolation");
00606
00607 if (count > 0)
00608 fluid_voice_effects (voice, count, dsp_left_buf, dsp_right_buf,
00609 dsp_reverb_buf, dsp_chorus_buf);
00610
00611
00612 if (count < FLUID_BUFSIZE)
00613 {
00614 fluid_profile(FLUID_PROF_VOICE_RELEASE, voice->ref);
00615 fluid_voice_off(voice);
00616 }
00617
00618 post_process:
00619 voice->ticks += FLUID_BUFSIZE;
00620 fluid_check_fpe ("voice_write postprocess");
00621 return FLUID_OK;
00622 }
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 static inline void
00656 fluid_voice_effects (fluid_voice_t *voice, int count,
00657 fluid_real_t* dsp_left_buf, fluid_real_t* dsp_right_buf,
00658 fluid_real_t* dsp_reverb_buf, fluid_real_t* dsp_chorus_buf)
00659 {
00660
00661 fluid_real_t dsp_hist1 = voice->hist1;
00662 fluid_real_t dsp_hist2 = voice->hist2;
00663
00664
00665 fluid_real_t dsp_a1 = voice->a1;
00666 fluid_real_t dsp_a2 = voice->a2;
00667 fluid_real_t dsp_b02 = voice->b02;
00668 fluid_real_t dsp_b1 = voice->b1;
00669 fluid_real_t dsp_a1_incr = voice->a1_incr;
00670 fluid_real_t dsp_a2_incr = voice->a2_incr;
00671 fluid_real_t dsp_b02_incr = voice->b02_incr;
00672 fluid_real_t dsp_b1_incr = voice->b1_incr;
00673 int dsp_filter_coeff_incr_count = voice->filter_coeff_incr_count;
00674
00675 fluid_real_t *dsp_buf = voice->dsp_buf;
00676
00677 fluid_real_t dsp_centernode;
00678 int dsp_i;
00679 float v;
00680
00681
00682
00683
00684 if (fabs (dsp_hist1) < 1e-20) dsp_hist1 = 0.0f;
00685
00686
00687
00688
00689
00690
00691 if (dsp_filter_coeff_incr_count > 0)
00692 {
00693
00694 for (dsp_i = 0; dsp_i < count; dsp_i++)
00695 {
00696
00697 dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
00698 dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
00699 dsp_hist2 = dsp_hist1;
00700 dsp_hist1 = dsp_centernode;
00701
00702 if (dsp_filter_coeff_incr_count-- > 0)
00703 {
00704 dsp_a1 += dsp_a1_incr;
00705 dsp_a2 += dsp_a2_incr;
00706 dsp_b02 += dsp_b02_incr;
00707 dsp_b1 += dsp_b1_incr;
00708 }
00709 }
00710 }
00711 else
00712 {
00713 for (dsp_i = 0; dsp_i < count; dsp_i++)
00714 {
00715 dsp_centernode = dsp_buf[dsp_i] - dsp_a1 * dsp_hist1 - dsp_a2 * dsp_hist2;
00716 dsp_buf[dsp_i] = dsp_b02 * (dsp_centernode + dsp_hist2) + dsp_b1 * dsp_hist1;
00717 dsp_hist2 = dsp_hist1;
00718 dsp_hist1 = dsp_centernode;
00719 }
00720 }
00721
00722
00723
00724
00725
00726
00727 if ((-0.5 < voice->pan) && (voice->pan < 0.5))
00728 {
00729
00730 for (dsp_i = 0; dsp_i < count; dsp_i++)
00731 {
00732 v = voice->amp_left * dsp_buf[dsp_i];
00733 dsp_left_buf[dsp_i] += v;
00734 dsp_right_buf[dsp_i] += v;
00735 }
00736 }
00737 else
00738 {
00739 if (voice->amp_left != 0.0)
00740 {
00741 for (dsp_i = 0; dsp_i < count; dsp_i++)
00742 dsp_left_buf[dsp_i] += voice->amp_left * dsp_buf[dsp_i];
00743 }
00744
00745 if (voice->amp_right != 0.0)
00746 {
00747 for (dsp_i = 0; dsp_i < count; dsp_i++)
00748 dsp_right_buf[dsp_i] += voice->amp_right * dsp_buf[dsp_i];
00749 }
00750 }
00751
00752
00753 if ((dsp_reverb_buf != NULL) && (voice->amp_reverb != 0.0))
00754 {
00755 for (dsp_i = 0; dsp_i < count; dsp_i++)
00756 dsp_reverb_buf[dsp_i] += voice->amp_reverb * dsp_buf[dsp_i];
00757 }
00758
00759
00760 if ((dsp_chorus_buf != NULL) && (voice->amp_chorus != 0))
00761 {
00762 for (dsp_i = 0; dsp_i < count; dsp_i++)
00763 dsp_chorus_buf[dsp_i] += voice->amp_chorus * dsp_buf[dsp_i];
00764 }
00765
00766 voice->hist1 = dsp_hist1;
00767 voice->hist2 = dsp_hist2;
00768 voice->a1 = dsp_a1;
00769 voice->a2 = dsp_a2;
00770 voice->b02 = dsp_b02;
00771 voice->b1 = dsp_b1;
00772 voice->filter_coeff_incr_count = dsp_filter_coeff_incr_count;
00773
00774 fluid_check_fpe ("voice_effects");
00775 }
00776
00777
00778
00779
00780 fluid_channel_t*
00781 fluid_voice_get_channel(fluid_voice_t* voice)
00782 {
00783 return voice->channel;
00784 }
00785
00786
00787
00788
00789 void fluid_voice_start(fluid_voice_t* voice)
00790 {
00791
00792
00793
00794
00795 fluid_voice_calculate_runtime_synthesis_parameters(voice);
00796
00797
00798
00799 voice->check_sample_sanity_flag=FLUID_SAMPLESANITY_STARTUP;
00800
00801 voice->ref = fluid_profile_ref();
00802
00803 voice->status = FLUID_VOICE_ON;
00804 }
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 int
00817 fluid_voice_calculate_runtime_synthesis_parameters(fluid_voice_t* voice)
00818 {
00819 fluid_real_t x;
00820 fluid_real_t q_db;
00821 int i;
00822
00823 int list_of_generators_to_initialize[35] = {
00824 GEN_STARTADDROFS,
00825 GEN_ENDADDROFS,
00826 GEN_STARTLOOPADDROFS,
00827 GEN_ENDLOOPADDROFS,
00828
00829 GEN_MODLFOTOPITCH,
00830 GEN_VIBLFOTOPITCH,
00831 GEN_MODENVTOPITCH,
00832 GEN_FILTERFC,
00833 GEN_FILTERQ,
00834 GEN_MODLFOTOFILTERFC,
00835 GEN_MODENVTOFILTERFC,
00836
00837 GEN_MODLFOTOVOL,
00838
00839 GEN_CHORUSSEND,
00840 GEN_REVERBSEND,
00841 GEN_PAN,
00842
00843
00844
00845 GEN_MODLFODELAY,
00846 GEN_MODLFOFREQ,
00847 GEN_VIBLFODELAY,
00848 GEN_VIBLFOFREQ,
00849 GEN_MODENVDELAY,
00850 GEN_MODENVATTACK,
00851 GEN_MODENVHOLD,
00852 GEN_MODENVDECAY,
00853
00854 GEN_MODENVRELEASE,
00855
00856
00857 GEN_VOLENVDELAY,
00858 GEN_VOLENVATTACK,
00859 GEN_VOLENVHOLD,
00860 GEN_VOLENVDECAY,
00861
00862 GEN_VOLENVRELEASE,
00863
00864
00865
00866 GEN_KEYNUM,
00867 GEN_VELOCITY,
00868 GEN_ATTENUATION,
00869
00870
00871
00872 GEN_OVERRIDEROOTKEY,
00873 GEN_PITCH,
00874 -1};
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895 for (i = 0; i < voice->mod_count; i++) {
00896 fluid_mod_t* mod = &voice->mod[i];
00897 fluid_real_t modval = fluid_mod_get_value(mod, voice->channel, voice);
00898 int dest_gen_index = mod->dest;
00899 fluid_gen_t* dest_gen = &voice->gen[dest_gen_index];
00900 dest_gen->mod += modval;
00901
00902 }
00903
00904
00905
00906
00907
00908
00909
00910
00911 if (fluid_channel_has_tuning(voice->channel)) {
00912
00913 #define __pitch(_k) fluid_tuning_get_pitch(tuning, _k)
00914 fluid_tuning_t* tuning = fluid_channel_get_tuning(voice->channel);
00915 voice->gen[GEN_PITCH].val = (__pitch(60) + (voice->gen[GEN_SCALETUNE].val / 100.0f *
00916 (__pitch(voice->key) - __pitch(60))));
00917 } else {
00918 voice->gen[GEN_PITCH].val = (voice->gen[GEN_SCALETUNE].val * (voice->key - 60.0f)
00919 + 100.0f * 60.0f);
00920 }
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936 for (i = 0; list_of_generators_to_initialize[i] != -1; i++) {
00937 fluid_voice_update_param(voice, list_of_generators_to_initialize[i]);
00938 }
00939
00940
00941 voice->min_attenuation_cB = fluid_voice_get_lower_boundary_for_attenuation(voice);
00942
00943 return FLUID_OK;
00944 }
00945
00946
00947
00948
00949 int calculate_hold_decay_buffers(fluid_voice_t* voice, int gen_base,
00950 int gen_key2base, int is_decay)
00951 {
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961 fluid_real_t timecents;
00962 fluid_real_t seconds;
00963 int buffers;
00964
00965
00966
00967
00968
00969
00970
00971
00972 timecents = (_GEN(voice, gen_base) + _GEN(voice, gen_key2base) * (60.0 - voice->key));
00973
00974
00975 if (is_decay){
00976
00977 if (timecents > 8000.0) {
00978 timecents = 8000.0;
00979 }
00980 } else {
00981
00982 if (timecents > 5000) {
00983 timecents = 5000.0;
00984 }
00985
00986
00987
00988 if (timecents <= -32768.) {
00989 return 0;
00990 }
00991 }
00992
00993 if (timecents < -12000.0) {
00994 timecents = -12000.0;
00995 }
00996
00997 seconds = fluid_tc2sec(timecents);
00998
00999
01000
01001 buffers = (int)(((fluid_real_t)voice->output_rate * seconds)
01002 / (fluid_real_t)FLUID_BUFSIZE
01003 +0.5);
01004
01005 return buffers;
01006 }
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027 void
01028 fluid_voice_update_param(fluid_voice_t* voice, int gen)
01029 {
01030 double q_dB;
01031 fluid_real_t x;
01032 fluid_real_t y;
01033 unsigned int count;
01034
01035 switch (gen) {
01036
01037 case GEN_PAN:
01038
01039 voice->pan = _GEN(voice, GEN_PAN);
01040 voice->amp_left = fluid_pan(voice->pan, 1) * voice->synth_gain / 32768.0f;
01041 voice->amp_right = fluid_pan(voice->pan, 0) * voice->synth_gain / 32768.0f;
01042 break;
01043
01044 case GEN_ATTENUATION:
01045 voice->attenuation = _GEN(voice, GEN_ATTENUATION);
01046
01047
01048
01049
01050 fluid_clip(voice->attenuation, 0.0, 1440.0);
01051 break;
01052
01053
01054
01055
01056 case GEN_PITCH:
01057 case GEN_COARSETUNE:
01058 case GEN_FINETUNE:
01059
01060 voice->pitch = (_GEN(voice, GEN_PITCH)
01061 + 100.0f * _GEN(voice, GEN_COARSETUNE)
01062 + _GEN(voice, GEN_FINETUNE));
01063 break;
01064
01065 case GEN_REVERBSEND:
01066
01067 voice->reverb_send = _GEN(voice, GEN_REVERBSEND) / 1000.0f;
01068 fluid_clip(voice->reverb_send, 0.0, 1.0);
01069 voice->amp_reverb = voice->reverb_send * voice->synth_gain / 32768.0f;
01070 break;
01071
01072 case GEN_CHORUSSEND:
01073
01074 voice->chorus_send = _GEN(voice, GEN_CHORUSSEND) / 1000.0f;
01075 fluid_clip(voice->chorus_send, 0.0, 1.0);
01076 voice->amp_chorus = voice->chorus_send * voice->synth_gain / 32768.0f;
01077 break;
01078
01079 case GEN_OVERRIDEROOTKEY:
01080
01081
01082
01083
01084
01085
01086 if (voice->gen[GEN_OVERRIDEROOTKEY].val > -1) {
01087 voice->root_pitch = voice->gen[GEN_OVERRIDEROOTKEY].val * 100.0f
01088 - voice->sample->pitchadj;
01089 } else {
01090 voice->root_pitch = voice->sample->origpitch * 100.0f - voice->sample->pitchadj;
01091 }
01092 voice->root_pitch = fluid_ct2hz(voice->root_pitch);
01093 if (voice->sample != NULL) {
01094 voice->root_pitch *= (fluid_real_t) voice->output_rate / voice->sample->samplerate;
01095 }
01096 break;
01097
01098 case GEN_FILTERFC:
01099
01100
01101
01102
01103
01104 voice->fres = _GEN(voice, GEN_FILTERFC);
01105
01106
01107
01108 voice->last_fres = -1.0f;
01109 break;
01110
01111 case GEN_FILTERQ:
01112
01113
01114 q_dB = _GEN(voice, GEN_FILTERQ) / 10.0f;
01115
01116
01117 fluid_clip(q_dB, 0.0f, 96.0f);
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134 q_dB -= 3.01f;
01135
01136
01137
01138 voice->q_lin = (fluid_real_t) (pow(10.0f, q_dB / 20.0f));
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151 voice->filter_gain = (fluid_real_t) (1.0 / sqrt(voice->q_lin));
01152
01153
01154 voice->last_fres = -1.;
01155 break;
01156
01157 case GEN_MODLFOTOPITCH:
01158 voice->modlfo_to_pitch = _GEN(voice, GEN_MODLFOTOPITCH);
01159 fluid_clip(voice->modlfo_to_pitch, -12000.0, 12000.0);
01160 break;
01161
01162 case GEN_MODLFOTOVOL:
01163 voice->modlfo_to_vol = _GEN(voice, GEN_MODLFOTOVOL);
01164 fluid_clip(voice->modlfo_to_vol, -960.0, 960.0);
01165 break;
01166
01167 case GEN_MODLFOTOFILTERFC:
01168 voice->modlfo_to_fc = _GEN(voice, GEN_MODLFOTOFILTERFC);
01169 fluid_clip(voice->modlfo_to_fc, -12000, 12000);
01170 break;
01171
01172 case GEN_MODLFODELAY:
01173 x = _GEN(voice, GEN_MODLFODELAY);
01174 fluid_clip(x, -12000.0f, 5000.0f);
01175 voice->modlfo_delay = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x));
01176 break;
01177
01178 case GEN_MODLFOFREQ:
01179
01180
01181
01182 x = _GEN(voice, GEN_MODLFOFREQ);
01183 fluid_clip(x, -16000.0f, 4500.0f);
01184 voice->modlfo_incr = (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate);
01185 break;
01186
01187 case GEN_VIBLFOFREQ:
01188
01189
01190
01191
01192
01193 x = _GEN(voice, GEN_VIBLFOFREQ);
01194 fluid_clip(x, -16000.0f, 4500.0f);
01195 voice->viblfo_incr = (4.0f * FLUID_BUFSIZE * fluid_act2hz(x) / voice->output_rate);
01196 break;
01197
01198 case GEN_VIBLFODELAY:
01199 x = _GEN(voice,GEN_VIBLFODELAY);
01200 fluid_clip(x, -12000.0f, 5000.0f);
01201 voice->viblfo_delay = (unsigned int) (voice->output_rate * fluid_tc2sec_delay(x));
01202 break;
01203
01204 case GEN_VIBLFOTOPITCH:
01205 voice->viblfo_to_pitch = _GEN(voice, GEN_VIBLFOTOPITCH);
01206 fluid_clip(voice->viblfo_to_pitch, -12000.0, 12000.0);
01207 break;
01208
01209 case GEN_KEYNUM:
01210
01211
01212
01213
01214
01215
01216
01217
01218 x = _GEN(voice, GEN_KEYNUM);
01219 if (x >= 0){
01220 voice->key = x;
01221 }
01222 break;
01223
01224 case GEN_VELOCITY:
01225
01226
01227
01228
01229
01230
01231
01232 x = _GEN(voice, GEN_VELOCITY);
01233 if (x > 0) {
01234 voice->vel = x;
01235 }
01236 break;
01237
01238 case GEN_MODENVTOPITCH:
01239 voice->modenv_to_pitch = _GEN(voice, GEN_MODENVTOPITCH);
01240 fluid_clip(voice->modenv_to_pitch, -12000.0, 12000.0);
01241 break;
01242
01243 case GEN_MODENVTOFILTERFC:
01244 voice->modenv_to_fc = _GEN(voice,GEN_MODENVTOFILTERFC);
01245
01246
01247
01248
01249
01250 fluid_clip(voice->modenv_to_fc, -12000.0, 12000.0);
01251 break;
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265 case GEN_STARTADDROFS:
01266 case GEN_STARTADDRCOARSEOFS:
01267 if (voice->sample != NULL) {
01268 voice->start = (voice->sample->start
01269 + (int) _GEN(voice, GEN_STARTADDROFS)
01270 + 32768 * (int) _GEN(voice, GEN_STARTADDRCOARSEOFS));
01271 voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
01272 }
01273 break;
01274 case GEN_ENDADDROFS:
01275 case GEN_ENDADDRCOARSEOFS:
01276 if (voice->sample != NULL) {
01277 voice->end = (voice->sample->end
01278 + (int) _GEN(voice, GEN_ENDADDROFS)
01279 + 32768 * (int) _GEN(voice, GEN_ENDADDRCOARSEOFS));
01280 voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
01281 }
01282 break;
01283 case GEN_STARTLOOPADDROFS:
01284 case GEN_STARTLOOPADDRCOARSEOFS:
01285 if (voice->sample != NULL) {
01286 voice->loopstart = (voice->sample->loopstart
01287 + (int) _GEN(voice, GEN_STARTLOOPADDROFS)
01288 + 32768 * (int) _GEN(voice, GEN_STARTLOOPADDRCOARSEOFS));
01289 voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
01290 }
01291 break;
01292
01293 case GEN_ENDLOOPADDROFS:
01294 case GEN_ENDLOOPADDRCOARSEOFS:
01295 if (voice->sample != NULL) {
01296 voice->loopend = (voice->sample->loopend
01297 + (int) _GEN(voice, GEN_ENDLOOPADDROFS)
01298 + 32768 * (int) _GEN(voice, GEN_ENDLOOPADDRCOARSEOFS));
01299 voice->check_sample_sanity_flag = FLUID_SAMPLESANITY_CHECK;
01300 }
01301 break;
01302
01303
01304 #define NUM_BUFFERS_DELAY(_v) (unsigned int) (voice->output_rate * fluid_tc2sec_delay(_v) / FLUID_BUFSIZE)
01305 #define NUM_BUFFERS_ATTACK(_v) (unsigned int) (voice->output_rate * fluid_tc2sec_attack(_v) / FLUID_BUFSIZE)
01306 #define NUM_BUFFERS_RELEASE(_v) (unsigned int) (voice->output_rate * fluid_tc2sec_release(_v) / FLUID_BUFSIZE)
01307
01308
01309
01310
01311
01312
01313
01314 case GEN_VOLENVDELAY:
01315 x = _GEN(voice, GEN_VOLENVDELAY);
01316 fluid_clip(x, -12000.0f, 5000.0f);
01317 count = NUM_BUFFERS_DELAY(x);
01318 voice->volenv_data[FLUID_VOICE_ENVDELAY].count = count;
01319 voice->volenv_data[FLUID_VOICE_ENVDELAY].coeff = 0.0f;
01320 voice->volenv_data[FLUID_VOICE_ENVDELAY].incr = 0.0f;
01321 voice->volenv_data[FLUID_VOICE_ENVDELAY].min = -1.0f;
01322 voice->volenv_data[FLUID_VOICE_ENVDELAY].max = 1.0f;
01323 break;
01324
01325 case GEN_VOLENVATTACK:
01326 x = _GEN(voice, GEN_VOLENVATTACK);
01327 fluid_clip(x, -12000.0f, 8000.0f);
01328 count = 1 + NUM_BUFFERS_ATTACK(x);
01329 voice->volenv_data[FLUID_VOICE_ENVATTACK].count = count;
01330 voice->volenv_data[FLUID_VOICE_ENVATTACK].coeff = 1.0f;
01331 voice->volenv_data[FLUID_VOICE_ENVATTACK].incr = count ? 1.0f / count : 0.0f;
01332 voice->volenv_data[FLUID_VOICE_ENVATTACK].min = -1.0f;
01333 voice->volenv_data[FLUID_VOICE_ENVATTACK].max = 1.0f;
01334 break;
01335
01336 case GEN_VOLENVHOLD:
01337 case GEN_KEYTOVOLENVHOLD:
01338 count = calculate_hold_decay_buffers(voice, GEN_VOLENVHOLD, GEN_KEYTOVOLENVHOLD, 0);
01339 voice->volenv_data[FLUID_VOICE_ENVHOLD].count = count;
01340 voice->volenv_data[FLUID_VOICE_ENVHOLD].coeff = 1.0f;
01341 voice->volenv_data[FLUID_VOICE_ENVHOLD].incr = 0.0f;
01342 voice->volenv_data[FLUID_VOICE_ENVHOLD].min = -1.0f;
01343 voice->volenv_data[FLUID_VOICE_ENVHOLD].max = 2.0f;
01344 break;
01345
01346 case GEN_VOLENVDECAY:
01347 case GEN_VOLENVSUSTAIN:
01348 case GEN_KEYTOVOLENVDECAY:
01349 y = 1.0f - 0.001f * _GEN(voice, GEN_VOLENVSUSTAIN);
01350 fluid_clip(y, 0.0f, 1.0f);
01351 count = calculate_hold_decay_buffers(voice, GEN_VOLENVDECAY, GEN_KEYTOVOLENVDECAY, 1);
01352 voice->volenv_data[FLUID_VOICE_ENVDECAY].count = count;
01353 voice->volenv_data[FLUID_VOICE_ENVDECAY].coeff = 1.0f;
01354 voice->volenv_data[FLUID_VOICE_ENVDECAY].incr = count ? -1.0f / count : 0.0f;
01355 voice->volenv_data[FLUID_VOICE_ENVDECAY].min = y;
01356 voice->volenv_data[FLUID_VOICE_ENVDECAY].max = 2.0f;
01357 break;
01358
01359 case GEN_VOLENVRELEASE:
01360 x = _GEN(voice, GEN_VOLENVRELEASE);
01361 fluid_clip(x, FLUID_MIN_VOLENVRELEASE, 8000.0f);
01362 count = 1 + NUM_BUFFERS_RELEASE(x);
01363 voice->volenv_data[FLUID_VOICE_ENVRELEASE].count = count;
01364 voice->volenv_data[FLUID_VOICE_ENVRELEASE].coeff = 1.0f;
01365 voice->volenv_data[FLUID_VOICE_ENVRELEASE].incr = count ? -1.0f / count : 0.0f;
01366 voice->volenv_data[FLUID_VOICE_ENVRELEASE].min = 0.0f;
01367 voice->volenv_data[FLUID_VOICE_ENVRELEASE].max = 1.0f;
01368 break;
01369
01370
01371 case GEN_MODENVDELAY:
01372 x = _GEN(voice, GEN_MODENVDELAY);
01373 fluid_clip(x, -12000.0f, 5000.0f);
01374 voice->modenv_data[FLUID_VOICE_ENVDELAY].count = NUM_BUFFERS_DELAY(x);
01375 voice->modenv_data[FLUID_VOICE_ENVDELAY].coeff = 0.0f;
01376 voice->modenv_data[FLUID_VOICE_ENVDELAY].incr = 0.0f;
01377 voice->modenv_data[FLUID_VOICE_ENVDELAY].min = -1.0f;
01378 voice->modenv_data[FLUID_VOICE_ENVDELAY].max = 1.0f;
01379 break;
01380
01381 case GEN_MODENVATTACK:
01382 x = _GEN(voice, GEN_MODENVATTACK);
01383 fluid_clip(x, -12000.0f, 8000.0f);
01384 count = 1 + NUM_BUFFERS_ATTACK(x);
01385 voice->modenv_data[FLUID_VOICE_ENVATTACK].count = count;
01386 voice->modenv_data[FLUID_VOICE_ENVATTACK].coeff = 1.0f;
01387 voice->modenv_data[FLUID_VOICE_ENVATTACK].incr = count ? 1.0f / count : 0.0f;
01388 voice->modenv_data[FLUID_VOICE_ENVATTACK].min = -1.0f;
01389 voice->modenv_data[FLUID_VOICE_ENVATTACK].max = 1.0f;
01390 break;
01391
01392 case GEN_MODENVHOLD:
01393 case GEN_KEYTOMODENVHOLD:
01394 count = calculate_hold_decay_buffers(voice, GEN_MODENVHOLD, GEN_KEYTOMODENVHOLD, 0);
01395 voice->modenv_data[FLUID_VOICE_ENVHOLD].count = count;
01396 voice->modenv_data[FLUID_VOICE_ENVHOLD].coeff = 1.0f;
01397 voice->modenv_data[FLUID_VOICE_ENVHOLD].incr = 0.0f;
01398 voice->modenv_data[FLUID_VOICE_ENVHOLD].min = -1.0f;
01399 voice->modenv_data[FLUID_VOICE_ENVHOLD].max = 2.0f;
01400 break;
01401
01402 case GEN_MODENVDECAY:
01403 case GEN_MODENVSUSTAIN:
01404 case GEN_KEYTOMODENVDECAY:
01405 count = calculate_hold_decay_buffers(voice, GEN_MODENVDECAY, GEN_KEYTOMODENVDECAY, 1);
01406 y = 1.0f - 0.001f * _GEN(voice, GEN_MODENVSUSTAIN);
01407 fluid_clip(y, 0.0f, 1.0f);
01408 voice->modenv_data[FLUID_VOICE_ENVDECAY].count = count;
01409 voice->modenv_data[FLUID_VOICE_ENVDECAY].coeff = 1.0f;
01410 voice->modenv_data[FLUID_VOICE_ENVDECAY].incr = count ? -1.0f / count : 0.0f;
01411 voice->modenv_data[FLUID_VOICE_ENVDECAY].min = y;
01412 voice->modenv_data[FLUID_VOICE_ENVDECAY].max = 2.0f;
01413 break;
01414
01415 case GEN_MODENVRELEASE:
01416 x = _GEN(voice, GEN_MODENVRELEASE);
01417 fluid_clip(x, -12000.0f, 8000.0f);
01418 count = 1 + NUM_BUFFERS_RELEASE(x);
01419 voice->modenv_data[FLUID_VOICE_ENVRELEASE].count = count;
01420 voice->modenv_data[FLUID_VOICE_ENVRELEASE].coeff = 1.0f;
01421 voice->modenv_data[FLUID_VOICE_ENVRELEASE].incr = count ? -1.0f / count : 0.0;
01422 voice->modenv_data[FLUID_VOICE_ENVRELEASE].min = 0.0f;
01423 voice->modenv_data[FLUID_VOICE_ENVRELEASE].max = 2.0f;
01424 break;
01425
01426 }
01427 }
01428
01456 int fluid_voice_modulate(fluid_voice_t* voice, int cc, int ctrl)
01457 {
01458 int i, k;
01459 fluid_mod_t* mod;
01460 int gen;
01461 fluid_real_t modval;
01462
01463
01464
01465 for (i = 0; i < voice->mod_count; i++) {
01466
01467 mod = &voice->mod[i];
01468
01469
01470
01471 if (fluid_mod_has_source(mod, cc, ctrl)) {
01472
01473 gen = fluid_mod_get_dest(mod);
01474 modval = 0.0;
01475
01476
01477
01478 for (k = 0; k < voice->mod_count; k++) {
01479 if (fluid_mod_has_dest(&voice->mod[k], gen)) {
01480 modval += fluid_mod_get_value(&voice->mod[k], voice->channel, voice);
01481 }
01482 }
01483
01484 fluid_gen_set_mod(&voice->gen[gen], modval);
01485
01486
01487
01488
01489 fluid_voice_update_param(voice, gen);
01490 }
01491 }
01492 return FLUID_OK;
01493 }
01494
01502 int fluid_voice_modulate_all(fluid_voice_t* voice)
01503 {
01504 fluid_mod_t* mod;
01505 int i, k, gen;
01506 fluid_real_t modval;
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517 for (i = 0; i < voice->mod_count; i++) {
01518
01519 mod = &voice->mod[i];
01520 gen = fluid_mod_get_dest(mod);
01521 modval = 0.0;
01522
01523
01524
01525 for (k = 0; k < voice->mod_count; k++) {
01526 if (fluid_mod_has_dest(&voice->mod[k], gen)) {
01527 modval += fluid_mod_get_value(&voice->mod[k], voice->channel, voice);
01528 }
01529 }
01530
01531 fluid_gen_set_mod(&voice->gen[gen], modval);
01532
01533
01534
01535 fluid_voice_update_param(voice, gen);
01536 }
01537
01538 return FLUID_OK;
01539 }
01540
01541
01542
01543
01544 int
01545 fluid_voice_noteoff(fluid_voice_t* voice)
01546 {
01547 fluid_profile(FLUID_PROF_VOICE_NOTE, voice->ref);
01548
01549 if (voice->channel && fluid_channel_sustained(voice->channel)) {
01550 voice->status = FLUID_VOICE_SUSTAINED;
01551 } else {
01552 if (voice->volenv_section == FLUID_VOICE_ENVATTACK) {
01553
01554
01555
01556
01557
01558
01559 if (voice->volenv_val > 0){
01560 fluid_real_t lfo = voice->modlfo_val * -voice->modlfo_to_vol;
01561 fluid_real_t amp = voice->volenv_val * pow (10.0, lfo / -200);
01562 fluid_real_t env_value = - ((-200 * log (amp) / log (10.0) - lfo) / 960.0 - 1);
01563 fluid_clip (env_value, 0.0, 1.0);
01564 voice->volenv_val = env_value;
01565 }
01566 }
01567 voice->volenv_section = FLUID_VOICE_ENVRELEASE;
01568 voice->volenv_count = 0;
01569 voice->modenv_section = FLUID_VOICE_ENVRELEASE;
01570 voice->modenv_count = 0;
01571 }
01572
01573 return FLUID_OK;
01574 }
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587 int
01588 fluid_voice_kill_excl(fluid_voice_t* voice){
01589
01590 if (!_PLAYING(voice)) {
01591 return FLUID_OK;
01592 }
01593
01594
01595
01596
01597 fluid_voice_gen_set(voice, GEN_EXCLUSIVECLASS, 0);
01598
01599
01600 if (voice->volenv_section != FLUID_VOICE_ENVRELEASE){
01601 voice->volenv_section = FLUID_VOICE_ENVRELEASE;
01602 voice->volenv_count = 0;
01603 voice->modenv_section = FLUID_VOICE_ENVRELEASE;
01604 voice->modenv_count = 0;
01605 }
01606
01607
01608
01609 fluid_voice_gen_set(voice, GEN_VOLENVRELEASE, -200);
01610 fluid_voice_update_param(voice, GEN_VOLENVRELEASE);
01611
01612
01613 fluid_voice_gen_set(voice, GEN_MODENVRELEASE, -200);
01614 fluid_voice_update_param(voice, GEN_MODENVRELEASE);
01615
01616 return FLUID_OK;
01617 }
01618
01619
01620
01621
01622
01623
01624
01625
01626 int
01627 fluid_voice_off(fluid_voice_t* voice)
01628 {
01629 fluid_profile(FLUID_PROF_VOICE_RELEASE, voice->ref);
01630
01631 voice->chan = NO_CHANNEL;
01632 voice->volenv_section = FLUID_VOICE_ENVFINISHED;
01633 voice->volenv_count = 0;
01634 voice->modenv_section = FLUID_VOICE_ENVFINISHED;
01635 voice->modenv_count = 0;
01636 voice->status = FLUID_VOICE_OFF;
01637
01638
01639 if (voice->sample) {
01640 fluid_sample_decr_ref(voice->sample);
01641 voice->sample = NULL;
01642 }
01643
01644 return FLUID_OK;
01645 }
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658 void
01659 fluid_voice_add_mod(fluid_voice_t* voice, fluid_mod_t* mod, int mode)
01660 {
01661 int i;
01662
01663
01664
01665
01666
01667
01668
01669 if (((mod->flags1 & FLUID_MOD_CC) == 0)
01670 && ((mod->src1 != 0)
01671 && (mod->src1 != 2)
01672 && (mod->src1 != 3)
01673 && (mod->src1 != 10)
01674 && (mod->src1 != 13)
01675 && (mod->src1 != 14)
01676 && (mod->src1 != 16))) {
01677 FLUID_LOG(FLUID_WARN, "Ignoring invalid controller, using non-CC source %i.", mod->src1);
01678 return;
01679 }
01680
01681 if (mode == FLUID_VOICE_ADD) {
01682
01683
01684 for (i = 0; i < voice->mod_count; i++) {
01685 if (fluid_mod_test_identity(&voice->mod[i], mod)) {
01686
01687 voice->mod[i].amount += mod->amount;
01688 return;
01689 }
01690 }
01691
01692 } else if (mode == FLUID_VOICE_OVERWRITE) {
01693
01694
01695 for (i = 0; i < voice->mod_count; i++) {
01696 if (fluid_mod_test_identity(&voice->mod[i], mod)) {
01697
01698 voice->mod[i].amount = mod->amount;
01699 return;
01700 }
01701 }
01702 }
01703
01704
01705
01706
01707 if (voice->mod_count < FLUID_NUM_MOD) {
01708 fluid_mod_clone(&voice->mod[voice->mod_count++], mod);
01709 }
01710 }
01711
01712 unsigned int fluid_voice_get_id(fluid_voice_t* voice)
01713 {
01714 return voice->id;
01715 }
01716
01717 int fluid_voice_is_playing(fluid_voice_t* voice)
01718 {
01719 return _PLAYING(voice);
01720 }
01721
01722
01723
01724
01725
01726
01727
01728
01729
01730
01731
01732
01733
01734 fluid_real_t fluid_voice_get_lower_boundary_for_attenuation(fluid_voice_t* voice)
01735 {
01736 int i;
01737 fluid_mod_t* mod;
01738 fluid_real_t possible_att_reduction_cB=0;
01739 fluid_real_t lower_bound;
01740
01741 for (i = 0; i < voice->mod_count; i++) {
01742 mod = &voice->mod[i];
01743
01744
01745 if ((mod->dest == GEN_ATTENUATION)
01746 && ((mod->flags1 & FLUID_MOD_CC) || (mod->flags2 & FLUID_MOD_CC))) {
01747
01748 fluid_real_t current_val = fluid_mod_get_value(mod, voice->channel, voice);
01749 fluid_real_t v = fabs(mod->amount);
01750
01751 if ((mod->src1 == FLUID_MOD_PITCHWHEEL)
01752 || (mod->flags1 & FLUID_MOD_BIPOLAR)
01753 || (mod->flags2 & FLUID_MOD_BIPOLAR)
01754 || (mod->amount < 0)) {
01755
01756 v *= -1.0;
01757 } else {
01758
01759 v = 0;
01760 }
01761
01762
01763
01764
01765
01766
01767 if (current_val > v){
01768 possible_att_reduction_cB += (current_val - v);
01769 }
01770 }
01771 }
01772
01773 lower_bound = voice->attenuation-possible_att_reduction_cB;
01774
01775
01776 if (lower_bound < 0) {
01777 lower_bound = 0;
01778 }
01779 return lower_bound;
01780 }
01781
01782
01783
01784
01785
01786
01787
01788 void fluid_voice_check_sample_sanity(fluid_voice_t* voice)
01789 {
01790 int min_index_nonloop=(int) voice->sample->start;
01791 int max_index_nonloop=(int) voice->sample->end;
01792
01793
01794 int min_index_loop=(int) voice->sample->start + FLUID_MIN_LOOP_PAD;
01795 int max_index_loop=(int) voice->sample->end - FLUID_MIN_LOOP_PAD + 1;
01796 fluid_check_fpe("voice_check_sample_sanity start");
01797
01798 if (!voice->check_sample_sanity_flag){
01799 return;
01800 }
01801
01802 #if 0
01803 printf("Sample from %i to %i\n",voice->sample->start, voice->sample->end);
01804 printf("Sample loop from %i %i\n",voice->sample->loopstart, voice->sample->loopend);
01805 printf("Playback from %i to %i\n", voice->start, voice->end);
01806 printf("Playback loop from %i to %i\n",voice->loopstart, voice->loopend);
01807 #endif
01808
01809
01810 if (voice->start < min_index_nonloop){
01811 voice->start = min_index_nonloop;
01812 } else if (voice->start > max_index_nonloop){
01813 voice->start = max_index_nonloop;
01814 }
01815
01816
01817 if (voice->end < min_index_nonloop){
01818 voice->end = min_index_nonloop;
01819 } else if (voice->end > max_index_nonloop){
01820 voice->end = max_index_nonloop;
01821 }
01822
01823
01824 if (voice->start > voice->end){
01825 int temp = voice->start;
01826 voice->start = voice->end;
01827 voice->end = temp;
01828
01829 }
01830
01831
01832 if (voice->start == voice->end){
01833 fluid_voice_off(voice);
01834 return;
01835 }
01836
01837 if ((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE)
01838 || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)) {
01839
01840 if (voice->loopstart < min_index_loop){
01841 voice->loopstart = min_index_loop;
01842 } else if (voice->loopstart > max_index_loop){
01843 voice->loopstart = max_index_loop;
01844 }
01845
01846
01847 if (voice->loopend < min_index_loop){
01848 voice->loopend = min_index_loop;
01849 } else if (voice->loopend > max_index_loop){
01850 voice->loopend = max_index_loop;
01851 }
01852
01853
01854 if (voice->loopstart > voice->loopend){
01855 int temp = voice->loopstart;
01856 voice->loopstart = voice->loopend;
01857 voice->loopend = temp;
01858
01859 }
01860
01861
01862 if (voice->loopend < voice->loopstart + FLUID_MIN_LOOP_SIZE){
01863 voice->gen[GEN_SAMPLEMODE].val = FLUID_UNLOOPED;
01864 }
01865
01866
01867
01868 if ((int)voice->loopstart >= (int)voice->sample->loopstart
01869 && (int)voice->loopend <= (int)voice->sample->loopend){
01870
01871 if (voice->sample->amplitude_that_reaches_noise_floor_is_valid){
01872 voice->amplitude_that_reaches_noise_floor_loop=voice->sample->amplitude_that_reaches_noise_floor / voice->synth_gain;
01873 } else {
01874
01875 voice->amplitude_that_reaches_noise_floor_loop=voice->amplitude_that_reaches_noise_floor_nonloop;
01876 };
01877 };
01878
01879 }
01880
01881
01882 if (voice->check_sample_sanity_flag & FLUID_SAMPLESANITY_STARTUP){
01883 if (max_index_loop - min_index_loop < FLUID_MIN_LOOP_SIZE){
01884 if ((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE)
01885 || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)){
01886 voice->gen[GEN_SAMPLEMODE].val = FLUID_UNLOOPED;
01887 }
01888 }
01889
01890
01891
01892 fluid_phase_set_int(voice->phase, voice->start);
01893 }
01894
01895
01896
01897 if (((_SAMPLEMODE(voice) == FLUID_LOOP_UNTIL_RELEASE) && (voice->volenv_section < FLUID_VOICE_ENVRELEASE))
01898 || (_SAMPLEMODE(voice) == FLUID_LOOP_DURING_RELEASE)) {
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908
01909
01910 int index_in_sample = fluid_phase_index(voice->phase);
01911 if (index_in_sample >= voice->loopend){
01912
01913 fluid_phase_set_int(voice->phase, voice->loopstart);
01914 }
01915 }
01916
01917
01918
01919
01920 voice->check_sample_sanity_flag=0;
01921 #if 0
01922 printf("Sane? playback loop from %i to %i\n", voice->loopstart, voice->loopend);
01923 #endif
01924 fluid_check_fpe("voice_check_sample_sanity");
01925 }
01926
01927
01928 int fluid_voice_set_param(fluid_voice_t* voice, int gen, fluid_real_t nrpn_value, int abs)
01929 {
01930 voice->gen[gen].nrpn = nrpn_value;
01931 voice->gen[gen].flags = (abs)? GEN_ABS_NRPN : GEN_SET;
01932 fluid_voice_update_param(voice, gen);
01933 return FLUID_OK;
01934 }
01935
01936 int fluid_voice_set_gain(fluid_voice_t* voice, fluid_real_t gain)
01937 {
01938
01939 if (gain < 0.0000001){
01940 gain = 0.0000001;
01941 }
01942
01943 voice->synth_gain = gain;
01944 voice->amp_left = fluid_pan(voice->pan, 1) * gain / 32768.0f;
01945 voice->amp_right = fluid_pan(voice->pan, 0) * gain / 32768.0f;
01946 voice->amp_reverb = voice->reverb_send * gain / 32768.0f;
01947 voice->amp_chorus = voice->chorus_send * gain / 32768.0f;
01948
01949 return FLUID_OK;
01950 }
01951
01952
01953
01954
01955
01956
01957 int fluid_voice_optimize_sample(fluid_sample_t* s)
01958 {
01959 signed short peak_max = 0;
01960 signed short peak_min = 0;
01961 signed short peak;
01962 fluid_real_t normalized_amplitude_during_loop;
01963 double result;
01964 int i;
01965
01966
01967 if (!s->valid) return (FLUID_OK);
01968
01969 if (!s->amplitude_that_reaches_noise_floor_is_valid){
01970
01971 for (i = (int)s->loopstart; i < (int) s->loopend; i ++){
01972 signed short val = s->data[i];
01973 if (val > peak_max) {
01974 peak_max = val;
01975 } else if (val < peak_min) {
01976 peak_min = val;
01977 }
01978 }
01979
01980
01981 if (peak_max >- peak_min){
01982 peak = peak_max;
01983 } else {
01984 peak =- peak_min;
01985 };
01986 if (peak == 0){
01987
01988 peak = 1;
01989 };
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999 normalized_amplitude_during_loop = ((fluid_real_t)peak)/32768.;
02000 result = FLUID_NOISE_FLOOR / normalized_amplitude_during_loop;
02001
02002
02003 s->amplitude_that_reaches_noise_floor = (double)result;
02004 s->amplitude_that_reaches_noise_floor_is_valid = 1;
02005 #if 0
02006 printf("Sample peak detection: factor %f\n", (double)result);
02007 #endif
02008 };
02009 return FLUID_OK;
02010 }