Metadata-Version: 2.2
Name: liquid-dsp
Version: 1.8.0
Summary: software-defined radio digital signal processing library
Keywords: digital,signal,processing,DSP,software-defined radio,SDR
Author-Email: "Joseph D. Gaeddert" <joseph@liquidsdr.org>
License: Copyright (c) 2007 - 2016 Joseph Gaeddert
         
         Permission is hereby granted, free of charge, to any person obtaining a copy
         of this software and associated documentation files (the "Software"), to deal
         in the Software without restriction, including without limitation the rights
         to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         copies of the Software, and to permit persons to whom the Software is
         furnished to do so, subject to the following conditions:
         
         The above copyright notice and this permission notice shall be included in
         all copies or substantial portions of the Software.
         
         THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         THE SOFTWARE.
         
         
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Scientific/Engineering
Classifier: Programming Language :: C
Classifier: Programming Language :: C++
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: License :: OSI Approved :: MIT License
Project-URL: Homepage, https://liquidsdr.org
Project-URL: Documentation, https://liquidsdr.org/doc
Project-URL: Repository, https://github.com/jgaeddert/liquid-dsp
Project-URL: Issues, https://github.com/jgaeddert/liquid-dsp/issues
Project-URL: Changelog, https://github.com/jgaeddert/liquid-dsp/blob/master/CHANGELOG.md
Requires-Python: >=3.7
Description-Content-Type: text/x-rst


liquid-dsp documentation
========================

Software-Defined Radio Digital Signal Processing Library -
`https://liquidsdr.org <https://liquidsdr.org>`_

liquid-dsp is a free and open-source digital signal processing (DSP)
library designed specifically for software-defined radios on embedded
platforms. The aim is to provide a lightweight DSP library that does not
rely on a myriad of external dependencies or proprietary and otherwise
cumbersome frameworks. All signal processing elements are designed to be
flexible, scalable, and dynamic, including filters, filter design,
oscillators, modems, synchronizers, complex mathematical operations, and
much more.

.. code-block:: c

    // get in, process data, get out
    #include <liquid/liquid.h>
    int main() {
        unsigned int M  = 4;     // interpolation factor
        unsigned int m  = 12;    // filter delay [symbols]
        float        As = 60.0f; // filter stop-band attenuation [dB]

        // create interpolator from prototype
        firinterp_crcf interp = firinterp_crcf_create_kaiser(M,m,As);
        float complex x = 1.0f;  // input sample
        float complex y[M];      // interpolated output buffer

        // repeat on input sample data as needed
        {
            firinterp_crcf_execute(interp, x, y);
        }

        // destroy interpolator object
        firinterp_crcf_destroy(interp);
        return 0;
    }


For more information, please refer to the
`documentation <https://liquidsdr.org/doc>`_ online.

Installation and Dependencies
=============================

liquid-dsp only relies on ``libc`` and ``libm`` (standard C and math)
libraries to run; however liquid will take advantage of other libraries
(such as `FFTW <http://www.fftw.org>`_) if they are available.
Starting with version 1.7.0, liquid-dsp has moved to the
`CMake <https://cmake.org>`_ build system which can be installed with
``brew install cmake`` on macOS,
``sudo apt-get install cmake`` on Debian variants.

Installation
------------

The recommended way to obtain the source code is to clone the entire
`repository <https://github.com/jgaeddert/liquid-dsp>`_ from
`GitHub <https://github.com>`_:

.. code-block:: bash

    git clone git://github.com/jgaeddert/liquid-dsp.git

Building and installing the main library is a simple as

.. code-block:: bash

    mkdir build
    cd build
    cmake ..
    make
    sudo make install

If you are installing on Linux for the first time, you will also need
to rebind your dynamic libraries with ``sudo ldconfig`` to make the
shared object available.
This is not necessary on macOS.

Build Options
-------------

Here is a table of CMake options available for configuring liquid:

+------------------------+---------+--------------------------------------------------------------------+
| Option                 | Default | Description                                                        |
+========================+=========+====================================================================+
| ``BUILD_EXAMPLES``     | ON      | Compile example programs                                           |
+------------------------+---------+--------------------------------------------------------------------+
| ``BUILD_AUTOTESTS``    | ON      | Parse and compile autotests into executable binary                 |
+------------------------+---------+--------------------------------------------------------------------+
| ``BUILD_BENCHMARKS``   | ON      | Parse and compile benchmarks into executable binary                |
+------------------------+---------+--------------------------------------------------------------------+
| ``BUILD_SHARED_LIBS``  | ON      | Build shared library                                               |
+------------------------+---------+--------------------------------------------------------------------+
| ``BUILD_STATIC_LIBS``  | OFF     | Build static library                                               |
+------------------------+---------+--------------------------------------------------------------------+
| ``ENABLE_SIMD``        | ON      | Enable use of single instruction, multiple data (SIMD) extensions  |
+------------------------+---------+--------------------------------------------------------------------+
| ``FIND_SIMD``          | ON      | Try to find available SIMD instruction sets on host computer       |
+------------------------+---------+--------------------------------------------------------------------+
| ``FIND_THREADS``       | ON      | Try to find available threading library for concurrency            |
+------------------------+---------+--------------------------------------------------------------------+
| ``FIND_FFTW``          | ON      | Try to find `FFTW <http://www.fftw.org)>`_ if available            |
+------------------------+---------+--------------------------------------------------------------------+
| ``BUILD_SANDBOX``      | OFF     | Compile sandbox (testing) programs                                 |
+------------------------+---------+--------------------------------------------------------------------+
| ``BUILD_DOC``          | OFF     | Generate documentation                                             |
+------------------------+---------+--------------------------------------------------------------------+
| ``BUILD_PYTHON``       | OFF     | Set flags to enable building python bindings                       |
+------------------------+---------+--------------------------------------------------------------------+
| ``COVERAGE``           | OFF     | Set flags to enable code coverage testing                          |
+------------------------+---------+--------------------------------------------------------------------+
| ``ENABLE_LOGGING``     | ON      | Enable global logging capabilities                                 |
+------------------------+---------+--------------------------------------------------------------------+
| ``LOGGING_LEVEL``      | trace   | Set minimum logging level to compile;                              |
|                        |         | select from "trace", "debug", "info", "warn", "error", or "fatal"  |
+------------------------+---------+--------------------------------------------------------------------+
| ``ENABLE_COLOR``       | ON      | Enable use of color terminal output                                |
+------------------------+---------+--------------------------------------------------------------------+

For example, if you want to benchmark how fast a vector dot product
runs without SIMD extensions, you could run the following:

.. code-block:: bash

    cmake -DENABLE_SIMD=OFF -DBUILD_BENCHMARKS=ON ..
    make
    ./benchmark -s dotprod_rrrf


Running Autotests
-----------------

Source code validation is a critical step in any software library,
particularly for verifying the portability of code to different
processors and platforms. Packaged with liquid-dsp are a number of
automatic test scripts to validate the correctness of the source code.
The test scripts are located under each module's ``tests/`` directory and
take the form of a C source file. When configured with ``BUILD_AUTOTESTS``
enabled, these tests are parsed, compiled, and linked into an executable
which will run the tests.

.. code-block:: bash

    ./xautotest
    # ...
    # 13:31:14 [info ] =========== autotest summary ===========
    # 13:31:14 [info ] tests:
    # 13:31:14 [info ]   pass     : 1341
    # 13:31:14 [info ]   fail     : 0
    # 13:31:14 [info ]   skip     : 0
    # 13:31:14 [info ] checks:
    # 13:31:14 [info ]   pass     : 716520
    # 13:31:14 [info ]   fail     : 0
    # 13:31:14 [info ] overall:
    # 13:31:14 [info ]   warn     : 55
    # 13:31:14 [info ]   PASS

There are currently more than 700,000 checks across 1,316 tests to verify
functional correctness. Drop me a line if these aren't running on your platform.

Testing Code Coverage
---------------------

In addition to the full test suite, you can configure ``gcc`` to export symbol
files to check for code coverage and then use ``gcovr`` to generate a full
report of precisely which lines are covered in the autotests. These symbol
files aren't generated by default and need to be enabled at compile-time
through a CMake option:

.. code-block:: bash

    cmake -DBUILD_AUTOTESTS=ON -DCOVERAGE=ON ..

A coverage report can be generated by running the autotests and running
`gcovr <https://gcovr.com/en/stable/>`_:

.. code-block:: bash

    make -j4 xautotest
    ./xautotest -q -o autotest.json
    cd ..
    gcovr --filter="src/.*/src/.*.c" --print-summary
    # ...
    # ------------------------------------------------------------------------------
    # TOTAL                                      20922   17396    83%
    # ------------------------------------------------------------------------------
    # lines: 83.1% (17396 out of 20922)
    # functions: 63.9% (1787 out of 2798)
    # branches: 64.8% (5762 out of 8896)

Running Example Programs
------------------------

Nearly all signal processing elements have a corresponding example in
the ``examples/`` directory.  Most example scripts generate an output
``.m`` file for plotting with `GNU octave <https://www.gnu.org/software/octave/>`_
All examples are built as stand-alone programs and can be compiled with
the ``BUILD_EXAMPLES`` CMake flag:

.. code-block:: bash

    cmake -DBUILD_EXAMPLES=ON ..
    make
    ./examples/modem_example -m qpsk
    # <liquid.modemcf, scheme="qpsk", order=4>
    #    0 :   0.70710677 + j*  0.70710677
    #    1 :  -0.70710677 + j*  0.70710677
    #    2 :   0.70710677 + j* -0.70710677
    #    3 :  -0.70710677 + j* -0.70710677
    # num sym errors:    0 /    4
    # num bit errors:    0 /    8
    # results written to modem_example.m.


Benchmarking Tool
-----------------

Packaged with liquid are benchmarks to determine the speed each signal
processing element can run on your machine. Initially the tool provides
an estimate of the processor's clock frequency and will then estimate
the number of trials so that each benchmark will take between 50 and
500 ms to run. You can build and run the benchmark program with the
following command:

.. code-block:: bash

    make bench


Linking from C++
----------------

Compiling and linking to C++ programs is straightforward.
Just include ``<complex>`` before ``<liquid/liquid.h>`` and use
``std::complex<float>`` in favor of ``float complex``.
Here is the same example as the one above but in C++ instead of C:

.. code-block:: c++

    // get in, process data, get out
    #include <complex>
    #include <liquid/liquid.h>
    int main() {
        unsigned int M  = 4;     // interpolation factor
        unsigned int m  = 12;    // filter delay [symbols]
        float        As = 60.0f; // filter stop-band attenuation [dB]

        // create interpolator from prototype
        firinterp_crcf interp = firinterp_crcf_create_kaiser(M,m,As);
        std::complex<float> x = 1.0f;   // input sample
        std::complex<float> y[M];       // interpolated output buffer

        // repeat on input sample data as needed
        {
            firinterp_crcf_execute(interp, x, y);
        }

        // destroy interpolator object
        firinterp_crcf_destroy(interp);
        return 0;
    }

Linking from External Project
-----------------------------

Installing with `CMake <https://cmake.org>`_ provides an
`exportable interface <https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html>`_
(``liquid::liquid``) that allows easy integration into external applications.
For example, say you have a simple application in ``main.c`` that requires
liquid-dsp as a dependency:

.. code-block:: c

    // main.c - test linking to liquid
    #include <stdio.h>
    #include <stdlib.h>
    #include <liquid/liquid.h>

    int main()
    {
        // create resampling object, print and return
        printf("creating test object...\n");
        resamp_crcf q = resamp_crcf_create(0.12345f, 12, 0.25f, 60.0f, 256);
        resamp_crcf_print(q);
        resamp_crcf_destroy(q);
        return 0;
    }

You now have two options within your project ``CMakeLists.txt`` file:

1. clone, build, and install using CMake, then use
   `find_package <https://cmake.org/cmake/help/latest/command/find_package.html>`_
2. dynamically fetch liquid-dsp with
   `FetchContent <https://cmake.org/cmake/help/latest/module/FetchContent.html>`_
   to pull down the source and build completely within your application

