📄 mod2midi.c
字号:
a = (start & 0xff); b = ((start >> 8) & 0xff); MIDIEVENT (at, ME_PATCH_OFFS, v, a, b); } if (ModV[v].wheel != bend) { ModV[v].wheel = bend; MIDIEVENT (at, ME_PITCHWHEEL, v, bend & 0x7F, (bend >> 7) & 0x7F); } MIDIEVENT (at, ME_NOTEON, v, ModV[v].noteon, 127);}voidVoice_Stop (UBYTE v){ int32 j; int n; if (v >= MOD_NUM_VOICES) return; if (ModV[v].noteon == -1) return;#define TURN_OFF_8(base, ofs) \ while (j & (0xFFL << (ofs))) { \ n = ofs + significantDigitsLessOne[(unsigned char) (j >> (ofs))]; \ MIDIEVENT (at, ME_NOTEOFF, v, (base) + n, 63); \ j ^= 1 << n; \ }#define TURN_OFF_32(base) \ do { \ TURN_OFF_8((base), 24) \ TURN_OFF_8((base), 16) \ TURN_OFF_8((base), 8) \ TURN_OFF_8((base), 0) \ } while(0) if ((j = ModV[v].noteson[0]) != 0) TURN_OFF_32(0); if ((j = ModV[v].noteson[1]) != 0) TURN_OFF_32(32); if ((j = ModV[v].noteson[2]) != 0) TURN_OFF_32(64); if ((j = ModV[v].noteson[3]) != 0) TURN_OFF_32(96); bitmapClear(ModV[v].noteson); ModV[v].noteon = -1;}BOOLVoice_Stopped (UBYTE v){ return (v >= MOD_NUM_VOICES) || (ModV[v].noteon == -1);}voidVoice_TickDone (){ at++;}voidVoice_NewTempo (UWORD bpm, UWORD sngspd){ mod_change_tempo(at, bpm);}voidVoice_EndPlaying (){ int v; at += 48 / (60.0/125.0); /* 1 second */ for(v = 0; v < MOD_NUM_VOICES; v++) MIDIEVENT(at, ME_ALL_NOTES_OFF, v, 0, 0);}voidVoice_StartPlaying (){ int v; readmidi_set_track(0, 1); current_file_info->divisions = 24; for(v = 0; v < MOD_NUM_VOICES; v++) { ModV[v].sample = -1; ModV[v].noteon = -1; ModV[v].time = -1; ModV[v].period = 0; ModV[v].wheel = 0x2000; ModV[v].vol = 127; ModV[v].pan = (v & 1) ? 127 : 0; bitmapClear(ModV[v].noteson); MIDIEVENT(0, ME_PAN, v, ModV[v].pan, 0); MIDIEVENT(0, ME_SET_PATCH, v, 1, 0); MIDIEVENT(0, ME_MAINVOLUME, v, 127, 0); MIDIEVENT(0, ME_EXPRESSION, v, 127, 0); /* MIDIEVENT(0, ME_MONO, v, 0, 0); */ MIDIEVENT(0, ME_RPN_LSB, v, 0, 0); MIDIEVENT(0, ME_RPN_MSB, v, 0, 0); MIDIEVENT(0, ME_DATA_ENTRY_MSB, v, WHEEL_SENSITIVITY, 0); MIDIEVENT(0, ME_DRUMPART, v, 0, 0); } at = 1;}/* convert from 8bit value to fractional offset (15.15) */static int32 env_offset(int offset){ return (int32)offset << (7+15);}/* calculate ramp rate in fractional unit; * diff = 8bit, time = msec */static int32 env_rate(int diff, double msec){ double rate; if(msec < 6) msec = 6; if(diff == 0) diff = 255; diff <<= (7+15); rate = ((double)diff / play_mode->rate) * control_ratio * 1000.0 / msec; if(fast_decay) rate *= 2; return (int32)rate;}void shrink_huge_sample (Sample *sp){ sample_t *orig_data; sample_t *new_data; unsigned int rate, new_rate; uint32 data_length, new_data_length; double loop_start, loop_end; double scale, scale2; double x, xfrac; double y; sample_t y1, y2, y3, y4; uint32 i, xtrunc; data_length = sp->data_length; if (data_length < (1 << FRACTION_BITS) - 1) return; loop_start = sp->loop_start; loop_end = sp->loop_end; rate = sp->sample_rate; scale = ((1 << (31 - FRACTION_BITS)) - 2.0) / data_length; new_rate = rate * scale; scale = new_rate / (float) rate; scale2 = (float) rate / new_rate; new_data_length = data_length * scale; loop_start *= scale; loop_end *= scale; ctl->cmsg(CMSG_INFO, VERB_NORMAL, "Sample too large (%ld): resampling down to %ld samples", data_length, new_data_length); orig_data = sp->data; new_data = calloc(new_data_length + 1, sizeof(sample_t)); new_data[0] = orig_data[0]; for (i = 1; i < new_data_length; i++) { x = i * scale2; xtrunc = (uint32) x; xfrac = x - xtrunc; if (xtrunc >= data_length - 1) { if (xtrunc == data_length) new_data[i] = orig_data[data_length]; else /* linear interpolation */ { y2 = orig_data[data_length - 1]; y3 = orig_data[data_length]; new_data[i] = ceil((y2 + (y3 - y2) * xfrac) - 0.5); } } else /* cspline interpolation */ { y1 = orig_data[xtrunc - 1]; y2 = orig_data[xtrunc]; y3 = orig_data[xtrunc + 1]; y4 = orig_data[xtrunc + 2]; y = (6*y3 + (5*y4 - 11*y3 + 7*y2 - y1) * 0.25 * (xfrac+1) * (xfrac-1)) * xfrac; y = (((6*y2 + (5*y1 - 11*y2 + 7*y3 - y4) * 0.25 * xfrac * (xfrac-2)) * (1-xfrac)) + y) / 6.0; if (y > 32767) y = 32767; if (y < -32767) y = -32767; new_data[i] = ceil(y - 0.5); } } free(sp->data); sp->data = new_data; sp->sample_rate = new_rate; sp->data_length = new_data_length << FRACTION_BITS; sp->loop_start = loop_start * (1 << FRACTION_BITS); sp->loop_end = loop_end * (1 << FRACTION_BITS);}void load_module_samples (SAMPLE * s, int numsamples, int ntsc){ int i; for(i = 1; numsamples--; i++, s++) { Sample *sp; char name[23]; if(!s->data) continue; ctl->cmsg(CMSG_INFO, VERB_DEBUG, "MOD Sample %d (%.22s)", i, s->samplename); special_patch[i] = (SpecialPatch *)safe_malloc(sizeof(SpecialPatch)); special_patch[i]->type = INST_MOD; special_patch[i]->samples = 1; special_patch[i]->sample = sp = (Sample *)safe_malloc(sizeof(Sample)); memset(sp, 0, sizeof(Sample)); strncpy(name, s->samplename, 22); name[22] = '\0'; code_convert(name, NULL, 23, NULL, "ASCII"); if(name[0] == '\0') special_patch[i]->name = NULL; else special_patch[i]->name = safe_strdup(name); special_patch[i]->sample_offset = 0; sp->data = (sample_t *)s->data; sp->data_alloced = 1; sp->data_length = s->length; sp->loop_start = s->loopstart; sp->loop_end = s->loopend; /* The sample must be padded out by 1 extra sample, so that the interpolation routines won't cause a "pop" by reading random data beyond data_length */ sp->data = (sample_t *) realloc(sp->data, (sp->data_length + 1) * sizeof(sample_t)); sp->data[sp->data_length] = 0; /* Stereo instruments (SF_STEREO) are dithered by libunimod into mono */ sp->modes = MODES_UNSIGNED; if (s->flags & SF_SIGNED) sp->modes ^= MODES_UNSIGNED; if (s->flags & SF_LOOP) sp->modes ^= MODES_LOOPING; if (s->flags & SF_BIDI) sp->modes ^= MODES_PINGPONG; if (s->flags & SF_REVERSE) sp->modes ^= MODES_REVERSE; if (s->flags & SF_16BITS) sp->modes ^= MODES_16BIT;#ifdef USE_ENVELOPE /* envelope (0,1:attack, 2:sustain, 3,4,5:release) */ sp->modes |= MODES_ENVELOPE; /* attack */ sp->envelope_offset[0] = env_offset(255); sp->envelope_rate[0] = env_rate(255, 0.0); /* fastest */ sp->envelope_offset[1] = sp->envelope_offset[0]; sp->envelope_rate[1] = 0; /* skip this stage */ /* sustain */ sp->envelope_offset[2] = sp->envelope_offset[1]; sp->envelope_rate[2] = 0; /* release */ sp->envelope_offset[3] = env_offset(0); sp->envelope_rate[3] = env_rate(255, 80.0); /* 80 msec */ sp->envelope_offset[4] = sp->envelope_offset[3]; sp->envelope_rate[4] = 0; /* skip this stage */ sp->envelope_offset[5] = sp->envelope_offset[4]; sp->envelope_rate[5] = 0; /* skip this stage, then the voice is disappeared */#endif sp->sample_rate = PAL_RATE >> s->divfactor; sp->low_freq = 0; sp->high_freq = 0x7fffffff; sp->root_freq = freq_table[MOD_ROOT_NOTE]; sp->volume = 1.0; /* I guess it should use globvol... */ sp->panning = s->panning == PAN_SURROUND ? 64 : s->panning * 128 / 255; sp->note_to_use = 0; sp->low_vel = 0; sp->high_vel = 127; sp->tremolo_sweep_increment = sp->tremolo_phase_increment = sp->tremolo_depth = sp->vibrato_sweep_increment = sp->vibrato_control_ratio = sp->vibrato_depth = 0; sp->cutoff_freq = sp->resonance = sp->tremolo_to_pitch = sp->tremolo_to_fc = sp->modenv_to_pitch = sp->modenv_to_fc = sp->vel_to_fc = sp->key_to_fc = sp->vel_to_resonance = 0; sp->envelope_velf_bpo = sp->modenv_velf_bpo = sp->vel_to_fc_threshold = 64; sp->key_to_fc_bpo = 60; sp->scale_freq = 60; sp->scale_factor = 1024; memset(sp->envelope_velf, 0, sizeof(sp->envelope_velf)); memset(sp->envelope_keyf, 0, sizeof(sp->envelope_keyf)); memset(sp->modenv_velf, 0, sizeof(sp->modenv_velf)); memset(sp->modenv_keyf, 0, sizeof(sp->modenv_keyf)); memset(sp->modenv_rate, 0, sizeof(sp->modenv_rate)); memset(sp->modenv_offset, 0, sizeof(sp->modenv_offset)); sp->envelope_delay = sp->modenv_delay = sp->tremolo_delay = sp->vibrato_delay = 0; sp->sample_type = SF_SAMPLETYPE_MONO; sp->sf_sample_link = -1; sp->sf_sample_index = 0; if (sp->data_length >= (1 << (31 - FRACTION_BITS)) - 1) shrink_huge_sample(sp); else { sp->data_length <<= FRACTION_BITS; sp->loop_start <<= FRACTION_BITS; sp->loop_end <<= FRACTION_BITS; } /* pitch detection for mod->midi file conversion and surround chorus */ if (play_mode->id_character == 'M' || opt_surround_chorus) { sp->chord = -1; sp->root_freq_detected = freq_fourier(sp, &(sp->chord)); sp->transpose_detected = assign_pitch_to_freq(sp->root_freq_detected) - assign_pitch_to_freq(sp->root_freq / 1024.0); } /* If necessary do some anti-aliasing filtering */ if (antialiasing_allowed) antialiasing((int16 *)sp->data, sp->data_length / 2, sp->sample_rate, play_mode->rate); s->data = NULL; /* Avoid free-ing */ s->id = i; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -