This is the documentation page for the standalone back end library of LTFAT the Matlab/Octave toolbox for working with time-frequency analysis and synthesis. It is intended both as an educational and a computational tool. The toolbox provides a large number of linear transforms including Gabor and wavelet transforms along with routines for constructing windows (filter prototypes) and routines for manipulating coefficients
The following modules are included in the libltfat repository and can be optionally compiled:
The function names are in the following format:
ltfat_<function_name>
[_<d|s|dc|sc>](<parameters>)
The ltfat_
prefix is present in all function names while the suffix is optional and identifies the data type the function is working with:
Suffix | Data type |
---|---|
d | double |
s | float |
dc | ltfat_complex_d |
sc | ltfat_complex_s |
float
or double
) will be referred to as LTFAT_REAL
and the complex data type (ltfat_complex_s
or ltfat_complex_d
) as LTFAT_COMPLEX
.LTFAT_TYPE
type will be used whenever there is a version of the function for each of the four aforementioned types.The source code of the library complies with both C99 and C++11 standards.
When compiled with C99 enabled, ltfat_complex_d
and ltfat_complex_s
are effectively the following typedefs:
Where complex
double
and complex
float
types are a C99 feature.
When compiled with C++11 enabled, the following typedefs are used:
The description can be found here std::complex.
Arrays of complex data types from both C99 and C++11 are binary compatible with simple arrays of basic types with the real and the imaginary parts interleaved in memory.
Therefore, in C99 it is legal to do the following casts
Similarly, in C++11 one can do
double*
(memory allocated as an array of double
) to complex
double*
or std::complex<double>*
might not work. See this stackoverflow question.The following table summarizes what type the ltfat_complex_d
expands to depending on the compiler
Single number | Array | Pointer | |
---|---|---|---|
C99 | complex double | complex double [] | complex double* |
C++11 | std::complex<double> | std::complex<double> [] | std::complex<double>* |
Compatibility (C++11 and LTFAT_CINTERFACE defined) | double [2] | double [][2] | double(*) [2] |
ltfat_complex_s
expands the same way.
The multidimensional arrays are contiguous in memory and therefore, they are reffered to by a single pointer and the individual dimensions are accessed trough an offset.
When an array represents a matrix, it is assumed that the columns are the first dimension and therefore they are stored continuously in memory.
In the function headers, the data arrays are denoted with array brackets [] and a pointer is used whenever referring to a single object. This distinction is just cosmetics as the arrays decay to pointers anyway.
Array sizes, indexes etc. are represented using ltfat_int , which is defined as:
Use ltfat_int_is_compatible() to test whether your signed integer type size is compatible with the one libltfat was compiled with. It is crucial the sizes match whenever an array of integers is passed to a libltfat function.
Further, the following naming conventions are used consistently:
Arg. name | Definition |
---|---|
f | Time domain signal |
g,gd,gt | Window (filter), canonical dual window, canonical tight window |
c | Coefficients |
a | Integer. Time hop size. |
M | Integer. Number of frequency channels (FFT length). |
M2 | Integer. Number of unique frequency channels for real signals: M2=M/2+1. |
L | Integer. Length of the signal. |
N | Integer. Number of time shifts: N=L/a. |
W | Integer. Number of signal channels. |
Every function which returns a status code should be checked by the user. Additionally, the error message is printed to the standard error stream. This behavior can be turned off or a custom error handler can be registered. For details see Error handling
When repeated computations with the same settings are desired, it is convenient to create a plan using the appropriate *_init function, call the *_execute function multiple times and destroy the plan by calling the *_done function. The plan usually contains some precomputed read-only data, working arrays and other plans. The plan is represented as a pointer to an opaque structure and here is an example how to use it:
A state is a plan which additionally holds some data which persists between the execute calls.