<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Signal-Processing on Lloyd Rochester's Geek Blog</title><link>https://lloydroc.github.io/tags/signal-processing/</link><description>Recent content in Signal-Processing on Lloyd Rochester's Geek Blog</description><generator>Hugo</generator><language>en</language><copyright>Copyright © 2025, Lloyd Rochester.</copyright><lastBuildDate>Fri, 01 May 2020 00:00:00 +0000</lastBuildDate><atom:link href="https://lloydroc.github.io/tags/signal-processing/index.xml" rel="self" type="application/rss+xml"/><item><title>Viterbi Example</title><link>https://lloydroc.github.io/post/c/viterbi-example/</link><pubDate>Fri, 01 May 2020 00:00:00 +0000</pubDate><guid>https://lloydroc.github.io/post/c/viterbi-example/</guid><description>&lt;h1 id="hahahugoshortcode44s0hbhb">Viterbi Example&lt;/h1>
&lt;p>Here we go! In this post I&amp;rsquo;m going to go through how Viterbi Decoders work. There is a lot to cover since we need to touch on Convolutional Coding, State Machines, Trellis Diagrams, Hamming Distances and Trellis Diagrams. I&amp;rsquo;ll illustrate this with the absolute simplest example possible and walk you through every step of the way. I highly recommending taking out a pencil and paper for this.&lt;/p>
&lt;h1 id="what-is-viterbi-decoding">What is Viterbi Decoding?&lt;/h1>
&lt;p>Viterbi Decoding allows us to detect and correct errors that were transmitted through a noisy channel.&lt;/p></description></item><item><title>Delay Lines in C</title><link>https://lloydroc.github.io/post/c/delay-line/</link><pubDate>Mon, 23 Mar 2020 08:43:05 +0000</pubDate><guid>https://lloydroc.github.io/post/c/delay-line/</guid><description>&lt;h1 id="hahahugoshortcode16s0hbhb">Delay Lines in C&lt;/h1>
&lt;p>There are many scenarios where a delay line is needed in signal processing. Scenarios ranging from Digital Filters, Convolution, Reverberation, Echo and others. Delay lines have a fixed length of &lt;strong>N&lt;/strong> samples. When delay lines take in a new sample they discard the oldest sample. In this post we discuss how delay lines work and implement a delay line in the C programming language.&lt;/p>
&lt;h1 id="a-theoretical-delay-line">A Theoretical Delay Line&lt;/h1>
&lt;p>For our purposes we will store primitive data types in an array. We&amp;rsquo;ll spare for this example both non-primitive data types, as well as, non-contiguous memory. The primitive data type in this array would be any of the following types: &lt;strong>int&lt;/strong>, &lt;strong>char&lt;/strong>, &lt;strong>complex&lt;/strong>, &lt;strong>double&lt;/strong>, or &lt;strong>float&lt;/strong>. The memory for the delay line is monotonically increasing and continuous, meaning all memory addresses for samples are next to one another. Essentially, we&amp;rsquo;ll have a &lt;code>int delay[N]&lt;/code> to declare our delay line. The delay line will store &lt;strong>N&lt;/strong> samples. With each new sample we&amp;rsquo;ll throw out the oldest sample. Below is a figure to depict the state of the delay line on each new sample received.&lt;/p></description></item><item><title>Implementing FIR Filters in C</title><link>https://lloydroc.github.io/post/c/fir-filter/</link><pubDate>Mon, 19 Aug 2019 16:00:21 +0000</pubDate><guid>https://lloydroc.github.io/post/c/fir-filter/</guid><description>&lt;h1 id="hahahugoshortcode23s0hbhb">Implementing FIR Filters in C&lt;/h1>
&lt;p>Implementing FIR filters in C is much easier if we make use of the static variables declared in our functions. In this blog post we will create some simple example FIR filters, and get their impulse response. To understand this post you will have to have the basic theory of FIR filtering down.&lt;/p>
&lt;h3 id="fir-filter-implementation">FIR Filter Implementation&lt;/h3>
&lt;p>There are a lot of ways to implement a FIR filter in C. The method provided makes the implementation simple because we can simply put the last time sample into the filter and the filtered result will come out. The filter function itself will handle the delay line of the time samples. It&amp;rsquo;s a bit abstract so let&amp;rsquo;s take an example of just creating a delay line of samples. Then later we&amp;rsquo;ll add in the FIR filter coefficients.&lt;/p></description></item><item><title>Example FFT in C</title><link>https://lloydroc.github.io/post/c/example-fft/</link><pubDate>Thu, 08 Aug 2019 00:00:00 +0000</pubDate><guid>https://lloydroc.github.io/post/c/example-fft/</guid><description>&lt;h1 id="hahahugoshortcode22s0hbhb">Example FFT in C&lt;/h1>
&lt;p>In this post we&amp;rsquo;ll provide the simplest possible Fast Fourier Transform (FFT) example in C. After understanding this example it can be adapted to modify for performance or computer architecture.&lt;/p>
&lt;h1 id="table-of-contents">Table of Contents&lt;/h1>
&lt;nav id="TableOfContents">
 &lt;ul>
 &lt;li>&lt;a href="#fft-example-usage">FFT Example Usage&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#c-header-of-the-fft">C Header of the FFT&lt;/a>
 &lt;ul>
 &lt;li>&lt;a href="#rearranging-the-input">Rearranging the Input&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#c-header-to-use-the-fft">C Header to use the FFT&lt;/a>&lt;/li>
 &lt;/ul>
 &lt;/li>
 &lt;li>&lt;a href="#c-implementation-of-the-fft">C Implementation of the FFT&lt;/a>&lt;/li>
 &lt;li>&lt;a href="#test-cases-for-the-fft">Test Cases for the FFT&lt;/a>&lt;/li>
 &lt;/ul>
&lt;/nav>
&lt;h2 id="fft-example-usage">FFT Example Usage&lt;/h2>
&lt;p>In the example below we&amp;rsquo;ll perform an FFT on a complex (real + imaginary) array of 32 elements. After the FFT has completed it will write over the provided arrays as the FFT is done &lt;em>in place&lt;/em>. Note, we&amp;rsquo;re using floating point here and not fixed width. Thus, if you don&amp;rsquo;t have a math coprocessor it will be very slow.&lt;/p></description></item><item><title>PSK31 Convolutional Decoder Implementation in C</title><link>https://lloydroc.github.io/psk31/cnvdec/</link><pubDate>Wed, 13 Feb 2019 00:00:00 +0000</pubDate><guid>https://lloydroc.github.io/psk31/cnvdec/</guid><description>&lt;h1 id="psk31-convolutional-decoder">PSK31 Convolutional Decoder&lt;/h1>
&lt;p>In my humble opinion decoding a convolutionally encoded PSK31 output stream is the most challenging part of all. Decoding is also where all the magic happens. The Viterbi Decoder corrects the erroneous bits and allows reception of the intended bit stream.&lt;/p>
&lt;p>If this is the first time you&amp;rsquo;ve heard of a &lt;a href="https://en.wikipedia.org/wiki/Viterbi_decoder">Viterbi Decoder&lt;/a> please look at the former link from Wikipedia as well as these great examples that are in links below. What these examples allow you do is better visualize the entire state machine since they have a very small value for &lt;code>K&lt;/code> and only &lt;code>4&lt;/code> states. What we have here in QPSK31 is &lt;code>32&lt;/code> states and it makes it a bit inconvenient to use this as the first example to learn Viterbi Decoding. Also, be very comfortable with &lt;a href="https://lloydroc.github.io/psk31/cnvenc/">PSK31 Convolutional Encoding&lt;/a> and the state machine it uses, the generator functions, shift register and process to encode a bit stream with the PSK31 convolutional encoder.&lt;/p></description></item><item><title>PSK31 Convolutional Encoder implementation in C</title><link>https://lloydroc.github.io/psk31/cnvenc/</link><pubDate>Wed, 13 Feb 2019 00:00:00 +0000</pubDate><guid>https://lloydroc.github.io/psk31/cnvenc/</guid><description>&lt;h1 id="hahahugoshortcode109s0hbhb">PSK31 Convolutional Encoder implementation in C&lt;/h1>
&lt;h1 id="psk31-convolution-encoding">PSK31 Convolution Encoding&lt;/h1>
&lt;p>Convolutional Codes are often charactarized by three aspects:&lt;/p>
&lt;ol>
&lt;li>&lt;code>n&lt;/code> Base Code Rate - Number of bits into the encoder&lt;/li>
&lt;li>&lt;code>k&lt;/code> Output Symbol Rate - Number of bits out for an input&lt;/li>
&lt;li>&lt;code>K&lt;/code> Memory Depth&lt;/li>
&lt;/ol>
&lt;p>For QPSK31 we have &lt;code>[n,k,K] = [1,2,5]&lt;/code>. We give the encoder 1-bit of input, out comes 2-bits, and 5-bits of input are stored in our shift register. For the 2-bits of output 1-bit is In-Phase and the other is Quadrature. Let&amp;rsquo;s look at a diagram that allows us to envision &lt;code>[n,k,K]&lt;/code>.&lt;/p></description></item><item><title>Root Raised Cosine Filter in C</title><link>https://lloydroc.github.io/psk31/rrc/</link><pubDate>Wed, 13 Feb 2019 00:00:00 +0000</pubDate><guid>https://lloydroc.github.io/psk31/rrc/</guid><description>&lt;h1 id="hahahugoshortcode110s0hbhb">Root Raised Cosine Filter in C&lt;/h1>
&lt;h1 id="root-raised-cosine-filtering">Root Raised Cosine Filtering&lt;/h1>
&lt;p>The PSK31 Standard uses &lt;a href="https://en.wikipedia.org/wiki/Root-raised-cosine_filter">Root Raised Cosine Filters&lt;/a> as a matched filter. Our PSK31 signal is convolved by the Root Raised Cosine waveform to mimimize Inter-Symbol Interference. For this project we can easily compute the RRC filter and then convolve it with our output stream. For the computation of the RRC we need a couple of constants specific to the PSK31 standard.&lt;/p></description></item><item><title>Simple Convolution in C</title><link>https://lloydroc.github.io/post/c/convolution/</link><pubDate>Wed, 17 Oct 2018 06:10:00 +0000</pubDate><guid>https://lloydroc.github.io/post/c/convolution/</guid><description>&lt;h1 id="hahahugoshortcode15s0hbhb">Simple Convolution in C&lt;/h1>
&lt;p>Updated April 21, 2020&lt;/p>
&lt;p>In this blog post we&amp;rsquo;ll create a simple 1D convolution in C. We&amp;rsquo;ll show the classic example of convolving two squares to create a triangle. When convolution is performed it&amp;rsquo;s usually between two discrete signals, or time series. In this example we&amp;rsquo;ll use C arrays to represent each signal.&lt;/p>
&lt;p>When implementing convolution it&amp;rsquo;s important to know the length of convolution result, since the resulting array is bigger than the two input arrays. This can cause memory problems. Computing the length of the convolution result is actually a simple computation. If you have array &lt;strong>H&lt;/strong> convolved with array &lt;strong>X&lt;/strong>, where the lengths are 5 and 5 respectively, the resulting size of &lt;strong>Y=H*X&lt;/strong> (&lt;strong>H&lt;/strong> convolved with &lt;strong>X&lt;/strong> to make &lt;strong>Y&lt;/strong>) will be &lt;strong>Length(H) + Length(X) - 1&lt;/strong>. For this example the resulting length of two size 5 arrays will be 5+5-1 = 9. This convolution is typically done where &lt;strong>H&lt;/strong> is a digital filter and &lt;strong>X&lt;/strong> is a time series to be filtered. The output array &lt;strong>Y&lt;/strong> is the time series that results after filtering. For our example we have input arrays &lt;strong>H&lt;/strong> and &lt;strong>X&lt;/strong>. The output of array of our convolution will be called &lt;strong>Y&lt;/strong>.&lt;/p></description></item></channel></rss>