Perché ricevo questo rumore crepitante sull'azzeramento delle alte frequenze?


8

Di recente ho iniziato a giocare con la trasformata di Fourier (dopo aver trascorso alcune settimane a conoscere la matematica dietro di essa). Ho deciso di provare a hackerare insieme un filtro passa-basso sul seguente morso audio:

In particolare, ho preso la trasformata di Fourier, azzerato la metà più alta delle frequenze e poi ho preso la trasformata inversa di Fourier. Questo è quello che ho ottenuto

Perché c'è quel rumore scoppiettante?


Inoltre, dovrei menzionare che non ho idea del perché sto applicando un filtro passa-basso a una clip audio. È puramente sperimentale. Questa operazione ha senso anche per una clip audio?
JeremyKun,

dovresti rendere questi campioni scaricabili
endolith il

Risposte:


11

Due potenziali problemi:

  1. Il filtraggio nel dominio della frequenza (utilizzando un FFT) richiede sovrapposizione, aggiunta, sovrapposizione o un algoritmo correlato. Ciò è causato dalla differenza tra la convoluzione lineare e circolare. Altrimenti si ottiene l'alias nel dominio del tempo
  2. Alcuni rumori sembrano semplici ritagli. Il filtro può effettivamente aumentare l'ampiezza del dominio del tempo per alcuni campioni e, se supera l'intervallo disponibile, può essere tagliato o spostato.

1
Mi è sembrato un ritaglio / avvolgimento.
Heltonbiker,

Cosa posso fare per interrompere il ritaglio / avvolgimento? Non avrei dovuto fare questa operazione in primo luogo?
JeremyKun,

Sta decisamente tagliando. Ho ridotto l'ampiezza del segnale in ingresso e i suoni scoppiettanti sono spariti.
JeremyKun,

7

Prima di tutto una nota, le trasformazioni di Fourier non sono ideali per i filtri passa basso / passa alto. I filtri Butterworth sono un buon punto di partenza e seguono i filtri Chebyshev / Ellittici se diventi più ambizioso.

Sembra che tu stia cercando di implementare un filtro ideale. Non è possibile implementare questi filtri "muro di mattoni" in cui escludiamo tutte le frequenze sopra / sotto un determinato valore. Tutti i filtri ben sviluppati si assottigliano da 1 a 0 attorno alla nostra frequenza di taglio.

I filtri ideali sono solo teorici e se avessi una Trasformata di Fourier continua il tuo metodo sopra funzionerebbe.

Ma stiamo facendo trasformazioni discrete di Fourier, quindi c'è altro di cui preoccuparsi. Dal momento che non sono sicuro del metodo di implementazione, immagino che tu stia facendo windowing dal momento che tirare fuori le frequenze è un modo sicuro per scoppiettare in un DFT con finestre.

Quando si esegue il windowing in un DFT, si potrebbe pensare che le ampiezze di frequenza tra le finestre siano relativamente continue. ad es. se la frequenza di 400Hz ha un'ampiezza di 0,5 nella finestra corrente che nella finestra successiva l'ampiezza sarà vicina a 0,5. Questo purtroppo non è vero, quindi se dovessimo semplicemente rimuovere la frequenza di 400Hz dal nostro DFT, potremmo sentire forti rumori o crepe tra le finestre.

Un piccolo esempio: la frequenza di taglio è di 600Hz. Window 1 sta riproducendo un seno di 800Hz. Window 2 si collega "continuamente" con la finestra 1 e riproduce 400Hz. Quindi sentiremo un pop tra la finestra perché la finestra 1 sarà silenziosa e la finestra 2 si accenderà immediatamente.

Un'altra cosa da tenere a mente è che possiamo rappresentare solo una quantità finita di frequenze con un DFT. Se abbiamo un file audio con un'onda sinusoidale di una frequenza tra due delle nostre frequenze discrete nel nostro DFT, allora lo rappresentiamo effettivamente con molte delle nostre frequenze discrete. Quindi, anche se un file audio di esempio può contenere un'onda sinusoidale inferiore al nostro cutoff, se la sua frequenza è tra le nostre frequenze DFT di quanto potremmo tagliarne una parte e distorcerla con il metodo sopra, poiché sono necessarie frequenze più alte per rappresentare l'audio file.

spero che aiuti


Ah, ritiro il mio commento sulla finestra (è più un problema DFT in tempo reale). La risposta di Hilmar sembra più accurata.
Matt Tytel,

4

È davvero possibile fare come suggerisci, ma non senza alcuni effetti collaterali. Supponiamo che formiamo un semplice segnale di provaS(t)=Slow(t)+Shiogh(t) dove:

Slow(t)=cos(2πf0t)+cos(2πf1t+π3)

Shiogh(t)=12cos(2πf2t+0.2)

dove diciamo che entrambi f0,f1 sono al di sotto di una frequenza di taglio passa basso scelta fcut tale che f0<f1<fcute scegliamo f2>fcut. Naturalmente possiamo scegliere le ampiezze che desideriamo e ho appena scelto quelle sopra per mantenere le cose semplici. Avendo due contributi di frequenza al di sotto della frequenza di taglio e uno sopra, è facile seguire e confrontare i segnali.

Nel seguito presumo che abbiamo N campioni prelevati con la frequenza fS>2f2. In realtà scegliamofS»2f2per rendere uniforme il segnale osservato. Si presume inoltre che prendiamo in considerazione solo un gruppo di campioni di dati. Se è necessario gestire diversi intervalli di tempo, consultare il documento di Fred Harris intitolato "Sull'uso di Windows per l'analisi armonica con la trasformata discreta di Fourier" di Proc. IEEE nel 1978.

Ho combinato un piccolo programma Python per illustrare alcuni dei concetti: il codice è piuttosto orribile, ma ho appena preso del vecchio codice che avevo per problemi simili. Sebbene non ci siano quasi commenti, dovrebbe essere abbastanza facile da seguire a causa dei piccoli moduli. Ci sono due DFT / IDFT funzioni; due funzioni fshiftn / fshiftp per spostare la frequenza del segnale nel dominio DFT per il filtraggio; una funzione dftlpass per eseguire il filtraggio nel dominio DFT; una funzione zpblpass per fare il filtraggio usando un filtro Butterworth; una funzione bbdftsig per formare il segnale di prova ed eseguire il filtraggio; ed infine una piccola funzione plotsigsper tracciare i segnali. Alla fine dello script, vengono impostati i diversi parametri e vengono realizzate le diverse figure.

"""
   Test of DFT versus scipy.signal.butter filtering with respect to
   signal reconstruction.

"""

# import ############################################################ import #
import matplotlib as mpl;   mpl.rcParams['backend'] = 'Agg'
import matplotlib.pyplot as mplpp
import matplotlib.mlab as mplml
import numpy as np
import scipy.signal as sps


# initialize #################################################### initialize #
try:
    mpl.rc('text', usetex=False)
    mpl.rc('font', family='serif')
    mpl.rc('font', serif='STIXGeneral')
    mpl.rc('font', size=8)
except AttributeError:
    None


# dft ################################################################## dft #
def dft(xt, fs, t0):
    N, d = len(xt), -2j*np.pi/len(xt)
    w = np.arange(N, dtype=np.float).reshape((N,1))
    c = np.exp(d*t0*fs*w)
    W = np.exp(d*np.dot(w,np.transpose(w)))
    xf = np.multiply(c,np.dot(W,xt)) / float(N)
    f = w*fs/float(N)
    return xf, f


# idft ################################################################ idft #
def idft( X, FS, T0 ):
    N, d = len(X), 2j*np.pi/len(X)
    w = np.arange(N, dtype=float).reshape((N,1))
    cc = np.exp(d*T0*FS*w)
    Wc = np.exp(d*np.dot(w, np.transpose(w)))
    Y = np.dot(Wc, np.multiply(cc, X))
    return Y



# fshiftn ########################################################## fshiftn #
def fshiftn( xf, f ):
    assert type(f) == np.ndarray, "f must be a np.ndarray"
    assert f.shape[1] == 1, "f must be a column array"
    assert xf.shape[1] == 1, "xf must be a column array"
    assert sum(f<0) == 0, "All frequency components must be 0 or positive"

    # Determine sampling rate, tolerance, and allocate output array
    fs, tol = len(f)*(np.abs(f[1,0]-f[0,0])), 1.E-2
    fshift = np.zeros((len(f),1), dtype=float)
    xfshift = np.zeros((len(f),1), dtype=complex)

    # Determine index where f > fs/2
    Nm = np.floor(len(f)/2.0)
    Np = np.floor((len(f)-1.0)/2.0)

    # Compute output frequency array such that -fs/2 <= f < fs/2 and the
    # corresponding Fourier coefficients
    fshift[:Nm,0] = f[Np+1:,0] - fs
    fshift[Nm,0] = f[0,0]
    fshift[Nm+1:,0] = f[1:Np+1,0]

    xfshift[:Nm,0] = xf[Np+1:,0]
    xfshift[Nm,0] = xf[0,0]
    xfshift[Nm+1:,0] = xf[1:Np+1,0]

    return xfshift, fshift


# fshiftp ########################################################## fshiftp #
def fshiftp(xf, f):
    assert type(f) == np.ndarray, "f must be a np.ndarray"
    assert f.shape[1] == 1, "f must be a column array"
    assert xf.shape[1] == 1, "xf must be a column array"
    assert sum(f<0) > 0, "Some input frequencies must be negative"

    # Determine sampling rate, tolerance, and allocate output array
    fs, tol = len(f)*(np.abs(f[1,0]-f[0,0])), 1.E-2
    fshift = np.zeros((len(f),1), dtype=float)
    xfshift = np.zeros((len(f),1), dtype=complex)

    # Determine index where f > fs/2
    #Nx = np.floor((len(f)+1+tol)/2)
    Nm = np.floor(len(f)/2.0)
    Np = np.floor((len(f)-1.0)/2.0)

    # Compute output frequency array such that -fs/2 <= f < fs/2 and the
    # corresponding Fourier coefficients
    fshift[Np+1:,0] = f[:Nm:,0] + fs
    fshift[0,0] = f[Nm,0]
    fshift[1:Np+1:,0] = f[Nm+1:,0]

    xfshift[Np+1:,0] = xf[:Nm:,0]
    xfshift[0,0] = xf[Nm,0]
    xfshift[1:Np+1:,0] = xf[Nm+1:,0]

    return xfshift, fshift


# dftlpass ######################################################## dftlpass #
def dftlpass(xt, fs, fcut):
    # Perform Discrete Fourier Transform
    xf, f = dft(xt, fs, 0.0)

    # Shift frequencies to -fs/2 <= f < fs/2 ... and coefficients
    xfshift, fshift = fshiftn(xf, f)

    # Perform filtration
    xfshift = xfshift * (np.abs(fshift) <= fcut)

    # Re-shift frequencies to 0 <= f < fs ... and coefficients
    xfrecon, frecon = fshiftp(xfshift, fshift)

    # Perform inverse Discrete Fourier Transform
    yt = idft(xfrecon, fs, 0.0)
    return yt.real


# zpblpass ######################################################## zpblpass #
def zpblpass(xn, fcal, fs, fcut):
    bz, az = sps.butter(5, fcut/(fs/2))

    # Gain calibration
    Ncal = np.max([np.int(20*fs/fcal), 30000])
    Nguard = np.int(0.1*Ncal)    
    t = np.arange(Ncal) / fs
    x0_cal = 1.0 * np.cos(2*np.pi*fcal*t)
    yi_cal = sps.filtfilt(bz, az, 2.0*x0_cal*np.cos(2*np.pi*fcal*t))
    k = 1.0/np.mean(yi_cal[Nguard:Ncal-Nguard])

    # Scaled output
    yn = k * sps.filtfilt(bz, az, xn)
    return yn


# bbdftsig ######################################################## bbdftsig #
def bbdftsig(f0, f1, f2, fcut, fs, N):
    t = np.arange(N).reshape((N,1)) / fs
    s0 = np.sin(2*np.pi*f0*t)
    s1 = np.sin(2*np.pi*f1*t + 0.2)
    s2 = 0.7 * np.sin(2*np.pi*f2*t + np.pi/3.0)
    slow = s0 + s1
    s = slow + s2

    sf = dftlpass(s, fs, fcut)
    sfdftv = sf.reshape((N))
    sv = s.reshape((N))
    slowv = slow.reshape((N))

    sv = s.reshape((N))
    sfzpbv = zpblpass(sv, f1, fs, fcut)
    #sfzpbv = sfzpb.reshape((N))
    return sv, slowv, sfdftv, sfzpbv


# plotsigs ######################################################## plotsigs #
def plotsigs(s, slow, sfdft, sfzpb, Nstart, Nstop, fname):
    n = np.arange(s.shape[0])

    # Plot results
    mplpp.figure(1, (5.0,2.25))
    mplpp.clf()
    mplpp.plot(n[Nstart:Nstop], s[Nstart:Nstop], 'm-',
               n[Nstart:Nstop:4], s[Nstart:Nstop:4], 'mx',
               n[Nstart:Nstop], slow[Nstart:Nstop], 'g-',
               n[Nstart:Nstop:10], slow[Nstart:Nstop:10], 'gx',
               n[Nstart:Nstop], sfdft[Nstart:Nstop], 'r-',
               n[Nstart:Nstop:15], sfdft[Nstart:Nstop:15], 'rx',
               n[Nstart:Nstop], sfzpb[Nstart:Nstop], 'b-',
               linewidth=1.5)
    mplpp.legend([r'$s$', r'$s$', r'$s_{\rm low}$', r'$s_{\rm low}$',
                  r'DFT', r'DFT', r'ZPB'], loc='upper right')
    mplpp.ylabel(r'Signal')
    mplpp.xlabel(r'$n$')
    #mplpp.axis([-10.0, 10.0, 1.0E-2, 1.0E2])
    mplpp.grid(True)
    mplpp.savefig(fname, dpi=600,
                bbox_inches='tight', pad_inches=0.05)
    mplpp.close()


# __main__ ######################################################## __main__ #
if __name__ == '__main__':
    # Initialize
    f0 = 3.0
    f1 = 11.5
    f2 = 20.0
    fcut = 15.0
    fs = 1000.0
    N = 5000

    s, slow, sfdft, sfzpb = bbdftsig(f0, f1, f2, fcut, fs, N)
    n = np.arange(s.shape[0])

    # Fig. 1: full data set
    Nstart = 0
    Nstop = N
    fname = 'full.pdf'
    plotsigs(s, slow, sfdft, sfzpb, Nstart, Nstop, fname)

    # Fig. 2: beginning
    Nstart = 0
    Nstop = 150
    fname = 'beginning.pdf'
    plotsigs(s, slow, sfdft, sfzpb, Nstart, Nstop, fname)

    # Fig. 3: middle
    Nstart = np.floor(N/2.0) - 75
    Nstop = Nstart + 100
    fname = 'middle.pdf'
    plotsigs(s, slow, sfdft, sfzpb, Nstart, Nstop, fname)

    # Fig. 4: ending
    Nstart = N - 150
    Nstop = N
    fname = 'ending.pdf'
    plotsigs(s, slow, sfdft, sfzpb, Nstart, Nstop, fname)

