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

📄 fxalgo.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{========================================================================}
{=                (c) 1995-98 SwiftSoft Ronald Dittrich                 =}
{========================================================================}
{=                          All Rights Reserved                         =}
{========================================================================}
{=  D 01099 Dresden             = Tel.: +0351-8012255                   =}
{=  Loewenstr.7a                = info@swiftsoft.de                     =}
{========================================================================}
{=  Actual versions on http://www.swiftsoft.de/mmtools.html             =}
{========================================================================}
{=  This code is for reference purposes only and may not be copied or   =}
{=  distributed in any format electronic or otherwise except one copy   =}
{=  for backup purposes.                                                =}
{=                                                                      =}
{=  No Delphi Component Kit or Component individually or in a collection=}
{=  subclassed or otherwise from the code in this unit, or associated   =}
{=  .pas, .dfm, .dcu, .asm or .obj files may be sold or distributed     =}
{=  without express permission from SwiftSoft.                          =}
{=                                                                      =}
{=  For more licence informations please refer to the associated        =}
{=  HelpFile.                                                           =}
{========================================================================}
{=  $Date: 20.01.1998 - 18:00:00 $                                      =}
{========================================================================}
unit Fxalgo;

interface

const
     BFSZ     = 4096    { main delay buffer }
     MAX_XTAB = 512;    { crossfade lookup table size for pitch change }

type
    // program description struct
    TProgram = record
       Name: String;        // ASCII name of program */
       dry_mix: Double;     // dry (unaffected) signal mix */
       wet_mix: Double;     // wet (affected) signal mix */
       feedback: Double;    // feedback */
       rate    : Double;    // usually rate of sweep */
       depth   : Double;    // width of sweep */
       delay   : Double;    // fixed delay factor (base pitch for phaser) */
    end;

    // handy typedefs
    Tbw = record
        case integer of
           1: b: array [0..1] of Byte;
           2: w: word;
        end;
    end;

    Twl = record
        case integer of
           1: w: array [0..1] of Word;
           2: l: Longint;
        end;
    end;

implementation

// macros for pitch_change delay index manipulation
procedure inc_index(var x: integer);
begin
   x := (x + 1) and (BFSZ - 1);
end;

procedure inc_indexes(var x1,x2: integer);
begin
   x2 := x1;
   inc_index(x1);
end;

(*// table of programs (it's very easy to modify and add programs)
var
   struct program programs[] = {
         /*  Name/vector      Dry     Wet   Feedback Rate    Depth   Delay */
     "Echoes", flange_chorus,  0.999,  0.999,  0.7,    0.0,    0.0,    250.0},
{"Slow flange",flange_chorus,  0.999,  0.999,  0.0,    2.0,    6.0,    0.0},
{ "Slow invert flange w FB",
                flange_chorus,  0.999,  -0.999, -0.7,   2.0,    6.0,    0.0},
{ "Slow chorus",flange_chorus,  0.999,  0.999,  0.0,    11.0,   20.0,   20.0},
{ "Cheesy \"take me to your leader\" robot voice",
                  flange_chorus,  0.0,    0.999,  0.75,   0.0,    0.0,    12.5},
{ "Crazy pitch bend chorus",
                   flange_chorus,  0.999,  0.999,  0.3,    150.0,  40.0,   40.0},

{ "Darth",pitch_change,            0.0,    0.999,  0.0,    -0.35,  25.0,   0.0},
{ "Major third up", pitch_change,  0.999,  0.999,  0.0,    0.2599, 35.0,   0.0},
{ "Octave up",pitch_change,        0.999,  0.999,  0.0,    1.0,    40.0,   0.0},
{ "Munchkins on helium",pitch_change,0.0,  0.999,  0.4,    0.3348, 35.0,   0.0},
{ "Descending echoes",pitch_change, 0.0,   0.999,  0.5,    -0.2,   35.0,   120.0},
{ "Ascending echoes",pitch_change,  0.0,   0.999,  0.4,    0.2599, 35.0,   120.0},

{ "Phase shift", phase_shift,       0.999,  0.999, 0.0,    1.0,    4.0,    100.0},
{ "Slow invert phase shift with feedback",
                   phase_shift,    0.999,  -0.999, -0.6,   0.2,    6.0,    100.0},
{ "Noise gate",    noise_gate,     NA,     NA,     NA,     500.0,  0.05,   NA},
{ "Straight Thru", thru,           NA,     NA,     NA,     NA,     NA,     NA},
};
*)

