Nonideal signal reconstruction

Mathematica definitions

Load needed packages for this notebook

<< Graphics`Colors`;
<< Miscellaneous`Audio`;

Set up defaults

Turn off annoying warning messages

Off[General::spell];
Off[General::spell1];

Set default options for specific functions

SetOptions[Plot, Frame -> True];
SetOptions[ListPlot, Frame -> True,  PlotJoined -> True,  
        Axes -> {True, False}];
SetOptions[Fourier, 
        FourierParameters -> {1, -1}];
SetOptions[InverseFourier, 
        FourierParameters -> {1, -1}];

Visualization functions

Fix time variable for sampled signals

FixTime[signal_, 
          sampleRate_] := 
Module[{time, 
            data}, 
time = 
            Table[i/sampleRate, {i, 1, 
                Length[signal]}]; 
data  =  {time, 
                signal} // Transpose
];

Generate periodic waveform from one period

PeriodicSignal[f, {dmin, dmax}, {t, min, max}] generates a periodic waveform for the interval [min, max]. It is assumed that one period of the function f(t) is defined over the interval [dmin, dmax].

PeriodicSignal[
          f_, {dmin_, dmax_}, {t_, min_, 
            max_}] := 
Module[{T, imin, 
            imax}, 
T  =  
            dmax  -  dmin; 
imin = 
            Floor[(min - dmin)/T]; 
imax = 
            Ceiling[(max - dmax)/T];  
Sum[
            f[t - i T] (UnitStep[t - dmin - i T]  -  
                  UnitStep[t - dmax - i T]), {i, imin, 
              imax}]
];

Plot periodic waveforms

PeriodicPlot[f, {dmin, dmax}, {t, min, max}, opts] plots a a periodic waveform for the interval [min, max]. It is assumed that one period of the function f(t) is defined over the interval [dmin, dmax]. The 'opts' argument passed plotting options to the Mathematica function Plot[ ].

PeriodicPlot[f_, {dmin_, dmax_}, {t_, min_, max_}, 
          opts___] := 
Module[{fnc}, 
fnc = PeriodicSignal[f, {dmin, dmax}, {t, min, max}]; 
Plot[
            fnc, {t, min, max}, opts]
];

Plot discrete-time signal as sequence of amplitude lines

DiscreteListPlot[signal_, color_:  Black, 
          opts___] := 
Module[{data, g1, 
            g2}, 
If[
            Length[signal[[1]]]  ==  2, 
data = 
              signal, 
data = 
              FixTime[signal, 
                1]
]; 
g1 = Line[{{#[[1]], 0}, {#[[1]], #[[2]]}}] &  /@  
              data; 
g2 = {PointSize[ .015], 
                  Point[#]} &  /@  data; 
Show[
            Graphics[{color, g1, g2}], 
            opts]
];

Filtering definitions

FourierRearrange[fft] rearranges the result of an FFT (Mathematica function Fourier[ ]), to a easier to visualize the spectrum represented by 'fft'. The length of the list 'fft' is assumed to be even; if it is not, the last term in 'fft' is dropped.

FourierRearrange[fft_,  
          samplingRate_] := 
Module[{fft2, n, 
            n2}, 
If[EvenQ[Length[fft]],  
            fft2  =  fft,  
            fft2  =  Drop[fft, -1]];  
n = 
            Length[fft]; 
          n2 = n/2; 
{Table[ 
                samplingRate i/n, {i, -n2 + 1, n2}], 
              Take[fft2, {n2 + 2, n2*2}]~Join~Take[fft2, {1, n2 + 1}]} // 
            Transpose
];

Filter[n, sampleRate, {lowFreq, highFreq}] generates an ideal discrete filter for an FFT list of length 'n' (sampled at 'sampleRate'), with a bandpass from 'lowFreq' to 'highFreq' (in Hz).

Filter[n_, 
          samplingRate_, {lowF_, 
            highF_}] := 
Module[{coeff, l, 
            h}, 
coeff = 
            Table[0, {n}]; 
l = Floor[lowF*n/samplingRate]; 
          h = Ceiling[highF*n/samplingRate]; 
If[
            l  ==  0,  l  =  1;  
            coeff = ReplacePart[coeff, 1, 1]]; 
coeff = 
            ReplacePart[coeff, 1, Table[{i}, {i, l + 1, h + 1}]]; 
          coeff = ReplacePart[coeff, 1, 
              Table[{i}, {i, n + 1 - h, 
                  n + 1 - l}]]
];

Signal reconstruction

Sinc2[t_] := Sin[π t]/(π t);

Pulse[t_] := UnitStep[t + 1/2] - UnitStep[t - 1/2];

Triangle[
          t_] :=  (t + 1) (UnitStep[t + 1]  -  
                UnitStep[t])  +  (-t + 1) (UnitStep[t]  -  
                UnitStep[t - 1]);

Reconstruction[t_, fs_, fnc_, range_: {0, 5},  
          padding_:  1] := 
Plus  @@  
          Table[x[n, fs] fnc[fs (t - n/fs)], {n, 
              Floor[(range[[1]] - padding)*fs], 
              Ceiling[(range[[2]] + padding)*fs]}];

Continuous-time function

Continuous-time function

xc[t_] := Cos[2  π t];

range = {0, 5};

gin = 
        Plot[xc[t], {t, range[[1]], range[[2]]},  
          PlotStyle -> {Blue,  Thickness[ .005]}];

gd = 
        Plot[xc[t], {t, range[[1]], range[[2]]},  
          PlotStyle -> {Blue,  Dashing[{ .02}]}];

Sampler (CT to DT converter)

x[n_,  fs_] :=  xc[n/fs];

sampler[fs_, 
          range_: {0, 5}] := 
Table[{n/fs, x[n, fs]}, {n, 
            range[[1]]*fs, range[[2]]*fs}];

Different reconstruction techniques: experiment #1

Sampled signal

sampleFrequency = 2.3;

xd  =  sampler[sampleFrequency,  range];
g2 = 
        DiscreteListPlot[xd, Red,  Frame -> True, 
          Axes -> {True, False}, PlotRange -> All];

gs = Show[gd, g2];

Replace each sample with rectangular pulse

gpulse = 
        Plot[Pulse[t], {t, -2, 2},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> {- .1, 2.1}];

gtmp1 = 
        Plot[Reconstruction[t,  sampleFrequency,  Pulse], {t, 0, 5}, 
          PlotPoints -> 100, 
          PlotStyle -> {Magenta, Thickness[ .01]},  
          DisplayFunction -> Identity, 
          Evaluate[AbsoluteOptions[gs]]];
gRpulse = 
        Show[gtmp1, gd, 
          DisplayFunction -> $DisplayFunction];

Replace each sample with triangular pulse

gtriangle = 
        Plot[Triangle[t], {t, -2, 2},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> {- .1, 2.1}];

gtmp1 = 
        Plot[Reconstruction[t,  sampleFrequency, Triangle], {t, 0, 5}, 
          PlotPoints -> 100, 
          PlotStyle -> {Magenta, Thickness[ .01]},  
          DisplayFunction -> Identity, 
          Evaluate[AbsoluteOptions[gs]]];
gRtriangle = 
        Show[gtmp1, gd, 
          DisplayFunction -> $DisplayFunction];

Replace each sample with sinc pulse

gsinc = 
        Plot[Sinc2[t], {t, -2, 2},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> All];
Sinc2[t]  //  TraditionalForm

gsinc2 = 
        Plot[Sinc2[t], {t, -10, 10},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> All];

gtmp1 = 
        Plot[Reconstruction[t,  sampleFrequency, Sinc2,  {0, 5}, 10], {t, 
            0, 5}, PlotPoints -> 100, 
          PlotStyle -> {Magenta, Thickness[ .01]},  
          DisplayFunction -> Identity, 
          Evaluate[AbsoluteOptions[gs]]];
gRsinc = 
        Show[gtmp1, gd, 
          DisplayFunction -> $DisplayFunction];

Show all

Show[
        GraphicsArray[{{gin, gs},  {gpulse, gRpulse}, {gtriangle, 
              gRtriangle}, {gsinc2, gRsinc}}], ImageSize -> 432, 
        GraphicsSpacing -> { .1,  .2}];

Different reconstruction techniques: experiment #2

Sampled signal

sampleFrequency = 6;

xd  =  sampler[sampleFrequency,  range];
g2 = 
        DiscreteListPlot[xd, Red,  Frame -> True, 
          Axes -> {True, False}, PlotRange -> All];

gs = Show[gd, g2];

Replace each sample with rectangular pulse

gpulse = 
        Plot[Pulse[t], {t, -2, 2},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> {- .1, 2.1}];

gtmp1 = 
        Plot[Reconstruction[t,  sampleFrequency,  Pulse], {t, 0, 5}, 
          PlotPoints -> 100, 
          PlotStyle -> {Magenta, Thickness[ .01]},  
          DisplayFunction -> Identity, 
          Evaluate[AbsoluteOptions[gs]]];
gRpulse = 
        Show[gtmp1, gd, 
          DisplayFunction -> $DisplayFunction];

Replace each sample with triangular pulse

gtriangle = 
        Plot[Triangle[t], {t, -2, 2},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> {- .1, 2.1}];

gtmp1 = 
        Plot[Reconstruction[t,  sampleFrequency, Triangle], {t, 0, 5}, 
          PlotPoints -> 100, 
          PlotStyle -> {Magenta, Thickness[ .01]},  
          DisplayFunction -> Identity, 
          Evaluate[AbsoluteOptions[gs]]];
gRtriangle = 
        Show[gtmp1, gd, 
          DisplayFunction -> $DisplayFunction];

Replace each sample with sinc pulse

gsinc = 
        Plot[Sinc2[t], {t, -2, 2},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> All];
Sinc2[t]  //  TraditionalForm

gsinc2 = 
        Plot[Sinc2[t], {t, -10, 10},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> All];

gtmp1 = 
        Plot[Reconstruction[t,  sampleFrequency, Sinc2,  {0, 5}, 10], {t, 
            0, 5}, PlotPoints -> 100, 
          PlotStyle -> {Magenta, Thickness[ .01]},  
          DisplayFunction -> Identity, 
          Evaluate[AbsoluteOptions[gs]]];
gRsinc = 
        Show[gtmp1, gd, 
          DisplayFunction -> $DisplayFunction];

Show all

Show[
        GraphicsArray[{{gin, gs},  {gpulse, gRpulse}, {gtriangle, 
              gRtriangle}, {gsinc2, gRsinc}}], ImageSize -> 432, 
        GraphicsSpacing -> { .1,  .2}];

Different reconstruction techniques: experiment #3

Sampled signal

sampleFrequency = 10;

xd  =  sampler[sampleFrequency,  range];
g2 = 
        DiscreteListPlot[xd, Red,  Frame -> True, 
          Axes -> {True, False}, PlotRange -> All];

gs = Show[gd, g2];

Replace each sample with rectangular pulse

gpulse = 
        Plot[Pulse[t], {t, -2, 2},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> {- .1, 2.1}];

gtmp1 = 
        Plot[Reconstruction[t,  sampleFrequency,  Pulse], {t, 0, 5}, 
          PlotPoints -> 100, 
          PlotStyle -> {Magenta, Thickness[ .01]},  
          DisplayFunction -> Identity, 
          Evaluate[AbsoluteOptions[gs]]];
gRpulse = 
        Show[gtmp1, gd, 
          DisplayFunction -> $DisplayFunction];

Replace each sample with triangular pulse

gtriangle = 
        Plot[Triangle[t], {t, -2, 2},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> {- .1, 2.1}];

gtmp1 = 
        Plot[Reconstruction[t,  sampleFrequency, Triangle], {t, 0, 5}, 
          PlotPoints -> 100, 
          PlotStyle -> {Magenta, Thickness[ .01]},  
          DisplayFunction -> Identity, 
          Evaluate[AbsoluteOptions[gs]]];
gRtriangle = 
        Show[gtmp1, gd, 
          DisplayFunction -> $DisplayFunction];

Replace each sample with sinc pulse

gsinc = 
        Plot[Sinc2[t], {t, -2, 2},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> All];
Sinc2[t]  //  TraditionalForm

gsinc2 = 
        Plot[Sinc2[t], {t, -10, 10},  
          PlotStyle -> {Magenta, Thickness[ .01]}, 
          PlotRange -> All];

gtmp1 = 
        Plot[Reconstruction[t,  sampleFrequency, Sinc2,  {0, 5}, 10], {t, 
            0, 5}, PlotPoints -> 100, 
          PlotStyle -> {Magenta, Thickness[ .01]},  
          DisplayFunction -> Identity, 
          Evaluate[AbsoluteOptions[gs]]];
gRsinc = 
        Show[gtmp1, gd, 
          DisplayFunction -> $DisplayFunction];

Show all

Show[
        GraphicsArray[{{gin, gs},  {gpulse, gRpulse}, {gtriangle, 
              gRtriangle}, {gsinc2, gRsinc}}], ImageSize -> 432, 
        GraphicsSpacing -> { .1,  .2}];