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

📄 fxalgo.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
=======================================================================*)
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 + -