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

📄 resample.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 3 页
字号:
      if (!cc--)	{	  cc = vp->vibrato_control_ratio;	  incr = update_vibrato(vp, 0);	}      RESAMPLATION;      ofs += incr;      if (ofs >= le)	{	  FINALINTERP;	  vp->timeout = 1;	  *countptr -= count;	  break;	}    }  vp->vibrato_control_counter = cc;  vp->sample_increment = incr;  vp->sample_offset = ofs; /* Update offset */  return resample_buffer + resample_buffer_offset;}static resample_t *rs_vib_loop(Voice *vp, int32 count){  /* Play sample until end-of-loop, skip back and continue. */  splen_t    ofs = vp->sample_offset,    ls = vp->sample->loop_start,    le = vp->sample->loop_end,    ll = le - vp->sample->loop_start;  resample_t *dest = resample_buffer + resample_buffer_offset;  sample_t *src = vp->sample->data;  int cc = vp->vibrato_control_counter;  int32 incr = vp->sample_increment;  resample_rec_t resrc;#ifdef PRECALC_LOOPS  int32 i, j;  int vibflag=0;#endif  resrc.loop_start = ls;  resrc.loop_end = le;  resrc.data_length =vp->sample->data_length;#ifdef PRECALC_LOOPS  while (count)    {      /* Hopefully the loop is longer than an increment */      while(ofs >= le) {ofs -= ll;}      /* Precalc how many times to go through the loop, taking	 the vibrato control ratio into account this time. */      i = PRECALC_LOOP_COUNT(ofs, le, incr);      if(i > count) {		  i = count;	  }      if(i > cc) {		  i = cc;		  vibflag = 1;	  } else {cc -= i;}      count -= i;      if(vibflag) {		  cc = vp->vibrato_control_ratio;		  incr = update_vibrato(vp, 0);		  vibflag = 0;	  }      for(j = 0; j < i; j++) {		  RESAMPLATION;		  ofs += incr;	  }    }#else /* PRECALC_LOOPS */  while (count--)    {      if (!cc--)	{	  cc=vp->vibrato_control_ratio;	  incr=update_vibrato(vp, 0);	}      RESAMPLATION;      ofs += incr;      if (ofs >= le)	ofs -= ll; /* Hopefully the loop is longer than an increment. */    }#endif /* PRECALC_LOOPS */  vp->vibrato_control_counter = cc;  vp->sample_increment = incr;  vp->sample_offset = ofs; /* Update offset */  return resample_buffer + resample_buffer_offset;}static resample_t *rs_vib_bidir(Voice *vp, int32 count){#if SAMPLE_LENGTH_BITS == 32  int32#else  splen_t#endif    ofs = vp->sample_offset,    le = vp->sample->loop_end,    ls = vp->sample->loop_start;  resample_t *dest = resample_buffer + resample_buffer_offset;  sample_t *src = vp->sample->data;  int cc=vp->vibrato_control_counter;  int32 incr = vp->sample_increment;  resample_rec_t resrc;#ifdef PRECALC_LOOPS#if SAMPLE_LENGTH_BITS == 32  int32#else  splen_t#endif    le2 = le << 1,    ls2 = ls << 1;  int32 i, j;  int vibflag = 0;  resrc.loop_start = ls;  resrc.loop_end = le;  resrc.data_length = vp->sample->data_length;  /* Play normally until inside the loop region */  while (count && incr > 0 && ofs < ls)    {      i = PRECALC_LOOP_COUNT(ofs, ls, incr);      if (i > count) i = count;      if (i > cc)	{	  i = cc;	  vibflag = 1;	}      else cc -= i;      count -= i;      if (vibflag)	{	  cc = vp->vibrato_control_ratio;	  incr = update_vibrato(vp, 0);	  vibflag = 0;	}      for(j = 0; j < i; j++)	{	  RESAMPLATION;	  ofs += incr;	}    }  /* Then do the bidirectional looping */  while (count)    {      /* Precalc how many times we should go through the loop */      i = PRECALC_LOOP_COUNT(ofs, incr > 0 ? le : ls, incr);      if(i > count) i = count;      if(i > cc)	{	  i = cc;	  vibflag = 1;	}      else cc -= i;      count -= i;      if (vibflag)	{	  cc = vp->vibrato_control_ratio;	  incr = update_vibrato(vp, (incr < 0));	  vibflag = 0;	}      while (i--)	{	  RESAMPLATION;	  ofs += incr;	}      if (ofs >= 0 && ofs >= le)	{	  /* fold the overshoot back in */	  ofs = le2 - ofs;	  incr *= -1;	}      else if (ofs <= 0 || ofs <= ls)	{	  ofs = ls2 - ofs;	  incr *= -1;	}    }#else /* PRECALC_LOOPS */  resrc.loop_start = ls;  resrc.loop_end = le;  resrc.data_length = vp->sample->data_length;  /* Play normally until inside the loop region */  if (ofs < ls)    {      while (count--)	{	  if (!cc--)	    {	      cc = vp->vibrato_control_ratio;	      incr = update_vibrato(vp, 0);	    }	  RESAMPLATION;	  ofs += incr;	  if (ofs >= ls)	    break;	}    }  /* Then do the bidirectional looping */  if (count > 0)    while (count--)      {	if (!cc--)	  {	    cc=vp->vibrato_control_ratio;	    incr=update_vibrato(vp, (incr < 0));	  }	RESAMPLATION;	ofs += incr;	if (ofs >= le)	  {	    /* fold the overshoot back in */	    ofs = le - (ofs - le);	    incr = -incr;	  }	else if (ofs <= ls)	  {	    ofs = ls + (ls - ofs);	    incr = -incr;	  }      }#endif /* PRECALC_LOOPS */  /* Update changed values */  vp->vibrato_control_counter = cc;  vp->sample_increment = incr;  vp->sample_offset = ofs;  return resample_buffer + resample_buffer_offset;}/*********************** portamento versions ***************************/static int rs_update_porta(int v){    Voice *vp = &voice[v];    int32 d;    d = vp->porta_dpb;    if(vp->porta_pb < 0)    {	if(d > -vp->porta_pb)	    d = -vp->porta_pb;    }    else    {	if(d > vp->porta_pb)	    d = -vp->porta_pb;	else	    d = -d;    }    vp->porta_pb += d;    if(vp->porta_pb == 0)    {	vp->porta_control_ratio = 0;	vp->porta_pb = 0;    }    recompute_freq(v);    return vp->porta_control_ratio;}static resample_t *porta_resample_voice(int v, int32 *countptr, int mode){    Voice *vp = &voice[v];    int32 n = *countptr, i;    resample_t *(* resampler)(int, int32 *, int);    int cc = vp->porta_control_counter;    int loop;    if(vp->vibrato_control_ratio)	resampler = vib_resample_voice;    else	resampler = normal_resample_voice;    if(mode != 1)	loop = 1;    else	loop = 0;    vp->cache = NULL;    resample_buffer_offset = 0;    while(resample_buffer_offset < n)    {	if(cc == 0)	{	    if((cc = rs_update_porta(v)) == 0)	    {		i = n - resample_buffer_offset;		resampler(v, &i, mode);		resample_buffer_offset += i;		break;	    }	}	i = n - resample_buffer_offset;	if(i > cc)	    i = cc;	resampler(v, &i, mode);	resample_buffer_offset += i;	if(!loop && (i == 0 || vp->status == VOICE_FREE))	    break;	cc -= i;    }    *countptr = resample_buffer_offset;    resample_buffer_offset = 0;    vp->porta_control_counter = cc;    return resample_buffer;}/* interface function */static resample_t *vib_resample_voice(int v, int32 *countptr, int mode){    Voice *vp = &voice[v];    vp->cache = NULL;    if(mode == 0)	return rs_vib_loop(vp, *countptr);    if(mode == 1)	return rs_vib_plain(v, countptr);    return rs_vib_bidir(vp, *countptr);}/* interface function */static resample_t *normal_resample_voice(int v, int32 *countptr, int mode){    Voice *vp = &voice[v];    if(mode == 0)	return rs_loop(vp, *countptr);    if(mode == 1)	return rs_plain(v, countptr);    return rs_bidir(vp, *countptr);}/* interface function */resample_t *resample_voice(int v, int32 *countptr){    Voice *vp = &voice[v];    int mode;    resample_t *result;    resampler_t saved_resample;	int32 i;    if(vp->sample->sample_rate == play_mode->rate &&       vp->sample->root_freq == get_note_freq(vp->sample, vp->sample->note_to_use) &&       vp->frequency == vp->orig_frequency)    {	int32 ofs;	/* Pre-resampled data -- just update the offset and check if	   we're out of data. */	ofs = (int32)(vp->sample_offset >> FRACTION_BITS); /* Kind of silly to use						   FRACTION_BITS here... */	if(*countptr >= (vp->sample->data_length >> FRACTION_BITS) - ofs)	{	    /* Note finished. Free the voice. */	    vp->timeout = 1;	    /* Let the caller know how much data we had left */	    *countptr = (int32)(vp->sample->data_length >> FRACTION_BITS) - ofs;	}	else	    vp->sample_offset += *countptr << FRACTION_BITS;	for (i = 0; i < *countptr; i++) {		resample_buffer[i] = vp->sample->data[i + ofs];	}	return resample_buffer;    }    mode = vp->sample->modes;    if((mode & MODES_LOOPING) &&       ((mode & MODES_ENVELOPE) ||	(vp->status & (VOICE_ON | VOICE_SUSTAINED))))    {	if(mode & MODES_PINGPONG)	{	    vp->cache = NULL;	    mode = 2;	/* Bidir loop */	}	else	    mode = 0;	/* loop */    }    else	mode = 1;	/* no loop */    saved_resample = cur_resample;#ifndef FIXED_RESAMPLATION    if (reduce_quality_flag && cur_resample != resample_none)	cur_resample = resample_linear;#endif    if(vp->porta_control_ratio)	result = porta_resample_voice(v, countptr, mode);    else if(vp->vibrato_control_ratio)	result = vib_resample_voice(v, countptr, mode);    else	result = normal_resample_voice(v, countptr, mode);#ifndef FIXED_RESAMPLATION    cur_resample = saved_resample; /* get back */#endif    return result;}void pre_resample(Sample * sp){  double a, b;  splen_t ofs, newlen;  sample_t *newdata, *dest, *src = (sample_t *)sp->data;  int32 i, count, incr, f, x;  resample_rec_t resrc;  ctl->cmsg(CMSG_INFO, VERB_DEBUG, " * pre-resampling for note %d (%s%d)",	    sp->note_to_use,	    note_name[sp->note_to_use % 12], (sp->note_to_use & 0x7F) / 12);  f = get_note_freq(sp, sp->note_to_use);  a = b = ((double) (sp->root_freq) * play_mode->rate) /      ((double) (sp->sample_rate) * f);  if((int64)sp->data_length * a >= 0x7fffffffL)  {      /* Too large to compute */      ctl->cmsg(CMSG_INFO, VERB_DEBUG, " *** Can't pre-resampling for note %d",		sp->note_to_use);      return;  }  newlen = (splen_t)(sp->data_length * a);  count = (newlen >> FRACTION_BITS);  ofs = incr = (sp->data_length - 1) / (count - 1);  if((double)newlen + incr >= 0x7fffffffL)  {      /* Too large to compute */      ctl->cmsg(CMSG_INFO, VERB_DEBUG, " *** Can't pre-resampling for note %d",		sp->note_to_use);      return;  }  dest = newdata = (sample_t *)safe_malloc((int32)(newlen >> (FRACTION_BITS - 1)) + 2);  dest[newlen >> FRACTION_BITS] = 0;  *dest++ = src[0];  resrc.loop_start = 0;  resrc.loop_end = sp->data_length;  resrc.data_length = sp->data_length;  /* Since we're pre-processing and this doesn't have to be done in     real-time, we go ahead and do the higher order interpolation. */  for(i = 1; i < count; i++)  {	x = cur_resample(src, ofs, &resrc);    *dest++ = (int16)((x > 32767) ? 32767: ((x < -32768) ? -32768 : x));    ofs += incr;  }  sp->data_length = newlen;  sp->loop_start = (splen_t)(sp->loop_start * b);  sp->loop_end = (splen_t)(sp->loop_end * b);  free(sp->data);  sp->data = (sample_t *) newdata;  sp->root_freq = f;  sp->sample_rate = play_mode->rate;  sp->low_freq = freq_table[0];  sp->high_freq = freq_table[127];}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -