def rrcos_resample(signal, fold, fnew, Ts=None, beta=None, taps=4001, renormalise=False, fftconv=True): """ Resample a signal using a root raised cosine filter. This performs pulse shaping and resampling a the same time. The resampling is done by scipy.signal.resample_poly. This function can be quite slow. Parameters ---------- signal : array_like input time domain signal fold : float sampling frequency of the input signal fnew : float desired sampling frequency Ts : float, optional time width of the RRCOS filter (default:None makes this 1/fold) beta : float, optional filter roll off factor between (0,1] (default:None will use the default filter in poly_resample) taps : int, optional taps of the interpolation filter if taps is None we filter by zeroinsertion upsampling and multipling with the full length rrcos frequency response in the spectral domain fftconv : bool, optional filter using zero insertion upsampling/decimation and filtering using fftconvolve. I often faster for long filters and power of two signal lengths. Returns ------- sig_out : array_like resampled output signal """ if beta is None: return resample_poly(signal, fold, fnew) assert 0 < beta <= 1, "beta needs to be in interval (0,1]" if Ts is None: Ts = 1/fold up, down = _resamplingfactors(fold, fnew) fup = up*fold # for very large tap lengths it is better to filter with fftconvolve # it could be better to use default values here, but this seems to depend on pc if fftconv or taps is None: sig_new = np.zeros((up*signal.size,), dtype=signal.dtype) sig_new[::up] = signal sig_new = rrcos_pulseshaping(sig_new, fup, Ts, beta, taps) sig_new = sig_new[::down] else: t = np.linspace(0, taps, taps, endpoint=False) t -= t[(t.size-1)//2] t /= fup nqf = rrcos_time(t, beta, Ts) nqf /= nqf.max() sig_new = scisig.resample_poly(signal, up, down, window=nqf) if renormalise: p = np.mean(abs(signal)**2) sig_new = normalise_and_center(sig_new)*np.sqrt(p) return sig_new
def rrcos_pulseshaping(sig, fs, T, beta, taps=1001): """ Root-raised cosine filter applied in the time domain using fftconvolve. Parameters ---------- sig : array_like input time distribution of the signal fs : float sampling frequency of the signal T : float width of the filter (typically this is the symbol period) beta : float filter roll-off factor needs to be in range [0, 1] taps : int, optional number of filter taps (if None do a spectral domain filter) Returns ------- sign_out : array_like filtered signal in time domain """ if taps is None: return _rrcos_pulseshaping_freq(sig, fs, T, beta) t = np.linspace(0, taps, taps, endpoint=False) t -= t[(t.size - 1) // 2] t /= fs nqt = rrcos_time(t, beta, T) nqt /= nqt.max() if sig.ndim > 1: sig_out = np.zeros_like(sig) for i in range(sig.shape[0]): sig_out[i] = scisig.fftconvolve(sig[i], nqt, 'same') else: sig_out = scisig.fftconvolve(sig, nqt, 'same') return sig_out