scelta N=5000 e fS=1000 ci dà una risoluzione in frequenza di fS/N=0.2Hz. Se scegliamof0,f1,f2in base a ciò possiamo ottenere un perfetto accordo scegliendo le frequenze come mostrato sopra. Se scegliamo prima le frequenze che sono sulla griglia comef0=3, f1=11, f2=21 e noi abbiamo fcut=15otteniamo la prima serie di risultati. Di seguito sono mostrate la prima, la parte centrale e l'ultima dei segnali pertinenti:

Inizio dei segnali - sulla griglia Centro di segnali - sulla griglia Fine dei segnali - sulla griglia

Come si vede dalla figura, abbiamo l'input combinato Scome segnale magenta; il segnale verde come possiamo vedere solo dai segni "x" èSlow(il segnale di input non elaborato quando includiamo semplicemente il segnale di input al di sotto della frequenza di taglio); il segnale rosso è quello che otteniamo usando il filtro DFT; e il segnale blu è quello che otteniamo dal filtro Butterworth. Come visto sopra, otteniamo un perfetto accordo traSlow e il segnale filtrato DFT - ma il filtro Butterworth ha un certo impatto sul segnale in banda (in particolare il componente a f1. Come è abbastanza tipico per questo tipo di elaborazione, abbiamo alcune differenze all'inizio e alla fine della sequenza a causa di effetti di margine e di ragionevole accordo tra entrambi i tipi di filtro nella sezione centrale.

Se cambiamo la frequenza f1 per f1=11.5 che non si trova sulla griglia di frequenza (e inoltre è abbastanza vicino alla frequenza di taglio) vediamo alcuni risultati diversi come mostrato di seguito.

Inizio dei segnali - off-grid Metà dei segnali - fuori griglia Fine dei segnali - off-grid

Ora vediamo differenze sostanziali tra segnali verdi, blu e rossi che nella situazione ideale dovrebbero essere identici. Nel mezzo del segnale sono tutti abbastanza d'accordo: il DFT e il riferimentoSlow d'accordo comunque.

Quindi, in conclusione, è possibile utilizzare il filtraggio diretto forzando a zero i coefficienti di Fourier, cosa che a volte viene eseguita anche nel rilevamento a compressione per ridurre il supporto di un segnale per forzare la scarsità su un segnale. Tuttavia, ci sono conseguenze di ciò come un aumento degli errori, in particolare ai bordi del segnale. Inoltre, quanto sopra è il caso migliore in cui l'intero segnale viene trattato come una sequenza. Se il segnale deve essere suddiviso in intervalli di tempo, diventa complicato in quanto è necessario considerare alcune finestre o altre tecniche per garantire la continuità del segnale tra i frame. Quindi il mio consiglio è simile ad alcuni degli altri post nel raccomandare di usare normalmente un Butterworth / Elliptic / .. o qualunque altro filtro.


0

I bin di azzeramento in una FFT possono effettivamente aumentare l'ampiezza di altre frequenze vicine ma non centrate sul bidone a zero o sui suoi bin adiacenti. Questo aumento può causare il clipping.

