📄 effects processor.c
字号:
int fp,ep1,ep2,ep3,ep4;
int depth,delay,min_sweep,max_sweep,sweep_up;
int i,step,xfade,xfade_cnt,active,active_cnt,chanA;
long scan = 0;
float inval,outval,comp,ifac = 65536.0;
float blendA,blendB,*fadeA,*fadeB;
static float fade_out[MAX_XTAB],fade_in[MAX_XTAB];
bw data;
wl sweep;
/* fetch params */
step = (int)(p->rate * 65535.0);
sweep_up = p->rate > 0;
depth = (int)(p->depth * (float)SampleRate / 1000.0);
delay = (int)(p->delay * (float)SampleRate / 1000.0);
xfade = (int)(12.0 * (float)SampleRate / 1000.0);
/* init/calc some stuff */
max_sweep = BFSZ - 2 - delay;
min_sweep = max_sweep - depth;
active = max_sweep - min_sweep - (int)(xfade * p->rate) - 2;
if(xfade > MAX_XTAB) {
printf("Can't do pitch change crossfade at this sample rate.\n");
exit(1);
}
if(min_sweep < 0) {
printf("Can't do that much delay or depth at this sample rate.\n");
exit(1);
}
/* build the crossfade lookup tables */
for(i = 0; i < xfade; i++) {
fade_in[i] = cos((float)i * M_PI_2 / (float)xfade);
fade_out[i] = sin((float)i * M_PI_2 / (float)xfade);
}
/* init store and read ptrs to known value, chanA active 1st */
fp = ep3 = ep4 = xfade_cnt = 0;
sweep.l = 0;
if(sweep_up)
ep1 = ep2 = min_sweep;
else
ep1 = ep2 = max_sweep;
active_cnt = active;
blendA = 1.0;
blendB = 0.0;
fadeA = fade_out;
fadeB = fade_in;
chanA = TRUE;
/* disable interrupts, go to it */
disable();
while(1) {
while((inp(SR) & 0x20) == 0); /* wait for input ready */
data.b[0] = inp(PDR); /* read input from chip */
data.b[1] = inp(PDR);
/* messy expression to interpolate from both pairs of read ptrs */
comp = ifac - sweep.w[0];
outval =
((Buf[ep1] * sweep.w[0] + Buf[ep2] * comp) * blendA +
(Buf[ep3] * sweep.w[0] + Buf[ep4] * comp) * blendB) / ifac;
/* store finished input plus feedback */
Buf[fp] = (inval = (float)data.w) + outval * p->feedback;
/* develop final output mix */
outval = outval * p->wet_mix + inval * p->dry_mix;
if(outval > 32767.0) /* clip output if necessary */
data.w = 32767;
else if(outval < -32768.0)
data.w = -32768;
else
data.w = (int)outval;
while((inp(SR) & 0x2) == 0); /* wait for output ready */
outp(PDR,data.b[0]); /* write output to chip */
outp(PDR,data.b[1]);
check_human(); /* check on human every so often */
/* see if crossfade active */
if(xfade_cnt) {
xfade_cnt--;
blendA = fadeA[xfade_cnt];
blendB = fadeB[xfade_cnt];
}
/* update store ptr */
inc_index(fp);
/* see which direction */
if(sweep_up) {
/* update sweep */
sweep.l += (unsigned)step;
/* always inc at least once */
inc_indexes(ep1,ep2);
inc_indexes(ep3,ep4);
/* if sweep didn't overflow, we're done */
if(sweep.w[1] == 0) continue;
/* sweep overflowed, inc again */
inc_indexes(ep1,ep2);
inc_indexes(ep3,ep4);
sweep.w[1] = 0;
/* see if it's time to switch over to other delay channel */
if(active_cnt-- == 0) {
xfade_cnt = xfade; /* initiate crossfade */
active_cnt = active; /* start counter on new channel */
if(chanA) { /* A has been active, go to B */
chanA = FALSE;
ep3 = (fp + min_sweep) & (BFSZ - 1);
fadeA = fade_out;
fadeB = fade_in;
}
else {
chanA = TRUE;
ep1 = (fp + min_sweep) & (BFSZ - 1);
fadeB = fade_out;
fadeA = fade_in;
}
}
}
/* do downward sweep */
else {
sweep.l += step; /* update sweep */
/* if sweep didn't overflow, inc ptrs, that's all */
if(sweep.w[1] == 0) {
inc_indexes(ep1,ep2);
inc_indexes(ep3,ep4);
continue;
}
/* sweep overflowed, check on stuff but skip ptr inc */
sweep.w[1] = 0;
/* see if it's time to switch over to other delay channel */
if(active_cnt-- == 0) {
xfade_cnt = xfade;
active_cnt = active;
if(chanA) { /* A has been active, go to B */
chanA = FALSE;
ep3 = (fp + max_sweep) & (BFSZ - 1);
fadeA = fade_out;
fadeB = fade_in;
}
else {
chanA = TRUE;
ep1 = (fp + max_sweep) & (BFSZ - 1);
fadeB = fade_out;
fadeA = fade_in;
}
}
} /* end down sweep */
} /* end main loop */
}
/*
phase_shift
Digital version of the popular '70s effect. This one
does 4 stages just like old MXR Phase 90 stompbox.
dry_mix mix of unaffected signal (-0.999 to 0.999)
wet_mix mix of affected signal (-0.999 - 0.999)
feedback amount of recirculation (-0.9 - 0.9)
rate rate of sweep in cycles per second
depth sweep range in octaves
delay base frequency of sweep
*/
void
phase_shift(register struct program *p)
{
long scan = 0;
float wp,min_wp,max_wp,range,coef,sweepfac;
float inval,x1,outval = 0.0;
static float lx1,ly1,lx2,ly2,lx3,ly3,lx4,ly4;
bw data;
/* calc params for sweeping filters */
wp = min_wp = (M_PI * p->delay) / (float)SampleRate;
range = pow(2.0,p->depth);
max_wp = (M_PI * p->delay * range) / (float)SampleRate;
p->rate = pow(range,p->rate / ((float)SampleRate / 2));
sweepfac = p->rate;
/* disable interrupts, go to it */
disable();
while(1) {
coef = (1.0 - wp) / (1.0 + wp); /* calc coef for current freq */
while((inp(SR) & 0x20) == 0); /* wait for input ready */
data.b[0] = inp(PDR); /* read input from chip */
data.b[1] = inp(PDR);
x1 = (inval = (float)data.w) + p->feedback * ly4;
ly1 = coef * (ly1 + x1) - lx1; /* do 1st filter */
lx1 = x1;
ly2 = coef * (ly2 + ly1) - lx2; /* do 2nd filter */
lx2 = ly1;
ly3 = coef * (ly3 + ly2) - lx3; /* do 3rd filter */
lx3 = ly2;
ly4 = coef * (ly4 + ly3) - lx4; /* do 4th filter */
lx4 = ly3;
/* develop final output mix */
outval = ly4 * p->wet_mix + inval * p->dry_mix;
if(outval > 32767.0) /* clip output if necessary */
data.w = 32767;
else if(outval < -32768.0)
data.w = -32768;
else
data.w = (int)outval;
while((inp(SR) & 0x2) == 0); /* wait for output ready */
outp(PDR,data.b[0]); /* write output to chip */
outp(PDR,data.b[1]);
wp *= sweepfac; /* adjust freq of filters */
if(wp > max_wp) /* max? */
sweepfac = 1.0 / p->rate; /* sweep back down */
else if(wp < min_wp) /* min? */
sweepfac = p->rate; /* sweep back up */
check_human(); /* check on human every so often */
}
}
/*
chk_keystroke
Sees if human has hit a key. If so, exits. This routine makes
a click cuz it has to turn on interrupts briefly.
*/
void
chk_keystroke(void)
{
enable();
if(kbhit()) {
getch();
exit(0);
}
disable();
}
/*
usage
*/
void
usage(void)
{
int i;
static char *use =
"Usage: fx [patch] [[samp_rate]] [[src_gain]]\n"
" patch Selects effect program. Value should be 0-%d.\n"
" samp_rate Selects sampling frequency. Value should be 5,6,8,\n"
" 9,11,16,18,22,27,32,33,37,44, or 48. Defaults to 16k.\n"
" src_gain Selects source and gain. 0-15 adjust line input level.\n"
" 16-31 select the microphone input and adjust its level.\n"
" Defaults to 23 for microphone input.\n";
printf(use,NPROGS - 1);
for(i = 0; i < NPROGS; i++)
printf("Patch %2d:\t%s\n",i,programs[i].name);
exit(1);
}
int iar_mce;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -