digitalcom

Digital Communications Function Module

Copyright (c) March 2017, Mark Wickert All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.

  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project.

sk_dsp_comm.digitalcom.awgn_channel(x_bits, eb_n0_dB)[source]
Parameters
x_bitsserial bit stream of 0/1 values.
eb_n0_dBEnergy per bit to noise power density ratio in dB of the serial bit stream sent through the AWGN channel. Frequently we equate EBN0 to SNR in link budget calculations.
Returns
y_bitsReceived serial bit stream following hard decisions. This bit will have bit errors. To check the estimated bit error probability use BPSK_BEP() or simply:
>>> Pe_est = sum(xor(x_bits,y_bits))/length(x_bits);
    ..
Mark Wickert, March 2015
sk_dsp_comm.digitalcom.bin2gray(d_word, b_width)[source]

Convert integer bit words to gray encoded binary words via Gray coding starting from the MSB to the LSB

Mark Wickert November 2018

sk_dsp_comm.digitalcom.bit_errors(tx_data, rx_data, n_corr=1024, n_transient=0)[source]

Count bit errors between a transmitted and received BPSK signal. Time delay between streams is detected as well as ambiquity resolution due to carrier phase lock offsets of \(k*\pi\), k=0,1.

sk_dsp_comm.digitalcom.bpsk_bep(tx_data, rx_data, n_corr=1024, n_transient=0)[source]

Count bit errors between a transmitted and received BPSK signal. Time delay between streams is detected as well as ambiquity resolution due to carrier phase lock offsets of \(k*\pi\), k=0,1. The ndarray tx_data is Tx +/-1 symbols as real numbers I. The ndarray rx_data is Rx +/-1 symbols as real numbers I. Note: Ncorr needs to be even

sk_dsp_comm.digitalcom.bpsk_tx(n_bits, ns, ach_fc=2.0, ach_lvl_dB=- 100, pulse='rect', alpha=0.25, m=6)[source]

Generates biphase shift keyed (BPSK) transmitter with adjacent channel interference.

Generates three BPSK signals with rectangular or square root raised cosine (SRC) pulse shaping of duration N_bits and Ns samples per bit. The desired signal is centered on f = 0, which the adjacent channel signals to the left and right are also generated at dB level relative to the desired signal. Used in the digital communications Case Study supplement.

Parameters
n_bitsthe number of bits to simulate
nsthe number of samples per bit
ach_fcthe frequency offset of the adjacent channel signals (default 2.0)
ach_lvl_dBthe level of the adjacent channel signals in dB (default -100)
pulsethe pulse shape ‘rect’ or ‘src’
alphasquare root raised cosine pulse shape factor (default = 0.25)
msquare root raised cosine pulse truncation factor (default = 6)
Returns
xndarray of the composite signal x0 + ach_lvl*(x1p + x1m)
bthe transmit pulse shape
data0the data bits used to form the desired signal; used for error checking

Examples

>>> x,b,data0 = bpsk_tx(1000,10,pulse='src')
sk_dsp_comm.digitalcom.chan_est_equalize(z, npbp, alpha, ht=None)[source]

This is a helper function for OFDM_rx() to unpack pilot blocks from from the entire set of received OFDM symbols (the Nf of N filled carriers only); then estimate the channel array H recursively, and finally apply H_hat to Y, i.e., X_hat = Y/H_hat carrier-by-carrier. Note if Np = -1, then H_hat = H, the true channel.

Parameters
zInput N_OFDM x Nf 2D array containing pilot blocks and OFDM data symbols.
npbpThe pilot block period; if -1 use the known channel impulse response input to ht.
alphaThe forgetting factor used to recursively estimate H_hat
htThe theoretical channel frquency response to allow ideal equalization provided Ncp is adequate.
Returns
zz_outThe input z with the pilot blocks removed and one-tap equalization applied to each of the Nf carriers.
HThe channel estimate in the frequency domain; an array of length Nf; will return Ht if provided as an input.

Examples

>>> from sk_dsp_comm.digitalcom import chan_est_equalize
>>> zz_out,H = chan_est_eq(z,Nf,npbp,alpha,Ht=None)
sk_dsp_comm.digitalcom.eye_plot(x, l, s=0)[source]

Eye pattern plot of a baseband digital communications waveform.

The signal must be real, but can be multivalued in terms of the underlying modulation scheme. Used for BPSK eye plots in the Case Study article.

Parameters
xndarray of the real input data vector/array
ldisplay length in samples (usually two symbols)
sstart index
Returns
NoneA plot window opens containing the eye plot

Notes

Increase S to eliminate filter transients.

Examples

1000 bits at 10 samples per bit with ‘rc’ shaping.

>>> import matplotlib.pyplot as plt
>>> from sk_dsp_comm import digitalcom as dc
>>> x,b, data = dc.nrz_bits(1000,10,'rc')
>>> dc.eye_plot(x,20,60)
>>> plt.show()

(Source code)

_images/digitalcom-1.png
sk_dsp_comm.digitalcom.farrow_resample(x, fs_old, fs_new)[source]
Parameters
xInput list representing a signal vector needing resampling.
fs_oldStarting/old sampling frequency.
fs_newNew sampling frequency.
Returns
yList representing the signal vector resampled at the new frequency.

Notes

A cubic interpolator using a Farrow structure is used resample the input data at a new sampling rate that may be an irrational multiple of the input sampling rate.

Time alignment can be found for a integer value M, found with the following:

\[f_{s,out} = f_{s,in} (M - 1) / M\]

The filter coefficients used here and a more comprehensive listing can be found in H. Meyr, M. Moeneclaey, & S. Fechtel, “Digital Communication Receivers,” Wiley, 1998, Chapter 9, pp. 521-523.

Another good paper on variable interpolators is: L. Erup, F. Gardner, & R. Harris, “Interpolation in Digital Modems–Part II: Implementation and Performance,” IEEE Comm. Trans., June 1993, pp. 998-1008.

A founding paper on the subject of interpolators is: C. W. Farrow, “A Continuously variable Digital Delay Element,” Proceedings of the IEEE Intern. Symp. on Circuits Syst., pp. 2641-2645, June 1988.

Mark Wickert April 2003, recoded to Python November 2013

Examples

The following example uses a QPSK signal with rc pulse shaping, and time alignment at M = 15.

>>> import matplotlib.pyplot as plt
>>> from numpy import arange
>>> from sk_dsp_comm import digitalcom as dc
>>> Ns = 8
>>> Rs = 1.
>>> fsin = Ns*Rs
>>> Tsin = 1 / fsin
>>> N = 200
>>> ts = 1
>>> x, b, data = dc.mpsk_bb(N+12, Ns, 4, 'rc')
>>> x = x[12*Ns:]
>>> xxI = x.real
>>> M = 15
>>> fsout = fsin * (M-1) / M
>>> Tsout = 1. / fsout
>>> xI = dc.farrow_resample(xxI, fsin, fsin)
>>> tx = arange(0, len(xI)) / fsin
>>> yI = dc.farrow_resample(xxI, fsin, fsout)
>>> ty = arange(0, len(yI)) / fsout
>>> plt.plot(tx - Tsin, xI)
>>> plt.plot(tx[ts::Ns] - Tsin, xI[ts::Ns], 'r.')
>>> plt.plot(ty[ts::Ns] - Tsout, yI[ts::Ns], 'g.')
>>> plt.title(r'Impact of Asynchronous Sampling')
>>> plt.ylabel(r'Real Signal Amplitude')
>>> plt.xlabel(r'Symbol Rate Normalized Time')
>>> plt.xlim([0, 20])
>>> plt.grid()
>>> plt.show()

(Source code)

_images/digitalcom-2.png
sk_dsp_comm.digitalcom.from_bin(bin_array)[source]

Convert binary array back a nonnegative integer. The array length is the bit width. The first input index holds the MSB and the last holds the LSB.

sk_dsp_comm.digitalcom.gmsk_bb(n_bits, ns, msk=0, bt=0.35)[source]

MSK/GMSK Complex Baseband Modulation x,data = gmsk(N_bits, Ns, BT = 0.35, MSK = 0)

