📄 reverb.c
字号:
static void do_ch_plate_reverb(int32 *buf, int32 count, InfoPlateReverb *info){ int32 i; int32 x, xd, val, outl, outr, temp1, temp2, temp3; delay *pd = &(info->pd), *od1l = &(info->od1l), *od2l = &(info->od2l), *od3l = &(info->od3l), *od4l = &(info->od4l), *od5l = &(info->od5l), *od6l = &(info->od6l), *od1r = &(info->od1r), *od2r = &(info->od2r), *od3r = &(info->od3r), *od4r = &(info->od4r), *od5r = &(info->od5r), *od7r = &(info->od7r), *od7l = &(info->od7l), *od6r = &(info->od6r), *td1 = &(info->td1), *td2 = &(info->td2), *td1d = &(info->td1d), *td2d = &(info->td2d); allpass *ap1 = &(info->ap1), *ap2 = &(info->ap2), *ap3 = &(info->ap3), *ap4 = &(info->ap4), *ap6 = &(info->ap6), *ap6d = &(info->ap6d); mod_allpass *ap5 = &(info->ap5), *ap5d = &(info->ap5d); lfo *lfo1 = &(info->lfo1), *lfo1d = &(info->lfo1d); filter_lowpass1 *lpf1 = &(info->lpf1), *lpf2 = &(info->lpf2); int32 t1 = info->t1, t1d = info->t1d; int32 decayi = info->decayi, ddif1i = info->ddif1i, ddif2i = info->ddif2i, idif1i = info->idif1i, idif2i = info->idif2i; double t; if(count == MAGIC_INIT_EFFECT_INFO) { init_lfo(lfo1, 1.30f, LFO_SINE, 0); init_lfo(lfo1d, 1.30f, LFO_SINE, 0); t = reverb_time_table[reverb_status_gs.time] / reverb_time_table[64] - 1.0; t = 1.0 + t / 2; set_delay(pd, reverb_status_gs.pre_delay_time * play_mode->rate / 1000); set_delay(td1, get_plate_delay(4453, t)), set_delay(td1d, get_plate_delay(4217, t)); set_delay(td2, get_plate_delay(3720, t)); set_delay(td2d, get_plate_delay(3163, t)); set_delay(od1l, get_plate_delay(266, t)); set_delay(od2l, get_plate_delay(2974, t)); set_delay(od3l, get_plate_delay(1913, t)); set_delay(od4l, get_plate_delay(1996, t)); set_delay(od5l, get_plate_delay(1990, t)); set_delay(od6l, get_plate_delay(187, t)); set_delay(od7l, get_plate_delay(1066, t)); set_delay(od1r, get_plate_delay(353, t)); set_delay(od2r, get_plate_delay(3627, t)); set_delay(od3r, get_plate_delay(1228, t)); set_delay(od4r, get_plate_delay(2673, t)); set_delay(od5r, get_plate_delay(2111, t)); set_delay(od6r, get_plate_delay(335, t)); set_delay(od7r, get_plate_delay(121, t)); set_allpass(ap1, get_plate_delay(142, t), PLATE_INPUT_DIFFUSION1); set_allpass(ap2, get_plate_delay(107, t), PLATE_INPUT_DIFFUSION1); set_allpass(ap3, get_plate_delay(379, t), PLATE_INPUT_DIFFUSION2); set_allpass(ap4, get_plate_delay(277, t), PLATE_INPUT_DIFFUSION2); set_allpass(ap6, get_plate_delay(1800, t), PLATE_DECAY_DIFFUSION2); set_allpass(ap6d, get_plate_delay(2656, t), PLATE_DECAY_DIFFUSION2); set_mod_allpass(ap5, get_plate_delay(672, t), get_plate_delay(16, t), PLATE_DECAY_DIFFUSION1); set_mod_allpass(ap5d, get_plate_delay(908, t), get_plate_delay(16, t), PLATE_DECAY_DIFFUSION1); lpf1->a = PLATE_BANDWIDTH, lpf2->a = 1.0 - PLATE_DAMPING; init_filter_lowpass1(lpf1); init_filter_lowpass1(lpf2); info->t1 = info->t1d = 0; info->decay = PLATE_DECAY; info->decayi = TIM_FSCALE(info->decay, 24); info->ddif1 = PLATE_DECAY_DIFFUSION1; info->ddif1i = TIM_FSCALE(info->ddif1, 24); info->ddif2 = PLATE_DECAY_DIFFUSION2; info->ddif2i = TIM_FSCALE(info->ddif2, 24); info->idif1 = PLATE_INPUT_DIFFUSION1; info->idif1i = TIM_FSCALE(info->idif1, 24); info->idif2 = PLATE_INPUT_DIFFUSION2; info->idif2i = TIM_FSCALE(info->idif2, 24); info->wet = PLATE_WET * (double)reverb_status_gs.level / 127.0; return; } else if(count == MAGIC_FREE_EFFECT_INFO) { free_delay(pd); free_delay(td1); free_delay(td1d); free_delay(td2); free_delay(td2d); free_delay(od1l); free_delay(od2l); free_delay(od3l); free_delay(od4l); free_delay(od5l); free_delay(od6l); free_delay(od7l); free_delay(od1r); free_delay(od2r); free_delay(od3r); free_delay(od4r); free_delay(od5r); free_delay(od6r); free_delay(od7r); free_allpass(ap1); free_allpass(ap2); free_allpass(ap3); free_allpass(ap4); free_allpass(ap6); free_allpass(ap6d); free_mod_allpass(ap5); free_mod_allpass(ap5d); return; } for (i = 0; i < count; i++) { outr = outl = 0; x = (reverb_effect_buffer[i] + reverb_effect_buffer[i + 1]) >> 1; reverb_effect_buffer[i] = reverb_effect_buffer[i + 1] = 0; do_delay(&x, pd->buf, pd->size, &pd->index); do_filter_lowpass1(&x, &lpf1->x1l, lpf1->ai, lpf1->iai); do_allpass(&x, ap1->buf, ap1->size, &ap1->index, idif1i); do_allpass(&x, ap2->buf, ap2->size, &ap2->index, idif1i); do_allpass(&x, ap3->buf, ap3->size, &ap3->index, idif2i); do_allpass(&x, ap4->buf, ap4->size, &ap4->index, idif2i); /* tank structure */ xd = x; x += imuldiv24(t1d, decayi); val = do_lfo(lfo1); do_mod_allpass(&x, ap5->buf, ap5->size, &ap5->rindex, &ap5->windex, ap5->ndelay, ap5->depth, val, &ap5->hist, ddif1i); temp1 = temp2 = temp3 = x; /* n_out_1 */ do_delay(&temp1, od5l->buf, od5l->size, &od5l->index); outl -= temp1; /* left output 5 */ do_delay(&temp2, od1r->buf, od1r->size, &od1r->index); outr += temp2; /* right output 1 */ do_delay(&temp3, od2r->buf, od2r->size, &od2r->index); outr += temp3; /* right output 2 */ do_delay(&x, td1->buf, td1->size, &td1->index); do_filter_lowpass1(&x, &lpf2->x1l, lpf2->ai, lpf2->iai); temp1 = temp2 = x; /* n_out_2 */ do_delay(&temp1, od6l->buf, od6l->size, &od6l->index); outl -= temp1; /* left output 6 */ do_delay(&temp2, od3r->buf, od3r->size, &od3r->index); outr -= temp2; /* right output 3 */ x = imuldiv24(x, decayi); do_allpass(&x, ap6->buf, ap6->size, &ap6->index, ddif2i); temp1 = temp2 = x; /* n_out_3 */ do_delay(&temp1, od7l->buf, od7l->size, &od7l->index); outl -= temp1; /* left output 7 */ do_delay(&temp2, od4r->buf, od4r->size, &od4r->index); outr += temp2; /* right output 4 */ do_delay(&x, td2->buf, td2->size, &td2->index); t1 = x; xd += imuldiv24(t1, decayi); val = do_lfo(lfo1d); do_mod_allpass(&x, ap5d->buf, ap5d->size, &ap5d->rindex, &ap5d->windex, ap5d->ndelay, ap5d->depth, val, &ap5d->hist, ddif1i); temp1 = temp2 = temp3 = xd; /* n_out_4 */ do_delay(&temp1, od1l->buf, od1l->size, &od1l->index); outl += temp1; /* left output 1 */ do_delay(&temp2, od2l->buf, od2l->size, &od2l->index); outl += temp2; /* left output 2 */ do_delay(&temp3, od6r->buf, od6r->size, &od6r->index); outr -= temp3; /* right output 6 */ do_delay(&xd, td1d->buf, td1d->size, &td1d->index); do_filter_lowpass1(&xd, &lpf2->x1r, lpf2->ai, lpf2->iai); temp1 = temp2 = xd; /* n_out_5 */ do_delay(&temp1, od3l->buf, od3l->size, &od3l->index); outl -= temp1; /* left output 3 */ do_delay(&temp2, od6r->buf, od6r->size, &od6r->index); outr -= temp2; /* right output 6 */ xd = imuldiv24(xd, decayi); do_allpass(&xd, ap6d->buf, ap6d->size, &ap6d->index, ddif2i); temp1 = temp2 = xd; /* n_out_6 */ do_delay(&temp1, od4l->buf, od4l->size, &od4l->index); outl += temp1; /* left output 4 */ do_delay(&temp2, od7r->buf, od7r->size, &od7r->index); outr -= temp2; /* right output 7 */ do_delay(&xd, td2d->buf, td2d->size, &td2d->index); t1d = xd; buf[i] += outl; buf[i + 1] += outr; ++i; } info->t1 = t1, info->t1d = t1d;}/*! initialize Reverb Effect */void init_reverb(void){ init_filter_lowpass1(&(reverb_status_gs.lpf)); /* Only initialize freeverb if stereo output */ /* Old non-freeverb must be initialized for mono reverb not to crash */ if (! (play_mode->encoding & PE_MONO) && (opt_reverb_control == 3 || opt_reverb_control == 4 || (opt_reverb_control < 0 && ! (opt_reverb_control & 0x100)))) { switch(reverb_status_gs.character) { /* select reverb algorithm */ case 5: /* Plate Reverb */ do_ch_plate_reverb(NULL, MAGIC_INIT_EFFECT_INFO, &(reverb_status_gs.info_plate_reverb)); REV_INP_LEV = reverb_status_gs.info_plate_reverb.wet; break; case 6: /* Delay */ do_ch_reverb_normal_delay(NULL, MAGIC_INIT_EFFECT_INFO, &(reverb_status_gs.info_reverb_delay)); REV_INP_LEV = 1.0; break; case 7: /* Panning Delay */ do_ch_reverb_panning_delay(NULL, MAGIC_INIT_EFFECT_INFO, &(reverb_status_gs.info_reverb_delay)); REV_INP_LEV = 1.0; break; default: /* Freeverb */ do_ch_freeverb(NULL, MAGIC_INIT_EFFECT_INFO, &(reverb_status_gs.info_freeverb)); REV_INP_LEV = reverb_status_gs.info_freeverb.wet; break; } } else { /* Old Reverb */ do_ch_standard_reverb(NULL, MAGIC_INIT_EFFECT_INFO, &(reverb_status_gs.info_standard_reverb)); REV_INP_LEV = 1.0; } memset(reverb_effect_buffer, 0, reverb_effect_bufsize); memset(direct_buffer, 0, direct_bufsize);}void do_ch_reverb(int32 *buf, int32 count){#ifdef SYS_EFFECT_PRE_LPF if ((opt_reverb_control == 3 || opt_reverb_control == 4 || (opt_reverb_control < 0 && ! (opt_reverb_control & 0x100))) && reverb_status_gs.pre_lpf) do_filter_lowpass1_stereo(reverb_effect_buffer, count, &(reverb_status_gs.lpf));#endif /* SYS_EFFECT_PRE_LPF */ if (opt_reverb_control == 3 || opt_reverb_control == 4 || (opt_reverb_control < 0 && ! (opt_reverb_control & 0x100))) { switch(reverb_status_gs.character) { /* select reverb algorithm */ case 5: /* Plate Reverb */ do_ch_plate_reverb(buf, count, &(reverb_status_gs.info_plate_reverb)); REV_INP_LEV = reverb_status_gs.info_plate_reverb.wet; break; case 6: /* Delay */ do_ch_reverb_normal_delay(buf, count, &(reverb_status_gs.info_reverb_delay)); REV_INP_LEV = 1.0; break; case 7: /* Panning Delay */ do_ch_reverb_panning_delay(buf, count, &(reverb_status_gs.info_reverb_delay)); REV_INP_LEV = 1.0; break; default: /* Freeverb */ do_ch_freeverb(buf, count, &(reverb_status_gs.info_freeverb)); REV_INP_LEV = reverb_status_gs.info_freeverb.wet; break; } } else { /* Old Reverb */ do_ch_standard_reverb(buf, count, &(reverb_status_gs.info_standard_reverb)); }}void do_mono_reverb(int32 *buf, int32 count){ do_ch_standard_reverb_mono(buf, count, &(reverb_status_gs.info_standard_reverb));}/* *//* Delay Effect *//* */static int32 delay_effect_buffer[AUDIO_BUFFER_SIZE * 2];static void do_ch_3tap_delay(int32 *, int32, InfoDelay3 *);static void do_ch_cross_delay(int32 *, int32, InfoDelay3 *);static void do_ch_normal_delay(int32 *, int32, InfoDelay3 *);void init_ch_delay(void){ memset(delay_effect_buffer, 0, sizeof(delay_effect_buffer)); init_filter_lowpass1(&(delay_status_gs.lpf)); do_ch_3tap_delay(NULL, MAGIC_INIT_EFFECT_INFO, &(delay_status_gs.info_delay));}void do_ch_delay(int32 *buf, int32 count){#ifdef SYS_EFFECT_PRE_LPF if ((opt_reverb_control == 3 || opt_reverb_control == 4 || (opt_reverb_control < 0 && ! (opt_reverb_control & 0x100))) && delay_status_gs.pre_lpf) do_filter_lowpass1_stereo(delay_effect_buffer, count, &(delay_status_gs.lpf));#endif /* SYS_EFFECT_PRE_LPF */ switch (delay_status_gs.type) { case 1: do_ch_3tap_delay(buf, count, &(delay_status_gs.info_delay)); break; case 2: do_ch_cross_delay(buf, count, &(delay_status_gs.info_delay)); break; default: do_ch_normal_delay(buf, count, &(delay_status_gs.info_delay)); break; }}#if OPT_MODE != 0#if defined(_MSC_VER) || defined(__WATCOMC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 1380) )void set_ch_delay(int32 *buf, int32 count, int32 level){ int32 *dbuf = delay_effect_buffer; if(!level) {return;} level = level * 65536 / 127; _asm { mov ecx, [count] mov esi, [buf] mov ebx, [level] test ecx, ecx jz short L2 mov edi, [dbuf]L1: mov eax, [esi] imul ebx shr eax, 16 shl edx, 16 or eax, edx /* u */ mov edx, [edi] /* v */ add esi, 4 /* u */ add edx, eax /* v */ mov [edi], edx /* u */ add edi, 4 /* v */ dec ecx /* u */ jnz L1 /* v */L2: }}#elsevoid set_ch_delay(register int32 *sbuffer, int32 n, int32 level){ register int32 i; int32 *buf = delay_effect_buffer; if(!level) {return;} level = level * 65536 / 127; for(i = n - 1; i >= 0; i--) {buf[i] += imuldiv16(sbuffer[i], level);}}#endif /* _MSC_VER */#elsevoid set_ch_delay(register int32 *sbuffer, int32 n, int32 level){ register int32 i; if(!level) {return;} FLOAT_T send_level = (FLOAT_T)level / 127.0f; for(i = 0; i < n; i++) { delay_effect_buffer[i] += sbuffer[i] * send_level; }}#endif /* OPT_MODE != 0 *//*! initialize Delay Effect; this implementation is specialized for system effect. */static void init_ch_3tap_delay(InfoDelay3 *info){ int32 i, x; info->size[0] = delay_status_gs.sample_c; info->size[1] = delay_status_gs.sample_l; info->size[2] = delay_status_gs.sample_r; x = info->size[0]; /* find maximum value */ for (i = 1; i < 3; i++) { if (info->size[i] > x) {x = info->size[i];} } x += 1; /* allowance */ set_delay(&(info->delayL), x); set_delay(&(info->delayR), x); for (i = 0; i < 3; i++) { /* set start-point */ info->index[i] = x - info->size[i]; } info->level[0] = delay_status_gs.level_ratio_c * MASTER_DELAY_LEVEL; info->level[1] = delay_status_gs.level_ratio_l * MASTER_DELAY_LEVEL; info->level[2] = delay_status_gs.level_ratio_r * MASTER_DELAY_LEVEL; info->feedback = delay_status_gs.feedback_ratio; info->send_reverb = delay_status_gs.send_reverb_ratio * REV_INP_LEV; for (i = 0; i < 3; i++) { info->leveli[i] = TIM_FSCALE(info->level[i], 24); } info->feedbacki = TIM_FSCALE(info->feedback, 24); info->send_reverbi = TIM_FSCALE(info->send_reverb, 24);}static void free_ch_3tap_delay(InfoDelay3 *info){ free_delay(&(info->delayL)); free_delay(&(info->delayR));}/*! 3-Tap Stereo Delay Effect; this implementation is specialized for system effect. */static void do_ch_3tap_delay(int32 *buf, int32 count, InfoDelay3 *info){ int32 i, x; 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], index1 = info->index[1], index2 = info->index[2]; int32 level0i = info->leveli[0], level1i = info->leveli[1], level2i = info->leveli[2], feedbacki = info->feedbacki, send_reverbi = info->send_reverbi; if(count == MAGIC_INIT_EFFECT_INFO) { init_ch_3tap_delay(info); return; } else if(count == MAGIC_FREE_EFFECT_INFO) { free_ch_3tap_delay(info); return; } for (i = 0; i < count; i++) { bufL[buf_index] = delay_effect_buffer[i] + imuldiv24(bufL[index0], feedbacki); x = imuldiv24(bufL[index0], level0i) + imuldiv24(bufL[index1] + bufR[index1], level1i); buf[i] += x; reverb_effect_buffer[i] += imuldiv24(x, send_reverbi); bufR[buf_index] = delay_effect_buffer[++i] + imuldiv24(bufR[index0], feedbacki); x = imuldiv24(bufR[index0], level0i) + imuldiv24(bufL[index2] + bufR[index2], level2i); buf[i] += x; reverb_effect_buffer[i] += imuldiv24(x, send_reverbi); if (++index0 == buf_size) {index0 = 0;} if (++index1 == buf_size) {index1 = 0;} if (++index2 == buf_size) {index2 = 0;} if (++buf_index == buf_size) {buf_index = 0;} } memset(delay_effect_buffer, 0, sizeof(int32) * count); info->index[0] = index0, info->index[1] = index1, info->index[2] = index2; delayL->index = delayR->index = buf_index;}/*! Cross Delay Effect; this implementation is specialized for system effect. */static void do_ch_cross_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, send_reverbi = info->send_reverbi; if(count == MAGIC_INIT_EFFECT_INFO) { init_ch_3tap_delay(info); return; } else if(count == MAGIC_FREE_EFFECT_INFO) { free_ch_3tap_delay(info); return; } for (i = 0; i < count; i++) { bufL[buf_index] = delay_effect_buffer[i] + imuldiv24(bufR[index0], feedbacki); l = imuldiv24(bufL[index0], level0i); bufR[buf_index] = delay_effect_buffer[i + 1] + imuldiv2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -