In the previous notebook we experienced that the soundcard does have significant attenuation in the lower frequency region. Hence, baseband transmission with RC filtered signals was not possible due to the strong distortion of the signal. As a result, we could not get a clear eye diagram of the received signal.

In this notebook, we will move the signal from baseband to passband, i.e. upconvert the signal to some carrier frequency. Note, that we still use real-valued signals for simplicity.

To further simplify the system, we use double-side band AM with large-carrier modulation (DSB-AM LC). In this system, we perform amplitude modulation of the carrier signal, given by

$$ s(t) = (1+g\cdot x(t))\cos(2\pi f_c t)$$where $s(t)$ is the transmitted signal, $x(t)$ is the baseband signal, $g$ is the modulation index and $f_c$ is the carrier frequency. With this modulation, we need to ensure that $g\cdot max(|x(t)|)<1$ such that the carrier is always present in the signal.

Let's start this notebook with the standard imports:

In [1]:

```
import matplotlib
import matplotlib.pyplot as plt
%matplotlib notebook
%load_ext autoreload
%autoreload 2
import numpy as np
import sys; sys.path.append('..')
```

In [2]:

```
try:
%load_ext tikzmagic
except ModuleNotFoundError:
print ("Did not find tikzmagic. You will not be able to compile the tex code!")
```

In [3]:

```
%matplotlib notebook
```

In [4]:

```
# Source code has been redacted in online version
# Omitting 4 lines of source code
```

Moreover, let's get our standard baseband transmitter from the previous notebook.

In [5]:

```
# Source code has been redacted in online version
# Omitting 19 lines of source code
```

`Upconversion`

block which is provided by the accompanying library. As the receiver, we use a signal recorder, which records the signal for a given amount of time and automatically stops the transmission afterwards. Subsequently, we have a look at the transmitted signal:

In [6]:

```
from audioComms.components import Upconversion, Recorder
def recordPassbandSignal(channelFunc):
samplerate = 44100
Fc = 3000 # carrier frequency
env = Environment(samplerate=samplerate)
Ts = 1/(441) # symbol duration
t = np.arange(-4*Ts, 4*Ts, 1/samplerate)
transmitter = TransmitSignal(env, get_filter('rc', Ts, rolloff=0.5)(t), Ts)
upconversion = Upconversion(env, Fc=Fc)
channel = channelFunc(env)
recorderBB = Recorder(env, duration=1) # record signal for one second
recorderUP = Recorder(env, duration=1)
transmitter.transmitsTo(upconversion)
transmitter.transmitsTo(recorderBB)
upconversion.transmitsTo(channel)
upconversion.transmitsTo(recorderUP)
env.run()
plt.figure(figsize=(8,3))
plt.plot(0.2+0.1*recorderBB._samples, lw=4, color='r', label='Envelope')
plt.plot(recorderBB._samples, label='Baseband signal')
plt.plot(recorderUP._samples, label='Passband signal')
plt.legend()
plt.xlim((10000, 12000))
recordPassbandSignal(lambda env: SimulatedChannel(environment=env, channelEffect=IdentityChannelEffect(gain=0.2)))
```

`Downconversion`

block, which is supplied by the accompanying library. In addition to performing the downconversion, this block removes the carrier from the signal and subtracts the mean from the baseband signal, yielding the original signal back. At the receiver side, we plot the eye diagram and receive spectrum. Pictorially, we have the following blocks in the chain:

In [7]:

```
# Source code has been redacted in online version
# Omitting 25 lines of source code
```

In [8]:

```
from audioComms.components import Downconversion
def runTransmission(Fc, channelFunc):
samplerate = 44100
env = Environment(samplerate=samplerate)
Ts = 1/(441) # symbol duration
t = np.arange(-4*Ts, Ts, 1/samplerate)
transmitter = TransmitSignal(env, get_filter('rc', Ts, rolloff=0.5)(t), Ts)
upconversion = Upconversion(env, Fc=Fc)
channel = channelFunc(env)
downconversion = Downconversion(env, Fc=Fc, B=4/Ts, removeCarrier=True)
plotSpec = PlotSpectrum(env, windowDuration=0.1, logScale=True, figsize=(8,3))
plotEye = PlotEyeDiagram(env, Ts, figsize=(8,3))
transmitter.transmitsTo(upconversion)
upconversion.transmitsTo(channel)
channel.transmitsTo(plotSpec)
channel.transmitsTo(downconversion)
downconversion.transmitsTo(plotEye)
env.run()
```

First, let's run the bandpass transmission over the simulated highpass channel:

In [9]:

```
runTransmission(18000, lambda env: SimulatedChannel(env, channelEffect=HighpassChannelEffect(gain=0.3)))
```

In [10]:

```
runTransmission(18000, lambda env: AudioChannel(env))
```

In [11]:

```
runTransmission(5000, lambda env: AudioChannel(env))
```

Now that we have a working eye diagram, we are ready to sample the received signal and detect the transmitted bits, right? Well, not yet.

Have you observed that the eye opening always appears at a different position in the eye diagram? Did you observe, that the opening might even move during the transmission over the audio channel? In order to sample the eye diagram, one has to optimally sample the eye pattern at the time of largest opening. However, this information is not yet available. We will tackle this timing recovery problem in the next notebook, using the Gardner Algorithm.

Copyright (C) 2018 - dspillustrations.com

DSPIllustrations.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to amazon.com, amazon.de, amazon.co.uk, amazon.it.