Пример #1
0
    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))
Пример #3
0
    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
Пример #4
0
 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)
Пример #5
0
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
Пример #6
0
    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
Пример #7
0
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')
Пример #8
0
    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
Пример #9
0
    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
Пример #10
0
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
Пример #11
0
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
Пример #12
0
    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
Пример #13
0
 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)
Пример #14
0
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
Пример #15
0
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])
Пример #17
0
    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)
Пример #18
0
    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)
Пример #19
0
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]
Пример #21
0
    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
Пример #22
0
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
Пример #23
0
    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)
Пример #24
0
 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)
Пример #25
0
 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)
Пример #26
0
    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)
Пример #27
0
    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)
Пример #28
0
    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)
Пример #29
0
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
Пример #30
0
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
Пример #31
0
 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)
Пример #32
0
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
Пример #33
0
 def time_upfirdn2d(self, up, down, axis):
     for h, x in self.pairs:
         signal.upfirdn(h, x, up=up, down=down, axis=axis)
Пример #34
0
 def time_upfirdn1d(self, up, down):
     for h, x in self.pairs:
         signal.upfirdn(h, x, up=up, down=down)