Lab 5: Rate Conversion
I. Introduction
Interpolation and decimation have
many applications in both image/video processing and data communication. For
example, if you want to display a PC monitor on a TV, you need a
"rate-converter" box, as the resolution of the PC monitor is different
from that of the US
broadcast TV (the NTSC standard). Interpolation and decimation are also very
useful for ADC and DAC, as explained in the lecture. Have you heard the
advertisement "8x oversampling" when you wanted to buy a
high-performance CD player? The CD player is nothing more than a high-grade DAC
using an up-sampling technique. In this lab, you will code a fractional rate
converter.
II. Purpose:
In this lab, we will look at some
of the applications of up-sampling and down-sampling for rate conversion. You
will use the DSP processor to do rate conversion of recorded audio. You will
then playback the rate converted output to hear what it sounds like. The reason
you cannot do the rate conversion in real-time is due to the hardware. The sampling
rates of the ADC and DAC in the AIC are coupled.
III. Readings:
- TMS320C55x
Assembly Language Tools User's Guide
Section 8.6 Linker Command Files
- TMS320C55x
DSP Programmer's Guide
Section 3.5.4 Allocating Code and
Data in the C55x Memory Map
- A TLV 320AIC23B Data Manual
Section 3.1.3 Register Map
Section 3.3.2 Audio Sampling
Rate
- TMS320VC5509A
DSK Technical Reference
Page 1-5, Figure 1-2, "Memory
Map. VC5509A DSK
Page 2-7, 2.2 AIC23 Codec
Pay special attention to the memory section 0x10_0000-0x1F_FFFF in data address
space. You will need to use this area to store audio data.
IV. Lab exercises:
You will write a rate conversion
code to down convert the recorded audio by 2/3. You may choose to simulate your
algorithm in Matlab first. It is recommended but not
required for grading. What you are graded on is the implementation of the rate
converter on the C55x DSP. The DSP library may reduce the amount of coding
effort, or it may not. It is your choice to use it.
This lab will be graded primarily on the performance of
your code. This is measured in terms of the processing cycle time and in terms
of playback quality.
A. Rate Converter Specifications
The specifications are defined to
make coding as easy as possible. There are a number of optional things also
discussed here that will make the rate converter more complete and will also
enhance the performance and the quality of the rate converter. In the interest
of time, we ask that you finish the basic rate converter before looking to
enhance it. But do go through the enhancements as they may give you ideas on
how you can improve your rate-converter performance.
- You are to convert, in real-time, an audio signal, sampled at 48 KHz, to an audio signal sampled at 32 KHz. In other words, you will be
designing a 2/3 rate converter.
- You are to store the rate
converted audio in data memory starting from 0x10_0000
until it is full, 0x1F_FFFF. This
corresponds to 16 seconds of playback
audio (32 KHz stereo) and 12 seconds of recorded audio (48 KHz stereo). (Note: address range 0x10_0000 to 0x1F_FFFF are SDRAM in C5509DSK,
and be sure not to use this area for other purpose.)
- The rate
conversion is done one receive buffer
at a time. You should choose a frame size that makes your job easier to
code and/or improves performance. (see audio.h)
For example, if you use a frame of 128
samples, then 85 to 86 samples will be generated and stored
in the data memory specified above for each receive buffer. Keep in mind
that your input frame does not have to be 128
samples, nor does it have to be even.
- The recording will begin when
you start your program. The program will stop (i.e. go into an infinite
loop) when the data memory is filled.
- You will need to devise some
method by which to play back the rate converted audio. Here are two possibilities:
- DSP playback:
You can write a playback routine that plays audio from the data memory
where the rate converted output is stored. You should be able to run this
playback routine manually, after you
stop your recorder/rate-converter. For this, you may need to use a flag to indicate whether you are
recording/rate-converting or playing back (the value of this flag can be
changed in memory while the program is stopped). It is conceivable that
you can modify this program so that the playback occurs automatically,
after the rate conversion completes (you don't have to do this).
The nice thing about running the playback manually is that you can change the sampling rate of the playback.
Changing the sampling rate may not be easily done if you run the playback
automatically. You can change the sampling
rate of ADC/DAC by changing values of AIC23_Params structure in audio.c
- Matlab playback:
You can playback the rate-converted samples by first reading the samples
into Matlab. This can be done by
reading SDRAM data using CCS Data Save with integer format, removing the first line
of the data file, then reading it in MATLAB. Once you
have the samples in Matlab, you can play them
back using the sound function, or you can write them to a wave
file using wavwrite.
- Memory
addressing across 64k word page boundary is not allowed in normal C55x.
You can use special functions provided in record.c to read / write
the data to SDRAM over multiple pages. (This is a kind of trick, in which
slow external memory is accessed directly. So it might be somewhat slow.
However, unless you make your filtering very poor, the performance
degradation due to this addressing would not be critical. Accessing
multiple pages of slow external memory can be efficiently done by DMA data
transfer with double buffering)
- First,
define 3 functions
void initRecordBuffer(
unsigned long start_addr, unsigned long length
);
Int16 writeBuf(
Int16 *src, Int16 len
);
Int16 readBuf(
Int16 *dst, Int16 len
);
- initialize
buffer at the end of main, as follows
initRecordBuffer( 0x100000L, 0x100000L );
- use writeBuf
to store a block of audio data to SDRAM, and readBuf
to fetch a block of audio data from SDRAM. These functions return nonzero
value at the end of buffer.
- You don't have to
worry about initial conditions of the filter or initial output alignment
for the first buffer. Boundary padding and output aligning is more
critical in image processing applications. Besides, the artifacts
introduced by the initial conditions and boundary padding is indiscernible in audio since the duration of this
transient is on the order of milliseconds. However, for verification
purposes, it is simple enough to initialize your data buffers to 0 so that
this transient goes away.
- You will
design your own low-pass filter in Matlab. Keep in mind that the purpose of this filter
is to remove aliasing, so we want adequate attenuation in the stopband and a small transition bandwidth. We will
impose the following design constraints on your filter:
- Your filter
should use no more than 40 taps.
- The transition bandwidth of the filter should be
no more than 0.1*pi (We will define
the transition bandwidth as omega_s - omega_p in Figure
7.2b on page 441 of the Oppenheim & Schafer
text).
- The cutoff
frequency, omega_c = (omega_s + omega_p) / 2, should be no more than pi/3 to
remove aliasing.
For the filter design, you may find the following Matlab functions useful: filter,
fir1, kaiserord, kaiser, firls, remez, freqz, (and perhaps some others).
- Include
the following filter specs in your report: number of
taps, stopband attenuation, passband
ripple, omega_p, omega_s,
and the transition bandwidth. Also, submit a freqz
plot of your filter with your report.
- Performance
HINT:
The rule of thumb in coding is not to do anything redundant. If you are
going to throw away data, you may as well not process it in the first
place. Understand the following characteristics of reduced complexity for
up and down-sampling before you start your rate converter design:
- Up-sampling (zero padding +
low-pass filtering): The algorithm complexity is on the order of N operations per input sample.
- Down-sampling (low-pass
filtering + decimation): The algorithm complexity is on the order of N operations per output sample.
The above assumes that the filter
size is N taps and an operation
refers to a filter operation, i.e. a
multiply and an add would be considered as one
operation.
B. DSP code
Make sure you have gone through
the rate conversion algorithm before you start to implement. You should have an
idea of how to efficiently make use of the data memory as it is a scarce
resource. You should also focus on implementing the rate converter as a system
rather than focus on making the individual parts of the rate converter as
efficient as possible.
- You will implement the rate
converter on top of your audio recorder and playback. Copy the source code from your Lab 2 audio recorder to a new directory.
- Implement
the rate-converter according to the specifications in part A.
- You
have two choices: time-domain filtering (like Lab 3) or
frequency-domain filtering (like Lab 4). But, keep in mind that the filter
taps are limited to 40 taps.
- Do
the following experiments when you complete your code. You may choose
to use any audio samples for this experiment:
- Record at 48 KHz. Manually stop the program after you
think the rate converter completes, and playback the rate converted audio
without changing the sampling rate. Report what you hear. How is this
different than the original audio?
- Record at 48 KHz. Manually stop the
program after you think the rate converter completes, and playback the
rate converted audio at 32
KHz. Report what you hear.
How is this different from the original audio? Can you tell the
difference from the previous audio? (try this with different audio
sources, human voice, classic music, pop music, ...)
C. MATLAB Verification
You will be expected to write a script to verify your
code. Here are the requirements.
- You will need to verify that
your recorded output buffer is equivalent to the ideal rate-converted
output.
- This should be done after
running the algorithm for at least 8 input frames.
- The input signal will be the
concatenation of all input frames
- The output will be the
corresponding output samples recorded in the output buffer
- The ideal rate-converted
output should be computed in MATLAB as follows:
- Up-sample the input sequence
by a factor of two (zero-pad). Here is an example of how to do this
easily in MATLAB:
- x =
1:10;
% some arbitrary input
- x_up = zeros(1,
2*length(x)); %
initialize to zero
- x_up(1:2:end) =
x;
% set every other sample to the samples of x,
leaving the rest as 0's
- Filter the up-sampled
sequence (using the same coefficients as used in your DSP code)
- Use conv to
perform the filtering (as in previous labs)
- Down-sample the filtered
sequence by a factor three. Example:
- output_ideal = x_up_filtered(1:3:end); % take every third sample, starting from the first
and going until the end
- Your DSP code should produce
an output that is comparable to the ideal output (as computed by
MATLAB). Here are some things to look out for:
- You will probably have to
take scaling into account when comparing the DSP output to the ideal
output. The MATLAB code is sometimes much larger than the DSP
result--this is perfectly OK (why is this?).
- If you are careful about how
you perform the operations in MATLAB, you can get the
exact result that is produced by your DSP. In order for this to
happen, you will have to do a couple of things:
- Read all
operands (data and coefficients) from DSP memory, so that your MATLAB
script will operates on the exact same numbers
- Have your MATLAB
code account for the fact that the DSP algorithm typically takes the
high word of the accumulator as the result. This corresponds to
dividing by 2^16 (or 2^15 if fractional mode is used) followed by
truncation (since the result is a 16-bit integer).
- You may also need to make
sure that your MATLAB code is taking the same output samples as your DSP
code when down-sampling. For example, your MATLAB code may
down-sample by taking samples 0, 3, 6, etc., while your DSP code may
actually take samples 1, 4, 7, etc..
Either way is OK, but make sure that your MATLAB is doing what your DSP
is doing, otherwise it will be difficult to compare the two.
Last modified: 5:15 pm 2/23/2008