To carry out our project in real-time on a DSP board from Texas
Instruments, we set out with the goal of adaptively filtering a simple
noise component out of a voice signal. The goal of implementing our
project onto a DSP board seemed at first trivial; all we had to do was
convert some MATLAB code into C and compile the code. It turned out to be
a non-trivial task.
When we began the project, nobody in the group had ever seen a DSP
board like the ones in the lab before, let alone used one. Our first
hurdle to overcome was to familiarize ourselves with the boards
functionality.
Using the Elec 434 web page as a basis for learning, we set out to
master the structure of the DSP boards use. Our first steps of
understanding the boards involved doing several of Dr. Choi's lab
assignments for 434. Upon completing the third lab, we understood how to
implement a low pass FIR filter. MATLAB is used to generate the desired
coefficients. These coefficients are then saved to a file as the two's
complement representation in Q15 (16 bit fixed point) format.
When the board is run, the main function is used to initialize all
variables, and an infinite loop with no operations is run to keep the
board running. However, the board has several interrupts built in that
will cause the board to perform various tasks. One of these interrupts is
used for inputing data from the CODEC. Our implementations of filters
involved using this interrupt (IRQ 11) to carry out our desired task.
Every time the interrupt is used, it means that there is an input
sample ready to be dealt with. In our code, we wrote our algorithms into
this section of the board. For most (non-adaptive) filters, this just
meant shifting our array, taking a dot product, and giving an
output. Having carried out the first three labs, we were fully capable of
creating low-pass, high-pass, and band-pass filters in real-time.
Previous to this stage, we were working on the DSK boards in the
lab, but due to limitations on the board, we had to switch over to the EVM
boards. The big advantage of doing this was that the DSK boards only have
one input on the CODECs, while the EVM boards have two. We needed
the second input if we were to have some reference to our noise
signal. Though it was only a small task, we had to make sure our FIR
filters worked on the EVM board. The EVM boards did offer one extra
challenge though - the gains on the two inputs is different, and therefore
it was increasingly difficult to match the decibel level between the
two. This didn't affect our algorithm on the board very much, but dealing
with different sized gains on the inputs made it difficult to not overflow
the registers on the EVM. The overflow of registers made it difficult to
tell when our code had actually started working. In the end, we learned
that extremely small input signals are needed to keep the board from
having overflow problems.
While testing our code, we attempted to use the oscilloscopes
available in the lab, but this proved to be another challenge unworthy of
the benefits. The CoDec on the DSP boards have a horrible resonance
apparent around 5.5 MHz. While this does not create a problem for hearing
the output, one cannot view the output on an oscilloscope without great
difficulty. It proved to be a much better measure of our achievements to
simply listen to the output on a pair of the PC speakers in the lab.
The last task was to translate and troubleshoot the MATLAB code
into C friendly code. While most of the algorithm remained the same, a
couple key points had to be modified. First, since the algorithm now
occurred in real-time with the use of interrupts, the first "for loop" used
in the MATLAB code was stricken out (since it is inherent in the
interrupt style of programming). Also, because of the number
representation on the board, the math had to be modified. Keeping the
numbers in Q15 format was essential, and so the result of every operation
on a number had to be modified to accommodate the change. The most
important of which was when two numbers were multiplied, the result had to
be right shifted 15 spaces to ensure the fixed point representation was
kept.
Another key factor in the math was number representation. Since
the board uses a two's complement number to represent the signal sample,
some of the constants needed to be changed. Specifically, the value for
mu now needed to be greater than one (not less than), but still close to
one. From our experiments, we found that a value between 1 and 10 worked
best, and we choose to use 2 for our demonstrations because it kept the
output voice signal the most clear. The tradeoff was that the background
noise now had a bit of a more vibrant pinging to it.
Our results proved to be satisfactory. Although there are no
sound clips available, the demonstration at the poster session clearly
demonstrated the capability of the board to handle simple reference
noises. The board adaptively filtered sinusoids and triangle waves very
well. It worked okay on square waves, but not quite as nicely. On white
noise, however, the filter wasn't very good. We attributed this to the
fact that our two white noise signals (overlay and reference) were
generated on two separate PC sound cards, and, due to the randomness
factor, were not very well correlated.