world leader in high performance signal processing
Trace: » libbfdsp

Blackfin DSP library (-lbfdsp)

The DSP library in uClinux-dist/lib/libbfdsp is ported from VisualDSP++ Dec 2005 update.

As quoted from VisualDSP++ DSP library manual: “The DSP run-time library which contains a broad collection of functions that are commonly required by signal processing applications. The services provided by the DSP run-time library include support for general-purpose signal processing such as companders, filters, and Fast Fourier Transform (FFT) functions. All these services are Analog Devices extensions to ANSI standard C. ”

Difference from the original library:

  • Renamed from libdsp (-ldsp) to libbfdsp (-lbfdsp).
  • math.h is renamed to math_bf.h -- The original library contains math function overlapping with uClibc math library. To avoid confusion, these functions are removed.
  • Please use uClibc math library. Also please include -lm in the linking step, since libbfdsp depends on this library.
  • C++ not tested yet.

The DSP library is documented at C/C++ Compiler and Library Manual for Blackfin Processors in chapter 4, DSP Run Time Library and includes various functions:

Complex Functions

Description Prototype
Complex Absolute Value double cabs (complex_double a)
float cabsf (complex_float a)
long double cabsd (complex_long_double a)
fract16 cabs_fr16 (complex_fract16 a)
Complex Addition complex_double cadd (complex_double a, complex_double b)
complex_float caddf (complex_float a, complex_float b)
complex_long_double caddd (complex_long_double a, complex_long_double b)
complex_fract16 cadd_fr16 (complex_fract16 a, complex_fract16 b)
Complex Subtraction complex_double csub (complex_double a, complex_double b)
complex_float csubf (complex_float a, complex_float b)
complex_long_double csubd (complex_long_double a, complex_long_double b)
complex_fract16 csub_fr16 (complex_fract16 a, complex_fract16 b)
Complex Multiply complex_double cmlt (complex_double a, complex_double b)
complex_float cmltf (complex_float a, complex_float b)
complex_long_double cmltd (complex_long_double a, complex_long_double b)
complex_fract16 cmlt_fr16 (complex_fract16 a, complex_fract16 b)
Complex Division complex_double cdiv (complex_double a, complex_double b)
complex_float cdivf (complex_float a, complex_float b)
complex_long_double cdivd (complex_long_double a, complex_long_double b)
complex_fract16 cdiv_fr16 (complex_fract16 a, complex_fract16 b)
Get Phase of a Complex Number double arg (complex_double a)
float argf (complex_float a)
long double argd (complex_long_double a)
fract16 arg_fr16 (complex_fract16 a)
Complex Conjugate complex_double conj (complex_double a)
complex_float conjf (complex_float a)
complex_long_double conjd (complex_long_double a)
complex_fract16 conj_fr16 (complex_fract16 a)
Convert Cartesian to Polar Coordinates double cartesian (complex_double a, double* phase)
float cartesianf (complex_float a, float* phase)
long double cartesiand (complex_long_double a, long_double* phase)
fract16 cartesian_fr16 (complex_fract16 a, fract16* phase)
Convert Polar to Cartesian Coordinates complex_double polar (double mag, double phase)
complex_float polarf (float mag, float phase)
complex_long_double polard (long double mag, long double phase)
complex_fract16 polar_fr16 (fract16 mag, fract16 phase)
Complex Exponential complex_double cexp (double a)
complex_long_double cexpd (long double a)
complex_float cexpf (float a)
Normalization complex_double norm (complex_double a)
complex_long_double normd (complex_long_double a)
complex_float normf (complex_float a)

Filters

Description Prototype
Finite Impulse Response Filter void fir_fr16 (const fract16 input[], fract16 output[], int length, fir_state_fr16 *filter_state)
Infinite Impulse Response Filter void iir_fr16 (const fract16 input[], fract16 output[], int length, iir_state_fr16 *filter_state)
Direct Form I Infinite Response Filter void iirdf1_fr16 (const fract16 input[], fract16 output[], int length, iirdf1_fr16_state *filter_state)
FIR Decimation Filter void fir_decima_fr16 (const fract16 input[], fract16 output[], int length, fir_state_fr16 *filter_state)
FIR Interpolation Filter void fir_interp_fr16 (const fract16 input[], fract16 output[], int length, fir_state_fr16 *filter_state)
Complex Finite Impulse Response Filter void cfir_fr16 (const complex_fract16 input[], complex_fract16 output[], int length, cfir_state_fr16 *filter_state)
Convert Coefficients for DF1 IIR void coeff_iirdf1_fr16 (const float acoeff[], const float bcoeff[ ], fract16 coeff[], int nstages)

Transformational Functions

Various forms of the FFT function are provided by the library corresponding to radix-2, radix-4, and two-dimensional FFTs. The number of points is provided as an argument. The header file also defines a complex FFT function that has been implemented using an optimized radix-4 algorithm. However, this function, cfftf_fr16, has certain requirements that may not be appropriate for some applications. The twiddle table for the FFT functions is supplied as a separate argument and is normally calculated once during program initialization.

Library functions are provided to initialize a twiddle table. A table can accommodate several FFTs of different sizes by allocating the table at maximum size, and then using the stride argument of the FFT function to specify the step size through the table. If the stride argument is set to 1, the FFT function uses all the table; if the FFT uses only half the number of points of the largest, the stride is 2.