//#define NPROGS (sizeof(programs) / sizeof(struct program))

// globals
var
   SampleRate: Longint;            // sample rate set by init_1848 */
   Buf: array[0..BFSZ-1] of Double;// buffer used by delay based effects */


(*=======================================================================
                                noise_gate

    Super simple noise gate to demonstrate how much of the hiss
    comes directly from the ADC on this card, but how quiet the
    DACs are by comparison.

    Only parms are:
        rate        decay time in ms
        depth       threshold for turn on
========================================================================*)
procedure noise_gate(p: PProgram);
var
   inval,decay_fac,gain: Double;
   data: tbw;
   scan: Longint;

begin
    gain := 0;
    scan := 0;
    // calculate decay factor for 20db atten in spec'd time
    decay_fac := pow(10.0,1.0 / ((p^.rate/1000.0) * SampleRate));
    decay_fac := 1.0 / decay_fac;

    // disable interrupts, go to it
    while (True) do
    begin
       while((inp(SR) & 0x20) == 0);       // wait for input ready

       data.b[0] := inp(PDR);              // read input from chip
       data.b[1] := inp(PDR);

       inval := data.w;
       if (inval > p^.depth) then      // see if we crossed threshold
           gain := 1.0;                // turn gate on */

       data.w := (inval * gain);

       while((inp(SR) & 0x2) == 0);    // wait for output ready */

       outp(PDR,data.b[0]);            // write output to chip */
       outp(PDR,data.b[1]);

       gain := gain * decay_fac;       // adjust attenuation */
    end;
end;


(*=======================================================================
                                flange_chorus

    Does flanging/chorusing family of effects based on a single
    varying delay.

    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 delay change in millisecs per sec
    sweep       sweep range in millisecs
    delay       fixed additional delay in millisecs
========================================================================*)
procedure flange_chorus(p: PProgram);
var
   fp,ep1,ep2: integer;
   step,depth,delay,min_sweep,max_sweep: integer;
   inval,outval,ifac: Double;
   scan: Longint;
   data:  Tbw;
   sweep: Twl;

begin
   ifac := 65536.0;
   scan := 0;
   // fetch params
   step := p^.rate * 65.536;
   depth := p^.depth * SampleRate div 1000;
   delay := p^.delay * SampleRate div 1000;

   // init/calc some stuff
   max_sweep := BFSZ - 2 - delay;
   min_sweep := max_sweep - depth;
   if (min_sweep < 0) then
   begin
        printf("Can't do that much delay or depth at this sample rate.\n");
        exit(1);
   end;
   sweep.w[1] := (min_sweep + max_sweep) div 2;
   sweep.w[0] := 0;

   // init store and read ptrs to known value
   fp := 0;
   ep1 := 0;
   ep2 := 0;

    while (True) do
    begin
        data.b[0] := inp(PDR);               /* read input from chip */
        data.b[1] := inp(PDR);

        // interpolate from the 2 read values
        outval := (Buf[ep1]*sweep.w[0]+
                   Buf[ep2]*(ifac-sweep.w[0]))/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
            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]);

        // update ptrs
        fp := (fp + 1) and (BFSZ - 1);
        sweep.l := sweep.l + step;
        ep1 := (fp + sweep.w[1]) and (BFSZ - 1);
        ep2 := (ep1 - 1) and (BFSZ - 1);

        // check for sweep reversal
        if (sweep.w[1] > max_sweep) or   // see if we hit top of sweep
           (sweep.w[1] < min_sweep) then // or if we hit bottom of sweep */
            step := -step;               // reverse

    end;
end;

(*=======================================================================
                                pitch_change

    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        amount of pitch change (see table below for values)
    depth       sweep range in millisecs for generating pitch shift
    delay       fixed additional delay

    Semitones      Up              Down
        1       0.059463        -0.056126
        2       0.122462        -0.109101
        3       0.189207        -0.159104
        4       0.259921        -0.206299
        5       0.334840        -0.250846
        6       0.414214        -0.292893
        7       0.498307        -0.332580
        8       0.587401        -0.370039
        9       0.681793        -0.405396
        10      0.781797        -0.438769
        11      0.887749        -0.470268
        12      1.000000        -0.500000

⌨️ 快捷键说明

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