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

📄 reverb.c

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