Lab 5: Rate Conversion

Winter 2012
Prof. Teresa Meng
Instructions, Notes


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