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.