Description Prototype
Fast Fourier Transforms
Generate FFT Twiddle Factors void twidfft_fr16 (complex_fract16 twiddle_table[], int fft_size)
Generate FFT Twiddle Factors for Radix-2 FFT void twidfftrad2_fr16 (complex_fract16 twiddle_table[], int fft_size)
Generate FFT Twiddle Factors for Radix-4 FFT void twidfftrad4_fr16 (complex_fract16 twiddle_table[], int fft_size)
Generate FFT Twiddle Factors for 2-D FFT void twidfft2d_fr16 (complex_fract16 twiddle_table[], int fft_size)
Generate FFT Twiddle Factors for Optimized FFT void twidfftf_fr16 (complex_fract16 twiddle_table[], int fft_size)
N Point Radix-2 Complex Input FFT void cfft_fr16 (const complex_fract16 *input, complex fract16 *temp, complex_fract16 *output, const complex_fract16 *twiddle_table, int twiddle_stride, nt fft_size, const complex_fract16 *twiddle_table, int twiddle_stride, int fft_size, int block_exponent, int scale_method)
N Point Radix-2 Real Input FFT void rfft_fr16 (const fract16 *input, complex_fract16 *temp, complex_fract16 *output, const complex_fract16 *twiddle_table, int twiddle_stride, int fft_size, int block_exponent, int scale_method)
N Point Radix-2 Inverse FFT void ifft_fr16 (const complex_fract16 *input, complex_fract16 *temp, complex_fract16 *output, const complex_fract16 *twiddle_table, int twiddle_stride, int fft_size, int block_exponent, int scale_method)
N Point Radix-4 Complex Input FFT void cfftrad4_fr16 (const complex_fract16 *input, complex fract16 *temp, complex_fract16 *output, const complex_fract16 *twiddle_table, int twiddle_stride, int fft_size, int block_exponent, int scale_method)
N Point Radix-4 Real Input FFT void rfftrad4_fr16 (const fract16 *input, complex_fract16 *temp, complex_fract16 *output, const complex_fract16 *twiddle_table, int twiddle_stride, int fft_size, int block_exponent, int scale_method)
N Point Radix-4 Inverse Input FFT void ifftrad4_fr16 (const complex_fract *input, complex_fract16 *temp, complex_fract16 *output, const complex_fract16 *twiddle_table, int twiddle_stride, int fft_size, int block_exponent, int scale_method)
Fast N point Radix-4 Complex Input FFT void cfftf_fr16 (const complex_fract16 *input, complex_fract16 *output, const complex_fract16 *twiddle_table, int twiddle_stride, int fft_size)
Nxn Point 2-D Complex Input FFT void cfft2d_fr16 (const complex_fract16 *input, complex fract16 *temp, complex_fract16 *output, const complex_fract16 *twiddle_table, int twiddle_stride, int fft_size, int block_exponent, int scale_method)
Nxn Point 2-D Real Input FFT void rfft2d_fr16 (const fract16 *input, complex_fract16 *temp, complex_fract16 *output, const complex_fract16 *twiddle_table, int twiddle_stride, int fft_size, int block_exponent, int scale_method)
Nxn Point 2-D Inverse FFT void ifft2d_fr16 (const complex_fract16 *input, complex_fract16 *temp, complex_fract16 *output, const complex_fract16 *twiddle_table, int twiddle_stride, int fft_size, int block_exponent, int scale_method)
Convolutions
Convolution void convolve_fr16 (const fract16 input_x[], int length_x, const fract16 input_y[], int length_y, fract16 output[])
2-D Convolution void conv2d_fr16 (const fract16 *input_x, int rows_x, int columns_x, const fract16 *input_y, int rows_y, int columns_y, fract16 *output)
2-D Convolution 3×3 Matrix void conv2d3x3_fr16 (const fract16 *input_x, int rows_x, int columns_x, const fract16 input_y [3] [3], fract16 *output)
Compression/Expansion
A-law compression void a_compress (const short input[], short output[], int length)
A-law expansion void a_expand (const short input[], short output[], int length)
μ-law compression void mu_compress (const short input[], short output[], int length)
μ-law expansion void mu_expand (const char input[], short output[], int length)

What is 1.15 format, and why does 1 * 8 = 0 ???

The blackfin DSP library represents data primarily in a 1.15 format. This requires a little bit of getting used to, but once the concept is understood it is straightforward. Basically it means that data is represented as a fractional number between -1 and 1. So what does the following code really mean?

complex_fract16 a,b,prod;
a.re = 1;
a.im = 0;
b.re = 8;
r.im = 0;
prod = cmult_fract16(a,b)
// prod.re and prod.im will both equal zero.  For why this is so, keep reading

Since complex_fract16 is signed and 16 bits for the real and imaginary, this really means that a.re = 1/32767 = .000030519 and b.re = 8/32767. Now what if we were to multiply these two numbers together? Basically, you would get (1 * 8)/(32768 * 32768) which is a number much smaller than the smallest represtentable number(.000030519), and so the answer is zero.

In a similiar vein, what is 32768 * 32768? Normally you would think that multiplying these two numbers and storing it into another 16 bit number would overflow. Not so with fract16, since what you are really saying 1.0 * 1.0 = 1.0 = 32768