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

📄 reverb.c

📁 MIDI解码程序(用VC编写)
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    TiMidity++ -- MIDI to WAVE converter and player    Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>    Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* * REVERB EFFECT FOR TIMIDITY++-1.X (Version 0.06e  1999/1/28) *  * Copyright (C) 1997,1998,1999  Masaki Kiryu <mkiryu@usa.net> *                           (http://w3mb.kcom.ne.jp/~mkiryu/) * * reverb.c  -- main reverb engine. * */#ifdef HAVE_CONFIG_H#include "config.h"#endif /* HAVE_CONFIG_H */#ifndef NO_STRING_H#include <string.h>#else#include <strings.h>#endif#include "timidity.h"#include "controls.h"#include "tables.h"#include "common.h"#include "output.h"#include "reverb.h"#include "mt19937ar.h"#include <math.h>#include <stdlib.h>#define SYS_EFFECT_PRE_LPF/* #define SYS_EFFECT_CLIP */#ifdef SYS_EFFECT_CLIP#define CLIP_AMP_MAX (1L << (32 - GUARD_BITS))#define CLIP_AMP_MIN (-1L << (32 - GUARD_BITS))#endif /* SYS_EFFECT_CLIP */static double REV_INP_LEV = 1.0;#define MASTER_CHORUS_LEVEL 1.7#define MASTER_DELAY_LEVEL 3.25/*              *//*  Dry Signal  *//*              */static int32 direct_buffer[AUDIO_BUFFER_SIZE * 2];static int32 direct_bufsize = sizeof(direct_buffer);#if OPT_MODE != 0 && ( defined(_MSC_VER) || defined(__WATCOMC__)|| (defined(__BORLANDC__) && (__BORLANDC__ >= 1380)) )void set_dry_signal(int32 *buf, int32 count){	int32 *dbuf = direct_buffer;	_asm {		mov		ecx, [count]		mov		esi, [buf]		test	ecx, ecx		jz		short L2		mov		edi, [dbuf]L1:		mov		eax, [esi]		mov		ebx, [edi]		add		esi, 4		add		ebx, eax		mov		[edi], ebx		add		edi, 4		dec		ecx		jnz		L1L2:	}}#elsevoid set_dry_signal(register int32 *buf, int32 n){#if USE_ALTIVEC  if(is_altivec_available()) {    v_set_dry_signal(direct_buffer, buf, n);  } else {#endif    register int32 i;	register int32 *dbuf = direct_buffer;    for(i = n - 1; i >= 0; i--)    {        dbuf[i] += buf[i];    }#if USE_ALTIVEC  }#endif}#endif/* XG has "dry level". */#if OPT_MODE != 0	/* fixed-point implementation */#if defined(_MSC_VER) || defined(__WATCOMC__) || (defined(__BORLANDC__) && (__BORLANDC__ >= 1380))void set_dry_signal_xg(int32 *buf, int32 count, int32 level){	int32 *dbuf = direct_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_dry_signal_xg(register int32 *sbuffer, int32 n, int32 level){    register int32 i;	int32 *buf = direct_buffer;	if(!level) {return;}	level = level * 65536 / 127;	for(i = n - 1; i >= 0; i--) {buf[i] += imuldiv16(sbuffer[i], level);}}#endif	/* _MSC_VER */#else	/* floating-point implementation */void set_dry_signal_xg(register int32 *sbuffer, int32 n, int32 level){    register int32 i;    register int32 count = n;	if(!level) {return;}    FLOAT_T send_level = (FLOAT_T)level / 127.0;    for(i = 0; i < count; i++)    {		direct_buffer[i] += sbuffer[i] * send_level;    }}#endif /* OPT_MODE != 0 */#ifdef SYS_EFFECT_CLIPvoid mix_dry_signal(int32 *buf, int32 n){	int32 i, x;	for (i = 0; i < n; i++) {		x = direct_buffer[i];		buf[i] = (x > CLIP_AMP_MAX) ? CLIP_AMP_MAX				: (x < CLIP_AMP_MIN) ? CLIP_AMP_MIN : x;	}	memset(direct_buffer, 0, sizeof(int32) * n);}#else /* SYS_EFFECT_CLIP */void mix_dry_signal(int32 *buf, int32 n){ 	memcpy(buf, direct_buffer, sizeof(int32) * n);	memset(direct_buffer, 0, sizeof(int32) * n);}#endif /* SYS_EFFECT_CLIP *//*                    *//*  Effect Utilities  *//*                    */static inline int isprime(int val){	int i;	if (val == 2) {return 1;}	if (val & 1) {		for (i = 3; i < (int)sqrt((double)val) + 1; i += 2) {			if ((val % i) == 0) {return 0;}		}		return 1; /* prime */	} else {return 0;} /* even */}/*! delay */static void free_delay(delay *delay){	if(delay->buf != NULL) {		free(delay->buf);		delay->buf = NULL;	}}static void set_delay(delay *delay, int32 size){	if(size < 1) {size = 1;} 	free_delay(delay);	delay->buf = (int32 *)safe_malloc(sizeof(int32) * size);	if(delay->buf == NULL) {return;}	delay->index = 0;	delay->size = size;	memset(delay->buf, 0, sizeof(int32) * delay->size);}static inline void do_delay(int32 *stream, int32 *buf, int32 size, int32 *index){	int32 output;	output = buf[*index];	buf[*index] = *stream;	if (++*index >= size) {*index = 0;}	*stream = output;}/*! LFO (low frequency oscillator) */static void init_lfo(lfo *lfo, double freq, int type, double phase){	int32 i, cycle, diff;	lfo->count = 0;	lfo->freq = freq;	if (lfo->freq < 0.05f) {lfo->freq = 0.05f;}	cycle = (double)play_mode->rate / lfo->freq;	if (cycle < 1) {cycle = 1;}	lfo->cycle = cycle;	lfo->icycle = TIM_FSCALE((SINE_CYCLE_LENGTH - 1) / (double)cycle, 24) - 0.5;	diff = SINE_CYCLE_LENGTH * phase / 360.0f;	if(lfo->type != type) {	/* generate LFO waveform */		switch(type) {		case LFO_SINE:			for(i = 0; i < SINE_CYCLE_LENGTH; i++)				lfo->buf[i] = TIM_FSCALE((lookup_sine(i + diff) + 1.0) / 2.0, 16);			break;		case LFO_TRIANGULAR:			for(i = 0; i < SINE_CYCLE_LENGTH; i++)				lfo->buf[i] = TIM_FSCALE((lookup_triangular(i + diff) + 1.0) / 2.0, 16);			break;		default:			for(i = 0; i < SINE_CYCLE_LENGTH; i++) {lfo->buf[i] = TIM_FSCALE(0.5, 16);}			break;		}	}	lfo->type = type;}/* returned value is between 0 and (1 << 16) */static inline int32 do_lfo(lfo *lfo){	int32 val;	val = lfo->buf[imuldiv24(lfo->count, lfo->icycle)];	if(++lfo->count == lfo->cycle) {lfo->count = 0;}	return val;}/*! modulated delay with allpass interpolation (for Chorus Effect,...) */static void free_mod_delay(mod_delay *delay){	if(delay->buf != NULL) {		free(delay->buf);		delay->buf = NULL;	}}static void set_mod_delay(mod_delay *delay, int32 ndelay, int32 depth){	int32 size = ndelay + depth + 1;	free_mod_delay(delay);	delay->buf = (int32 *)safe_malloc(sizeof(int32) * size);	if(delay->buf == NULL) {return;}	delay->rindex = 0;	delay->windex = 0;	delay->hist = 0;	delay->ndelay = ndelay;	delay->depth = depth;	delay->size = size;	memset(delay->buf, 0, sizeof(int32) * delay->size);}static inline void do_mod_delay(int32 *stream, int32 *buf, int32 size, int32 *rindex, int32 *windex,								int32 ndelay, int32 depth, int32 lfoval, int32 *hist){	int32 t1, t2;	if (++*windex == size) {*windex = 0;}	t1 = buf[*rindex];	t2 = imuldiv24(lfoval, depth);	*rindex = *windex - ndelay - (t2 >> 8);	if (*rindex < 0) {*rindex += size;}	t2 = 0xFF - (t2 & 0xFF);	*hist = t1 + imuldiv8(buf[*rindex] - *hist, t2);	buf[*windex] = *stream;	*stream = *hist;}/*! modulated allpass filter with allpass interpolation (for Plate Reverberator,...) */static void free_mod_allpass(mod_allpass *delay){	if(delay->buf != NULL) {		free(delay->buf);		delay->buf = NULL;	}}static void set_mod_allpass(mod_allpass *delay, int32 ndelay, int32 depth, double feedback){	int32 size = ndelay + depth + 1;	free_mod_allpass(delay);	delay->buf = (int32 *)safe_malloc(sizeof(int32) * size);	if(delay->buf == NULL) {return;}	delay->rindex = 0;	delay->windex = 0;	delay->hist = 0;	delay->ndelay = ndelay;	delay->depth = depth;	delay->size = size;	delay->feedback = feedback;	delay->feedbacki = TIM_FSCALE(feedback, 24);	memset(delay->buf, 0, sizeof(int32) * delay->size);}static inline void do_mod_allpass(int32 *stream, int32 *buf, int32 size, int32 *rindex, int32 *windex,								  int32 ndelay, int32 depth, int32 lfoval, int32 *hist, int32 feedback){	int t1, t2, t3;	if (++*windex == size) {*windex = 0;}	t3 = *stream + imuldiv24(*hist, feedback);	t1 = buf[*rindex];	t2 = imuldiv24(lfoval, depth);	*rindex = *windex - ndelay - (t2 >> 8);	if (*rindex < 0) {*rindex += size;}	t2 = 0xFF - (t2 & 0xFF);	*hist = t1 + imuldiv8(buf[*rindex] - *hist, t2);	buf[*windex] = t3;	*stream = *hist - imuldiv24(t3, feedback);}/* allpass filter */static void free_allpass(allpass *allpass){	if(allpass->buf != NULL) {		free(allpass->buf);		allpass->buf = NULL;	}}static void set_allpass(allpass *allpass, int32 size, double feedback){	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;	allpass->feedback = feedback;	allpass->feedbacki = TIM_FSCALE(feedback, 24);	memset(allpass->buf, 0, sizeof(int32) * allpass->size);}static inline void do_allpass(int32 *stream, int32 *buf, int32 size, int32 *index, int32 feedback){	int32 bufout, output;	bufout = buf[*index];	output = *stream - imuldiv24(bufout, feedback);	buf[*index] = output;	if (++*index >= size) {*index = 0;}	*stream = bufout + imuldiv24(output, feedback);}static void init_filter_moog(filter_moog *svf){	svf->b0 = svf->b1 = svf->b2 = svf->b3 = svf->b4 = 0;}/*! calculate Moog VCF coefficients */void calc_filter_moog(filter_moog *svf){	double res, fr, p, q, f;	if (svf->freq > play_mode->rate / 2) {svf->freq = play_mode->rate / 2;}	else if(svf->freq < 20) {svf->freq = 20;}	if(svf->freq != svf->last_freq || svf->res_dB != svf->last_res_dB) {		if(svf->last_freq == 0) {init_filter_moog(svf);}		svf->last_freq = svf->freq, svf->last_res_dB = svf->res_dB;		res = pow(10, (svf->res_dB - 96) / 20);		fr = 2.0 * (double)svf->freq / (double)play_mode->rate;		q = 1.0 - fr;		p = fr + 0.8 * fr * q;		f = p + p - 1.0;		q = res * (1.0 + 0.5 * q * (1.0 - q + 5.6 * q * q));		svf->f = TIM_FSCALE(f, 24);		svf->p = TIM_FSCALE(p, 24);		svf->q = TIM_FSCALE(q, 24);	}}static inline void do_filter_moog(int32 *stream, int32 *high, int32 f, int32 p, int32 q,								  int32 *b0, int32 *b1, int32 *b2, int32 *b3, int32 *b4){	int32 t1, t2, t3, tb0 = *b0, tb1 = *b1, tb2 = *b2, tb3 = *b3, tb4 = *b4;	t3 = *stream - imuldiv24(q, tb4);	t1 = tb1;	tb1 = imuldiv24(t3 + tb0, p) - imuldiv24(tb1, f);	t2 = tb2;	tb2 = imuldiv24(tb1 + t1, p) - imuldiv24(tb2, f);	t1 = tb3;	tb3 = imuldiv24(tb2 + t2, p) - imuldiv24(tb3, f);	*stream = tb4 = imuldiv24(tb3 + t1, p) - imuldiv24(tb4, f);

⌨️ 快捷键说明

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