CASPT Quick Start Guide
CASPT Naming Conventions
The CLanguage Adaptive Signal Processing Toolbox (CASPT) defines each of its filters as
a Clanguage structure. The library provides APIs to easily and efficiently work with each filter
without the need to know details of the filter internal data structures. CASPT provides several
implementations for each filter in the different supported data types. For instance, a single precision and double
precision floating point LMS adaptive filters can be used simultaneously in the same application
by using an asptLms32f and an asptLms64f filters. Other applications might use 16bit and 32bit
signed integer NLMS filters by declaring an asptNlms16s and asptNlms32s variables. The naming
convention should be clear by now, CASPT filter names consist of three sections. The first is
the aspt prefix, the second is the algorithm name with the first letter in Capital, and the
third is the data type used in the calculations. The data type part can be one of the following,
64f (64bit float), 32f (32bit float), 32s (32bit signed integer), or 16s (16bit signed integers).
Note that the current release implements the 64f and 32f versions only.
CASPT defines several API functions for each filter, the most important ones are those performing
initialization and filtering/update functions. The APIs are consistent throughout the whole library,
which makes it very easy to learn how to use it. For instance, if you know how to use one filter, you
will probably be able to use any other filter as easily, since the API functions are almost
the same for all the filters (within the range the filter algorithm itself allows). The naming conventions
of the API functions are also easy to understand, and you do not need to memorize the function names for
each filter. For instance, to initialize an NLMS filter of 10 adaptive coefficients and filter a signal
of L samples stored in the array x[] through the filter while updating the coefficients so that the
filter output approaches the signal d[], you would use the following code fragment (assuming using
single precision floating point).
#include "aspt32f.h" /* All aspt declarations */
asptNlms32f nlms; /* declare a static NLMS structure */
/* initialize nlms to be 10 coef. and use 0.01 step size */
nlms32fInit(&nlms,10, 0.01f);
for(i=0;i<L;i++) /* filter and update the coefficients */
nlms32fFilterUpdate(&nlms, x[i], d[i]);

From this example, you can guess the CASPT API naming conventions. Each API name consists
of three parts. The first indicates the algorithm used (for example nlms or bfdaf), the second
indicates the data type, and the third indicates the function performed by the API with the
first letter in Capital. As another
simple example, suppose we would like to replace the above NLMS by a simpler (in terms of
computation complexity) LMS filter. This is easily done by just replacing each occurrence of
nlms in the above code by lms as following.
#include "aspt32f.h" /* All aspt declarations */
asptLms32f lms; /* declare a static NLMS structure */
/* initialize nlms to be 10 coef. and use 0.01 step size */
lms32fInit(&lms,10, 0.01f);
for (i=0;i<L;i++) /* filter and update the coefficients */
lms32fFilterUpdate(&lms, x[i], d[i]);

The above example is very simplistic, since the API parameters of the LMS matches those
of the NLMS filter, but the example clearly shows the naming convention, which is essential
to using ASPT.
Back To Top
CASPT API Summary
Several API functions are defined for each CASPT filter. The main API functions are more or less
identical across all filters, although more complex filter algorithms define more APIs, and less
complex ones define less APIs. The table below summarizes the API functions common to most filters
and explain their purpose. The single precision floating point NLMS filter is used here as an
example. The input parameters and return values have been omitted in the table for clarity. APIs
implemented as macros are indicated by [MACRO] sign.
API  Description 
API to create and delete an asptNlms32f filters 
nlms32fInit()  Initializes an asptNlms32f filter using the input parameters and dynamically allocates the memory storage required for the filter coefficients, delay line, and other necessary storage. 
nlms32fInitStatic()  Initializes an asptNlms32f but does no memory allocation. Pointers to a two preallocated (possibly static) memory location are passed to this function, one to be used for filter coefficients and the other for data storage. This separation makes ASPT ready for porting to platforms with several memory buses (DSPs). 
nlms32fFree()  This function is used to free the memory previously allocated by nlms32fInit(). No similar function is needed for nlms32fInitStatic() since it does not allocate any memory, it uses the given preallocated (or static) memory. 
API to filter through and update an asptNlms32f filters 
nlms32fFilterUpdate()  Filters one sample through this filter (FIR mode) and updates the filter coefficients according to the NLMS algorithm. 
nlms32fFilterOnly()  Filters one sample through this filter (FIR mode) but does not update the filter coefficients. It also updates the internal filter states to quickly converge when updating starts again. This function is required by many ITUT standards, such as the G.165 and G.168 echo cancellers. 
nlms32fLCFilterUpdate()  Filters one sample through this filter (Linear Combiner mode) and updates the filter coefficients according to the NLMS algorithm. The linear combiner mode allows many input signals to be processed in parallel, which is necessary for array processing for instance. 
nlms32fLCFilterOnly()  Filters one sample through this filter (Linear Combiner mode) but does not update the filter coefficients. It also updates the internal filter states to quickly converge when updating starts again. 
API to retrieve the properties of an asptNlms32f filter 
nlms32fGetCoef()  Copies N internal filter coefficients starting from coefficient number I to a given buffer, optionally inverting the coefficient order while copying. 
nlms32fGetDelayLine()  Copies N samples from the filter internal delay line starting from coefficient number I to a given buffer, optionally inverting the samples order while copying. 
nlms32fGetCoefPtr()  [MACRO] Returns a pointer to the filter coefficients vector. 
nlms32fGetFilterLength()  [MACRO] Returns this filter's number of filter coefficients. 
nlms32fGetDelayLineLength()  [MACRO] Returns this filter's delay line length. Delay line length is not necessary equals to the filter length. 
nlms32fGetLastErrorSample()  [MACRO] FilterUpdate functions store the error sample in an internal variable that can be retrieved by calling this macro. 
nlms32fGetStepSize()  [MACRO] Returns this filter's convergence constant (step size). 
API to set the properties of an asptNlms32f filter 
nlms32fReset()  Resets all filter coefficients of this filter to zeros. This function is necessary for many ITUT standards such as G165 and G168 echo cancellers. It is an external reset button for the filter. 
nlms32fResetDelayLine()  Resets all samples in this filter's delay line to zeros. 
nlms32fResize()  Changes the filter size (number of coefficients) onthefly while keeping as much of the filter state as possible, so that no interruption of the filter output occur for samples processed after resizing. This function can be used with dynamically allocated filters only. 
nlms32fSetCoef()  Sets N of this filter's coefficients starting from coefficient number I to the contents of the given buffer, optionally reversing the order of the buffer contents while copying. 
nlms32fSetDelayLine()  Sets N of this filter's delay line samples starting from sample number I to the contents of the given buffer, optionally reversing the order of the buffer contents while copying. 
nlms32fSetStepSize()  [MACRO] Changes this filter's step size to the new given value. 

Back To Top
A Complete Example
In this section the complete source code for a practical system identification application
using the Block Frequency Domain Adaptive Filter (BFDAF) is given. The BFDAF filter is a very
efficient and fast converging filter, which makes it very attractive for demanding realtime
adaptive applications, and also makes the example more interesting. This example demonstrate how
CASPT functions are used in block processing mode, and shows how little code is needed
to create and successfully employ such a complex filter in an practical application. The code assumes
that an experiment has already been performed to collect the required data for the system
identification process (obtaining a model for a physical system). The experiment is simply
feeding the physical system to be modeled by an input signal and recording both the input and
the system response (its output). The measured input signal is used as input to the adaptive
filter and the system output is used as a desired signal as shown in the figure below. The
code assumes that 5000 samples have been collected, the input samples are to be placed in
the inpBuf[] array and the system output (adaptive model desired signal) is to be placed in
the desBuf[]. The adaptive system identification process then tries to adjust the filter
coefficients so that the filter output becomes as close as possible to the measured physical
system response. If this is successful, the adaptive filters coefficients will be close to
the physical system impulse response.
The application first declares an asptBfdaf32f filter and initializes it using
bfdaf32fInit() to have 10 time domain coefficients (we expect the physical system
response to be approximately 10 samples long), and the filter will process 6 samples each
call to bfdaf32fFilterUpdate(). In this example, constrained BFDAF filter is used
with a step size of 0.05. Note that the pointers to the tables required for the Fast Fourier
Transform (FFT) are also passed to bfdaf32fInit(). Those tables can be created
in a header file (in this case rfft16.h) by the mktable tool provided with
CASPT. The application also checks that the filter has been created successfully by looking
whether the init function returned an integer less than zero, which indicates an error.
Following initialization, the processing loop is started, in each iteration, 6 samples of
the input and desired are processed by bfdaf32fFilterUpdate() to calculate 6 samples
of the model output and update the frequency domain filter coefficients. After processing all
samples, the model coefficients should be a good estimate of the physical system transfer
function (assuming the process has converged). The timedomain filter coefficients are then
copied to the sys[] buffer to be used, for example, in designing a controller for this
physical system.
#include "asptbfdaf32f.h" /* defines the BFDAF filter and its APIs */
#include "rfft16.h" /* defines bit reversal and twiddle factor
tables for 16point real FFT */
#define NSAMPLES 5000
int main(int argc, char* argv[])
{
int i;
asptBfdaf32f bfdaf ; /* adaptive filter */
int NC = 10; /* filter length */
int NL = 6; /* block length */
int cs = 1; /* use constrained BFDAF */
float mu = 0.05f; /* step size */
int *ip = ip16; /* FFT twiddle factor table */
float *w = w16; /* bit reversal table */
float sys[10]; /* unknown system coefficients */
float inpBuf[NSAMPLES]; /* measured system input signal */
float desBuf[NSAMPLES]; /* measured system output signal */
float errBuf[NSAMPLES]; /* estimation error */
float outBuf[NSAMPLES]; /* filter output */
/* Copy here the measured system input to inpBuf */
/* Copy here the measured system output to outBuf */
/* Initialize the asptBfdaf filter */
i = bfdaf32fInit(&bfdaf,NC,NL,mu,cs, ip,w);
if (i < 0){
printf("Error creating asptBfdaf filter\n");
exit(1);
}
for (i=0; i < (NSAMPLESNl);i+=Nl) {
/* filter and update the filter coefficients */
bfdaf32fFilterUpdate(&bfdaf, inpBuf[i], desBuf[i], outBuf[i],errBuf[i]);
}
/* coefficients of bfdaf are now equal to the system transfer function
copy NL coefficients starting at index 0 to external buffer. */
bfdaf32fGetCoef(&bfdaf, sys, 0, NL, 0);
bfdaf32fFree(&bfdaf);
return 0;
}

Back To Top
