📄 reverb.c
字号:
/* R */ LPFR = LPFR * lpflev + (buf2_R[spt2] + tb) * lpfinp + ta * width; ta = buf3_R[spt3]; s = buf3_R[spt3] = buf0_R[spt0]; buf0_R[spt0] = LPFR; t = (HPFR + fixp) * hpflev; HPFR = t - fixp; buf2_R[spt2] = (s - fixp * fbklev) * nmixlev; tb = buf1_R[spt1]; buf1_R[spt1] = t; EPFR = EPFR * epflev + ta * epfinp; buf[i] = (ta + EPFR) * wet + fixp; if (++spt0 == rpt0) {spt0 = 0;} if (++spt1 == rpt1) {spt1 = 0;} if (++spt2 == rpt2) {spt2 = 0;} if (++spt3 == rpt3) {spt3 = 0;} } memset(reverb_effect_buffer, 0, sizeof(int32) * count); info->spt0 = spt0, info->spt1 = spt1, info->spt2 = spt2, info->spt3 = spt3, info->ta = ta, info->tb = tb, info->HPFL = HPFL, info->HPFR = HPFR, info->LPFL = LPFL, info->LPFR = LPFR, info->EPFL = EPFL, info->EPFR = EPFR;}/* dummy */void reverb_rc_event(int rc, int32 val){ switch(rc) { case RC_CHANGE_REV_EFFB: break; case RC_CHANGE_REV_TIME: break; }}/* *//* Freeverb *//* */static void set_freeverb_allpass(allpass *allpass, int32 size){ if(allpass->buf != NULL) { free(allpass->buf); allpass->buf = NULL; } allpass->buf = (int32 *)safe_malloc(sizeof(int32) * size); if(allpass->buf == NULL) {return;} allpass->index = 0; allpass->size = size;}static void init_freeverb_allpass(allpass *allpass){ memset(allpass->buf, 0, sizeof(int32) * allpass->size);}static void set_freeverb_comb(comb *comb, int32 size){ if(comb->buf != NULL) { free(comb->buf); comb->buf = NULL; } comb->buf = (int32 *)safe_malloc(sizeof(int32) * size); if(comb->buf == NULL) {return;} comb->index = 0; comb->size = size; comb->filterstore = 0;}static void init_freeverb_comb(comb *comb){ memset(comb->buf, 0, sizeof(int32) * comb->size);}#define scalewet 0.06f#define scaledamp 0.4f#define scaleroom 0.28f#define offsetroom 0.7f#define initialroom 0.5f#define initialdamp 0.5f#define initialwet 1 / scalewet#define initialdry 0#define initialwidth 0.5f#define initialallpassfbk 0.65f#define stereospread 23static int combtunings[numcombs] = {1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617};static int allpasstunings[numallpasses] = {225, 341, 441, 556};#define fixedgain 0.025f#define combfbk 3.0fstatic void realloc_freeverb_buf(InfoFreeverb *rev){ int i; int32 tmpL, tmpR; double time, samplerate = play_mode->rate; time = reverb_time_table[reverb_status_gs.time] * gs_revchar_to_rt(reverb_status_gs.character) * combfbk / (60 * combtunings[numcombs - 1] / (-20 * log10(rev->roomsize1) * 44100.0)); for(i = 0; i < numcombs; i++) { tmpL = combtunings[i] * samplerate * time / 44100.0; tmpR = (combtunings[i] + stereospread) * samplerate * time / 44100.0; if(tmpL < 10) tmpL = 10; if(tmpR < 10) tmpR = 10; while(!isprime(tmpL)) tmpL++; while(!isprime(tmpR)) tmpR++; rev->combL[i].size = tmpL; rev->combR[i].size = tmpR; set_freeverb_comb(&rev->combL[i], rev->combL[i].size); set_freeverb_comb(&rev->combR[i], rev->combR[i].size); } for(i = 0; i < numallpasses; i++) { tmpL = allpasstunings[i] * samplerate * time / 44100.0; tmpR = (allpasstunings[i] + stereospread) * samplerate * time / 44100.0; if(tmpL < 10) tmpL = 10; if(tmpR < 10) tmpR = 10; while(!isprime(tmpL)) tmpL++; while(!isprime(tmpR)) tmpR++; rev->allpassL[i].size = tmpL; rev->allpassR[i].size = tmpR; set_freeverb_allpass(&rev->allpassL[i], rev->allpassL[i].size); set_freeverb_allpass(&rev->allpassR[i], rev->allpassR[i].size); }}static void update_freeverb(InfoFreeverb *rev){ int i; double allpassfbk = 0.55, rtbase, rt; rev->wet = (double)reverb_status_gs.level / 127.0f * gs_revchar_to_level(reverb_status_gs.character) * fixedgain; rev->roomsize = gs_revchar_to_roomsize(reverb_status_gs.character) * scaleroom + offsetroom; rev->width = 0.5f; rev->wet1 = rev->width / 2.0f + 0.5f; rev->wet2 = (1.0f - rev->width) / 2.0f; rev->roomsize1 = rev->roomsize; rev->damp1 = rev->damp; realloc_freeverb_buf(rev); rtbase = 1.0 / (44100.0 * reverb_time_table[reverb_status_gs.time] * gs_revchar_to_rt(reverb_status_gs.character)); for(i = 0; i < numcombs; i++) { rt = pow(10.0f, -combfbk * (double)combtunings[i] * rtbase); rev->combL[i].feedback = rt; rev->combR[i].feedback = rt; rev->combL[i].damp1 = rev->damp1; rev->combR[i].damp1 = rev->damp1; rev->combL[i].damp2 = 1 - rev->damp1; rev->combR[i].damp2 = 1 - rev->damp1; rev->combL[i].damp1i = TIM_FSCALE(rev->combL[i].damp1, 24); rev->combR[i].damp1i = TIM_FSCALE(rev->combR[i].damp1, 24); rev->combL[i].damp2i = TIM_FSCALE(rev->combL[i].damp2, 24); rev->combR[i].damp2i = TIM_FSCALE(rev->combR[i].damp2, 24); rev->combL[i].feedbacki = TIM_FSCALE(rev->combL[i].feedback, 24); rev->combR[i].feedbacki = TIM_FSCALE(rev->combR[i].feedback, 24); } for(i = 0; i < numallpasses; i++) { rev->allpassL[i].feedback = allpassfbk; rev->allpassR[i].feedback = allpassfbk; rev->allpassL[i].feedbacki = TIM_FSCALE(rev->allpassL[i].feedback, 24); rev->allpassR[i].feedbacki = TIM_FSCALE(rev->allpassR[i].feedback, 24); } rev->wet1i = TIM_FSCALE(rev->wet1, 24); rev->wet2i = TIM_FSCALE(rev->wet2, 24); set_delay(&(rev->pdelay), (int32)((double)reverb_status_gs.pre_delay_time * play_mode->rate / 1000.0f));}static void init_freeverb(InfoFreeverb *rev){ int i; for(i = 0; i < numcombs; i++) { init_freeverb_comb(&rev->combL[i]); init_freeverb_comb(&rev->combR[i]); } for(i = 0; i < numallpasses; i++) { init_freeverb_allpass(&rev->allpassL[i]); init_freeverb_allpass(&rev->allpassR[i]); }}static void alloc_freeverb_buf(InfoFreeverb *rev){ int i; if(rev->alloc_flag) {return;} for (i = 0; i < numcombs; i++) { set_freeverb_comb(&rev->combL[i], combtunings[i]); set_freeverb_comb(&rev->combR[i], combtunings[i] + stereospread); } for (i = 0; i < numallpasses; i++) { set_freeverb_allpass(&rev->allpassL[i], allpasstunings[i]); set_freeverb_allpass(&rev->allpassR[i], allpasstunings[i] + stereospread); rev->allpassL[i].feedback = initialallpassfbk; rev->allpassR[i].feedback = initialallpassfbk; } rev->wet = initialwet * scalewet; rev->damp = initialdamp * scaledamp; rev->width = initialwidth; rev->roomsize = initialroom * scaleroom + offsetroom; rev->alloc_flag = 1;}static void free_freeverb_buf(InfoFreeverb *rev){ int i; for(i = 0; i < numcombs; i++) { if(rev->combL[i].buf != NULL) { free(rev->combL[i].buf); rev->combL[i].buf = NULL; } if(rev->combR[i].buf != NULL) { free(rev->combR[i].buf); rev->combR[i].buf = NULL; } } for(i = 0; i < numallpasses; i++) { if(rev->allpassL[i].buf != NULL) { free(rev->allpassL[i].buf); rev->allpassL[i].buf = NULL; } if(rev->allpassR[i].buf != NULL) { free(rev->allpassR[i].buf); rev->allpassR[i].buf = NULL; } } free_delay(&(rev->pdelay));}static inline void do_freeverb_allpass(int32 *stream, int32 *buf, int32 size, int32 *index, int32 feedback){ int32 bufout, output; bufout = buf[*index]; output = -*stream + bufout; buf[*index] = *stream + imuldiv24(bufout, feedback); if (++*index >= size) {*index = 0;} *stream = output;}static inline void do_freeverb_comb(int32 input, int32 *stream, int32 *buf, int32 size, int32 *index, int32 damp1, int32 damp2, int32 *fs, int32 feedback){ int32 output; output = buf[*index]; *fs = imuldiv24(output, damp2) + imuldiv24(*fs, damp1); buf[*index] = input + imuldiv24(*fs, feedback); if (++*index >= size) {*index = 0;} *stream += output;}static void do_ch_freeverb(int32 *buf, int32 count, InfoFreeverb *rev){ int32 i, k = 0; int32 outl, outr, input; comb *combL = rev->combL, *combR = rev->combR; allpass *allpassL = rev->allpassL, *allpassR = rev->allpassR; delay *pdelay = &(rev->pdelay); if(count == MAGIC_INIT_EFFECT_INFO) { alloc_freeverb_buf(rev); update_freeverb(rev); init_freeverb(rev); return; } else if(count == MAGIC_FREE_EFFECT_INFO) { free_freeverb_buf(rev); return; } for (k = 0; k < count; k++) { input = reverb_effect_buffer[k] + reverb_effect_buffer[k + 1]; outl = outr = reverb_effect_buffer[k] = reverb_effect_buffer[k + 1] = 0; do_delay(&input, pdelay->buf, pdelay->size, &pdelay->index); for (i = 0; i < numcombs; i++) { do_freeverb_comb(input, &outl, combL[i].buf, combL[i].size, &combL[i].index, combL[i].damp1i, combL[i].damp2i, &combL[i].filterstore, combL[i].feedbacki); do_freeverb_comb(input, &outr, combR[i].buf, combR[i].size, &combR[i].index, combR[i].damp1i, combR[i].damp2i, &combR[i].filterstore, combR[i].feedbacki); } for (i = 0; i < numallpasses; i++) { do_freeverb_allpass(&outl, allpassL[i].buf, allpassL[i].size, &allpassL[i].index, allpassL[i].feedbacki); do_freeverb_allpass(&outr, allpassR[i].buf, allpassR[i].size, &allpassR[i].index, allpassR[i].feedbacki); } buf[k] += imuldiv24(outl, rev->wet1i) + imuldiv24(outr, rev->wet2i); buf[k + 1] += imuldiv24(outr, rev->wet1i) + imuldiv24(outl, rev->wet2i); ++k; }}/* *//* Reverb: Delay & Panning Delay *//* *//*! initialize Reverb: Delay Effect; this implementation is specialized for system effect. */static void init_ch_reverb_delay(InfoDelay3 *info){ int32 x; info->size[0] = (double)reverb_status_gs.time * 3.75f * play_mode->rate / 1000.0f; x = info->size[0] + 1; /* allowance */ set_delay(&(info->delayL), x); set_delay(&(info->delayR), x); info->index[0] = x - info->size[0]; info->level[0] = (double)reverb_status_gs.level * 1.82f / 127.0f; info->feedback = sqrt((double)reverb_status_gs.delay_feedback / 127.0f) * 0.98f; info->leveli[0] = TIM_FSCALE(info->level[0], 24); info->feedbacki = TIM_FSCALE(info->feedback, 24);}static void free_ch_reverb_delay(InfoDelay3 *info){ free_delay(&(info->delayL)); free_delay(&(info->delayR));}/*! Reverb: Panning Delay Effect; this implementation is specialized for system effect. */static void do_ch_reverb_panning_delay(int32 *buf, int32 count, InfoDelay3 *info){ int32 i, l, r; delay *delayL = &(info->delayL), *delayR = &(info->delayR); int32 *bufL = delayL->buf, *bufR = delayR->buf; int32 buf_index = delayL->index, buf_size = delayL->size; int32 index0 = info->index[0], level0i = info->leveli[0], feedbacki = info->feedbacki; if(count == MAGIC_INIT_EFFECT_INFO) { init_ch_reverb_delay(info); return; } else if(count == MAGIC_FREE_EFFECT_INFO) { free_ch_reverb_delay(info); return; } for (i = 0; i < count; i++) { bufL[buf_index] = reverb_effect_buffer[i] + imuldiv24(bufR[index0], feedbacki); l = imuldiv24(bufL[index0], level0i); bufR[buf_index] = reverb_effect_buffer[i + 1] + imuldiv24(bufL[index0], feedbacki); r = imuldiv24(bufR[index0], level0i); buf[i] += r; buf[++i] += l; if (++index0 == buf_size) {index0 = 0;} if (++buf_index == buf_size) {buf_index = 0;} } memset(reverb_effect_buffer, 0, sizeof(int32) * count); info->index[0] = index0; delayL->index = delayR->index = buf_index;}/*! Reverb: Normal Delay Effect; this implementation is specialized for system effect. */static void do_ch_reverb_normal_delay(int32 *buf, int32 count, InfoDelay3 *info){ int32 i; delay *delayL = &(info->delayL), *delayR = &(info->delayR); int32 *bufL = delayL->buf, *bufR = delayR->buf; int32 buf_index = delayL->index, buf_size = delayL->size; int32 index0 = info->index[0], level0i = info->leveli[0], feedbacki = info->feedbacki; if(count == MAGIC_INIT_EFFECT_INFO) { init_ch_reverb_delay(info); return; } else if(count == MAGIC_FREE_EFFECT_INFO) { free_ch_reverb_delay(info); return; } for (i = 0; i < count; i++) { bufL[buf_index] = reverb_effect_buffer[i] + imuldiv24(bufL[index0], feedbacki); buf[i] += imuldiv24(bufL[index0], level0i); bufR[buf_index] = reverb_effect_buffer[++i] + imuldiv24(bufR[index0], feedbacki); buf[i] += imuldiv24(bufR[index0], level0i); if (++index0 == buf_size) {index0 = 0;} if (++buf_index == buf_size) {buf_index = 0;} } memset(reverb_effect_buffer, 0, sizeof(int32) * count); info->index[0] = index0; delayL->index = delayR->index = buf_index;}/* *//* Plate Reverberator *//* */#define PLATE_SAMPLERATE 29761.0#define PLATE_DECAY 0.50#define PLATE_DECAY_DIFFUSION1 0.70#define PLATE_DECAY_DIFFUSION2 0.50#define PLATE_INPUT_DIFFUSION1 0.750#define PLATE_INPUT_DIFFUSION2 0.625#define PLATE_BANDWIDTH 0.9955#define PLATE_DAMPING 0.0005#define PLATE_WET 0.25/*! calculate delay sample in current sample-rate */static inline int32 get_plate_delay(double delay, double t){ return (int32)(delay * play_mode->rate * t / PLATE_SAMPLERATE);}/*! Plate Reverberator; this implementation is specialized for system effect. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -