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
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