Your ``CMakeLists.txt`` file might look something like this:

.. code-block:: cmake

    # CMakeLists.txt - test finding package and linking against it
    cmake_minimum_required(VERSION 3.10)
    project(liquid_test C)

    # option 1: check for local installation
    #find_package(liquid REQUIRED)

    # option 2: dynamically fetch content
    include(FetchContent)
    FetchContent_Declare(
        liquid
        GIT_REPOSITORY https://github.com/jgaeddert/liquid-dsp.git
        GIT_TAG        v1.7.0
        )
    set(BUILD_AUTOTESTS  OFF CACHE INTERNAL "Disable building liquid tests")
    set(BUILD_BENCHMARKS OFF CACHE INTERNAL "Disable building liquid benchmarks")
    set(BUILD_EXAMPLES   OFF CACHE INTERNAL "Disable building liquid examples")
    FetchContent_MakeAvailable(liquid)
    # FetchContent_Populate(liquid) <- older policy, see CMP0169

    add_executable(main main.c)
    target_link_libraries(main liquid)

You can then compile and run your application the typical way:

.. code-block:: bash

    mkdir build
    cd build
    cmake ..
    make
    ./main
    # creating test object...
    # <liquid.resamp_crcf, rate=0.12345, m=12, as=60.000, fc=0.25, npfb=256>


C++ Bindings
------------

While C is (mostly) a subset of C++, sometimes having a class structure
is more convenient than using C-style structs. These bindings do two things:

1. Wrap the C-style functionality into a set of header-only C++ class libraries
2. Bind these C++ classes into python3

The original C example can be re-written in C++ as follows:

.. code-block:: c++

    // get in, process data, get out
    #include "firinterp.hh"
    int main() {
        unsigned int M  = 4;     // interpolation factor
        unsigned int m  = 12;    // filter delay [symbols]
        float        As = 60.0f; // filter stop-band attenuation [dB]

        // instantiate interpolator object from prototype
        liquid::firinterp interp(M,m,As);
        std::complex<float> x = 1.0f;  // input sample
        std::complex<float> y[M];      // interpolated output buffer

        // repeat on input sample data as needed
        {
            interp.execute(x, y);
        }
        return 0;
    }


Python Bindings
---------------

Building python bindings depends on
`pybind11 <https://pybind11.readthedocs.io/en/stable/>`_,
the ``python3`` development libraries, and
a compatible C++14 compiler (e.g.
``brew install pybind11`` on macOS or
``sudo apt-get install pybind11-dev`` on Debian variants).
Once these dependencies are installed, you can build the liquid-dsp python
library with

.. code-block:: python

    pip install .

From python3 simply use ``import liquid as dsp``.
Our interpolation example used throughout this document can be written
in python3 as:

.. code-block:: python

    # get in, process data, get out
    import liquid as dsp, numpy as np

    # create the interpolator
    interp = dsp.firinterp(M=4, m=12, As=60.)

    # run on a single sample
    buf = interp.execute(1+1j,)


PlatformIO
----------

Cross-compling for embedded platforms is most easily achieved with
`platformio <https://platformio.org>`_.
Just add ``liquid-dsp`` to your ``platform.io`` list of dependencies:

.. code-block:: ini

    [env:native]
    platform = native
    lib_deps = https://github.com/jgaeddert/liquid-dsp.git

To test this, compile the example program for a
`Raspberry Pi Pico microcontroller <https://www.raspberrypi.com/documentation/microcontrollers/pico-series.html>`_:

.. code-block:: bash

    # create a virtual environment, install platformio, and compile an example
    virtualenv pio
    source pio/bin/activate
    pip install platformio
    pio ci --lib="." --board=pico examples/platformio_example.c
    # ...
    # Generating UF2 image
    # elf2uf2 ".pio/build/pico/firmware.elf" ".pio/build/pico/firmware.uf2"
    # Checking size .pio/build/pico/firmware.elf
    # Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
    # RAM:   [==        ]  15.5% (used 41820 bytes from 270336 bytes)
    # Flash: [          ]   0.2% (used 5196 bytes from 2097152 bytes)
    # Building .pio/build/pico/firmware.bin
    # ===================== [SUCCESS] Took 23.63 seconds =====================


