📄 playmidi.c
字号:
(bend_fine[-tmp >> 5 & 0xff] * bend_coarse[-tmp >> 13 & 0x7f]); } voice[v].frequency = voice[v].orig_frequency * channel[ch].pitchfactor; if (voice[v].frequency != voice[v].orig_frequency) voice[v].cache = NULL; } } else { /* Portamento */ pb -= 0x2000; tmp = pb * channel[ch].rpnmap[RPN_ADDR_0000] + (voice[v].porta_pb << 5) + tuning; if (tmp >= 0) pf = bend_fine[tmp >> 5 & 0xff] * bend_coarse[tmp >> 13 & 0x7f]; else pf = 1.0 / (bend_fine[-tmp >> 5 & 0xff] * bend_coarse[-tmp >> 13 & 0x7f]); voice[v].frequency = voice[v].orig_frequency * pf; voice[v].cache = NULL; } root_freq = voice[v].sample->root_freq; a = TIM_FSCALE(((double) voice[v].sample->sample_rate * ((double)voice[v].frequency + channel[ch].pitch_offset_fine)) / (root_freq * play_mode->rate), FRACTION_BITS) + 0.5; /* need to preserve the loop direction */ voice[v].sample_increment = (voice[v].sample_increment >= 0) ? a : -a;#ifdef ABORT_AT_FATAL if (voice[v].sample_increment == 0) { fprintf(stderr, "Invalid sample increment a=%e %ld %ld %ld %ld%s\n", (double)a, (long) voice[v].sample->sample_rate, (long) voice[v].frequency, (long) voice[v].sample->root_freq, (long) play_mode->rate, (voice[v].cache) ? " (Cached)" : ""); abort(); }#endif /* ABORT_AT_FATAL */}static int32 calc_velocity(int32 ch,int32 vel){ int32 velocity; velocity = channel[ch].velocity_sense_depth * vel / 64 + (channel[ch].velocity_sense_offset - 64) * 2; if(velocity > 127) {velocity = 127;} return velocity;}static void recompute_voice_tremolo(int v){ Voice *vp = &(voice[v]); int ch = vp->channel; int32 depth = vp->sample->tremolo_depth; depth += get_midi_controller_amp_depth(&(channel[ch].mod)) + get_midi_controller_amp_depth(&(channel[ch].bend)) + get_midi_controller_amp_depth(&(channel[ch].caf)) + get_midi_controller_amp_depth(&(channel[ch].paf)) + get_midi_controller_amp_depth(&(channel[ch].cc1)) + get_midi_controller_amp_depth(&(channel[ch].cc2)); if(depth > 256) {depth = 256;} vp->tremolo_depth = depth;}static void recompute_amp(int v){ FLOAT_T tempamp; int ch = voice[v].channel; /* master_volume and sample->volume are percentages, used to scale * amplitude directly, NOT perceived volume * * all other MIDI volumes are linear in perceived volume, 0-127 * use a lookup table for the non-linear scalings */ if (opt_user_volume_curve) { tempamp = master_volume * voice[v].sample->volume * user_vol_table[calc_velocity(ch, voice[v].velocity)] * user_vol_table[channel[ch].volume] * user_vol_table[channel[ch].expression]; /* 21 bits */ } else if (play_system_mode == GM2_SYSTEM_MODE) { tempamp = master_volume * voice[v].sample->volume * gm2_vol_table[calc_velocity(ch, voice[v].velocity)] * /* velocity: not in GM2 standard */ gm2_vol_table[channel[ch].volume] * gm2_vol_table[channel[ch].expression]; /* 21 bits */ } else if(play_system_mode == GS_SYSTEM_MODE) { /* use measured curve */ tempamp = master_volume * voice[v].sample->volume * sc_vel_table[calc_velocity(ch, voice[v].velocity)] * sc_vol_table[channel[ch].volume] * sc_vol_table[channel[ch].expression]; /* 21 bits */ } else if (IS_CURRENT_MOD_FILE) { /* use linear curve */ tempamp = master_volume * voice[v].sample->volume * calc_velocity(ch, voice[v].velocity) * channel[ch].volume * channel[ch].expression; /* 21 bits */ } else { /* use generic exponential curve */ tempamp = master_volume * voice[v].sample->volume * perceived_vol_table[calc_velocity(ch, voice[v].velocity)] * perceived_vol_table[channel[ch].volume] * perceived_vol_table[channel[ch].expression]; /* 21 bits */ } /* every digital effect increases amplitude, * so that it must be reduced in advance. */ if (! (play_mode->encoding & PE_MONO) && (opt_reverb_control || opt_chorus_control || opt_delay_control || (opt_eq_control && (eq_status_gs.low_gain != 0x40 || eq_status_gs.high_gain != 0x40)) || opt_insertion_effect)) tempamp *= 1.35f * 0.55f; else tempamp *= 1.35f; /* NRPN - drum instrument tva level */ if(ISDRUMCHANNEL(ch)) { if(channel[ch].drums[voice[v].note] != NULL) { tempamp *= channel[ch].drums[voice[v].note]->drum_level; } tempamp *= (double)opt_drum_power * 0.01f; /* global drum power */ } /* MIDI controllers amplitude control */ if(opt_channel_pressure) { tempamp *= get_midi_controller_amp(&(channel[ch].mod)) * get_midi_controller_amp(&(channel[ch].bend)) * get_midi_controller_amp(&(channel[ch].caf)) * get_midi_controller_amp(&(channel[ch].paf)) * get_midi_controller_amp(&(channel[ch].cc1)) * get_midi_controller_amp(&(channel[ch].cc2)); recompute_voice_tremolo(v); } if (voice[v].fc.type != 0) { tempamp *= voice[v].fc.gain; /* filter gain */ } /* applying panning to amplitude */ if(!(play_mode->encoding & PE_MONO)) { if(voice[v].panning == 64) { voice[v].panned = PANNED_CENTER; voice[v].left_amp = voice[v].right_amp = TIM_FSCALENEG(tempamp * pan_table[64], 27); } else if (voice[v].panning < 2) { voice[v].panned = PANNED_LEFT; voice[v].left_amp = TIM_FSCALENEG(tempamp, 20); voice[v].right_amp = 0; } else if(voice[v].panning == 127) {#ifdef SMOOTH_MIXING if(voice[v].panned == PANNED_MYSTERY) { voice[v].old_left_mix = voice[v].old_right_mix; voice[v].old_right_mix = 0; }#endif voice[v].panned = PANNED_RIGHT; voice[v].left_amp = TIM_FSCALENEG(tempamp, 20); voice[v].right_amp = 0; } else {#ifdef SMOOTH_MIXING if(voice[v].panned == PANNED_RIGHT) { voice[v].old_right_mix = voice[v].old_left_mix; voice[v].old_left_mix = 0; }#endif voice[v].panned = PANNED_MYSTERY; voice[v].left_amp = TIM_FSCALENEG(tempamp * pan_table[128 - voice[v].panning], 27); voice[v].right_amp = TIM_FSCALENEG(tempamp * pan_table[voice[v].panning], 27); } } else { voice[v].panned = PANNED_CENTER; voice[v].left_amp = TIM_FSCALENEG(tempamp, 21); }}#define RESONANCE_COEFF 0.2393void recompute_channel_filter(int ch, int note){ double coef = 1.0f, reso = 0; if(channel[ch].special_sample > 0) {return;} /* Soft Pedal */ if(channel[ch].soft_pedal != 0) { if(note > 49) { /* tre corde */ coef *= 1.0 - 0.20 * ((double)channel[ch].soft_pedal) / 127.0f; } else { /* una corda (due corde) */ coef *= 1.0 - 0.25 * ((double)channel[ch].soft_pedal) / 127.0f; } } if(!ISDRUMCHANNEL(ch)) { /* NRPN Filter Cutoff */ coef *= pow(1.26, (double)(channel[ch].param_cutoff_freq) / 8.0f); /* NRPN Resonance */ reso = (double)channel[ch].param_resonance * RESONANCE_COEFF; } channel[ch].cutoff_freq_coef = coef; channel[ch].resonance_dB = reso;}void init_voice_filter(int i){ memset(&(voice[i].fc), 0, sizeof(FilterCoefficients)); if(opt_lpf_def && voice[i].sample->cutoff_freq) { voice[i].fc.orig_freq = voice[i].sample->cutoff_freq; voice[i].fc.orig_reso_dB = (double)voice[i].sample->resonance / 10.0f - 3.01f; if (voice[i].fc.orig_reso_dB < 0.0f) {voice[i].fc.orig_reso_dB = 0.0f;} if (opt_lpf_def == 2) { voice[i].fc.gain = 1.0; voice[i].fc.type = 2; } else if(opt_lpf_def == 1) { voice[i].fc.gain = pow(10.0f, -voice[i].fc.orig_reso_dB / 2.0f / 20.0f); voice[i].fc.type = 1; } voice[i].fc.start_flag = 0; } else { voice[i].fc.type = 0; }}#define CHAMBERLIN_RESONANCE_MAX 24.0void recompute_voice_filter(int v){ int ch = voice[v].channel, note = voice[v].note; double coef = 1.0, reso = 0, cent = 0, depth_cent = 0, freq; FilterCoefficients *fc = &(voice[v].fc); Sample *sp = (Sample *) &voice[v].sample; if(fc->type == 0) {return;} coef = channel[ch].cutoff_freq_coef; if(ISDRUMCHANNEL(ch) && channel[ch].drums[note] != NULL) { /* NRPN Drum Instrument Filter Cutoff */ coef *= pow(1.26, (double)(channel[ch].drums[note]->drum_cutoff_freq) / 8.0f); /* NRPN Drum Instrument Filter Resonance */ reso += (double)channel[ch].drums[note]->drum_resonance * RESONANCE_COEFF; } /* MIDI controllers filter cutoff control and LFO filter depth */ if(opt_channel_pressure) { cent += get_midi_controller_filter_cutoff(&(channel[ch].mod)) + get_midi_controller_filter_cutoff(&(channel[ch].bend)) + get_midi_controller_filter_cutoff(&(channel[ch].caf)) + get_midi_controller_filter_cutoff(&(channel[ch].paf)) + get_midi_controller_filter_cutoff(&(channel[ch].cc1)) + get_midi_controller_filter_cutoff(&(channel[ch].cc2)); depth_cent += get_midi_controller_filter_depth(&(channel[ch].mod)) + get_midi_controller_filter_depth(&(channel[ch].bend)) + get_midi_controller_filter_depth(&(channel[ch].caf)) + get_midi_controller_filter_depth(&(channel[ch].paf)) + get_midi_controller_filter_depth(&(channel[ch].cc1)) + get_midi_controller_filter_depth(&(channel[ch].cc2)); } if(sp->vel_to_fc) { /* velocity to filter cutoff frequency */ if(voice[v].velocity > sp->vel_to_fc_threshold) cent += sp->vel_to_fc * (double)(127 - voice[v].velocity) / 127.0f; else coef += sp->vel_to_fc * (double)(127 - sp->vel_to_fc_threshold) / 127.0f; } if(sp->vel_to_resonance) { /* velocity to filter resonance */ reso += (double)voice[v].velocity * sp->vel_to_resonance / 127.0f / 10.0f; } if(sp->key_to_fc) { /* filter cutoff key-follow */ cent += sp->key_to_fc * (double)(voice[v].note - sp->key_to_fc_bpo); } if(opt_modulation_envelope) { if(voice[v].sample->tremolo_to_fc + (int16)depth_cent) { cent += ((double)voice[v].sample->tremolo_to_fc + depth_cent) * lookup_triangular(voice[v].tremolo_phase >> RATE_SHIFT); } if(voice[v].sample->modenv_to_fc) { cent += (double)voice[v].sample->modenv_to_fc * voice[v].last_modenv_volume; } } if(cent != 0) {coef *= pow(2.0, cent / 1200.0f);} freq = (double)fc->orig_freq * coef; if (freq > play_mode->rate / 2) {freq = play_mode->rate / 2;} else if(freq < 5) {freq = 5;} else if(freq > 20000) {freq = 20000;} fc->freq = (int32)freq; fc->reso_dB = fc->orig_reso_dB + channel[ch].resonance_dB + reso; if(fc->reso_dB < 0.0f) {fc->reso_dB = 0.0f;} else if(fc->reso_dB > 96.0f) {fc->reso_dB = 96.0f;} if(fc->type == 1) { /* Chamberlin filter */ if(fc->freq > play_mode->rate / 6) { if (fc->start_flag == 0) {fc->type = 0;} /* turn off. */ else {fc->freq = play_mode->rate / 6;} } if(fc->reso_dB > CHAMBERLIN_RESONANCE_MAX) {fc->reso_dB = CHAMBERLIN_RESONANCE_MAX;} } else if(fc->type == 2) { /* Moog VCF */ if(fc->reso_dB > fc->orig_reso_dB / 2) { fc->gain = pow(10.0f, (fc->reso_dB - fc->orig_reso_dB / 2) / 20.0f); } } fc->start_flag = 1; /* filter is started. */}float calc_drum_tva_level(int ch, int note, int level){ int def_level, nbank, nprog; ToneBank *bank; if(channel[ch].special_sample > 0) {return 1.0;} nbank = channel[ch].bank; nprog = note; instrument_map(channel[ch].mapID, &nbank, &nprog); if(ISDRUMCHANNEL(ch)) { bank = drumset[nbank]; if(bank == NULL) {bank = drumset[0];} } else { return 1.0; } def_level = bank->tone[nprog].tva_level; if(def_level == -1 || def_level == 0) {def_level = 127;} else if(def_level > 127) {def_level = 127;} return (sc_drum_level_table[level] / sc_drum_level_table[def_level]);}static int32 calc_random_delay(int ch, int note){ int nbank, nprog; ToneBank *bank; if(channel[ch].special_sample > 0) {return 0;} nbank = channel[ch].bank; if(ISDRUMCHANNEL(ch)) { nprog = note; instrument_map(channel[ch].mapID, &nbank, &nprog); bank = drumset[nbank]; if (bank == NULL) {bank = drumset[0];} } else { nprog = channel[ch].program; if(nprog == SPECIAL_PROGRAM) {return 0;} instrument_map(channel[ch].mapID, &nbank, &nprog); bank = tonebank[nbank]; if(bank == NULL) {bank = tonebank[0];} } if (bank->tone[nprog].rnddelay == 0) {return 0;} else {return (int32)((double)bank->tone[nprog].rnddelay * play_mode->rate / 1000.0 * (get_pink_noise_light(&global_pink_noise_light) + 1.0f) * 0.5);}}void recompute_bank_parameter(int ch, int note){ int nbank, nprog; ToneBank *bank; struct DrumParts *drum; if(channel[ch].special_sample > 0) {return;} nbank = channel[ch].bank; if(ISDRUMCHANNEL(ch)) { nprog = note; instrument_map(channel[ch].mapID, &nbank, &nprog); bank = drumset[nbank]; if (bank == NULL) {bank = drumset[0];} if (channel[ch].drums[note] == NULL) play_midi_setup_drums(ch, note); drum = channel[ch].drums[note]; if (drum->reverb_level == -1 && bank->tone[nprog].reverb_send != -1) { drum->reverb_level = bank->tone[nprog].reverb_send; } if (drum->chorus_level == -1 && bank->tone[nprog].chorus_send != -1) { drum->chorus_level = bank->tone[nprog].chorus_send; } if (drum->delay_level == -1 && bank->tone[nprog].delay_send != -1) { drum->delay_level = bank->tone[nprog].delay_send; } } else { nprog = channel[ch].program; if (nprog == SPECIAL_PROGRAM) {return;} instrument_map(channel[ch].mapID, &nbank, &nprog); bank = tonebank[nbank]; if (bank == NULL) {bank = tonebank[0];} channel[ch].legato = bank->tone[nprog].legato; channel[ch].damper_mode = bank->tone[nprog].damper_mode; channel[ch].loop_timeout = bank->tone[nprog].loop_timeout; }}Instrument *play_midi_load_instrument(int dr, int bk, int prog){ ToneBank **bank = (dr) ? drumset : tonebank; Instrument *ip; int load_success = 0; if (bank[bk] == NULL) alloc_instrument_bank(dr, bk); if (bank[bk]->tone[prog].name) { /* Instrument is found. */ if ((ip = bank[bk]->tone[prog].instrument) == MAGIC_LOAD_INSTRUMENT#ifndef SUPPRESS_CHANNEL_LAYER || ip == NULL /* see also readmidi.c: groom_list(). */#endif ) {ip = bank[bk]->tone[prog].instrument = load_instrument(dr, bk, prog);} if (ip == NULL || IS_MAGIC_INSTRUMENT(ip)) { bank[bk]->tone[prog].instrument = MAGIC_ERROR_INSTRUMENT; } else { load_success = 1; } } else { /* Instrument is not found. Try to load the instrument from bank 0 */ if ((ip = bank[0]->tone[prog].instrument) == NULL || ip == MAGIC_LOAD_INSTRUMENT) ip = bank[0]->tone[prog].instrument = load_instrument(dr, 0, prog); if (ip == NULL || IS_MAGIC_INSTRUMENT(ip)) { bank[0]->tone[prog].instrument = MAGIC_ERROR_INSTRUMENT; } else { copy_tone_bank_element(&bank[bk]->tone[prog], &bank[0]->tone[prog]); bank[bk]->tone[prog].instrument = ip; load_success = 1; } } if (load_success) aq_add(NULL, 0); /* Update software buffer */ if (ip == MAGIC_ERROR_INSTRUMENT)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -