16.6 Extended Topic – Digital Signal Processing
Much has been said in this chapter concerning the ability of personal computers to store and manipulate data in the digital domain. This process is called digital signal processing (DSP). The sampled data is generally stored in RAM as a large array of values. Normally, the data is in integer form. This is because microprocessors are generally faster at performing integer calculations than floating point calculations. Also, AD converters produce integer values, so this is doubly convenient. As an example, if 8-bit resolution is used, each sample point will require one byte (8 bits). The byte is the fundamental unit of computer memory storage, and thus storage as a simple byte multiple (8 bits, 16 bits, 32 bits) is straightforward. The data may be stored in either unipolar (unsigned) or bipolar (signed) formats. For unsigned systems, the data value “0” means “most negative peak”. In signed systems, a two’s compliment form is normally used. Here, a data value of “0” means “0 V”. All negative values have their most significant bit set (for an 8 bit representation, −1=11111111,−2=11111110, etc.). Input signals are often AC, thus signed representations are quite common.
In BASIC, the data array might be called data()
, and individual elements are accessed by properly setting the array index. The first element is data(1)
, the second is data(2)
, and the N
th element is data(N)
. Although BASIC is useful, it is not as powerful as languages such as C, which offer direct manipulation of memory addresses via pointers. In C, the starting, or base, address of the data might be given the name data\_ptr
. To access different elements in the array, an offset is added to the base. The address of the second element is data\_ptr + 1
, the third is data\_ptr + 2
, and so on. Alternately, we could just increment the pointer continuously, as in data\_ptr++
. Direct manipulation of pointers is generally faster for the microprocessor than array indexing. To find the value stored at a given address, C uses the indirection operator, *
. To assign the second data value to the variable x
, you would say x = *(data\_ptr + 1)
or simply x = *data\_ptr++
if the pointer is being continuously incremented. The BASIC equivalent is x = data(2)
.
No matter how the data is accessed, any mathematical function may be applied to the data elements. In the examples below, C is used to illustrate the concepts. Only the processing portion of the code is shown. The source array is called src()
and has TOTAL
number of elements. The destination array is called dest()
. Also, questions concerning integer versus floating point representation are bypassed in order to keep the examples as straightforward as possible. In the real world, problems such as execution speed, round-off error, and overflow cannot be ignored.
Let’s start with something simple. Suppose we would like to simulate the operation of an inverting buffer. An inverting buffer simply multiplies the input signal by −1. Here is how we do this in the digital domain: each point is multiplied by −1.
for( i=0; i<TOTAL; i++ ) { *dest++ = -1 * (*src++); }
We can extend this concept a bit further by replacing “−1” with a variable called “gain”. In this way, we can alter the signal amplitude digitally.
Another useful calculation is average value. For signed data, the average value is equal to the DC offset component.
sum = 0; for( i=0; i<TOTAL; i++ ) { sum += *src++; } average = sum / TOTAL;
In order to add a DC offset, a constant is added to each data element in turn.
for( i=0; i<TOTAL; i++ ) { *dest++ = offset + (*src++); }
We might wish to combine two different waveforms into a third waveform. Simple addition is all that is required. (The example assumes that both arrays are the same size).
for( i=0; i<TOTAL; i++ ) { *dest++ = (*src++) + (*src2++); }
If the two source arrays are multiplied instead of added, signal modulation may be produced.
These examples are relatively simple. With proper programming, a wide variety of functions may be simulated including spectral analysis, translation to new sampling rates, and the realization of complex filter functions that are impractical to implement in the analog domain. The major drawback of DSP techniques is the inherent computing power required. Thus, real-time application of complex DSP principles is not possible without using powerful computers. Specialized ICs have been designed to implement DSP sub-functions very quickly. These chips make realtime DSP practical and ecomical. The DSP ICs are programmable, thus they offer the distinct advantage of being able to produce different functions at different times by loading new programs. In this way, they are far more flexible than dedicated analog circuits. For example, an all-DSP guitar effects unit encompassing a broad range of functions such as equalization, pitch shifting, chorusing, reverberation and other effects can be designed. The amplitude and spectral shaping is performed directly in the digital domain instead of using dedicated analog circuitry.