Available Modules
-----------------

* **agc**: automatic gain control, received signal strength
* **audio**: source audio encoders/decoders: cvsd, filterbanks
* **buffer**: internal buffering, circular/static, ports (threaded)
* **channel**: additive noise, multi-path fading, carrier phase/frequency
  offsets, timing phase/rate offsets
* **core**: core functionality (error handling, logging)
* **dotprod**: inner dot products (real, complex), vector sum of squares
* **equalization**: adaptive equalizers: least mean-squares, recursive
  least squares, semi-blind
* **fec**: basic forward error correction codes including several
  Hamming codes, single error correction/double error detection,
  Golay block code, as well as several checksums and cyclic
  redundancy checks, interleaving, soft decoding
* **fft**: fast Fourier transforms (arbitrary length), discrete sin/cos
  transforms
* **filter**: finite/infinite impulse response, polyphase, hilbert,
  interpolation, decimation, filter design, resampling, symbol
  timing recovery
* **framing**: flexible framing structures for amazingly easy packet
  software radio; dynamically adjust modulation and coding on the
  fly with single- and multi-carrier framing structures
* **math**: transcendental functions not in the C standard library
  (gamma, besseli, etc.), polynomial operations (curve-fitting,
  root-finding, etc.)
* **matrix**: basic math, LU/QR/Cholesky factorization, inversion,
  Gauss elimination, Gram-Schmidt decomposition, linear solver,
  sparse matrix representation
* **modem**: modulate, demodulate, PSK, differential PSK, QAM, optimal
  QAM, as well as analog and non-linear digital modulations GMSK)
* **multichannel**: filterbank channelizers, OFDM
* **nco**: numerically-controlled oscillator: mixing, frequency
  synthesis, phase-locked loops
* **optim**: (non-linear optimization) Newton-Raphson, evoluationary
  algorithms, gradient descent, line search
* **quantization**: analog/digital converters, compression/expansion
* **random**: (random number generators) uniform, exponential, gamma,
  Nakagami-m, Gauss, Rice-K, Weibull
* **sequence**: linear feedback shift registers, complementary codes,
  maximal-length sequences
* **utility**: useful miscellany, mostly bit manipulation (shifting,
  packing, and unpacking of arrays)
* **vector**: generic vector operations

License
-------

liquid projects are released under the X11/MIT license.
By default, this project will try to link to
`FFTW <http://www.fftw.org>`_
if it is available on your build platform.
Because FFTW starting with version 1.3 is
`licensed <http://www.fftw.org/faq/section1.html>`_
under the `GNU General Public License v2 <http://www.fftw.org/doc/License-and-Copyright.html>`_
this unfortunately means that (and I'm clearly not a lawyer, here)
you cannot distribute ``liquid-dsp`` without also distributing the source code
if you link to FFTW.
This is a similar situation with the classic
`libfec <https://github.com/quiet/libfec>`_
which uses the
`GNU Lesser GPL <https://www.gnu.org/licenses/licenses.html#LGPL>`_.
Finally, ``liquid-dsp`` makes extensive use of GNU
`autoconf <https://www.gnu.org/software/autoconf/>`_,
`automake <https://www.gnu.org/software/automake/>`_,
and related tools.
These are fantastic libraries with amazing functionality and their authors
should be lauded for their efforts.
In a similar vain, much the software I write for a living I give away for
free;
however I believe in more permissive licenses to allow individuals the
flexibility to use software with fewer limitations.
If these restrictions are not acceptable, ``liquid-dsp`` can be compiled and run
without use of these external libraries, albeit a bit slower and with limited
functionality.

Short version: this code is copyrighted to me (Joseph D. Gaeddert),
I give you full permission to do whatever you want with it except remove my
name from the credits.
Seriously, go nuts! but take caution when linking to other libraries with
different licenses.
See the `license <https://opensource.org/licenses/MIT>`_ for specific terms.

