📄 m2m.c
字号:
"Couldn't open mod cfg file! Proceeding without it.");}/* Fill the delta time byte array used in the mod->midi output routine */int set_dt_array(unsigned char *dt_array, int32 delta_time){ int num_dt_bytes = 0, i = 0; int32 dt_byte; if (delta_time < 0) { ctl->cmsg(CMSG_INFO, VERB_NORMAL, "WTF? Delta Time = %ld", delta_time); delta_time = 0; } /* Delta time is variable length, max of 4 bytes long. Each byte contains 7 bits of the number. Every byte but the last one has an MSB of 1, while the last byte has an MSB of 0 to indicate it is the last byte. */ dt_byte = (delta_time & 0x0FFFFFFF) >> 21; if (dt_byte) { dt_array[i++] = dt_byte | 0x80; num_dt_bytes = 4; } dt_byte = (delta_time & 0x001FFFFF) >> 14; if (dt_byte || num_dt_bytes) { dt_array[i++] = dt_byte | 0x80; if (!num_dt_bytes) num_dt_bytes = 3; } dt_byte = (delta_time & 0x00003FFF) >> 7; if (dt_byte || num_dt_bytes) { dt_array[i++] = dt_byte | 0x80; if (!num_dt_bytes) num_dt_bytes = 2; } dt_byte = delta_time & 0x0000007F; dt_array[i] = dt_byte; if (!num_dt_bytes) num_dt_bytes = 1; return num_dt_bytes;}void scan_ahead_for_m2m_tweaks(MidiEvent * ev, int midi_ch, int midi_note, int samplenum){ int ch, event_type, init_ch, init_note, init_velocity; int32 bend = 0, lowbend = 0, highbend = 0; int32 pb_offset1 = 0, pb_offset2 = 0; int note_offset1 = 0, note_offset2 = 0; uint32 init_time, cur_time, old_time, cut_time = 0; Sample *sp; double a, bent_length = 0, delta_length; uint32 length; float root_freq, pitch, freq; init_time = cur_time = old_time = ev->time; init_ch = ev->channel; init_note = ev->a; init_velocity = ev->b; sp = special_patch[samplenum]->sample; root_freq = pitch_freq_table[36]; length = sp->data_length >> FRACTION_BITS; /* check for a pitch bend prior to the note */ if ((ev-1)->type == ME_PITCHWHEEL && (ev-1)->channel == init_ch) { bend = (ev-1)->b * 128 + (ev-1)->a; bend = ROUND((bend - 0x2000) * old_pb_sensitivity / (float) pb_sensitivity); bend += fine_tune[samplenum]; if (bend < lowbend) lowbend = bend; if (bend > highbend) highbend = bend; pitch = init_note + notes_per_pb * bend; freq = 13.75 * exp((pitch - 9) * 0.05776226505f); } else freq = pitch_freq_table[init_note]; a = (freq * sp->sample_rate) / (root_freq * play_mode->rate); for (++ev; ev->type != ME_EOT; ev++) { event_type = ev->type; if (event_type != ME_ALL_NOTES_OFF && event_type != ME_NOTEOFF && event_type != ME_PITCHWHEEL) continue; ch = ev->channel; if (ch != init_ch) continue; cur_time = ev->time; if (event_type == ME_ALL_NOTES_OFF) break; if (event_type == ME_NOTEOFF) { if (ev->a == init_note) break; continue; } delta_length = (cur_time - old_time) * a; if (!cut_time && bent_length + delta_length > length) { cut_time = ROUND(cur_time - (bent_length + delta_length - length) / delta_length * (cur_time - old_time)); } bent_length += delta_length; old_time = cur_time; bend = ev->b * 128 + ev->a; bend = ROUND((bend - 0x2000) * old_pb_sensitivity / (float) pb_sensitivity); bend += fine_tune[samplenum]; if (bend < lowbend) lowbend = bend; if (bend > highbend) highbend = bend; pitch = init_note + notes_per_pb * bend; freq = 13.75 * exp((pitch - 9) * 0.05776226505f); a = (freq * sp->sample_rate) / (root_freq * play_mode->rate); } delta_length = (cur_time - old_time) * a; if (!cut_time && bent_length + delta_length > length) { cut_time = ROUND(cur_time - (bent_length + delta_length - length) / delta_length * (cur_time - old_time)); } bent_length += delta_length; if (highbend > 8191) { pb_offset1 = highbend - 8191; note_offset1 = ceil(notes_per_pb * pb_offset1); pb_offset1 = -note_offset1 * pb_per_note; } if (lowbend < -8191) { pb_offset2 = lowbend - -8191; note_offset2 = floor(notes_per_pb * pb_offset2); pb_offset2 = -note_offset2 * pb_per_note; } if (note_offset1 > -note_offset2) { tweak_note_offset[midi_ch] = note_offset1; tweak_pb_offset[midi_ch] = pb_offset1; } else { tweak_note_offset[midi_ch] = note_offset2; tweak_pb_offset[midi_ch] = pb_offset2; } if (note_offset1 || note_offset2) num_big_pitch_slides++; if (highbend - lowbend > 16382) num_huge_pitch_slides++; /* hmm, need to kill this one early */ kill_early_time[init_ch] = 0; if (!(sp->modes & MODES_LOOPING)) { if (bent_length > length) { kill_early_note[init_ch] = midi_note + tweak_note_offset[midi_ch]; kill_early_velocity[init_ch] = init_velocity; kill_early_time[init_ch] = cut_time; kill_early_ch[init_ch] = midi_ch; } }}void m2m_kill_notes_early(MidiEvent * ev, double time){ int i, j; int chord, chord_type, chord_subtype; int extra, newnote; uint32 kill_time; int kill_sample; int kill_ch; int kill_n; /* kill notes early if unlooped samples are causing problems */ for (j = 0; j < 34; j++) { if (kill_early_time[j] && kill_early_time[j] <= ev->time) { kill_sample = current_track_sample[j]; kill_ch = kill_early_ch[j]; kill_time = ROUND(time - ((ev->time - kill_early_time[j]) * divisions_ratio) / samples_per_tick); /* looks like we got screwed by a tempo event, so skip it */ if (kill_time < last_track_event_time[kill_ch]) { kill_early_time[j] = 0; continue; } /* yet another tempo muck up */ if (current_channel_note[kill_ch] != kill_early_note[j]) { kill_early_time[j] = 0; continue; } if (kill_time > maxtime) maxtime = kill_time; kill_n = 3; newnote = kill_early_note[j]; while (newnote > 127) newnote -= 12; while (newnote < 0) newnote += 12; event[0] = 0x80 | (kill_ch & 0x0F); event[1] = newnote; event[2] = kill_early_velocity[j]; current_track_note[j] = -1; current_channel_note[kill_ch] = -1; /* resize the track event array */ length = track_size[kill_ch]; num_dt_bytes = set_dt_array(dt_array, kill_time - last_track_event_time[kill_ch]); track_size[kill_ch] += kill_n + num_dt_bytes; track_events[kill_ch] = safe_realloc(track_events[kill_ch], track_size[kill_ch] * sizeof(unsigned char)); /* save the delta_time */ p_track_event = track_events[kill_ch] + length; for (i = 0; i < num_dt_bytes; i++) { p_track_event[i] = dt_array[i]; } /* save the events */ p_track_event += num_dt_bytes; for (i = 0; i < kill_n; i++) { p_track_event[i] = event[i]; } /* spawn extra events for chords */ chord = sample_chords[kill_sample]; if (chord >= 0) { extra = 2; length = track_size[kill_ch]; track_size[kill_ch] += 4 * extra; track_events[kill_ch] = safe_realloc(track_events[kill_ch], track_size[kill_ch] * sizeof(unsigned char)); p_track_event = track_events[kill_ch] + length; for (i = 0; i < 3; i++) { chord_type = chord / 3; chord_subtype = chord % 3; newnote = event[kill_n - 2] + chord_table[chord_type][chord_subtype][i]; if (newnote == event[kill_n - 2]) continue; while (newnote > 127) newnote -= 12; while (newnote < 0) newnote += 12; p_track_event[0] = 0x00; p_track_event[1] = event[kill_n - 3]; p_track_event[2] = newnote; p_track_event[3] = event[kill_n - 1]; p_track_event += 4; } } last_track_event_time[kill_ch] = kill_time; kill_early_time[j] = 0; num_killed_early++; } }}void m2m_prescan(MidiEvent * ev){ int i, ch; /* find out which tracks will wind up with notes on them */ for (; ev->type != ME_EOT; ev++) { if (ev->type == ME_NOTEON || ev->type == ME_SET_PATCH) { ch = ev->channel; if (ch >= 25) ch++; if (ev->type == ME_NOTEON) { if (silent_samples[current_track_sample[ch]]) continue; tracks_useless[ch] = 0; /* move drums to drum channel */ if (is_drum_sample[current_track_sample[ch]]) ch = 9; else if (ch == 9) { non_drums_on_drums = 1; continue; } if (!tracks_enabled[ch]) { tracks_enabled[ch] = 1; num_tracks++; } } else current_track_sample[ch] = ev->a; } } for (i = 0; i < 34; i++) { if (!tracks_enabled[i]) { if (i != 9 && i != 25 && first_free_track < 0) first_free_track = i; } else { if (min_enabled_track < 0) min_enabled_track = i; max_enabled_track = i; } } /* all tracks were filled, set it to the last track anyways */ if (first_free_track < 0) first_free_track = 63; /* we're going to add another track to move stuff off of the drums */ if (non_drums_on_drums) { tracks_enabled[first_free_track] = 1; num_tracks++; } /* re-initialize to unseen sample number to make sure it's not a drum */ for (i = 0; i < 34; i++) { current_track_sample[i] = 255; } /* Initialize Port Numbers for channels > 15 */ for (i = 0; i < 34; i++) { if (tracks_enabled[i]) { length = track_size[i]; track_size[i] += 5; track_events[i] = safe_realloc(track_events[i], track_size[i] * sizeof(unsigned char)); p_track_event = track_events[i] + length; /* Port Change Event */ p_track_event[0] = 0x00; p_track_event[1] = 0xFF; p_track_event[2] = 0x21; p_track_event[3] = 0x01; p_track_event[4] = i / 16; } } /* Issue Initial Drum Stuff */ length = track_size[9]; track_size[9] += 15; track_events[9] = safe_realloc(track_events[9], track_size[9] * sizeof(unsigned char)); p_track_event = track_events[9] + length; /* program change to Standard Drums */ p_track_event[0] = 0x00; p_track_event[1] = 0xC9; p_track_event[2] = 0x00; /* set initial volume */ p_track_event[3] = 0x00; p_track_event[4] = 0xB9; p_track_event[5] = 0x07; p_track_event[6] = 127; /* set initial expression */ p_track_event[7] = 0x00; p_track_event[8] = 0xB9; p_track_event[9] = 0x0B; p_track_event[10] = 127; /* set center pan */ p_track_event[11] = 0x00; p_track_event[12] = 0xB9; p_track_event[13] = 0x0A; p_track_event[14] = 64;}void m2m_process_events(MidiEvent * ev){ int i; int moved_to_drums; int event_type; int skip_ch_expr_flag; uint32 oldtime = 0, deltatime; double time = 0; int chord, chord_type, chord_subtype; int ch, n, old_ch, newnote, mod_sample, expression; int extra; /* go through the list for real this time */ for (; ev->type != ME_EOT; ev++) { /* convert timidity times to midi event times */ samples_per_tick = (double) play_mode->rate * (double) tempo / (double) 1000000 / (double) orig_divisions; deltatime = ev->time - oldtime; oldtime = ev->time; time += (deltatime * divisions_ratio) / samples_per_tick; if (time > maxtime) maxtime = time; m2m_kill_notes_early(ev, time); n = 0; ch = ev->channel; if (ch >= 25) ch++; if (ev->type != ME_TEMPO && tracks_useless[ch]) continue; if (ev->type != ME_TEMPO) mod_sample = current_track_sample[ch]; /* skip silent sample events */ if (silent_samples[mod_sample] && (ev->type == ME_NOTEON || ev->type == ME_NOTEOFF || ev->type == ME_KEYPRESSURE)) continue; if (ev->type == ME_SET_PATCH && silent_samples[ev->a]) { continue; } if (ev->type == ME_EXPRESSION && silent_samples[ev->a] && !current_track_note[ch]) { orig_track_expr[ch] = ev->a; continue; } skip_ch_expr_flag = 0; moved_to_drums = 0; old_ch = ch; if (ev->type != ME_TEMPO && ev->type != ME_SET_PATCH) { /* move non-drums off to first free channel, drums to drum channel */ if (ch == 9 && (!is_drum_sample[mod_sample] || (ev->type != ME_NOTEON && ev->type != ME_NOTEOFF && ev->type != ME_KEYPRESSURE))) { ch = first_free_track; } else if (is_drum_sample[mod_sample]) { if (ch != 9) { ch = 9; moved_to_drums = 1; } } } event_type = ev->type; switch (ev->type) { case ME_NOTEOFF: n = 3; if (is_drum_sample[mod_sample]) newnote = sample_to_program[mod_sample]; else { newnote = ev->a + transpose[mod_sample]; newnote += tweak_note_offset[ch]; } while (newnote > 127) newnote -= 12; while (newnote < 0) newnote += 12;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -