Digital Signal Processing (DSP) is a field that can be incredibly useful to almost any programmer. When you think about DSP, you probably think of complex computational tasks for audio filtering, image processing, or video editing, but DSP is much more general than that.
The name 'DSP' aptly describes what it is. It has to do with the digital domain, which is directly applicable to any kind of programming. It deals with signals,
which includes much more than the normal audio and video signals we normally
think about as signals. Any series of data points that changes over
time is a signal. That means a stock's price history is a signal, your
kid's height over time is a signal, and the number of users on a website
is a signal. Signals are all around us, and we deal with them every
day. Finally, DSP involves processing those signals in some way
to either transform the signal into something more useful for a given
purpose or extract desirable information from the signal. Encoding that
processing in a fast, automated program is a natural fit for what a
Advanced DSP can certainly get
complicated with quadrature processing, Hilbert transforms, and cascaded
infinite impulse response filters, but this series on DSP isn't going
to get that complicated. I want to look at some examples of how simple
DSP techniques can be applied to common problems, and build up an
intuition for how to combine and use those techniques in different ways
and new situations. Before getting into these DSP
techniques, we should go over some of the fundamental building blocks of
DSP. In this post, we'll look at a few common types of signals that are
useful in signal processing. In the next couple posts we'll cover
transformations and sampling.
Any time-series of values is a signal, and
the most basic of these signals is one that stays constant over time.
Such a signal is called a DC signal, where DC stands for Direct Current.
That term may seem strange for a signal that could represent anything, not necessarily related to electrical circuits, but it was probably originally used to describe electrical signals with a constant current. Over time the 'DC' label stuck and took on a meaning of its own, so now when we talk about DC signals, it means any signal with a constant value. Here's what a DC signal would look like visually:
The x-axis of the graph is in units of time, and the y-axis is in whatever units the signal values are in. It's not a terribly interesting signal and not all that common to see on its own, but it's an important part of most other signals. For example, an audio signal will have a DC component that offsets the waveform to a mid-range value. The signal that we would actually hear coming out of a speaker varies around that mid-range value. Sometimes we want to be able to remove that DC component before analyzing the signal further, sometimes we want to pick it out and use it as a reference, and other times we simply need to be aware that it's there. In any case, DC components of signals come up a lot in signal processing, so we need to keep them in mind.
The next signal type we'll look at is the impulse. An impulse is an infinitely narrow spike in an otherwise DC signal. The spike could be of any amplitude and positive or negative, but a special case happens when it is a value of one. This signal is then called a unit impulse, and it has some special uses, especially in sampling. Here is an example of an impulse moving through a system over time:
At first it may seem strange that the impulse is moving from right to left, but imagine that the time t on the x-axis is increasing, as if we are looking through a sliding window at the signal. Then we would see the signal enter on the right and move across the window, exiting on the left. That is the behavior that the graph is showing. It would be similar to how the signal may behave in a memory buffer. The buffer would start as an array of zeros:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
The older samples are on the left and the newer samples are on the right. Then the impulse would appear on the right:
[0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
And travel to the left:
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0]
Until it passed through the entire memory buffer and exited on the left:
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
This ends up being a more natural way of thinking about signals and makes other concepts less confusing later.
Impulses have a variety of applications. For one, digital sampling can be modeled as a series of unit impulses multiplied by the signal to be digitized. Whatever value the signal has at the time of an impulse is the value that the digital signal will have. We'll go into more detail on sampling in a later post. For another example, impulses can be used to analyze the behavior of a DSP algorithm. If you inject an impulse into a system, the output of the algorithm is the impulse response of the system. The impulse response can be useful for verifying the stability and basic behavior of the system.
Another type of signal similar to an impulse is the step function. If you take an impulse and let it maintain the value at its peak, you have a step function. The signal starts at one constant value and instantaneously jumps to a different constant value at a point in time. The step function looks like this:
This signal is actually a combination of two step functions, one that steps up in value and another that steps down to the original value. This combination makes a square wave, and every microprocessor in the world uses such a signal as a clock to keep all of its logic circuits in sync. (Although at high frequencies, clock signals tend to look more like a distorted version of the next signal we'll discuss instead of the pristine signal above.)
Step functions can show up in signals, revealing where discontinuities are occurring, and they are generally points of interest that also happen to be fairly easy to detect. Step functions are also used, like impulses, to analyze DSP algorithms, and the algorithm's output from an injected step function is called its step response. Many DSP algorithms will produce an oscillation or ringing on the output when fed a step function, so characterizing the algorithm's step response can be important.
The final signal we'll look at today is the sine wave. The sine wave is so fundamental to signal processing that you can express any other type of signal as a sum of sine waves of different amplitudes and frequencies, even the previous three basic signals we've talked about. The DC signal is a special case of a sine wave with zero amplitude or zero frequency, the impulse is the continuous sum of sines over all frequencies, and the square wave is the sum of an infinite number of sines with frequencies that are a multiple of the square wave frequency. We'll get into representing signals as sums of sines more in the next post, but for now here is what the sine wave looks like:
Notice how there is also a DC component to the sine wave, since it is offset from zero on the y-axis. Normally a sine wave would be centered around f(t)=0, but by adding a constant value, this signal was shifted up so that it has a sine component and a DC component. Beyond being able to represent any signal as a sum of sines, the sine wave is incredibly useful in signal processing. Most analysis and processing is done using sine waves, filters are built up with sine waves, and the DFT (Discrete Fourier Transform) is a large matrix of sine wave frequency detectors. The sine wave is the most integral part of DSP design, and we will be using it constantly as we look at different DSP techniques.
These four basic signals—the DC signal, the impulse, the step function, and especially the sine wave—are the fundamental building blocks for digital signal processing. They each have their practical uses, and we can do a lot of amazing, useful stuff by combining these signals and some simple operations. Advanced DSP design can get extremely complicated, but it doesn't have to be. There are plenty of interesting problems we can solve with the intelligent application of simpler DSP concepts, and that's what we'll do over the coming weeks. Next week we'll lay some more groundwork with signal transformations before moving on to some of those applications.
Other DSP posts:
Step Response of Averaging
The Discrete Fourier Transform
The DFT in Use
Spectral Peak Detection
DC and Impulsive Noise Removal