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

📄 effects processor.c

📁 语音信号进行Fir滤波
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -