⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mod2midi.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 2 页
字号:
      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 + -