Parameters
n_bitsnumber of symbols processed
nsthe number of samples per bit
msk0 for no shaping which is standard MSK, MSK <> 0 –> GMSK is generated.
btpremodulation Bb*T product which sets the bandwidth of the Gaussian lowpass filter
Mark Wickert Python version November 2014
sk_dsp_comm.digitalcom.gray2bin(d_word, b_width)[source]

Convert gray encoded binary words to integer bit words via Gray decoding starting from the MSB to the LSB

Mark Wickert November 2018

sk_dsp_comm.digitalcom.mpsk_bb(n_symb, ns, mod, pulse='rect', alpha=0.25, m=6)[source]

Generate a complex baseband MPSK signal with pulse shaping.

Parameters
n_symbnumber of MPSK symbols to produce
nsthe number of samples per bit,
modMPSK modulation order, e.g., 4, 8, 16, …
pulse‘rect’ , ‘rc’, ‘src’ (default ‘rect’)
alphaexcess bandwidth factor(default 0.25)
msingle sided pulse duration (default = 6)
Returns
xndarray of the MPSK signal values
bndarray of the pulse shape
datandarray of the underlying data bits

Notes

Pulse shapes include ‘rect’ (rectangular), ‘rc’ (raised cosine), ‘src’ (root raised cosine). The actual pulse length is 2*M+1 samples. This function is used by BPSK_tx in the Case Study article.

Examples

>>> from sk_dsp_comm import digitalcom as dc
>>> import scipy.signal as signal
>>> import matplotlib.pyplot as plt
>>> x,b,data = dc.mpsk_bb(500,10,8,'src',0.35)
>>> # Matched filter received signal x
>>> y = signal.lfilter(b,1,x)
>>> plt.plot(y.real[12*10:],y.imag[12*10:])
>>> plt.xlabel('In-Phase')
>>> plt.ylabel('Quadrature')
>>> plt.axis('equal')
>>> # Sample once per symbol
>>> plt.plot(y.real[12*10::10],y.imag[12*10::10],'r.')
>>> plt.show()

(Source code)

_images/digitalcom-3.png
sk_dsp_comm.digitalcom.mpsk_bep_thy(snr_dB, mod, eb_n0_mode=True)[source]

Approximate the bit error probability of MPSK assuming Gray encoding

Mark Wickert November 2018

sk_dsp_comm.digitalcom.mpsk_gray_decode(x_hat, mod=4)[source]

Decode MPSK IQ symbols to a serial bit stream using gray2bin decoding

Parameters
x_hatsymbol spaced samples of the MPSK waveform taken at the maximum

eye opening. Normally this is following the matched filter

modModulation scheme
Mark Wickert November 2018
sk_dsp_comm.digitalcom.mpsk_gray_encode_bb(n_symb, ns, mod=4, pulse='rect', alpha=0.35, m_span=6, ext_data=None)[source]

MPSK_gray_bb: A gray code mapped MPSK complex baseband transmitter x,b,tx_data = MPSK_gray_bb(K,Ns,M)

Parameters
n_symbthe number of symbols to process
nsnumber of samples per symbol
modmodulation order: 2, 4, 8, 16 MPSK
alphasquareroot raised cosine excess bandwidth factor. Can range over 0 < alpha < 1.
pulse‘rect’, ‘src’, or ‘rc’
Returns
xcomplex baseband digital modulation
btransmitter shaping filter, rectangle or SRC
tx_dataxI+1j*xQ = inphase symbol sequence + 1j*quadrature symbol sequence
Mark Wickert November 2018
sk_dsp_comm.digitalcom.mux_pilot_blocks(iq_data, npb)[source]
Parameters
iq_dataa 2D array of input QAM symbols with the columns

representing the NF carrier frequencies and each row the QAM symbols used to form an OFDM symbol

npbthe period of the pilot blocks; e.g., a pilot block is

inserted every Np OFDM symbols (Np-1 OFDM data symbols of width Nf are inserted in between the pilot blocks.

Returns
IQ_datapIQ_data with pilot blocks inserted

See also

OFDM_tx

Notes

A helper function called by OFDM_tx() that inserts pilot block for use in channel estimation when a delay spread channel is present.

sk_dsp_comm.digitalcom.my_psd(x, NFFT=1024, Fs=1)[source]

A local version of NumPy’s PSD function that returns the plot arrays.

A mlab.psd wrapper function that returns two ndarrays; makes no attempt to auto plot anything.

Parameters
xndarray input signal
NFFTa power of two, e.g., 2**10 = 1024
Fsthe sampling rate in Hz
Returns
Pxndarray of the power spectrum estimate
fndarray of frequency values

Notes

This function makes it easier to overlay spectrum plots because you have better control over the axis scaling than when using psd() in the autoscale mode.

Examples

>>> import matplotlib.pyplot as plt
>>> from sk_dsp_comm import digitalcom as dc
>>> from numpy import log10
>>> x,b, data = dc.nrz_bits(10000,10)
>>> Px,f = dc.my_psd(x,2**10,10)
>>> plt.plot(f, 10*log10(Px))
>>> plt.show()

(Source code)

_images/digitalcom-4.png
sk_dsp_comm.digitalcom.ofdm_rx(x, nf, nc, npb=0, cp=False, ncp=0, alpha=0.95, ht=None)[source]
Parameters
xReceived complex baseband OFDM signal
nfNumber of filled carriers, must be even and Nf < N
ncTotal number of carriers; generally a power 2, e.g., 64, 1024, etc
npbPeriod of pilot code blocks; 0 <=> no pilots; -1 <=> use the ht impulse response input to equalize the OFDM symbols; note equalization still requires Ncp > 0 to work on a delay spread channel.
cpFalse/True <=> if False assume no CP is present
ncpThe length of the cyclic prefix
alphaThe filter forgetting factor in the channel estimator. Typically alpha is 0.9 to 0.99.
htInput the known theoretical channel impulse response
Returns
z_outRecovered complex baseband QAM symbols as a serial stream; as appropriate channel estimation has been applied.
Hchannel estimate (in the frequency domain at each subcarrier)

See also

OFDM_tx

Examples

>>> import matplotlib.pyplot as plt
>>> from sk_dsp_comm import digitalcom as dc
>>> from scipy import signal
>>> from numpy import array
>>> hc = array([1.0, 0.1, -0.05, 0.15, 0.2, 0.05]) # impulse response spanning five symbols
>>> # Quick example using the above channel with no cyclic prefix
>>> x1,b1,IQ_data1 = dc.QAM_bb(50000,1,'16qam')
>>> x_out = dc.ofdm_tx(IQ_data1,32,64,0,True,0)
>>> x1,b1,IQ_data1 = dc.qam_bb(50000,1,'16qam')
>>> x_out = dc.ofdm_tx(IQ_data1,32,64,0,True,0)
>>> c_out = signal.lfilter(hc,1,x_out) # Apply channel distortion
>>> r_out = dc.cpx_awgn(c_out,100,64/32) # Es/N0 = 100 dB
>>> z_out,H = dc.ofdm_rx(r_out,32,64,-1,True,0,alpha=0.95,ht=hc)
>>> plt.plot(z_out[200:].real,z_out[200:].imag,'.')
>>> plt.xlabel('In-Phase')
>>> plt.ylabel('Quadrature')
>>> plt.axis('equal')
>>> plt.grid()
>>> plt.show()

Another example with noise using a 10 symbol cyclic prefix and channel estimation:

>>> x_out = dc.ofdm_tx(IQ_data1,32,64,100,True,10)
>>> c_out = signal.lfilter(hc,1,x_out) # Apply channel distortion
>>> r_out = dc.cpx_awgn(c_out,25,64/32) # Es/N0 = 25 dB
>>> z_out,H = dc.ofdm_rx(r_out,32,64,100,True,10,alpha=0.95,ht=hc);
>>> plt.figure() # if channel estimation is turned on need this
>>> plt.plot(z_out[-2000:].real,z_out[-2000:].imag,'.') # allow settling time
>>> plt.xlabel('In-Phase')
>>> plt.ylabel('Quadrature')
>>> plt.axis('equal')
>>> plt.grid()
>>> plt.show()

(Source code)

sk_dsp_comm.digitalcom.ofdm_tx(iq_data, nf, nc, npb=0, cp=False, ncp=0)[source]
Parameters
iq_data+/-1, +/-3, etc complex QAM symbol sample inputs
nfnumber of filled carriers, must be even and Nf < N
nctotal number of carriers; generally a power 2, e.g., 64, 1024, etc
npbPeriod of pilot code blocks; 0 <=> no pilots
cpFalse/True <=> bypass cp insertion entirely if False
ncpthe length of the cyclic prefix
Returns
x_outcomplex baseband OFDM waveform output after P/S and CP insertion

See also

OFDM_rx

Examples

>>> import matplotlib.pyplot as plt
>>> from sk_dsp_comm import digitalcom as dc
>>> x1,b1,IQ_data1 = dc.QAM_bb(50000,1,'16qam')
>>> x_out = dc.ofdm_tx(IQ_data1,32,64)
>>> x1,b1,IQ_data1 = dc.qam_bb(50000,1,'16qam')
>>> x_out = dc.ofdm_tx(IQ_data1,32,64)
>>> plt.psd(x_out,2**10,1);
>>> plt.xlabel(r'Normalized Frequency ($\omega/(2\pi)=f/f_s$)')
>>> plt.ylim([-40,0])
>>> plt.xlim([-.5,.5])
>>> plt.show()

(Source code)

sk_dsp_comm.digitalcom.pcm_decode(x_bits, n_bits)[source]
Parameters
x_bitsserial bit stream of 0/1 values. The length of

x_bits must be a multiple of N_bits

n_bitsbit precision of PCM samples
Returns
xhatdecoded PCM signal samples
Mark Wickert, March 2015
sk_dsp_comm.digitalcom.pcm_encode(x, n_bits)[source]
Parameters
xsignal samples to be PCM encoded
n_bitsbit precision of PCM samples
Returns
x_bitsencoded serial bit stream of 0/1 values. MSB first.
Mark Wickert, Mark 2015
sk_dsp_comm.digitalcom.q_fctn(x)[source]

Gaussian Q-function

sk_dsp_comm.digitalcom.qam_bb(n_symb, ns, mod='16qam', pulse='rect', alpha=0.35)[source]

A complex baseband transmitter

Parameters
n_symbthe number of symbols to process
nsnumber of samples per symbol
modmodulation type: qpsk, 16qam, 64qam, or 256qam
alphasquareroot raised codine pulse shape bandwidth factor.

For DOCSIS alpha = 0.12 to 0.18. In general alpha can range over 0 < alpha < 1.

pulse: pulse shapes: src, rc, rect
Returns
xcomplex baseband digital modulation
btransmitter shaping filter, rectangle or SRC
tx_dataxI+1j*xQ = inphase symbol sequence +

1j*quadrature symbol sequence

Mark Wickert November 2014
sk_dsp_comm.digitalcom.qam_bep_thy(snr_dB, mod, eb_n0_mode=True)[source]

Approximate the bit error probability of QAM assuming Gray encoding

Mark Wickert November 2018

sk_dsp_comm.digitalcom.qam_gray_decode(x_hat, mod=4)[source]

Decode MQAM IQ symbols to a serial bit stream using gray2bin decoding

x_hat = symbol spaced samples of the QAM waveform taken at the maximum

eye opening. Normally this is following the matched filter

Mark Wickert April 2018

sk_dsp_comm.digitalcom.qam_gray_encode_bb(n_symb, ns, mod=4, pulse='rect', alpha=0.35, m_span=6, ext_data=None)[source]

QAM_gray_bb: A gray code mapped QAM complex baseband transmitter x,b,tx_data = QAM_gray_bb(K,Ns,M)

Parameters
n_symbThe number of symbols to process
nsNumber of samples per symbol
modModulation order: 2, 4, 16, 64, 256 QAM. Note 2 <=> BPSK, 4 <=> QPSK
alphaSquare root raised cosine excess bandwidth factor.

For DOCSIS alpha = 0.12 to 0.18. In general alpha can range over 0 < alpha < 1.

pulse‘rect’, ‘src’, or ‘rc’
Returns
xComplex baseband digital modulation
bTransmitter shaping filter, rectangle or SRC
tx_dataxI+1j*xQ = inphase symbol sequence + 1j*quadrature symbol sequence

See also

QAM_gray_decode
sk_dsp_comm.digitalcom.qam_sep(tx_data, rx_data, mod_type, Ncorr=1024, Ntransient=0)[source]

Count symbol errors between a transmitted and received QAM signal. The received symbols are assumed to be soft values on a unit square. Time delay between streams is detected. The ndarray tx_data is Tx complex symbols. The ndarray rx_data is Rx complex symbols. Note: Ncorr needs to be even

sk_dsp_comm.digitalcom.qpsk_bb(n_symb, ns, lfsr_len=5, pulse='src', alpha=0.25, m=6)[source]
sk_dsp_comm.digitalcom.qpsk_bep(tx_data, rx_data, n_corr=1024, n_transient=0)[source]

Count bit errors between a transmitted and received QPSK signal. Time delay between streams is detected as well as ambiquity resolution due to carrier phase lock offsets of \(k*\frac{\pi}{4}\), k=0,1,2,3. The ndarray sdata is Tx +/-1 symbols as complex numbers I + j*Q. The ndarray data is Rx +/-1 symbols as complex numbers I + j*Q. Note: Ncorr needs to be even

sk_dsp_comm.digitalcom.qpsk_rx(fc, n_symb, rs, es_n0=100, fs=125, lfsr_len=10, phase=0, pulse='src')[source]

This function generates

sk_dsp_comm.digitalcom.qpsk_tx(fc, n_symb, rs, fs=125, lfsr_len=10, pulse='src')[source]
sk_dsp_comm.digitalcom.rc_imp(ns, alpha, m=6)[source]

A truncated raised cosine pulse used in digital communications.

The pulse shaping factor \(0 < \alpha < 1\) is required as well as the truncation factor M which sets the pulse duration to be \(2*M*T_{symbol}\).

Parameters
nsnumber of samples per symbol
alphaexcess bandwidth factor on (0, 1), e.g., 0.35
mequals RC one-sided symbol truncation factor
Returns
bndarray containing the pulse shape

See also

sqrt_rc_imp

Notes

The pulse shape b is typically used as the FIR filter coefficients when forming a pulse shaped digital communications waveform.

Examples

Ten samples per symbol and \(\alpha = 0.35\).

>>> import matplotlib.pyplot as plt
>>> from sk_dsp_comm.digitalcom import rc_imp
>>> from numpy import arange
>>> b = rc_imp(10,0.35)
>>> n = arange(-10*6,10*6+1)
>>> plt.stem(n,b)
>>> plt.show()

(Source code)

_images/digitalcom-7.png
sk_dsp_comm.digitalcom.rz_bits(n_bits, ns, pulse='rect', alpha=0.25, m=6)[source]

Generate return-to-zero (RZ) data bits with pulse shaping.

A baseband digital data signal using +/-1 amplitude signal values and including pulse shaping.

Parameters
n_bitsnumber of RZ {0,1} data bits to produce
nsthe number of samples per bit,
pulse‘rect’ , ‘rc’, ‘src’ (default ‘rect’)
alphaexcess bandwidth factor(default 0.25)
msingle sided pulse duration (default = 6)
Returns
xndarray of the RZ signal values
bndarray of the pulse shape
datandarray of the underlying data bits

Notes

Pulse shapes include ‘rect’ (rectangular), ‘rc’ (raised cosine), ‘src’ (root raised cosine). The actual pulse length is 2*M+1 samples. This function is used by BPSK_tx in the Case Study article.

Examples

>>> import matplotlib.pyplot as plt
>>> from numpy import arange
>>> from sk_dsp_comm.digitalcom import rz_bits
>>> x,b,data = rz_bits(100,10)
>>> t = arange(len(x))
>>> plt.plot(t,x)
>>> plt.ylim([-0.01, 1.01])
>>> plt.show()

(Source code)

_images/digitalcom-8.png
sk_dsp_comm.digitalcom.scatter(x, ns, start)[source]

Sample a baseband digital communications waveform at the symbol spacing.

Parameters
xndarray of the input digital comm signal
nsnumber of samples per symbol (bit)
startthe array index to start the sampling
Returns
xIndarray of the real part of x following sampling
xQndarray of the imaginary part of x following sampling

Notes

Normally the signal is complex, so the scatter plot contains clusters at point in the complex plane. For a binary signal such as BPSK, the point centers are nominally +/-1 on the real axis. Start is used to eliminate transients from the FIR pulse shaping filters from appearing in the scatter plot.

Examples

>>> import matplotlib.pyplot as plt
>>> from sk_dsp_comm import digitalcom as dc
>>> x,b, data = dc.nrz_bits(1000,10,'rc')

Add some noise so points are now scattered about +/-1.

>>> y = dc.cpx_awgn(x,20,10)
>>> yI,yQ = dc.scatter(y,10,60)
>>> plt.plot(yI,yQ,'.')
>>> plt.grid()
>>> plt.xlabel('In-Phase')
>>> plt.ylabel('Quadrature')
>>> plt.axis('equal')
>>> plt.show()

(Source code)

_images/digitalcom-9.png
sk_dsp_comm.digitalcom.sqrt_rc_imp(ns, alpha, m=6)[source]

A truncated square root raised cosine pulse used in digital communications.

The pulse shaping factor \(0 < \alpha < 1\) is required as well as the truncation factor M which sets the pulse duration to be \(2*M*T_{symbol}\).

Parameters
nsnumber of samples per symbol
alphaexcess bandwidth factor on (0, 1), e.g., 0.35
mequals RC one-sided symbol truncation factor
Returns
bndarray containing the pulse shape

Notes

The pulse shape b is typically used as the FIR filter coefficients when forming a pulse shaped digital communications waveform. When square root raised cosine (SRC) pulse is used to generate Tx signals and at the receiver used as a matched filter (receiver FIR filter), the received signal is now raised cosine shaped, thus having zero intersymbol interference and the optimum removal of additive white noise if present at the receiver input.

Examples

Ten samples per symbol and \(\alpha = 0.35\).

>>> import matplotlib.pyplot as plt
>>> from numpy import arange
>>> from sk_dsp_comm.digitalcom import sqrt_rc_imp
>>> b = sqrt_rc_imp(10,0.35)
>>> n = arange(-10*6,10*6+1)
>>> plt.stem(n,b)
>>> plt.show()

(Source code)

_images/digitalcom-10.png
sk_dsp_comm.digitalcom.strips(x, nx, fig_size=(6, 4))[source]

Plots the contents of real ndarray x as a vertical stacking of strips, each of length Nx. The default figure size is (6,4) inches. The yaxis tick labels are the starting index of each strip. The red dashed lines correspond to zero amplitude in each strip.

strips(x,Nx,my_figsize=(6,4))

Mark Wickert April 2014

sk_dsp_comm.digitalcom.time_delay(x, d, n=4)[source]

A time varying time delay which takes advantage of the Farrow structure for cubic interpolation:

y = time_delay(x,D,N = 3)

Note that D is an array of the same length as the input signal x. This allows you to make the delay a function of time. If you want a constant delay just use D*zeros(len(x)). The minimum delay allowable is one sample or D = 1.0. This is due to the causal system nature of the Farrow structure.

A founding paper on the subject of interpolators is: C. W. Farrow, “A Continuously variable Digital Delay Element,” Proceedings of the IEEE Intern. Symp. on Circuits Syst., pp. 2641-2645, June 1988.

Mark Wickert, February 2014

sk_dsp_comm.digitalcom.to_bin(data, width)[source]

Convert an unsigned integer to a numpy binary array with the first element the MSB and the last element the LSB.

sk_dsp_comm.digitalcom.xcorr(x1, x2, n_lags)[source]

r12, k = xcorr(x1,x2,Nlags), r12 and k are ndarray’s Compute the energy normalized cross correlation between the sequences x1 and x2. If x1 = x2 the cross correlation is the autocorrelation. The number of lags sets how many lags to return centered about zero