Inoltre, se stai eseguendo la FFT usando blocchi un-zero-padded (e non sovrapposti) (al contrario dell'intera canzone in un grande FFT), qualsiasi modifica dei dati FFT si avvolgerà dalla parte posteriore alla parte anteriore del sequenza nel dominio del tempo in ogni blocco, aggiungendo così altre strane discontinuità nei posti sbagliati.


0

Ecco un filtro passa-banda FFT azzeramento rapido e sporco, con anche il codice FFT.

void FFT(int n, int inverse, double *gRe, double *gIm, double *GRe, double *GIm)
{

    int m = 0;
    int p = 1;
    int j = 0;
    int i1=0;
    int k=0;
    double ca=0;
    double sa=0;
    int l1,l2,l3;
    double u1,u2;
    double t1 = 0;
    double t2 = 0;
    int i2=0;
    double z;
    /* Calculate m=log_2(n) */
    while(p < n)
    {
        p *= 2;
        m++;
    }
    /* Bit reversal */
    GRe[n - 1] = gRe[n - 1];
    GIm[n - 1] = gIm[n - 1];
    for(i1 = 0; i1 < n - 1; i1++)
    {
        GRe[i1] = gRe[j];
        GIm[i1] = gIm[j];
        k = n / 2;
        while(k <= j)
        {
            j -= k;
            k /= 2;
        }
        j += k;
    }
    /* Calculate the FFT */
    ca = -1.0;
    sa = 0.0;
    l1 = 1;
    l2 = 1;
    l3=0;
    for(l3 = 0; l3 < m; l3++)
    {
        l1 = l2;
        l2 *= 2;
        u1 = 1.0;
        u2 = 0.0;       
    for(j = 0; j < l1; j++)
        {
            i2=j;
            for(i2 = j; i2 < n; i2 += l2)
            {
                i1 = i2 + l1;
                t1 = u1 * GRe[i1] - u2 * GIm[i1];
                t2 = u1 * GIm[i1] + u2 * GRe[i1];
                GRe[i1] = GRe[i2] - t1;
                GIm[i1] = GIm[i2] - t2;
                GRe[i2] += t1;
                GIm[i2] += t2;
            }
            z =  u1 * ca - u2 * sa;
            u2 = u1 * sa + u2 * ca;
            u1 = z;
        }
        sa = sqrt((1.0 - ca) / 2.0);
        if(!inverse) sa =- sa;
        ca = sqrt((1.0 + ca) / 2.0);

    }
    /* Divide through n if it isn't the IDFT */
    if(!inverse)
    {
        int i3=0;
        for(i3 = 0; i3 < n; i3++)
        {
            GRe[i3] /= n;
            GIm[i3] /= n;
        }
    }
}


void mainfftBandPass(double *insamples, double *outsamples, unsigned long fftsize, long lowfreq, long highfreq, long srate)
{
    static double *inbuf=NULL;
    static double *realn=NULL;
    static double *imags=NULL;
    static double *spectr=NULL;
    static double *zer0=NULL;
    static double *olds=NULL;
    static double *infader=NULL;
    static double *outfader=NULL;
    int notched=(highfreq<lowfreq) ? 1 : 0;
    long incounter=0;
    /* treble is the highest baseband frequency */
    /* bass the the lowest baseband frequency */
    /* this function is called twice per FFT block */
    long midcounter=0;
    long outcounter=0;
    long bass=lowfreq*(fftsize/(double)srate);
    long treble=(highfreq)*(fftsize/(double)srate);
    static long halffft=2;
    static long old_fftsize=0;
    static short first=1;
    if(first==1 || fftsize!=old_fftsize)
    {
        if(inbuf)
             free(inbuf);
        if(realn)
            free(realn);
        if(imags)
            free(imags);
        if(spectr)
            free(spectr);
        if(zer0)
            free(zer0);
        if(olds)
            free(olds);
        if(infader)
            free(infader);
        if(outfader)
            free(outfader);
        infader=(double*)malloc(fftsize*sizeof(double));
        outfader=(double*)malloc(fftsize*sizeof(double));
        inbuf=(double*)malloc(fftsize*sizeof(double));
        realn=(double*)malloc(fftsize*sizeof(double));
        imags=(double*)malloc(fftsize*sizeof(double));
        spectr=(double*)malloc(fftsize*sizeof(double));
        zer0=(double*)malloc(fftsize*sizeof(double));
        olds=(double*)malloc(fftsize*sizeof(double));
        if((!inbuf) || (!realn) ||(!imags) ||(!spectr)||(!zer0)||(!ol   ds))
        {
            printf("Not enough memory for FFT!\n");
                    exit(1);
        }
        halffft=fftsize/2;
        long infade=0;
        long outfade=halffft;
        for(infade=0;infade<halffft;infade++)
        {
            outfade--;
            outfader[infade]=(0.5 * cos((infade) *  M_PI/(double)(halffft))+0.5);
            infader[outfade]=outfader[infade];
        }
        first=0;
    }
    memset(realn,0,sizeof(double)*fftsize);
    for(incounter=0;incounter<halffft;incounter++)
    {
        inbuf[incounter]=inbuf[incounter+halffft];
    }
    for(incounter=0;incounter<halffft;incounter++)
    {
        inbuf[incounter+halffft]=insamples[incounter];
    }
    for(incounter=0;incounter<fftsize;incounter++)
    {
        realn[incounter]=inbuf[incounter];
    }   
    memset(imags,0,sizeof(double)*fftsize);
    FFT(fftsize, 0, realn,imags, spectr,zer0);
    memset(realn,0,sizeof(double)*fftsize);
    memset(imags,0,sizeof(double)*fftsize);
    if(notched==0)
    {
        for(midcounter=bass;midcounter<treble;midcounter++)
        {
            realn[midcounter]=spectr[midcounter] * 2.0;
            imags[midcounter]= zer0[midcounter] * 2.0;
        }
        if(bass==0)
            realn[0]=spectr[0];

    }
    else if(notched==1)
    {
        for(midcounter=0;midcounter<halffft;midcounter++)
        {
            if((midcounter<treble) ||(midcounter>bass))
            {
                realn[midcounter]=spectr[midcounter] * 2.0;
                imags[midcounter]= zer0[midcounter] * 2.0;
            }
        }
        if(bass==0)
        {
            realn[0]=0;
        }
        else
        {
            realn[0]=spectr[0];
        }
    }
    FFT(fftsize, 1, realn, imags,spectr,zer0);
    for(outcounter=0;outcounter<halffft;outcounter++)
    {
        outsamples[outcounter]=(((spectr[outcounter] )*infader[outcounter])+(olds[outcounter+halffft]*outfader[outcounter])) ;
    }
    for(outcounter=0;outcounter<fftsize;outcounter++)
    {
        olds[outcounter]=spectr[outcounter];
    }
    memset(spectr,0,fftsize*sizeof(double));
    memset(zer0,0,fftsize*sizeof(double));
    old_fftsize=fftsize;
}

signed short mainbandpass(signed short input, double lowcut, double highcut,long rate,long fftsize)
{
    double retvalue=0;
    static double *insamp=NULL;
    static double *outsamp=NULL;
    static int first=1;
    static int q=0;
    if(first==1)
    {
            insamp=(double*)malloc(fftsize * sizeof(double));
            outsamp=(double*)malloc(fftsize * sizeof(double));
            if(insamp==NULL || outsamp==NULL)
            {
                   printf("Not enough memory for FFT buffers.\n");
                   exit(1);
            }
        memset(insamp,0,fftsize * sizeof(double));
        memset(outsamp,0,fftsize * sizeof(double));
        first=0;
    }

    insamp[q]=input;
    retvalue=outsamp[q];
    if(retvalue> 32767)
        retvalue=32767;
    if(retvalue <-32768)
        retvalue=-32768;
    q++;
    if(q>(fftsize/2)-1)
    {
        mainfftBandPass(insamp,outsamp, fftsize, lowcut,highcut,rate);
        q=0;
    }
    return (signed short)retvalue;
}

per ogni campione dell'audio in ingresso, chiama mainbandpass con il campione in ingresso e la gamma di frequenze che desideri mantenere in modalità lowcut e highcut. Se lowcut è maggiore di highcut, il risultato sarà un filtro di rifiuto della banda. È in corso una convoluzione circolare, ma non ci saranno emissioni fuori banda che vanno bene per i modem.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.