📄 resample.c
字号:
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 + -