📄 playmidi.c
字号:
for(i = 0; i < max_voices; i++) { voice[i].status = VOICE_FREE; voice[i].temper_instant = 0; voice[i].chorus_link = i; } upper_voices = 0; memset(vidq_head, 0, sizeof(vidq_head)); memset(vidq_tail, 0, sizeof(vidq_tail));}static void kill_note(int i){ voice[i].status = VOICE_DIE; if(!prescanning_flag) ctl_note_event(i);}static void kill_all_voices(void){ int i, uv = upper_voices; for(i = 0; i < uv; i++) if(voice[i].status & ~(VOICE_FREE | VOICE_DIE)) kill_note(i); memset(vidq_head, 0, sizeof(vidq_head)); memset(vidq_tail, 0, sizeof(vidq_tail));}static void reset_drum_controllers(struct DrumParts *d[], int note){ int i,j; if(note == -1) { for(i = 0; i < 128; i++) if(d[i] != NULL) { d[i]->drum_panning = NO_PANNING; for(j=0;j<6;j++) {d[i]->drum_envelope_rate[j] = -1;} d[i]->pan_random = 0; d[i]->drum_level = 1.0f; d[i]->coarse = 0; d[i]->fine = 0; d[i]->delay_level = -1; d[i]->chorus_level = -1; d[i]->reverb_level = -1; d[i]->play_note = -1; d[i]->drum_cutoff_freq = 0; d[i]->drum_resonance = 0; init_rx_drum(d[i]); } } else { d[note]->drum_panning = NO_PANNING; for(j = 0; j < 6; j++) {d[note]->drum_envelope_rate[j] = -1;} d[note]->pan_random = 0; d[note]->drum_level = 1.0f; d[note]->coarse = 0; d[note]->fine = 0; d[note]->delay_level = -1; d[note]->chorus_level = -1; d[note]->reverb_level = -1; d[note]->play_note = -1; d[note]->drum_cutoff_freq = 0; d[note]->drum_resonance = 0; init_rx_drum(d[note]); }}static void reset_module_dependent_controllers(int c){ int module = get_module(); switch(module) { /* TONE MAP-0 NUMBER */ case MODULE_SC55: channel[c].tone_map0_number = 1; break; case MODULE_SC88: channel[c].tone_map0_number = 2; break; case MODULE_SC88PRO: channel[c].tone_map0_number = 3; break; case MODULE_SC8850: channel[c].tone_map0_number = 4; break; default: channel[c].tone_map0_number = 0; break; } switch(module) { /* MIDI Controllers */ case MODULE_SC55: channel[c].mod.lfo1_pitch_depth = 10; break; case MODULE_SC88: channel[c].mod.lfo1_pitch_depth = 10; break; case MODULE_SC88PRO: channel[c].mod.lfo1_pitch_depth = 10; break; default: channel[c].mod.lfo1_pitch_depth = 50; break; }}static void reset_nrpn_controllers(int c){ int i; /* NRPN */ reset_drum_controllers(channel[c].drums, -1); channel[c].vibrato_ratio = 1.0; channel[c].vibrato_depth = 0; channel[c].vibrato_delay = 0; channel[c].param_cutoff_freq = 0; channel[c].param_resonance = 0; channel[c].cutoff_freq_coef = 1.0; channel[c].resonance_dB = 0; /* System Exclusive */ channel[c].dry_level = 127; channel[c].eq_gs = 1; channel[c].insertion_effect = 0; channel[c].velocity_sense_depth = 0x40; channel[c].velocity_sense_offset = 0x40; channel[c].pitch_offset_fine = 0; if(play_system_mode == GS_SYSTEM_MODE) {channel[c].assign_mode = 1;} else { if(ISDRUMCHANNEL(c)) {channel[c].assign_mode = 1;} else {channel[c].assign_mode = 2;} } for (i = 0; i < 12; i++) channel[c].scale_tuning[i] = 0; channel[c].prev_scale_tuning = 0; channel[c].temper_type = 0; init_channel_layer(c); init_part_eq_xg(&(channel[c].eq_xg)); /* channel pressure & polyphonic key pressure control */ init_midi_controller(&(channel[c].mod)); init_midi_controller(&(channel[c].bend)); init_midi_controller(&(channel[c].caf)); init_midi_controller(&(channel[c].paf)); init_midi_controller(&(channel[c].cc1)); init_midi_controller(&(channel[c].cc2)); channel[c].bend.pitch = 2; init_rx(c); channel[c].note_limit_high = 127; channel[c].note_limit_low = 0; channel[c].vel_limit_high = 127; channel[c].vel_limit_low = 0; free_drum_effect(c); channel[c].legato = 0; channel[c].damper_mode = 0; channel[c].loop_timeout = 0; channel[c].sysex_gs_msb_addr = channel[c].sysex_gs_msb_val = channel[c].sysex_xg_msb_addr = channel[c].sysex_xg_msb_val = channel[c].sysex_msb_addr = channel[c].sysex_msb_val = 0;}/* Process the Reset All Controllers event */static void reset_controllers(int c){ int j; /* Some standard says, although the SCC docs say 0. */ if(play_system_mode == XG_SYSTEM_MODE) channel[c].volume = 100; else channel[c].volume = 90; if (prescanning_flag) { if (channel[c].volume > mainvolume_max) { /* pick maximum value of mainvolume */ mainvolume_max = channel[c].volume; ctl->cmsg(CMSG_INFO,VERB_DEBUG,"ME_MAINVOLUME/max (CH:%d VAL:%#x)",c,mainvolume_max); } } channel[c].expression = 127; /* SCC-1 does this. */ channel[c].sustain = 0; channel[c].sostenuto = 0; channel[c].pitchbend = 0x2000; channel[c].pitchfactor = 0; /* to be computed */ channel[c].mod.val = 0; channel[c].bend.val = 0; channel[c].caf.val = 0; channel[c].paf.val = 0; channel[c].cc1.val = 0; channel[c].cc2.val = 0; channel[c].portamento_time_lsb = 0; channel[c].portamento_time_msb = 0; channel[c].porta_control_ratio = 0; channel[c].portamento = 0; channel[c].last_note_fine = -1; for(j = 0; j < 6; j++) {channel[c].envelope_rate[j] = -1;} update_portamento_controls(c); set_reverb_level(c, -1); if(opt_chorus_control == 1) channel[c].chorus_level = 0; else channel[c].chorus_level = -opt_chorus_control; channel[c].mono = 0; channel[c].delay_level = 0;}static void redraw_controllers(int c){ ctl_mode_event(CTLE_VOLUME, 1, c, channel[c].volume); ctl_mode_event(CTLE_EXPRESSION, 1, c, channel[c].expression); ctl_mode_event(CTLE_SUSTAIN, 1, c, channel[c].sustain); ctl_mode_event(CTLE_MOD_WHEEL, 1, c, channel[c].mod.val); ctl_mode_event(CTLE_PITCH_BEND, 1, c, channel[c].pitchbend); ctl_prog_event(c); ctl_mode_event(CTLE_TEMPER_TYPE, 1, c, channel[c].temper_type); ctl_mode_event(CTLE_MUTE, 1, c, (IS_SET_CHANNELMASK(channel_mute, c)) ? 1 : 0); ctl_mode_event(CTLE_CHORUS_EFFECT, 1, c, get_chorus_level(c)); ctl_mode_event(CTLE_REVERB_EFFECT, 1, c, get_reverb_level(c));}static void reset_midi(int playing){ int i, cnt; for (i = 0; i < MAX_CHANNELS; i++) { reset_controllers(i); reset_nrpn_controllers(i); reset_module_dependent_controllers(i); /* The rest of these are unaffected * by the Reset All Controllers event */ channel[i].program = default_program[i]; channel[i].panning = NO_PANNING; channel[i].pan_random = 0; /* tone bank or drum set */ if (ISDRUMCHANNEL(i)) { channel[i].bank = 0; channel[i].altassign = drumset[0]->alt; } else { if (special_tonebank >= 0) channel[i].bank = special_tonebank; else channel[i].bank = default_tonebank; } channel[i].bank_lsb = channel[i].bank_msb = 0; if (play_system_mode == XG_SYSTEM_MODE && i % 16 == 9) channel[i].bank_msb = 127; /* Use MSB=127 for XG */ update_rpn_map(i, RPN_ADDR_FFFF, 0); channel[i].special_sample = 0; channel[i].key_shift = 0; channel[i].mapID = get_default_mapID(i); channel[i].lasttime = 0; } if (playing) { kill_all_voices(); if (temper_type_mute) { if (temper_type_mute & 1) FILL_CHANNELMASK(channel_mute); else CLEAR_CHANNELMASK(channel_mute); } for (i = 0; i < MAX_CHANNELS; i++) redraw_controllers(i); if (midi_streaming && free_instruments_afterwards) { free_instruments(0); /* free unused memory */ cnt = free_global_mblock(); if (cnt > 0) ctl->cmsg(CMSG_INFO, VERB_VERBOSE, "%d memory blocks are free", cnt); } } else reset_voices(); master_volume_ratio = 0xffff; adjust_amplification(); init_freq_table_tuning(); if (current_file_info) { COPY_CHANNELMASK(drumchannels, current_file_info->drumchannels); COPY_CHANNELMASK(drumchannel_mask, current_file_info->drumchannel_mask); } else { COPY_CHANNELMASK(drumchannels, default_drumchannels); COPY_CHANNELMASK(drumchannel_mask, default_drumchannel_mask); } ctl_mode_event(CTLE_MASTER_VOLUME, 0, amplification, 0); ctl_mode_event(CTLE_KEY_OFFSET, 0, note_key_offset, 0); ctl_mode_event(CTLE_TIME_RATIO, 0, 100 / midi_time_ratio + 0.5, 0);}void recompute_freq(int v){ int i; int ch = voice[v].channel; int note = voice[v].note; int32 tuning = 0; int8 st = channel[ch].scale_tuning[note % 12]; int8 tt = channel[ch].temper_type; uint8 tp = channel[ch].rpnmap[RPN_ADDR_0003]; int32 f; int pb = channel[ch].pitchbend; int32 tmp; FLOAT_T pf, root_freq; int32 a; Voice *vp = &(voice[v]); if (! voice[v].sample->sample_rate) return; if (! opt_modulation_wheel) channel[ch].mod.val = 0; if (! opt_portamento) voice[v].porta_control_ratio = 0; voice[v].vibrato_control_ratio = voice[v].orig_vibrato_control_ratio; if (voice[v].vibrato_control_ratio || channel[ch].mod.val > 0) { /* This instrument has vibrato. Invalidate any precomputed * sample_increments. */ /* MIDI controllers LFO pitch depth */ if (opt_channel_pressure || opt_modulation_wheel) { vp->vibrato_depth = vp->sample->vibrato_depth + channel[ch].vibrato_depth; vp->vibrato_depth += get_midi_controller_pitch_depth(&(channel[ch].mod)) + get_midi_controller_pitch_depth(&(channel[ch].bend)) + get_midi_controller_pitch_depth(&(channel[ch].caf)) + get_midi_controller_pitch_depth(&(channel[ch].paf)) + get_midi_controller_pitch_depth(&(channel[ch].cc1)) + get_midi_controller_pitch_depth(&(channel[ch].cc2)); if (vp->vibrato_depth > VIBRATO_DEPTH_MAX) {vp->vibrato_depth = VIBRATO_DEPTH_MAX;} else if (vp->vibrato_depth < 1) {vp->vibrato_depth = 1;} if (vp->sample->vibrato_depth < 0) { /* in opposite phase */ vp->vibrato_depth = -vp->vibrato_depth; } } /* fill parameters for modulation wheel */ if (channel[ch].mod.val > 0) { if(vp->vibrato_control_ratio == 0) { vp->vibrato_control_ratio = vp->orig_vibrato_control_ratio = (int)(cnv_Hz_to_vib_ratio(5.0) * channel[ch].vibrato_ratio); } vp->vibrato_delay = 0; } for (i = 0; i < VIBRATO_SAMPLE_INCREMENTS; i++) vp->vibrato_sample_increment[i] = 0; vp->cache = NULL; } /* fine: [0..128] => [-256..256] * 1 coarse = 256 fine (= 1 note) * 1 fine = 2^5 tuning */ tuning = (channel[ch].rpnmap[RPN_ADDR_0001] - 0x40 + (channel[ch].rpnmap[RPN_ADDR_0002] - 0x40) * 64) << 7; /* for NRPN Coarse Pitch of Drum (GS) & Fine Pitch of Drum (XG) */ if (ISDRUMCHANNEL(ch) && channel[ch].drums[note] != NULL && (channel[ch].drums[note]->fine || channel[ch].drums[note]->coarse)) { tuning += (channel[ch].drums[note]->fine + channel[ch].drums[note]->coarse * 64) << 7; } /* MIDI controllers pitch control */ if (opt_channel_pressure) { tuning += get_midi_controller_pitch(&(channel[ch].mod)) + get_midi_controller_pitch(&(channel[ch].bend)) + get_midi_controller_pitch(&(channel[ch].caf)) + get_midi_controller_pitch(&(channel[ch].paf)) + get_midi_controller_pitch(&(channel[ch].cc1)) + get_midi_controller_pitch(&(channel[ch].cc2)); } if (opt_modulation_envelope) { if (voice[v].sample->tremolo_to_pitch) { tuning += lookup_triangular(voice[v].tremolo_phase >> RATE_SHIFT) * (voice[v].sample->tremolo_to_pitch << 13) / 100.0 + 0.5; channel[ch].pitchfactor = 0; } if (voice[v].sample->modenv_to_pitch) { tuning += voice[v].last_modenv_volume * (voice[v].sample->modenv_to_pitch << 13) / 100.0 + 0.5; channel[ch].pitchfactor = 0; } } /* GS/XG - Scale Tuning */ if (! ISDRUMCHANNEL(ch)) { tuning += (st << 13) / 100.0 + 0.5; if (st != channel[ch].prev_scale_tuning) { channel[ch].pitchfactor = 0; channel[ch].prev_scale_tuning = st; } } if (! opt_pure_intonation && opt_temper_control && voice[v].temper_instant) { switch (tt) { case 0: f = freq_table_tuning[tp][note]; break; case 1: if (current_temper_keysig < 8) f = freq_table_pytha[current_temper_freq_table][note]; else f = freq_table_pytha[current_temper_freq_table + 12][note]; break; case 2: if (current_temper_keysig < 8) f = freq_table_meantone[current_temper_freq_table + ((temper_adj) ? 36 : 0)][note]; else f = freq_table_meantone[current_temper_freq_table + ((temper_adj) ? 24 : 12)][note]; break; case 3: if (current_temper_keysig < 8) f = freq_table_pureint[current_temper_freq_table + ((temper_adj) ? 36 : 0)][note]; else f = freq_table_pureint[current_temper_freq_table + ((temper_adj) ? 24 : 12)][note]; break; default: /* user-defined temperament */ if ((tt -= 0x40) >= 0 && tt < 4) { if (current_temper_keysig < 8) f = freq_table_user[tt][current_temper_freq_table + ((temper_adj) ? 36 : 0)][note]; else f = freq_table_user[tt][current_temper_freq_table + ((temper_adj) ? 24 : 12)][note]; } else f = freq_table[note]; break; } voice[v].orig_frequency = f; } if (! voice[v].porta_control_ratio) { if (tuning == 0 && pb == 0x2000) voice[v].frequency = voice[v].orig_frequency; else { pb -= 0x2000; if (! channel[ch].pitchfactor) { /* Damn. Somebody bent the pitch. */ tmp = pb * channel[ch].rpnmap[RPN_ADDR_0000] + tuning; if (tmp >= 0) channel[ch].pitchfactor = bend_fine[tmp >> 5 & 0xff] * bend_coarse[tmp >> 13 & 0x7f]; else channel[ch].pitchfactor = 1.0 /
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -