Fxalgo.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:18k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1. {========================================================================}
  2. {=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
  3. {========================================================================}
  4. {=                          All Rights Reserved                         =}
  5. {========================================================================}
  6. {=  D 01099 Dresden             = Tel.: +0351-8012255                   =}
  7. {=  Loewenstr.7a                = info@swiftsoft.de                     =}
  8. {========================================================================}
  9. {=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
  10. {========================================================================}
  11. {=  This code is for reference purposes only and may not be copied or   =}
  12. {=  distributed in any format electronic or otherwise except one copy   =}
  13. {=  for backup purposes.                                                =}
  14. {=                                                                      =}
  15. {=  No Delphi Component Kit or Component individually or in a collection=}
  16. {=  subclassed or otherwise from the code in this unit, or associated   =}
  17. {=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
  18. {=  without express permission from SwiftSoft.                          =}
  19. {=                                                                      =}
  20. {=  For more licence informations please refer to the associated        =}
  21. {=  HelpFile.                                                           =}
  22. {========================================================================}
  23. {=  $Date: 20.01.1998 - 18:00:00 $                                      =}
  24. {========================================================================}
  25. unit Fxalgo;
  26. interface
  27. const
  28.      BFSZ     = 4096    { main delay buffer }
  29.      MAX_XTAB = 512;    { crossfade lookup table size for pitch change }
  30. type
  31.     // program description struct
  32.     TProgram = record
  33.        Name: String;        // ASCII name of program */
  34.        dry_mix: Double;     // dry (unaffected) signal mix */
  35.        wet_mix: Double;     // wet (affected) signal mix */
  36.        feedback: Double;    // feedback */
  37.        rate    : Double;    // usually rate of sweep */
  38.        depth   : Double;    // width of sweep */
  39.        delay   : Double;    // fixed delay factor (base pitch for phaser) */
  40.     end;
  41.     // handy typedefs
  42.     Tbw = record
  43.         case integer of
  44.            1: b: array [0..1] of Byte;
  45.            2: w: word;
  46.         end;
  47.     end;
  48.     Twl = record
  49.         case integer of
  50.            1: w: array [0..1] of Word;
  51.            2: l: Longint;
  52.         end;
  53.     end;
  54. implementation
  55. // macros for pitch_change delay index manipulation
  56. procedure inc_index(var x: integer);
  57. begin
  58.    x := (x + 1) and (BFSZ - 1);
  59. end;
  60. procedure inc_indexes(var x1,x2: integer);
  61. begin
  62.    x2 := x1;
  63.    inc_index(x1);
  64. end;
  65. (*// table of programs (it's very easy to modify and add programs)
  66. var
  67.    struct program programs[] = {
  68.          /*  Name/vector      Dry     Wet   Feedback Rate    Depth   Delay */
  69.      "Echoes", flange_chorus,  0.999,  0.999,  0.7,    0.0,    0.0,    250.0},
  70. {"Slow flange",flange_chorus,  0.999,  0.999,  0.0,    2.0,    6.0,    0.0},
  71. { "Slow invert flange w FB",
  72.                 flange_chorus,  0.999,  -0.999, -0.7,   2.0,    6.0,    0.0},
  73. { "Slow chorus",flange_chorus,  0.999,  0.999,  0.0,    11.0,   20.0,   20.0},
  74. { "Cheesy "take me to your leader" robot voice",
  75.                   flange_chorus,  0.0,    0.999,  0.75,   0.0,    0.0,    12.5},
  76. { "Crazy pitch bend chorus",
  77.                    flange_chorus,  0.999,  0.999,  0.3,    150.0,  40.0,   40.0},
  78. { "Darth",pitch_change,            0.0,    0.999,  0.0,    -0.35,  25.0,   0.0},
  79. { "Major third up", pitch_change,  0.999,  0.999,  0.0,    0.2599, 35.0,   0.0},
  80. { "Octave up",pitch_change,        0.999,  0.999,  0.0,    1.0,    40.0,   0.0},
  81. { "Munchkins on helium",pitch_change,0.0,  0.999,  0.4,    0.3348, 35.0,   0.0},
  82. { "Descending echoes",pitch_change, 0.0,   0.999,  0.5,    -0.2,   35.0,   120.0},
  83. { "Ascending echoes",pitch_change,  0.0,   0.999,  0.4,    0.2599, 35.0,   120.0},
  84. { "Phase shift", phase_shift,       0.999,  0.999, 0.0,    1.0,    4.0,    100.0},
  85. { "Slow invert phase shift with feedback",
  86.                    phase_shift,    0.999,  -0.999, -0.6,   0.2,    6.0,    100.0},
  87. { "Noise gate",    noise_gate,     NA,     NA,     NA,     500.0,  0.05,   NA},
  88. { "Straight Thru", thru,           NA,     NA,     NA,     NA,     NA,     NA},
  89. };
  90. *)
  91. //#define NPROGS (sizeof(programs) / sizeof(struct program))
  92. // globals
  93. var
  94.    SampleRate: Longint;            // sample rate set by init_1848 */
  95.    Buf: array[0..BFSZ-1] of Double;// buffer used by delay based effects */
  96. (*=======================================================================
  97.                                 noise_gate
  98.     Super simple noise gate to demonstrate how much of the hiss
  99.     comes directly from the ADC on this card, but how quiet the
  100.     DACs are by comparison.
  101.     Only parms are:
  102.         rate        decay time in ms
  103.         depth       threshold for turn on
  104. ========================================================================*)
  105. procedure noise_gate(p: PProgram);
  106. var
  107.    inval,decay_fac,gain: Double;
  108.    data: tbw;
  109.    scan: Longint;
  110. begin
  111.     gain := 0;
  112.     scan := 0;
  113.     // calculate decay factor for 20db atten in spec'd time
  114.     decay_fac := pow(10.0,1.0 / ((p^.rate/1000.0) * SampleRate));
  115.     decay_fac := 1.0 / decay_fac;
  116.     // disable interrupts, go to it
  117.     while (True) do
  118.     begin
  119.        while((inp(SR) & 0x20) == 0);       // wait for input ready
  120.        data.b[0] := inp(PDR);              // read input from chip
  121.        data.b[1] := inp(PDR);
  122.        inval := data.w;
  123.        if (inval > p^.depth) then      // see if we crossed threshold
  124.            gain := 1.0;                // turn gate on */
  125.        data.w := (inval * gain);
  126.        while((inp(SR) & 0x2) == 0);    // wait for output ready */
  127.        outp(PDR,data.b[0]);            // write output to chip */
  128.        outp(PDR,data.b[1]);
  129.        gain := gain * decay_fac;       // adjust attenuation */
  130.     end;
  131. end;
  132. (*=======================================================================
  133.                                 flange_chorus
  134.     Does flanging/chorusing family of effects based on a single
  135.     varying delay.
  136.     dry_mix     mix of unaffected signal (-0.999 to 0.999)
  137.     wet_mix     mix of affected signal (-0.999 - 0.999)
  138.     feedback    amount of recirculation (-0.9 - 0.9)
  139.     rate        rate of delay change in millisecs per sec
  140.     sweep       sweep range in millisecs
  141.     delay       fixed additional delay in millisecs
  142. ========================================================================*)
  143. procedure flange_chorus(p: PProgram);
  144. var
  145.    fp,ep1,ep2: integer;
  146.    step,depth,delay,min_sweep,max_sweep: integer;
  147.    inval,outval,ifac: Double;
  148.    scan: Longint;
  149.    data:  Tbw;
  150.    sweep: Twl;
  151. begin
  152.    ifac := 65536.0;
  153.    scan := 0;
  154.    // fetch params
  155.    step := p^.rate * 65.536;
  156.    depth := p^.depth * SampleRate div 1000;
  157.    delay := p^.delay * SampleRate div 1000;
  158.    // init/calc some stuff
  159.    max_sweep := BFSZ - 2 - delay;
  160.    min_sweep := max_sweep - depth;
  161.    if (min_sweep < 0) then
  162.    begin
  163.         printf("Can't do that much delay or depth at this sample rate.n");
  164.         exit(1);
  165.    end;
  166.    sweep.w[1] := (min_sweep + max_sweep) div 2;
  167.    sweep.w[0] := 0;
  168.    // init store and read ptrs to known value
  169.    fp := 0;
  170.    ep1 := 0;
  171.    ep2 := 0;
  172.     while (True) do
  173.     begin
  174.         data.b[0] := inp(PDR);               /* read input from chip */
  175.         data.b[1] := inp(PDR);
  176.         // interpolate from the 2 read values
  177.         outval := (Buf[ep1]*sweep.w[0]+
  178.                    Buf[ep2]*(ifac-sweep.w[0]))/ifac;
  179.         // store finished input plus feedback
  180.         inval := data.w + outval * p^.feedback;
  181.         Buf[fp] := inval;
  182.         // develop final output mix
  183.         outval := outval * p^.wet_mix + inval * p^.dry_mix;
  184.         if (outval > 32767.0) then
  185.             data.w := 32767
  186.         else if (outval < -32768.0) then
  187.             data.w := -32768;
  188.         else
  189.             data.w := outval;
  190.         outp(PDR,data.b[0]);                // write output to chip
  191.         outp(PDR,data.b[1]);
  192.         // update ptrs
  193.         fp := (fp + 1) and (BFSZ - 1);
  194.         sweep.l := sweep.l + step;
  195.         ep1 := (fp + sweep.w[1]) and (BFSZ - 1);
  196.         ep2 := (ep1 - 1) and (BFSZ - 1);
  197.         // check for sweep reversal
  198.         if (sweep.w[1] > max_sweep) or   // see if we hit top of sweep
  199.            (sweep.w[1] < min_sweep) then // or if we hit bottom of sweep */
  200.             step := -step;               // reverse
  201.     end;
  202. end;
  203. (*=======================================================================
  204.                                 pitch_change
  205.     dry_mix     mix of unaffected signal (-0.999 to 0.999)
  206.     wet_mix     mix of affected signal (-0.999 - 0.999)
  207.     feedback    amount of recirculation (-0.9 - 0.9)
  208.     rate        amount of pitch change (see table below for values)
  209.     depth       sweep range in millisecs for generating pitch shift
  210.     delay       fixed additional delay
  211.     Semitones      Up              Down
  212.         1       0.059463        -0.056126
  213.         2       0.122462        -0.109101
  214.         3       0.189207        -0.159104
  215.         4       0.259921        -0.206299
  216.         5       0.334840        -0.250846
  217.         6       0.414214        -0.292893
  218.         7       0.498307        -0.332580
  219.         8       0.587401        -0.370039
  220.         9       0.681793        -0.405396
  221.         10      0.781797        -0.438769
  222.         11      0.887749        -0.470268
  223.         12      1.000000        -0.500000
  224. =======================================================================*)
  225. procedure pitch_change(p: PPRogram);
  226. var
  227.    fp,ep1,ep2,ep3,ep4: integer;
  228.    depth,delay,min_sweep,max_sweep,sweep_up: integer;
  229.    i,step,xfade,xfade_cnt,active,active_cnt,chanA: integer;
  230.    scan: Longint;
  231.    inval,outval,comp,ifac: Double;
  232.    blendA,blendB: Double;
  233.    fadeA,fadeB: ^Double;
  234.    fade_out,fade_in: array[0..MAX_XTAB-1] of Double;
  235.    data: Tdw;
  236.    sweep: tlw;
  237. begin
  238.    scan := 0;
  239.    ifac := 65536.0;
  240.     // fetch params
  241.     step := p^.rate * 65535.0;
  242.     sweep_up := 1;
  243.     depth := (p^.depth * SampleRate div 1000;
  244.     delay := (p^.delay * SampleRate div 1000;
  245.     xfade := 12 * SampleRate div 1000;
  246.     // init/calc some stuff
  247.     max_sweep := BFSZ - 2 - delay;
  248.     min_sweep := max_sweep - depth;
  249.     active := max_sweep - min_sweep - (xfade * p^.rate) - 2;
  250.     if (xfade > MAX_XTAB) then
  251.     begin
  252.         printf("Can't do pitch change crossfade at this sample rate.n");
  253.         exit(1);
  254.     end;
  255.     if (min_sweep < 0) then
  256.     begin
  257.         printf("Can't do that much delay or depth at this sample rate.n");
  258.         exit(1);
  259.     end;
  260.     // build the crossfade lookup tables
  261.     for i := 0 to xfade-1 do
  262.     begin
  263.        fade_in[i] := cos(i * M_PI_2 / xfade);
  264.        fade_out[i] := sin(i * M_PI_2 / xfade);
  265.     end;
  266.     // init store and read ptrs to known value, chanA active 1st
  267.     fp := 0;
  268.     ep3 := 0;
  269.     ep4 := 0;
  270.     xfade_cnt := 0;
  271.     sweep.l := 0;
  272.     if (sweep_up) then
  273.     begin
  274.         ep1 := min_sweep;
  275.         ep2 := min_sweep;
  276.     end
  277.     else
  278.     begin
  279.        ep1 := max_sweep;
  280.        ep2 := max_sweep;
  281.     end;
  282.     active_cnt := active;
  283.     blendA := 1.0;
  284.     blendB := 0.0;
  285.     fadeA := fade_out;
  286.     fadeB := fade_in;
  287.     chanA := True;
  288.     while (True) do
  289.     begin
  290.         data.b[0] = inp(PDR);               /* read input from chip */
  291.         data.b[1] = inp(PDR);
  292.         // messy expression to interpolate from both pairs of read ptrs
  293.         comp := ifac - sweep.w[0];
  294.         outval := ((Buf[ep1] * sweep.w[0] + Buf[ep2] * comp) * blendA +
  295.                    (Buf[ep3] * sweep.w[0] + Buf[ep4] * comp) * blendB)
  296.                    / ifac;
  297.         // store finished input plus feedback
  298.         inval := data.w + outval * p^.feedback;
  299.         Buf[fp] := inval
  300.         // develop final output mix
  301.         outval := outval * p^.wet_mix + inval * p^.dry_mix;
  302.         if (outval > 32767.0) then               // clip output if necessary
  303.             data.w := 32767;
  304.         else if(outval < -32768.0) then
  305.             data.w := -32768;
  306.         else
  307.             data.w := outval;
  308.         outp(PDR,data.b[0]);                /* write output to chip */
  309.         outp(PDR,data.b[1]);
  310.         // see if crossfade active
  311.         if (xfade_cnt > 0) then
  312.         begin
  313.             dec(xfade_cnt);
  314.             blendA := fadeA[xfade_cnt];
  315.             blendB := fadeB[xfade_cnt];
  316.         end;
  317.         // update store ptr
  318.         inc_index(fp);
  319.         // see which direction
  320.         if (sweep_up) then
  321.         begin
  322.             // update sweep
  323.             sweep.l := sweep.l + word(step);
  324.             // always inc at least once
  325.             inc_indexes(ep1,ep2);
  326.             inc_indexes(ep3,ep4);
  327.             // if sweep didn't overflow, we're done
  328.             if(sweep.w[1] = 0) continue;
  329.             // sweep overflowed, inc again
  330.             inc_indexes(ep1,ep2);
  331.             inc_indexes(ep3,ep4);
  332.             sweep.w[1] := 0;
  333.             // see if it's time to switch over to other delay channel
  334.             dec(active_cnt);
  335.             if (active_cnt = 0) then
  336.             begin
  337.                 xfade_cnt := xfade;      // initiate crossfade */
  338.                 active_cnt := active;    // start counter on new channel */
  339.                 if (chanA) then              // A has been active, go to B */
  340.                 begin
  341.                    chanA = FALSE;
  342.                    ep3 := (fp + min_sweep) and (BFSZ - 1);
  343.                    fadeA := fade_out;
  344.                    fadeB := fade_in;
  345.                 end
  346.                 else
  347.                 begin
  348.                    chanA := TRUE;
  349.                    ep1 := (fp + min_sweep) and (BFSZ - 1);
  350.                    fadeB := fade_out;
  351.                    fadeA := fade_in;
  352.                 end;
  353.             end;
  354.         end
  355.         else  // do downward sweep
  356.         begin
  357.            sweep.l := sweep.l + step;   // update sweep
  358.            // if sweep didn't overflow, inc ptrs, that's all
  359.            if (sweep.w[1] = 0) then
  360.            begin
  361.               inc_indexes(ep1,ep2);
  362.               inc_indexes(ep3,ep4);
  363.               continue;
  364.            end;
  365.            // sweep overflowed, check on stuff but skip ptr inc
  366.            sweep.w[1] := 0;
  367.            // see if it's time to switch over to other delay channel
  368.            dec(active_cnt);
  369.             if(active_cnt = 0) then
  370.             begin
  371.                xfade_cnt := xfade;
  372.                active_cnt := active;
  373.                if(chanA) then       // A has been active, go to B */
  374.                begin
  375.                   chanA := FALSE;
  376.                   ep3 := (fp + max_sweep) and (BFSZ - 1);
  377.                   fadeA := fade_out;
  378.                   fadeB := fade_in;
  379.                end
  380.                else
  381.                begin
  382.                   chanA := TRUE;
  383.                   ep1 := (fp + max_sweep) and (BFSZ - 1);
  384.                   fadeB := fade_out;
  385.                   fadeA := fade_in;
  386.                end;
  387.             end;
  388.         end
  389.     end;
  390. end;
  391. (*=======================================================================
  392.                                 phase_shift
  393.     Digital version of the popular '70s effect.  This one
  394.     does 4 stages just like old MXR Phase 90 stompbox.
  395.     dry_mix     mix of unaffected signal (-0.999 to 0.999)
  396.     wet_mix     mix of affected signal (-0.999 - 0.999)
  397.     feedback    amount of recirculation (-0.9 - 0.9)
  398.     rate        rate of sweep in cycles per second
  399.     depth       sweep range in octaves
  400.     delay       base frequency of sweep
  401. =======================================================================*)
  402. procedure phase_shift(p: PProgram);
  403. var
  404.    wp,min_wp,max_wp,range,coef,sweepfac: Double;
  405.    inval,x1,outval: Double;
  406.    lx1,ly1,lx2,ly2,lx3,ly3,lx4,ly4: Double;
  407.    data: Tdw;
  408. begin
  409.    outval := 0.0;
  410.    // calc params for sweeping filters
  411.    min_wp := (M_PI * p^.delay) / SampleRate;
  412.    wp := min_wp;
  413.    range := pow(2.0,p^.depth);
  414.    max_wp := (M_PI * p^.delay * range) / SampleRate;
  415.    p^.rate := pow(range,p^.rate / (SampleRate / 2));
  416.    sweepfac := p^.rate;
  417.    while (True) do
  418.    begin
  419.       coef := (1.0 - wp) / (1.0 + wp);   // calc coef for current freq
  420.       data.b[0] = inp(PDR);               /* read input from chip */
  421.       data.b[1] = inp(PDR);
  422.       inval := data.w + p^.feedback * ly4;
  423.       x1 := inval;
  424.       ly1 := coef * (ly1 + x1) - lx1;     // do 1st filter
  425.       lx1 := x1;
  426.       ly2 := coef * (ly2 + ly1) - lx2;    // do 2nd filter
  427.       lx2 := ly1;
  428.       ly3 := coef * (ly3 + ly2) - lx3;    // do 3rd filter
  429.       lx3 := ly2;
  430.       ly4 := coef * (ly4 + ly3) - lx4;    // do 4th filter
  431.       lx4 := ly3;
  432.       // develop final output mix
  433.       outval := ly4 * p^.wet_mix + inval * p^.dry_mix;
  434.       if (outval > 32767.0) then          // clip output if necessary
  435.           data.w := 32767
  436.       else if (outval < -32768.0) then
  437.           data.w := -32768
  438.       else
  439.           data.w := outval;
  440.       outp(PDR,data.b[0]);                // write output to chip
  441.       outp(PDR,data.b[1]);
  442.       wp := wp * sweepfac;                // adjust freq of filters
  443.       if (wp > max_wp) then               // max?
  444.           sweepfac := 1.0 / p^.rate       // sweep back down
  445.       else if (wp < min_wp) then          // min?
  446.           sweepfac := p^.rate;            // sweep back up
  447.    end;
  448. end;