def resampling(self, ch, fs): self.myprint("original samplerate = ", fs) if fs == self.fs: self.myprint("resampling not required") else: self.myprint("resampling to ", self.fs) resample_fs_id = str(self.fs) original_fs_id = str(fs) has_valid_filter_specs = resample_fs_id in self.filter_specs and\ original_fs_id in self.filter_specs[resample_fs_id] if has_valid_filter_specs: try: self.loaded_channels[ch] = signal.upfirdn( self.filter_specs[resample_fs_id][original_fs_id]["numerator"], self.loaded_channels[ch], self.filter_specs[resample_fs_id][original_fs_id]["up"], self.filter_specs[resample_fs_id][original_fs_id]["down"], ) if self.fs == 100: if fs == 256 or fs == 512: # Matlab creates a filtercascade which requires the 128 Hz filter be applied afterwards self.loaded_channels[ch] = signal.upfirdn( self.filter_specs[resample_fs_id]["128"]["numerator"], self.loaded_channels[ch], self.filter_specs[resample_fs_id]["128"]["up"], self.filter_specs[resample_fs_id]["128"]["down"], ) except: self.myprint('Warning: Exception caught during resampling. Using automated resampling filter ' 'coefficients.') self.loaded_channels[ch] = signal.resample_poly(self.loaded_channels[ch], self.fs, fs, axis=0, window=('kaiser', 5.0)) else: self.loaded_channels[ch] = signal.resample_poly(self.loaded_channels[ch], self.fs, fs, axis=0, window=('kaiser', 5.0))
def modulate(self, bitsToModulate): bitsToModulate = [1 if x > 0 else -1 for x in bitsToModulate] N = int(len(bitsToModulate) / 2) signalI = signal.upfirdn([1], bitsToModulate[0::2], self.symbolLength) signalQ = signal.upfirdn([1], bitsToModulate[1::2], self.symbolLength) filteredI = np.convolve(signalI, self.psfFilter) signalI = filteredI[int(self.symbolLength * 5): - int(self.symbolLength * 5) + 1] filteredQ = np.convolve(signalQ, self.psfFilter) signalQ = filteredQ[int(self.symbolLength * 5): - int(self.symbolLength * 5) + 1] t = np.arange(0, N * self.symbolLength * self.sampleTime, self.sampleTime) return np.multiply(signalI, np.cos(2 * np.pi * self.carrierFreq * t + self.fi)) - 1j * np.multiply(signalQ, np.sin(2 * np.pi * self.carrierFreq * t + self.fi))
def modulate(self, coded_bits: np.ndarray) -> np.ndarray: """ Take a series of bits (the baseband digital signal) and modulate it into an analog bandpass signal at the carrier frequency using IQ modulation. Coded bits -> QPSK Map -> Upsample Comb -> RRC Filter -> IQ Modulation -> Waveform (sampled analog signal) :param coded_bits: digital baseband signal as series of bits (probably encoded) :return: sampled analog signal of the modulated waveform """ # map bits to QPSK symbols qam_symbols = self._modem.modulate(coded_bits) # upsample the qam symbols to a comb signal and apply pulse shaping rrc filter from scipy.signal import upfirdn baseband_signal = upfirdn(self._rrc_fir, qam_symbols, self._upsmple_factor) baseband_signal_t = np.arange(len(baseband_signal)) / self._f_sample # compute the in-phase and quadrature components of the signal i_quad = baseband_signal.real * np.cos( self._w_carrier * baseband_signal_t) q_quad = baseband_signal.imag * np.sin( self._w_carrier * baseband_signal_t) * (-1) # sum the quadrature signals to get a real-valued signal for transmission signal = i_quad + q_quad logging.info('Modulated {}-bit coded signal with {} samples'.format( len(coded_bits), len(signal))) return signal
def test_length_factors(self, len_h, len_x, up, down, expected): # gh-9844: weird factors h = np.zeros(len_h) h[0] = 1. x = np.ones(len_x) y = upfirdn(h, x, up, down) assert_allclose(y, expected)
def upconvert(x, sps, fc, fs=2.0, g=None): """Upconvert a complex baseband signal with pulse shaping. This function supports upconversion by an integer factor. For a more general passband conversion (but without pulse shaping), see :func:`arlpy.signal.bb2pb`. If the carrier frequency is 0, the upsampled (at passband sampling rate) and pulse shaped complex baseband data is returned. If the pulse shape is None, a rectangular pulse shape is assumed. The upconversion process introduces a group delay depending on the pulse shaping filter. It is usually (len(g)-1)/2 passband samples. When g is None, the group delay is (sps-1)/2 passband samples. :param x: complex baseband data :param sps: number of passband samples per baseband symbol :param fc: carrier frequency in Hz :param fs: passband sampling rate :param g: pulse shaping filter >>> import arlpy >>> rrc = arlpy.comms.rrcosfir(0.25, 6) >>> bb = arlpy.comms.modulate(arlpy.comms.random_data(100), arlpy.comms.psk()) >>> pb = arlpy.comms.upconvert(bb, 6, 27000, 108000, rrc) """ x = _np.asarray(x, dtype=_np.complex) if g is None: y = _np.repeat(x, sps) / _np.sqrt(sps) else: y = _sp.upfirdn(g, x, up=sps) if fc != 0: y *= _sqrt(2) * _np.exp(2j * _pi * fc * _time(y, fs)) y = y.real return y
def get_samples(self, n: int) -> np.ndarray: h = np.empty(n) # Fill out the first values with the fading value from last call to # `get_samples` number_from_last = min(self.prev_left, n) if number_from_last != 0: h[:number_from_last] = np.repeat(self.prev_alpha, number_from_last) n -= number_from_last self.prev_left -= number_from_last if n <= 0: return h # Pull out enough values from Rayleigh to satisfy n samples alpha = rayleigh(int(np.ceil(n / self.samples_per_realization))) # Upsample alpha so that each value is repeated samples_per_realization # times upsampled = signal.upfirdn(h=np.ones(self.samples_per_realization), x=alpha, up=self.samples_per_realization) # Copy the needed samples into h h[number_from_last:] = upsampled[:n] # Check that some values from up sampled should be added to the next # `get_sampled` call nr_leftover = len(upsampled) - n if nr_leftover > 0: self.prev_left = nr_leftover self.prev_alpha = alpha[-1] return h
def generate_symbols(n_symbols,oversamp=2,mod='qpsk', same_pkt = 0): #sps=2 # need to regenerate filter to change it sps=oversamp h=sps_filter[int(sps)] skp=int(np.floor(h.size)/2) n_symbols=int((n_symbols)) #/sps # rcosdesign(0.2,10,2) order=mod_dict[mod]['order'] const=mod_dict[mod]['constellation'] if same_pkt == 0: symbs=np.random.randint(0,order,n_symbols) elif same_pkt == 1: st = np.random.get_state() np.random.seed(5) # Omitted for speed #itr = (np.random.randint(0,order) for x in range(n_symbols)) #symbs = np.fromiter(itr,dtype='int', count = n_symbols) symbs=np.random.randint(0,order,n_symbols) np.random.set_state(st) #print(symbs) s=const[symbs] mod=upfirdn(h, s,sps).astype('complex64') return mod[skp:-skp].astype('complex64')
def modulateData(self, data): """ Modulates the given data for a given frequency center and sampling frequency. Parameeters ------------- data : str data represented as a string Returns -------- 1-D ndarray of floats """ # Get Pulse Shaping Filter g = self.pulseShapingFilter(self.D, self.alpha, self.P) _pilots = self.pilot_sequence # alias # symbol mapping symbols = self.symbolMap(data, False) # create packet by concatenating pilots with data packet = list(_pilots) packet.extend(symbols) # upsample packet and convolve packetup with pulse shaping filter g m = sig.upfirdn(g, packet, self.P) return m
def modulate(self, bit_sequence: np.ndarray) -> np.ndarray: """ GFSK modulate a bit sequence Returns signal complex QI signal """ # Prevent underflow in case of a bit_sequence of unsigned int (2*0-1 = # underflow). bit_sequence_signed = bit_sequence.astype(int) # upsample the bit_sequence, and make et NRZ (i.e. {0,1}-> {-1,1}) c_t = upfirdn(h=[1] * self.L, x=2 * bit_sequence_signed - 1, up=self.L) h_t = self.gaussianLPF() # convolve the gaussian filter with the NRZ sequence b_t = np.convolve(h_t, c_t, 'full') # normalize the b_t sequence to be between -1 and 1 bnorm_t = b_t / np.abs(b_t).max() # Integrate over the output of the gaussian filter to get phase information # using lfilter makes a low pass filter, corresponding to integrating phi_t = lfilter(b=[1], a=[1, -1], x=bnorm_t * self.Ts) * self.h * np.pi / self.Tb # calculate inphase and quadrature for baseband signal I = np.cos(phi_t) Q = np.sin(phi_t) # make complex baseband signal s_bb = I - 1j * Q return s_bb
def upsample(x, n, axis=0, trim=False): x = np.atleast_1d(x) x = signal.upfirdn([1], x, n, axis=axis) pads = np.zeros((x.ndim, 2), dtype=int) pads[axis, 1] = n - 1 y = x if trim else np.pad(x, pads) return y
def get_annot_activation(times, freqs, mtrack_duration): n_time_frames = int(np.ceil(mtrack_duration * float(44100))) time_grid = librosa.core.frames_to_time(range(n_time_frames), sr=44100, hop_length=1) time_bins = grid_to_bins(time_grid, 0.0, time_grid[-1]) annot_time_idx = np.digitize(times, time_bins) - 1 good_indices = annot_time_idx < len(time_grid) annot_time_idx = annot_time_idx[good_indices] # print(time_grid.shape) # print(good_indices.shape) # print(annot_time_idx.shape) freq_complete = np.zeros(time_grid.shape) freq_complete[annot_time_idx] = freqs[good_indices] annot_activation = np.array(freq_complete > 0, dtype=float) annot_activation = upfirdn(np.ones((256, )), annot_activation) # blur the edges temp = np.zeros(annot_activation.shape) temp += annot_activation for i in [1, 4, 8, 16, 32, 64, 128]: temp[256 * i:] += annot_activation[:-(256 * i)] temp[:-(256 * i)] += annot_activation[256 * i:] annot_activation = np.array(temp > 0, dtype=float) annot_activation = np.convolve(annot_activation, np.ones((2048, )) / 2048.0, mode='same') return annot_activation
def convolve_input(self, tx_value, rx_value, filename): fs, data = wavfile.read(filename) self.h = upfirdn([1], self.h, 10) other = resample(self.h, fs) length = len(data) plt.figure() plt.plot(data) plt.title(f"Input speech, fs={fs}") plt.ylabel('Amplitude') plt.xlabel('Time index') print(data.dtype) output = np.convolve(other, data) plt.figure() plt.plot(output[0:length]) plt.title( f"Tx:{tx_value}, Rx:{rx_value}, Convolved, max_order = {self.max_order}, fs = {fs}" ) plt.ylabel('Amplitude') plt.xlabel('Time index') folder_str = "output_speeches/" tx_str = str(tx_value).replace(".", "_") rx_str = str(rx_value).replace(".", "_") out_filename = folder_str + tx_str + rx_str + "_output.wav" wavfile.write(out_filename, fs, output.astype('int16')) return output
def test_singleton(self, len_h, len_x): # gh-9844: lengths producing expected outputs h = np.zeros(len_h) h[len_h // 2] = 1. # make h a delta x = np.ones(len_x) y = upfirdn(h, x, 1, 1) want = np.pad(x, (len_h // 2, (len_h - 1) // 2), 'constant') assert_allclose(y, want)
def cell2sparse(Xcq, octaves, bins, firstcenter, atomHOP, atomNr): ''' %Generates a sparse matrix containing the CQT coefficients (rasterized). % %The sparse matrix representation of the CQT coefficients contains all %computed coefficients at the corresponding time-frequency location %(similar to a spectrogram). For lower frequencies this means, that %each coefficient is followed by zeros stemming from the fact, that the time %resolution for lower frequencies decreases as the frequency resolution %increases. Due to the design of the CQT kernel, however, the coefficients %of different octaves are synchronised, meaning that for the second highest %octave each coefficient is followed by one zero, for the next octave down %two zeros are inserted, for the next octave four zeros are inserted and so %on. % %INPUT: % Xcq ... Dict array consisting of all coefficients for all octaves % octaves ... Number of octaves processed % bins ... Number of bins per octave % firstcenter ... Location of the leftmost atom-stack in the temporal % kernel % atomHOP ... Spacing of two consecutive atom stacks % atomNr ... Number of atoms per bin within the kernel % %%He Wang, 2020/12/01 [email protected] ''' # this version uses less memory but is noticable slower emptyHops = firstcenter/atomHOP drops = emptyHops*np.power(2, octaves - np.arange(1, octaves + 1)) - emptyHops Len = int(np.max((np.asarray([atomNr*c.shape[1] for _,c in Xcq.items()]) - drops) * np.power(2, np.arange(octaves)))) # number of columns of output matrix spCQT = np.empty((0,Len)).astype(np.complex) for i in range(1, octaves+1)[::-1]: drop = int(emptyHops*2**(octaves-i)-emptyHops) # first coefficients of all octaves have to be in synchrony X = Xcq[i] if atomNr > 1: # more than one atom per bin --> reshape Xoct = np.zeros((bins, atomNr*X.shape[1] - drop)).astype(np.complex) for u in range(bins): # reshape to continous windows for each bin (for the case of several wins per frame) octX_bin = X[u*atomNr:(u+1)*atomNr,:] Xcont = octX_bin.T.reshape(-1) Xoct[u,:] = Xcont[drop:] X = Xoct else: X = X[:,drop:] X = np.pad(upfirdn([1], X.T, 2**(i-1), axis=0), [[0,2**(i-1)-1],[0,0]], mode='constant').T # upfirdn: upsampling with zeros insertion X = np.append(X, np.zeros((bins, Len-X.shape[1])), axis=1) spCQT = np.append(spCQT, X, axis=0) return spCQT
def writeInterpolateTests(config, startNb, format): #interpolate=[2,4,8] #blocks=[1,2,4,8,16] #numTaps =[1,2,4,8,16] interpolate = [1, 2, 4, 5, 8, 9] blocks = [ Tools.loopnb(format, Tools.TAILONLY), Tools.loopnb(format, Tools.BODYONLY), Tools.loopnb(format, Tools.BODYANDTAIL), ] numTapsFactor = [4, 8] ref = [] allConfigs = cartesian(interpolate, blocks, numTapsFactor) allsamples = [] allcoefs = [] alloutput = [] for (q, blockSize, numTapsF) in allConfigs: # numTaps must be a multiple of q numTaps = numTapsF * q b = np.array(list(range(1, numTaps + 1))) / (3.0 * (numTaps + 2)) nbsamples = blockSize samples = np.random.randn(nbsamples) samples = Tools.normalize(samples) #output=scipy.signal.decimate(samples,q,ftype=scipy.signal.dlti(b,1.0),zero_phase=False) output = upfirdn(b, samples, up=q, down=1, axis=-1, mode='constant', cval=0) output = output[0:blockSize * q] #print(debug-output) allsamples += list(samples) alloutput += list(output) allcoefs += list(reversed(b)) ref += [q, len(b), len(samples), len(output)] config.writeInput(startNb, allsamples) config.writeInput(startNb, allcoefs, "Coefs") config.writeReference(startNb, alloutput) config.writeInputU32(startNb, ref, "Configs") startNb = startNb + 1 return (startNb)
def prop(self, signal: Signal): from scipy.signal import upfirdn signal.data_sample = upfirdn(self.h, signal.symbol, signal.sps, 1) signal.data_sample = roll(signal.data_sample, int(-self.span / 2 * self.sps), axis=-1) tempx = signal.data_sample[0, 0:signal.sps * signal.data_len] tempy = signal.data_sample[1, 0:signal.sps * signal.data_len] signal.data_sample = np.array([tempx, tempy])
def test_modes(self, size, h_len, mode, dtype): random_state = np.random.RandomState(5) x = random_state.randn(size).astype(dtype) if dtype in (np.complex64, np.complex128): x += 1j * random_state.randn(size) h = np.arange(1, 1 + h_len, dtype=x.real.dtype) y = upfirdn(h, x, up=1, down=1, mode=mode) # expected result: pad the input, filter with zero padding, then crop npad = h_len - 1 if mode in ['antisymmetric', 'antireflect', 'smooth', 'line']: # use _pad_test test function for modes not supported by np.pad. xpad = _pad_test(x, npre=npad, npost=npad, mode=mode) else: xpad = np.pad(x, npad, mode=mode) ypad = upfirdn(h, xpad, up=1, down=1, mode='constant') y_expected = ypad[npad:-npad] assert_allclose(y, y_expected, atol=1e-6, rtol=1e-6)
def test_upfirdn2d(self, rand_2d_data_gen, num_samps, up, down, use_numba): cpu_sig, gpu_sig = rand_2d_data_gen(num_samps) h = [1, 1, 1] cpu_resample = signal.upfirdn(h, cpu_sig, up, down) gpu_resample = cp.asnumpy( cusignal.upfirdn(h, gpu_sig, up, down, use_numba=use_numba)) assert array_equal(cpu_resample, gpu_resample)
def ex2_6_interpolate(signal=None, ts=None, up_factor=2, down_factor=11, sampling_frequency=sf, ftype='fir', show=False): if signal is None and ts is None: ts, signal = ex2_1_generate_sinusoid() sampling_frequency = sf if signal is not None and ts is None: ts = np.linspace(0, len(signal) / sf, len(signal), endpoint=False) # just do the beginning (bc of time complexity) ts, signal = ts[:5000], signal[:5000] if ftype == 'fir': nyq_rate = sampling_frequency / 2 width = 400.0 / nyq_rate # with a 400 Hz transition width ripple_db = 60.0 # attenuation in the stop band (dB) filter_order, beta = kaiserord( ripple_db, width) # order and Kaiser parameter for the FIR filter cutoff = 0.5 / up_factor filter_taps = firwin(filter_order, cutoff * nyq_rate, window=('kaiser', beta), fs=sampling_frequency) print("Filter order", filter_order) resampled_signal = upfirdn(filter_taps, signal, up=up_factor, down=down_factor) if ftype == 'cheby2': pass # TODO: with Chebychev II filter sampling_frequency *= up_factor / down_factor resampled_ts = np.linspace(0, len(resampled_signal) / sampling_frequency, len(resampled_signal), endpoint=False) plt.plot_signal_processed(ts, signal, resampled_ts, resampled_signal, 'Interpolated', 'Interpolated with factor ' + str(up_factor) + '/' + str(down_factor), show=show, xlim=xlim) return resampled_ts, resampled_signal
def interp(arr, factor): #linear interpolation by factor #For the correct FIR coefficents of a Linear Interpolation method, harr is going to hold such coefficents harr=[]#we create an arry as to be the input of FIR at the upfirdn function, used from scipy harr.extend(np.linspace(1,factor-1,factor-1)) #we use extend as to iterate over the array generated and keep it in a single dimension harr.append(factor)#for signal dimension 'extension' we simply use append function harr.extend((np.linspace(factor-1,1,factor-1))) #inside the extend brackets one could also use: np.flip(np.linspace(1,factor-1,factor-1)) harr=np.divide(harr,factor) return signal.upfirdn(harr, arr, factor)[:-factor]
def upsample(self, x, upsampling_rate): self.sampling_frequency *= upsampling_rate self.nyquist_frequency *= upsampling_rate filterlen = 101 b = firwin(101, 1.0 / upsampling_rate) y = upfirdn(b, x, up=upsampling_rate) y = [i * upsampling_rate for i in y] y = y[filterlen / 2:len(y) - filterlen / 2] return y
def shape_symbols(h, p_data_p_symbols): """ Use the pulse h to shape the p_data_p_symbols given, and up-sample by USF before :param h: The pulse to use to do the pulse shaping :param p_data_p_symbols: The preamble-data-preamble symbols to shape :return: The preamble-data-preamble sample resulting from the pulse shaping """ if params.logs: print("Pulse shaping the symbols...") if params.MOD == 1 or params.MOD == 2: p_data_p_samples = upfirdn(h, p_data_p_symbols, params.USF) if params.logs: print("Samples: {}\n{}".format(np.shape(p_data_p_samples), p_data_p_samples)) print("Up-sampling factor: {}".format(params.USF)) if params.plots: plot_helper.samples_fft_plots(p_data_p_samples, "Samples after the pulse shaping", shift=True) elif params.MOD == 3: p_data_p_samples = [] for i in range(len(p_data_p_symbols)): p_data_p_samples.append(upfirdn(h, p_data_p_symbols[i], params.USF)) if params.plots: for i in range(len(p_data_p_samples)): plot_helper.samples_fft_plots( p_data_p_samples[i], "Samples {} after the pulse shaping".format(i), shift=True) else: raise ValueError("This mapping type does not exist yet... He he he") if params.logs: print("--------------------------------------------------------") return p_data_p_samples
def pf_run(self, sig_array, pf_bank, rate=1): """ Runs the input array through the polyphase filter bank. """ fil_out = [] offset = self.paths / self.rate for j in range(rate): for i, input_vec in enumerate(sig_array): # remember in channelizer samples are fed to last path first -- it is a decimating filter. index = i + j * offset fil_out.append( signal.upfirdn(pf_bank[index, :], sig_array[i, :])) return np.asarray(fil_out)
def scrub(self, x, axis=-1): yr = np.apply_along_axis(upfirdn_naive, axis, x, self.h, self.up, self.down) y = upfirdn(self.h, x, self.up, self.down, axis=axis) dtypes = (self.h.dtype, x.dtype) if all(d == np.complex64 for d in dtypes): assert_equal(y.dtype, np.complex64) elif np.complex64 in dtypes and np.float32 in dtypes: assert_equal(y.dtype, np.complex64) elif all(d == np.float32 for d in dtypes): assert_equal(y.dtype, np.float32) elif np.complex128 in dtypes or np.complex64 in dtypes: assert_equal(y.dtype, np.complex128) else: assert_equal(y.dtype, np.float64) assert_allclose(yr, y)
def test_vs_lfilter(self): # Check that up=1.0 gives same answer as lfilter + slicing random_state = np.random.RandomState(17) try_types = (int, np.float32, np.complex64, float, complex) size = 10000 down_factors = [2, 11, 79] for dtype in try_types: x = random_state.randn(size).astype(dtype) if dtype in (np.complex64, np.complex128): x += 1j * random_state.randn(size) for down in down_factors: h = firwin(31, 1. / down, window='hamming') yl = lfilter(h, 1.0, x)[::down] y = upfirdn(h, x, up=1, down=down) assert_allclose(yl, y[:yl.size], atol=1e-7, rtol=1e-7)
def test_vs_convolve(self, down, want_len): # Check that up=1.0 gives same answer as convolve + slicing random_state = np.random.RandomState(17) try_types = (int, np.float32, np.complex64, float, complex) size = 10000 for dtype in try_types: x = random_state.randn(size).astype(dtype) if dtype in (np.complex64, np.complex128): x += 1j * random_state.randn(size) h = firwin(31, 1. / down, window='hamming') yl = upfirdn_naive(x, h, 1, down) y = upfirdn(h, x, up=1, down=down) assert y.shape == (want_len, ) assert yl.shape[0] == y.shape[0] assert_allclose(yl, y, atol=1e-7, rtol=1e-7)
def downconvert(x, sps, fc, fs=2.0, g=None): """Downconvert a passband signal with a matched pulse shaping filter. This function supports downconversion by an integer factor. For a more general baseband conversion (but without matched filtering), see :func:`arlpy.signal.pb2bb`. If the carrier frequency is 0, the input is assumed to be complex baseband, and only undergoes matched filtering and downsampling. If the pulse shape is None, a rectangular pulse shape is assumed. The downconversion process introduces a group delay depending on the matched filter. It is usually (len(g)-1)/2 passband samples. :param x: real passband data (or complex baseband data at passband sampling rate, if fc=0) :param sps: number of passband samples per baseband symbol :param fc: carrier frequency in Hz :param fs: passband sampling rate :param g: pulse shaping filter (for matched filtering) >>> import arlpy >>> d1 = arlpy.comms.random_data(100, 4) >>> qpsk = arlpy.comms.psk(4) >>> bb1 = arlpy.comms.modulate(d1, qpsk) >>> rrc = arlpy.comms.rrcosfir(0.25, 6) >>> pb = arlpy.comms.upconvert(bb1, 6, 27000, 108000, rrc) >>> bb2 = arlpy.comms.downconvert(pb, 6, 27000, 108000, rrc) >>> delay = (len(rrc)-1)/2 # compute passband group delay of rrc FIR filter >>> delay = 2*delay/6 # compute baseband group delay after filtering twice >>> d2 = arlpy.comms.demodulate(bb2[delay:-delay], qpsk) >>> arlpy.comms.ser(d1, d2) 0.0 """ if fc == 0: y = _np.asarray(x, dtype=_np.complex) else: y = _sp.hilbert(x) / 2 y *= _sqrt(2) * _np.exp(-2j * _pi * fc * _time(y, fs)) if g is None: y = _np.sum(_np.reshape(y, (sps, -1), order='F'), axis=0) / _np.sqrt(sps) else: y = _sp.upfirdn(g, y, down=sps) return y
def dtmfcut(xx, fs): """DTMFCUT find the DTMF tones within x[n] usage: indx = dtmfmain(xx,fs) length of nstart = M = number of tones found nstart is the set of STARTING indices nstop is the set of ENDING indices xx = input signal vector fs = sampling frequency Looks for silence regions which must at least 10 millisecs long. Also the tones must be longer than 100 msec """ xx = np.asarray(xx) xx = (xx / max(np.abs(xx))) # normalize xx Lx = len(xx) if (0.01 * fs) == 0.5: Lz = 1 else: Lz = round(0.01*fs) setpoint = 0.02 # make everything below 2% zero xx = upfirdn(np.ones(Lz)/ Lz, np.abs(xx)) xx = np.diff(((xx > setpoint) * 1)) jkl = np.asarray(np.where(xx != 0)) if xx[jkl.take(0)] < 0: jkl = np.insert(jkl, 0, 1) if x[jkl.take(-1)] > 0: jkl = np.append(jkl, Lx-1) indx = np.array([-1, -1]).reshape(2,1) while len(jkl) > 1: if jkl[1] > (jkl[0] + 10 * Lz): indx = np.append(indx, np.vstack((jkl[[0, 1]])), axis=1) jkl = np.delete(jkl, [0, 1]) nstart = indx[0,1:] nstop = indx[1,1:] return nstart, nstop
def scrub(self, x, axis=-1): yr = np.apply_along_axis(upfirdn_naive, axis, x, self.h, self.up, self.down) want_len = _output_len(len(self.h), x.shape[axis], self.up, self.down) assert yr.shape[axis] == want_len y = upfirdn(self.h, x, self.up, self.down, axis=axis) assert y.shape[axis] == want_len assert y.shape == yr.shape dtypes = (self.h.dtype, x.dtype) if all(d == np.complex64 for d in dtypes): assert_equal(y.dtype, np.complex64) elif np.complex64 in dtypes and np.float32 in dtypes: assert_equal(y.dtype, np.complex64) elif all(d == np.float32 for d in dtypes): assert_equal(y.dtype, np.float32) elif np.complex128 in dtypes or np.complex64 in dtypes: assert_equal(y.dtype, np.complex128) else: assert_equal(y.dtype, np.float64) assert_allclose(yr, y)
def resample_matlab_like(x_orig,p,q): if len(x_orig.shape)>2: raise ValueError('x must be a vector or 2d matrix') if x_orig.shape[0]<x_orig.shape[1]: x=x_orig.T else: x= x_orig beta = 5 N = 10 frac=Fraction(p, q) p = frac.numerator q = frac.denominator pqmax = max(p,q) fc = 1/2/pqmax L = 2*N*pqmax + 1 h = firls( L, np.array([0,2*fc,2*fc,1]), np.array([1,1,0,0]))*kaiser(L,beta) h = p*h/sum(h) Lhalf = (L-1)/2 Lx = x.shape[0] nz = int(np.floor(q-np.mod(Lhalf,q))) z = np.zeros((nz,)) h = np.concatenate((z,h)) Lhalf = Lhalf + nz delay = int(np.floor(np.ceil(Lhalf)/q)) nz1 = 0 while np.ceil( ((Lx-1)*p+len(h)+nz1 )/q ) - delay < np.ceil(Lx*p/q): nz1 = nz1+1 h = np.concatenate((h,np.zeros(nz1,))) y = upfirdn(h,x,p,q,axis=0) Ly = int(np.ceil(Lx*p/q)) y = y[delay:] y = y[:Ly] if x_orig.shape[0]<x_orig.shape[1]: y=y.T return y
def time_upfirdn2d(self, up, down, axis): for h, x in self.pairs: signal.upfirdn(h, x, up=up, down=down, axis=axis)
def time_upfirdn1d(self, up, down): for h, x in self.pairs: signal.upfirdn(h, x, up=up, down=down)