This project studies how to create a real-time audio frequency spectrum analyser using a Digital Signal Processor (DSP). It also explains the theory behind digital signal processing, the DSP architecture incorporated in the board, software capabilities of the DSP and the relevant software codes used.
In order to achieve a frequency spectrum analyser, signal processing algorithms such as Discrete Fourier Transform (DFT) and Fast Fourier Transform (FFT) are used and explained in detail.
The DSP development kit used in the project was the Analog Devices SHARC 21161 DSP.
Overview of the project
The project involves designing a real time audio frequency spectrum analyser with the help of a Digital Signal Processor (DSP). The DSP development kit uses Analog Devices ADSP 21161 which incorporates the Super Harvard Architecture (SHARC).
Audio signal is generally in time domain. This is because audio samples are taken at certain intervals of time. In order to change the signal into the frequency domain a signal processing algorithm such the Discrete Fourier Transform (DFT) can be used.
The nature of the audio frequency spectrum analyser is such that it is required to process the signal in real-time. This provides its own challenges and requires the knowledge of programming concepts such as circular buffering among others.
The DSP development kit and its memory architecture lends itself well for real-time signal processing.
Real world applications of DSP
Broad applications
DSP technology has found uses in many new and current digital products. Most of these applications require collection, processing, transmission, analysis or storage of data, sometimes doing so in real time. Notable examples where DSP's are used would be mobile telephony, personal computers, bio-electronics and digital audio enhancement.[1.a]
Specific applications
Many multi million dollar industries have been formed around specific DSP algorithms which help achieve
Noise removal however remains to be one of the most common applications of DSP. A simple case could be where noise signal is band limited and removed by applying a band stop filter. The main objective being to increase signal-to-noise ratio (SNR).
Benefits of digital signal processing
Before digital signals came into widespread use, analog signals were the norm. These were achieved using analog components such as resistors, capacitors, transistors, op-amps etc.
While they are easy to assemble analog circuits can be difficult to calibrate, modify or maintain. It is much easier to rely on a DSP for designing filters as it is software based, flexible and repeatable. In addition to this, creating higher order filters using a DSP only requires modifications to the software and no hardware changes, something that would have been unlikely to achieve with analog circuits. [2]
The DSP however can achieve the same (and often complex) tasks through a single device--consuming far less power and at a much lower cost. The complexity of a task when using a DSP is dependent on software management rather than the hardware.
A good example to appreciate the processing prowess of a DSP would be of a mobile phone. A single DSP chip in a mobile phone is capable of real-time speech compression, noise cancellation, echo cancellation, modulation/demodulation, interleaving, automatic frequency and many more routines. All this processing power could not have been easy to achieve with analog circuits, requiring tens of thousands of op-amps thereby adding to the cost. With the DSP, a few thousand lines of coding can achieve all this.
Advantages of digital signal processing
Limitations of digital signal processing
What is a DSP?
DSP's are processors that involve hardware, software and instructions sets that have been optimized for high-speed numeric calculations, thus making them ideal for real-time signal processing.
For example when behaving as a digital filter the DSP would take digital samples of the signal, pass a filtering algorithm and output the filter values. The high speed arithmetic and logical hardware of DSP's gives them the ability to rapidly execute algorithms modelling the filter transformation.
A combination of design elements such as arithmetic operators,instruction set, memory handling, parallelism, data addressing etc helps differentiate DSP's from microprocessors.
When a real-time signal goes into a DSP, it does so as a stream of individual samples from an analog-to-digital converter (ADC). To filter in real-time the DSP has to perform calculations and operations on these samples before the next set of sample arrives.
Discrete Fourier transform
The Fourier transform is named after Jean Baptise Joseph Fourier, an 18th century French mathematician.
Why are sinusoids used instead of square or triangular waves??
This is so because a sinusoidal signal input guarantees to produce a sinusoidal signal output. Only the phase and amplitude of the signal might change, albeit the frequency and wave shape remains the same.
Figure 1: Performing DFT on a signal [9]
The dft changes an n point input signal into two point output signals. The input signal is a decomposed form of the signal and the output signals contain amplitude of the sine and cosine components.
figure 2: Shifting between time and frequency domain[9]
The input signal is usually in the time domain as the signal is sampled at regular intervals of time.
Frequency domain is used when describing the amplitude of a sine or cosine wave. It is usually possible to calculate one domain from the other. If a time domain signal is given then calculating the frequency domain is called the DFT and if the frequency domain is known, then bringing it into the time domain is called inverse DFT.
The number of samples taken are usually represented by the variable N. although N can be any positive integer usually a power of 2 is chosen for example 64,128 or 1024 among others. One of the reasons for choosing a power of 2 is because the FFT also operates with N that is of some power to two.
DFT by correlation
DSP architecture
Typical DSP tasks require many mathematical operations such as addition or multiplication. These simple operations require the DSP to
fetch two operands, perform the addition/multiplication, store or hold the result for the next iteration
To fetch the two operands in one instruction cycle both the memory locations have to be accessed simultaneously.
However the DSP can only use a single memory bus at a given time and to help achieve this a DSP architecture could be considered.
Harvard
The Harvard architecture uses two physical memory buses. This means that the dsp can now access two memory locations simultaneously. One of the buses is dedicated to fetching instructions while the other is used to fetch operands.
In a situation where the dsp might require two operands for a given mathematical operation, using one bus to fetch the operands might not be sufficient. In such a case the dsp Harvard architecture might allow for the ‘program bus' to be used for fetching the operands. It should be noted that usually three things have to be fetched- the instruction and the two operands. Clearly the Harvard architecture is insufficient to support this either. This calls for a modified Harvard architecture to be used which is known as the super Harvard architecture(SHARC). This includes a cache memory along with two memory buses. The cache memory is used to store instructions while the memory buses are free to fetch the operands.
Figure 3: Different DSP architectures[3]
ADSP-21161 SHARC DSP Hardware
The 21161 SHARC DSP by Analog Devices is part of a large family of DSP's by the same company. It is a 32-bit DSP which means that it can output a total of 64 bits of information after it has performed the calculations. It has a dual-ported on-chip SRAM, integrated I/O peripherals, Data Address Generators(DAG), a floating-point computational unit containing a multiplier, Arithmetic Logic Unit(ALU), Shifter and a Single-Instruction-Multiple-Data(SIMD) processor all on the same board.
It contains high performance program memory, data memory and I/O buses in addition to a high performance processor core. The core can execute an instruction in a single cycle, while the buses and instruction cache provide a rapid flow of uninterrupted data. Its architecture is such that it allows shared global memory, which means that between two to six SHARC processors can access each other's internal RAM at upto full data rate.
Due to the fact that it incorporates the Super Harvard Architecture it lends itself useful for real-time audio processing. It is also used for communications, imaging and motor control among other applications.
The following diagram shows the architectural features of the 21161 SHARC DSP
Figure 4 : ADSP 21161 Block Diagram
EZKIT-Lite architecture
Figure 5 : Architecture of the SHARC DSP
The ADSP-21161 possesses the following features
The ADSP-21161 offers a complete set of arithmetic operations. It has the ability to execute all instructions in a single cycle and has a fast cycle time. It allows interrupt on arithmetic exception or latched status exception handling.
It uses the Super Harvard Architecture in combination with a 10-port data file register. This means that in one cycle alone the DSP can read/write two operands from the register file, supply two operands to the ALU and the multiplier and receive three results from the ALU and the multiplier.
It uses 32-bit IEEE floating-point format and 40-bit floating-point format for extended precision.
The DSP makes use of two Data Address Generators which provide immediate or indirect addressing. It also supports circular buffering, modulus operations and bit-reverse.
It supports nestable loops and allows the use of interrupts. Loops can have a single-cycle setup. It also supports delayed and non-delayed branches.
Floating point DSP
Floating-point is a type of data format used by DSP's to carry out arithmetic on signal data. It helps the DSP in handling signals of different precision, dynamic range and signal-to-noise ratios. It minimizes certain DSP downsides such as overflows, roundoff errors, coefficient quantization errors etc.
A Floating point DSP allows the software designer to develop algorithms in a high level language and then port them to a DSP device. This makes them a popular choice among developers.[12]Arithmetic Logic Unit (ALU)----pg 66
The ALU executes arithmetic operations on fixed-point and floating-point data. It is also capable of carrying out logical operations on fixed-point data.
It can operate on 32-bit fixed-point operands and floating-point operands in 32-bit or 40-bit. It can also output the respective fixed-point or floating-point results.
Some of the ALU instructions include
ALU operation
The ALU instructions can take two inputs (operands). These inputs can be any data registers in the register file. The results for these operations can be returned to any location in the register file.
The DSP makes efficient use of the ALU by making it read and write from a register file during a single cycle. It does so by transferring the input operands from the register file during the first half of the cycle and transferring the results in the second half of the cycle.
Most times the ALU operations would return one result; however in add/subtract operations it might be required to return two results. For ‘compare' operations the ALU does not return any results; but only updates the flags.
Multiply-Accumulator (Multiplier) page 72
The multiplier executes multiplication on fixed-point and floating-point data. It can also perform fixed-point multiply/accumulate operations.
It can operate on 32-bit fixed-point data and produce 80-bit results. It can also operate on 32-bit floating-point and 40-bit floating-point data operands and give the respective results.
Some of the Multiplier instructions include
Multiplier operation
The Multiplier can take two inputs (operands). The inputs can be any data registers in the register file. The results for Multiplier operations can be written in the register file.
The Multiplier uses the local Multiplier Result (MRF) registers to accumulate fixed-point results or writes them in the register file. The results in MRF can be rounded in separate operations.
The Multiplier uses the same logic as the ALU by allowing the DSP to perform read and write instruction in a single cycle.
Shifter page80
The shifter carries out bit-wise operations. It does this on 32-bit fixed-point operands. Some of the Shifter operations include:
Shifter operation
The shifter can take upto three inputs from the register file. Within a shifter instruction these three inputs serve as follows:
Data Register File pg87
A data register file contains a set of data registers that transfer data between data buses and the computational units. The registers also store operands and results.
There are two register files each containing 16 primary registers and 16 secondary registers. All the registers are 40-bit wide and 32-bits are always left-justified.
Program memory and data memory acess to/from the register files occurs via the PM data bus and DM data bus respectively.
If a specific location in the register file is considered as both the input and the output, the read occurs during first half of the cycle and the write during the other half. This means that old data is treated as operand(s) and the result(s) replaces the older data. If more than one write takes place to a single location preference is given to the one with high priority. Priority for the write operation is determined by the source of data, which is as follows (high to low):
Secondary (Alternate) Data Registers pg89
Each register file has an alternate register set. This allows the DSP to assist fast context switching by having alternate registers for data, results and Data Address Generators.
Bits in the ‘MODE 1' register control when alternate registers become available. If unavailable the data in these registers is not affected by DSP operations. It should be noted that there is a latency of one cycle between writing to ‘MODE1' and accessing an alternate register set.
Multifunction computations pg90-91
The DSP supports multifunction computations using parallel data paths within its computational units. This means that it can combine parallel operations of the ALU and the multiplier in a single cycle. The diagram below shows the registers available for the multifunction computations of ALU and Multiplier.
Figure Multifunction computation of the ALU and Multiplier
Circular buffering-concept
Circular buffering is a programming terminology that is associated with the way a data stream is handled.
Data can be processed in two ways, off-line processing and real-time processing. An example of offline processing would be an MRI scan. What happens here is that the input signal is recorded and stored into the machine's memory first and then processed later. However the key point to note is that during processing all the information is available simultaneously.
In the case of real time processing the output signal is produced at the same time that the input signal is being acquired, although there might be a small delay of a few milliseconds. An example would be when recording audio speech in real time.
During real-time processing the DSP acquires a stream of data, for example sine values, performs an algorithm and outputs the samples. An efficient way to handle this stream of data would be by using circular buffering.
Figure 6: A Circular Buffer[10]
Circular buffering - example and application
Consider the following example code
B8= sine;
L8=@sine;
M8=1;
I8=sine;
What this code does is that it sets up a circular buffer that can be used to calculate a stream of data, say for example a sine wave.
B8 is the base pointer that points to the base or start of the data.
L8 points to the last sample value in the data and gets the length or size of the stream of data for which circular buffering will be carried out.
M8 stores the step size. It tells the compiler how many steps to move the pointer when circular buffering occurs.
I8 is the index pointer that moves about during circular buffering. It points to the data that is currently being read.
What happens during circular buffering is that the base pointer points to the start of the data stream. L8 provides the size of the data stream that will be dealt with hence defining the length of the circular buffer. The index pointer I8 points to the base address as it is the beginning of data. It then increments its position by the value defined by M8. Hence in this example the index pointer will read each of the sample values. When it reaches the end of the data table it will go back to the base address and repeat the process, thereby giving a steady flow of input data to the DSP.
Block diagram
Digital filter
A filter is a system that has the ability to change the wave shape, amplitude-frequency or phase-frequency characteristics of a signal in a user-defined manner. Most common uses of a filter might be to remove/reduce noise or separate two previously combined signals, to make efficient use of a communication channel.
Filter design
The design of a digital filter involves the following steps
Filter specification
This involves stating the type of filter needed, such as lowpass or bandpass, desired amplitude and phase response and sampling frequency.
Coefficient calculation
DSP assembly program - Audio through with gain control
Below is an example code used to calculate the gain.
TalkThro.ASM
//---------------------------------------------------------------------------------------------------------------------
// Basic Audio IO application
//---------------------------------------------------------------------------------------------------------------------
#include "def21161.h" // ADSP-21161 System Register bit definitions
.EXTERNLeft_Channel_In0;
.EXTERNRight_Channel_In0;
.EXTERNLeft_Channel_Out2;
.EXTERNRight_Channel_Out2;
.GLOBALprocess_audio;
.GLOBALuser_code_init;
//---------------------------------------------------------------------------------------------------------------------
.section /pm pm_data;//define your user program memory variables here
//---------------------------------------------------------------------------------------------------------------------
.section /dm dm_data;//define your user data memory variables here
.varGain = 0.7;
//---------------------------------------------------------------------------------------------------------------------
.section /pm pm_code;
//---------------------------------------------------------------------------------------------------------------------
user_code_init:
nop;
rts;
user_code_init.end:
//---------------------------------------------------------------------------------------------------------------------
// audio processing routine
//---------------------------------------------------------------------------------------------------------------------
process_audio:
r1 = -31; // scale the input samples to the range of +/-1.0
r0 = DM(Left_Channel_In0);// get left AD1836 ADC0 input sample
r2 = DM(Right_Channel_In0); // get right AD1836 ADC0 input sample
r1 = -31; // scale the input samples to the range of +/-1.0
f0 = float r0 by r1; // convert to floating point
f2 = float r2 by r1;
f3 = dm(Gain);
f0 = f0 * f3;
f1 = f1 * f3;
r1 = 31;// scale the result back up to MSBs
r0 = fix f0 by r1;// convert back to fixed point
r2 = fix f2 by r1;
rts (db);
DM(Left_Channel_Out2) = r0; // send left channel result to AD1836 Left DAC0
DM(Right_Channel_Out2) = r2;// send right channel result to AD1836 Right DAC0
process_audio.end:
This section of the code defines the header files, audio inputs and outputs to the DSP board and sub-routines.
The sections pm_data and dm_data are used to define variables in the program memory and data memory respectively.
The section pm_code can contain codes that the user wishes to run in the program memory.
The section user_code_init can contain any user written code. However, this code will only run once during boot up.
The command rts returns the compiler to another sub-routine and must be present.
Phase problems
Small amplitude signals
In certain cases when the magnitude of the DFT is very small, round off errors can lead to a situation where the magnitude tends to zero. However using equation…. it might have a significant resulting phase. This situation can be misleading as the phase has meaning to it when the magnitude is zero.
Possible solution
An appropriate algorithm can be used which takes into account the magnitude of the DFT or sets the phase value to be zero if it is below a certain threshold.
Divide by zero
If the real part Re[X(m)] in the above equation is equal to zero then an error will occur giving an ambiguous figure for phase. In reality however if the DFT output at a given frequency (m) gives a zero real component but a non zero imaginary component then the resulting phase could be set to +/- 90°.
Possible solution
An algorithm can be used that tests if the real part equals zero and subsequently avoids carrying out the division in equation…. it can instead check the sign for the imaginary component and based on that set the phase as +90° for a positive sign or -90° for a negative sign.
Polar ambiguity
In a given case where Re[X(m)]=0.707 and Im[X(m)]=0.707 the phase can be calculated to give 45°. If however Re[X(m)]= -0.707 and Im[X(m)]= -0.707 the phase would again be 45° which is wrong as it should be 135° now.
Possible solution
An algorithm can be used that checks the real and imaginary parts and applies the following corrections
If Re[X(m)] and Im[X(m)] are negative then subtract 180° from the resulting phase
If Re[X(m)] is negative and Im[X(m)] is positive then add 180° to the resulting phase
References
1a) Ifeachor, E.C / Jervis, B.W. “Overview of real-world applications of DSP.” Digital Signal Processing, second edition (2002) pp 13-14
2) Bateman, Andrew / Paterson-Stephens, Iain “Benefits of Digital Signal Processing” The DSP Handbook, second edition(2002) pp 10-11
3) Bores Signal Processing, “Introduction to DSP processor memory architecture,” 25 April 2008,
http://www.bores.com/courses/intro/chips/6_mem.htm
9) Smith, S.W.“Fig 8-2, Fig 8-3 Chapter 8- Discrete Fourier Transform” The Scientists and Engineer's Guide To Digital Signal Processing, second edition pp 145-147
10) LuaVIEW data logger, “Reading from Tags”,25 April 2008,
http://www.citengineering.com/LuaVIEW/datalog_manual.html#About
12) Ifeachor, E.C / Jervis, B.W. “Floating point Digital Signal Processors.” Digital Signal Processing, second edition (2002) pp 756-757