Example #1
0
def nsgtf_sl(f_slices, g, wins, nn, M=None, real=False, reducedform=0, measurefft=False, multithreading=False):
    M = chkM(M,g)
    dtype = g[0].dtype
    
    fft = fftp(measure=measurefft, dtype=dtype)
    ifft = ifftp(measure=measurefft, dtype=dtype)
    
    if real:
        assert 0 <= reducedform <= 2
        sl = slice(reducedform,len(g)//2+1-reducedform)
    else:
        sl = slice(0,None)
    
    maxLg = max(int(ceil(float(len(gii))/mii))*mii for mii,gii in izip(M[sl],g[sl]))
    temp0 = None
    
    if multithreading and MP is not None:
        mmap = MP.Pool().map
    else:
        mmap = map

    loopparams = []
    for mii,gii,win_range in izip(M[sl],g[sl],wins[sl]):
        Lg = len(gii)
        col = int(ceil(float(Lg)/mii))
        assert col*mii >= Lg
        gi1 = gii[:(Lg+1)//2]
        gi2 = gii[-(Lg//2):]
        p = (mii,gii,gi1,gi2,win_range,Lg,col)
        loopparams.append(p)

    # main loop over slices
    for f in f_slices:
        Ls = len(f)
        
        # some preparation    
        ft = fft(f)

        if temp0 is None:
            # pre-allocate buffer (delayed because of dtype)
            temp0 = np.empty(maxLg, dtype=ft.dtype)
        
        # A small amount of zero-padding might be needed (e.g. for scale frames)
        if nn > Ls:
            ft = np.concatenate((ft, np.zeros(nn-Ls, dtype=ft.dtype)))
        
        # The actual transform
        c = nsgtf_loop(loopparams, ft, temp0)
            
        # TODO: if matrixform, perform "2D" FFT along one axis
        # this could also be nicely parallelized
        y = mmap(ifft,c)
        
        yield y
Example #2
0
def nsigtf_sl(cseq, gd, wins, nn, Ls=None, real=False, reducedform=0, measurefft=False, multithreading=False):
    cseq = iter(cseq)
    dtype = gd[0].dtype

    fft = fftp(measure=measurefft, dtype=dtype)
    ifft = irfftp(measure=measurefft, dtype=dtype) if real else ifftp(measure=measurefft, dtype=dtype)
    
    if real:
        ln = len(gd)//2+1-reducedform*2
        fftsymm = lambda c: np.hstack((c[0],c[-1:0:-1])).conj()
        if reducedform:
            # no coefficients for f=0 and f=fs/2
            symm = lambda fc: chain(fc, imap(fftsymm,fc[::-1]))
            sl = lambda x: chain(x[reducedform:len(gd)//2+1-reducedform],x[len(gd)//2+reducedform:len(gd)+1-reducedform])
        else:
            symm = lambda fc: chain(fc,imap(fftsymm,fc[-2:0:-1]))
            sl = lambda x: x
    else:
        ln = len(gd)
        symm = lambda fc: fc
        sl = lambda x: x
        
    maxLg = max(len(gdii) for gdii in sl(gd))

    # get first slice
    c0 = cseq.next()

    fr = np.empty(nn, dtype=c0[0].dtype)  # Allocate output
    temp0 = np.empty(maxLg, dtype=fr.dtype)  # pre-allocation
    
    if multithreading and MP is not None:
        mmap = MP.Pool().map
    else:
        mmap = map

    loopparams = []
    for gdii,win_range in izip(sl(gd), sl(wins)):
        Lg = len(gdii)
        temp = temp0[:Lg]
        wr1 = win_range[:(Lg)//2]
        wr2 = win_range[-((Lg+1)//2):]
#        wr1,wr2 = win_range
        sl1 = slice(None, (Lg+1)//2)
        sl2 = slice(-(Lg//2), None)
        p = (gdii,wr1,wr2,sl1,sl2,temp)
        loopparams.append(p)
        
    # main loop over slices
    for c in chain((c0,),cseq):
        assert len(c) == ln

        # do transforms on coefficients
        # TODO: for matrixform we could do a FFT on the whole matrix along one axis
        # this could also be nicely parallalized
        fc = mmap(fft, c)
        fc = symm(fc)
        
        # The overlap-add procedure including multiplication with the synthesis windows
        fr = nsigtf_loop(loopparams, fr, fc)

        ftr = fr[:nn//2+1] if real else fr

        sig = ifft(ftr, outn=nn)

        sig = sig[:Ls] # Truncate the signal to original length (if given)

        yield sig