📄 fxalgo.pas
字号:
=======================================================================*)
procedure pitch_change(p: PPRogram);
var
fp,ep1,ep2,ep3,ep4: integer;
depth,delay,min_sweep,max_sweep,sweep_up: integer;
i,step,xfade,xfade_cnt,active,active_cnt,chanA: integer;
scan: Longint;
inval,outval,comp,ifac: Double;
blendA,blendB: Double;
fadeA,fadeB: ^Double;
fade_out,fade_in: array[0..MAX_XTAB-1] of Double;
data: Tdw;
sweep: tlw;
begin
scan := 0;
ifac := 65536.0;
// fetch params
step := p^.rate * 65535.0;
sweep_up := 1;
depth := (p^.depth * SampleRate div 1000;
delay := (p^.delay * SampleRate div 1000;
xfade := 12 * SampleRate div 1000;
// init/calc some stuff
max_sweep := BFSZ - 2 - delay;
min_sweep := max_sweep - depth;
active := max_sweep - min_sweep - (xfade * p^.rate) - 2;
if (xfade > MAX_XTAB) then
begin
printf("Can't do pitch change crossfade at this sample rate.\n");
exit(1);
end;
if (min_sweep < 0) then
begin
printf("Can't do that much delay or depth at this sample rate.\n");
exit(1);
end;
// build the crossfade lookup tables
for i := 0 to xfade-1 do
begin
fade_in[i] := cos(i * M_PI_2 / xfade);
fade_out[i] := sin(i * M_PI_2 / xfade);
end;
// init store and read ptrs to known value, chanA active 1st
fp := 0;
ep3 := 0;
ep4 := 0;
xfade_cnt := 0;
sweep.l := 0;
if (sweep_up) then
begin
ep1 := min_sweep;
ep2 := min_sweep;
end
else
begin
ep1 := max_sweep;
ep2 := max_sweep;
end;
active_cnt := active;
blendA := 1.0;
blendB := 0.0;
fadeA := fade_out;
fadeB := fade_in;
chanA := True;
while (True) do
begin
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
inval := data.w + outval * p^.feedback;
Buf[fp] := inval
// develop final output mix
outval := outval * p^.wet_mix + inval * p^.dry_mix;
if (outval > 32767.0) then // clip output if necessary
data.w := 32767;
else if(outval < -32768.0) then
data.w := -32768;
else
data.w := outval;
outp(PDR,data.b[0]); /* write output to chip */
outp(PDR,data.b[1]);
// see if crossfade active
if (xfade_cnt > 0) then
begin
dec(xfade_cnt);
blendA := fadeA[xfade_cnt];
blendB := fadeB[xfade_cnt];
end;
// update store ptr
inc_index(fp);
// see which direction
if (sweep_up) then
begin
// update sweep
sweep.l := sweep.l + word(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
dec(active_cnt);
if (active_cnt = 0) then
begin
xfade_cnt := xfade; // initiate crossfade */
active_cnt := active; // start counter on new channel */
if (chanA) then // A has been active, go to B */
begin
chanA = FALSE;
ep3 := (fp + min_sweep) and (BFSZ - 1);
fadeA := fade_out;
fadeB := fade_in;
end
else
begin
chanA := TRUE;
ep1 := (fp + min_sweep) and (BFSZ - 1);
fadeB := fade_out;
fadeA := fade_in;
end;
end;
end
else // do downward sweep
begin
sweep.l := sweep.l + step; // update sweep
// if sweep didn't overflow, inc ptrs, that's all
if (sweep.w[1] = 0) then
begin
inc_indexes(ep1,ep2);
inc_indexes(ep3,ep4);
continue;
end;
// 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
dec(active_cnt);
if(active_cnt = 0) then
begin
xfade_cnt := xfade;
active_cnt := active;
if(chanA) then // A has been active, go to B */
begin
chanA := FALSE;
ep3 := (fp + max_sweep) and (BFSZ - 1);
fadeA := fade_out;
fadeB := fade_in;
end
else
begin
chanA := TRUE;
ep1 := (fp + max_sweep) and (BFSZ - 1);
fadeB := fade_out;
fadeA := fade_in;
end;
end;
end
end;
end;
(*=======================================================================
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
=======================================================================*)
procedure phase_shift(p: PProgram);
var
wp,min_wp,max_wp,range,coef,sweepfac: Double;
inval,x1,outval: Double;
lx1,ly1,lx2,ly2,lx3,ly3,lx4,ly4: Double;
data: Tdw;
begin
outval := 0.0;
// calc params for sweeping filters
min_wp := (M_PI * p^.delay) / SampleRate;
wp := min_wp;
range := pow(2.0,p^.depth);
max_wp := (M_PI * p^.delay * range) / SampleRate;
p^.rate := pow(range,p^.rate / (SampleRate / 2));
sweepfac := p^.rate;
while (True) do
begin
coef := (1.0 - wp) / (1.0 + wp); // calc coef for current freq
data.b[0] = inp(PDR); /* read input from chip */
data.b[1] = inp(PDR);
inval := data.w + p^.feedback * ly4;
x1 := inval;
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) then // clip output if necessary
data.w := 32767
else if (outval < -32768.0) then
data.w := -32768
else
data.w := outval;
outp(PDR,data.b[0]); // write output to chip
outp(PDR,data.b[1]);
wp := wp * sweepfac; // adjust freq of filters
if (wp > max_wp) then // max?
sweepfac := 1.0 / p^.rate // sweep back down
else if (wp < min_wp) then // min?
sweepfac := p^.rate; // sweep back up
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -