links and files
code composer studio
tms320c6713 dsk
The SpectrumDigital DSK technical reference.
AIC23 codec datasheet.
A PDF version of the BSL API reference. Note that it is slightly out of date since it references a different codec than the AIC23. I don't believe the updated BSL API reference has been released yet.
tms320c6000 assembly/c programming reference material
TMS320C6000 CPU Instruction Set and Reference Guide.
TMS320C6000 Programmer's Guide
TMS320C6000 Assembly Language Tools User's Guide. This reference includes details about the sections in the linker command file which are summarized below:
.text > IRAM /* Executable code */
.const > IRAM /* Initialized constants */
.bss > IRAM /* Global and static variables */
.data > IRAM /* Data declared in .asm code */
.cinit > IRAM /* Tables for initializing variables and constants */
.stack > IRAM /* Stack for local variables */
.far > IRAM /* Global and static variables declared far */
.sysmem > IRAM /* Heap and also used by malloc, etc. */
.cio > IRAM /* Buffers for C stdio library functions *//
.csldata > IRAM /* Chip support library? */
.switch > IRAM /* Tables for switch instructions */
.tables > IRAM /* ? */
Some useful information about C6000 memory models.
tms320c6713 dsp chip
The TI TMS320C6713 datasheet.
The PDF version of the CSL API reference. Again, sections may be out of date.
Some information about the IEEE floating point standard.
matlab
A handy Matlab cheatsheet covering most of the basic operations in Matlab.
A large number of Matlab tutorials and other information are indexed here.
If you have specific questions about Matlab or Matlab functions, try the Matlab help system.
how to record signals from the dsk directly into matlab
Matlab has some built-in recording capabilities that you can use to easily obtain signals for analysis without using an external sound recorder and saving things to a wav file. Here is one way to record a stereo signal at 44.1kHz with 16 bits per sample.
r = audiorecorder(44100,16,2);
record(r); % start recording
pause(10); % pause for 10 seconds
stop(r); % stop recording
y = getaudiodata(r); % extract the audio data
max(abs(y)) % make sure no clipping
You will get better recordings by using the line-in jack on the computer, not the microphone jack. The last line of this code will show you the largest sample recorded on the left and right channels. Full scale is -1 to +1. If max(abs(y)) = 1 in either channel, you are saturating the input of the sound card and you should lower the recording volume (in the Windows sound control panel). If you are getting small numbers here (much smaller than one), you should increase the recording volume in Windows to use at least 50% of the full scale (80-90% is better).
As a final note, you may want to poke around in the Windows control panel to make sure that there are no weird sound properties turned on like "reverberation" or anything else that will distort your recordings. The goal here is to just get a clean recording at something close to the full scale of the sound card input without any additional processing by the sound card or Windows.
white noise links
The following web sites offer white noise generators. You should test these to ensure they have a flat spectrum before using them to test your filters.
Whitenoise.fm. This site requires Flash.
Burn-in Wave. This site has lots of test signals for headphone burn-in (if you believe in that sort of thing) including white noise. No plugins required.
how to plot the magnitude response of your filter using white noise
Here is a quick outline of how to plot the magnitude response of your filter using white noise and Matlab. The approach described below is to save your recording to a separate wav file before processing in Matlab. As discussed above, you can modify this procedure by recording the signal directly in Matlab if you prefer.
Step 1: In Matlab, generate some white noise. One way to do this is
fs = 44100; % sampling frequency
T = 10; % duration
x = randn(fs*T,2); % stereo white noise
x = 0.99*x/max(max(abs(x))); % normalize
sound(x,fs); % play sound
Step 2: Make sure you have a clean playback/recording loop and that your volume levels are set correctly. Connect your line out (or headphone out) jack directly to your line in (or mic in) jack. Begin recording in, for example, Goldwave, and then run your Matlab script to play the white noise. You should not see any clipping during this test.
Step 3: Get ready to test your filter. Connect your line out (or headphone out) jack to the line in jack of the DSK. Connect your DSK's line out jack to the line in (or mic in) jack of your computer. Go into CCS and load your filter program to the DSK. Run it.
Step 4: Test your filter. While the DSK is running your filter code, start recording in Goldwave. Play the white noise signal from Matlab until it finishes. Make sure there was no clipping in the recorded signal. Trim off the ends of the recording to remove the transients and background system noise. Save the recording as a .wav file.
Step 5: In Matlab, analyze the recording. One way to do this is
[y,fs] = wavread('fname.wav'); % read your recording
[Py1,f] = pwelch(y(:,1),1024,512,1024,fs); % estimate psd of left channel
[Py2,f] = pwelch(y(:,2),1024,512,1024,fs); % estimate psd of right channel
plot(f/1e3,10*log10(Py1),f/1e3,10*log10(Py2)); % plot psd in dB
grid on
xlabel('frequency (kHz)');
ylabel('magnitude response (dB)');
Step 6: Compare your results to your theoretical predictions. Note that you may need to apply overall scaling to the PSD but you should otherwise have good agreement between the theory and the actual filter realization.
Can you explain how this technique works?
how to interpret the df-ii second order sections header file generated by matlab
The C header files generated by Matlab for IIR filters with the DF-II SOS realization structure can be a bit cryptic. Here is how to interpret those header files.
When you open your C header file, you will see that there are two two-dimensional arrays, one for the numerator coefficients in each SOS and the other for the denominator coefficients in each SOS. Here is what the coefficient arrays might look like:
const int NL[MWSPT_NSEC] = { 1,3,1,3,1,3,1 };
const real32_T NUM[MWSPT_NSEC][3] = {
{
0.2557556629, 0, 0
},
{
1, 2, 1
},
{
0.191392228, 0, 0
},
{
1, 2, 1
},
{
0.1671115905, 0, 0
},
{
1, 2, 1
},
{
1, 0, 0
}
};
const int DL[MWSPT_NSEC] = { 1,3,1,3,1,3,1 };
const real32_T DEN[MWSPT_NSEC][3] = {
{
1, 0, 0
},
{
1, -0.5886620283, 0.6116847396
},
{
1, 0, 0
},
{
1, -0.4405193925, 0.2060882896
},
{
1, 0, 0
},
{
1, -0.3846336901, 0.05308004469
},
{
1, 0, 0
}
};
Each row contains 3 coefficients. The numerator (NUM) coefficients in each row, from left to right, are b[0], b[1], and b[2], in our class notation. By the same token, the denominator (DEN) coefficients in each row are a[0], a[1], and a[2]. Note that a[0] is always equal to 1 and that we don't use it in our calculations (refer to the input/output equation given in lecture and in your textbook). The rows are processed from top to bottom. Denoting the first row of each array as "row 0", here is how it works.
Notice that the second and third coefficients in each of the even numbered (0,2,4,...) rows are always equal to zero. If you were to actually do all of the SOS computations here, you would see that these rows only apply a gain to the current input. For example, the effect of row 0 in this case is to multiply the current input sample by the gain of 0.255755629. That is all this row does. The same idea applies for rows 2, 4, and 6 (note that row 6 is just a gain of 1, which does nothing). These gains are part of the realization structure (see Matlab's help) and it is important that you implement them correctly to get the correct overall gain for your IIR filter.
Notice that the odd numbered rows (1,3,5,...) usually have non-zero numbers in all three coefficients. In this case, we have three such rows, which agrees with fdatool's design generating three second order sections (for this example). You have to do all of the SOS calculations for these rows. Just follow the procedure discussed in class: (i) compute u[n] using the denominator coefficients (and your scaled x[n] from the prior row) and then (ii) compute y[n] using the numerator coefficients. Since you know that you always have 3 coefficients in this case, you should be able to write one SOS function that does this efficiently.
Here also is a pictoral example of how to interpret Matlab's DF-II SOS header files.