xref: /btstack/3rd-party/lc3-google/README.md (revision 6897da5c53aac5b1f90f41b5b15d0bd43d61dfff)
14930cef6SMatthias Ringwald# Low Complexity Communication Codec (LC3)
24930cef6SMatthias Ringwald
3*6897da5cSDirk HelbigLC3 and LC3 Plus are audio codecs designed for low-latency audio transport.
44930cef6SMatthias Ringwald
5*6897da5cSDirk Helbig- LC3 is specified by [_the Bluetooth Special Interset Group for the LE Audio
6*6897da5cSDirk Helbig  protocol_](https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=502107&vId=542963)
7*6897da5cSDirk Helbig
8*6897da5cSDirk Helbig- LC3 Plus is defined by [_ETSI TS 103 634_](https://www.etsi.org/deliver/etsi_ts/103600_103699/103634/01.04.01_60/ts_103634v010401p.pdf)
9*6897da5cSDirk Helbig
10*6897da5cSDirk HelbigIn addition to LC3, following features of LC3 Plus are proposed:
11*6897da5cSDirk Helbig- Frame duration of 2.5 and 5ms.
12*6897da5cSDirk Helbig- High-Resolution mode, 48 KHz, and 96 kHz sampling rates.
134930cef6SMatthias Ringwald
144930cef6SMatthias Ringwald## Overview
154930cef6SMatthias Ringwald
164930cef6SMatthias RingwaldThe directory layout is as follows :
174930cef6SMatthias Ringwald- include:      Library interface
184930cef6SMatthias Ringwald- src:          Source files
194930cef6SMatthias Ringwald- tools:        Standalone encoder/decoder tools
20*6897da5cSDirk Helbig- python:       Python wrapper
21*6897da5cSDirk Helbig- test:         Unit testing framework
22*6897da5cSDirk Helbig- fuzz:         Roundtrip fuzz testing harness
234930cef6SMatthias Ringwald- build:        Building outputs
244930cef6SMatthias Ringwald- bin:          Compilation output
254930cef6SMatthias Ringwald
264930cef6SMatthias Ringwald## How to build
274930cef6SMatthias Ringwald
284930cef6SMatthias RingwaldThe default toolchain used is GCC. Invoke `make` to build the library.
294930cef6SMatthias Ringwald
304930cef6SMatthias Ringwald```sh
314930cef6SMatthias Ringwald$ make -j
324930cef6SMatthias Ringwald```
334930cef6SMatthias Ringwald
34*6897da5cSDirk HelbigCompiled library `liblc3.so` will be found in `bin` directory.
35*6897da5cSDirk Helbig
36*6897da5cSDirk HelbigLC3 Plus features can be selectively disabled :
37*6897da5cSDirk Helbig- `LC3_PLUS=0` disable the support of 2.5ms and 5ms frame durations.
38*6897da5cSDirk Helbig- `LC3_PLUS_HR=0` turns off the support of the High-Resolution mode.
39*6897da5cSDirk Helbig
40*6897da5cSDirk HelbigOnly Bluetooth LC3 features will be included using the following command:
41*6897da5cSDirk Helbig
42*6897da5cSDirk Helbig```sh
43*6897da5cSDirk Helbig$ make LC3_PLUS=0 LC3_PLUS_HR=0 -j
44*6897da5cSDirk Helbig```
454930cef6SMatthias Ringwald
464930cef6SMatthias Ringwald#### Cross compilation
474930cef6SMatthias Ringwald
484930cef6SMatthias RingwaldThe cc, as, ld and ar can be selected with respective Makefile variables `CC`,
494930cef6SMatthias Ringwald`AS`, `LD` and `AR`. The `AS` and `LD` selections are optionnal, and fallback
504930cef6SMatthias Ringwaldto `CC` selection when not defined.
514930cef6SMatthias Ringwald
524930cef6SMatthias RingwaldThe `LIBC` must be set to `bionic` for android cross-compilation. This switch
534930cef6SMatthias Ringwaldprevent link with `pthread` and `rt` libraries, that is included in the
544930cef6SMatthias Ringwaldbionic libc.
554930cef6SMatthias Ringwald
564930cef6SMatthias RingwaldFollowing example build for android, using NDK toolset.
574930cef6SMatthias Ringwald
584930cef6SMatthias Ringwald```sh
594930cef6SMatthias Ringwald$ make -j CC=path_to_android_ndk_prebuilt/toolchain-prefix-clang LIBC=bionic
604930cef6SMatthias Ringwald```
614930cef6SMatthias Ringwald
624930cef6SMatthias RingwaldCompiled library will be found in `bin` directory.
634930cef6SMatthias Ringwald
64*6897da5cSDirk Helbig#### Web Assembly (WASM)
65*6897da5cSDirk Helbig
66*6897da5cSDirk HelbigWeb assembly compilation is supported using LLVM WebAssembly backend.
67*6897da5cSDirk HelbigInstallation of LLVM compiler and linker is needed:
68*6897da5cSDirk Helbig
69*6897da5cSDirk Helbig```sh
70*6897da5cSDirk Helbig# apt install clang lld
71*6897da5cSDirk Helbig```
72*6897da5cSDirk Helbig
73*6897da5cSDirk HelbigThe webasm object is compiled using:
74*6897da5cSDirk Helbig```sh
75*6897da5cSDirk Helbig$ make CC="clang --target=wasm32"
76*6897da5cSDirk Helbig```
77*6897da5cSDirk Helbig
784930cef6SMatthias Ringwald## Tools
794930cef6SMatthias Ringwald
80*6897da5cSDirk HelbigTools can be all compiled, while invoking `make` as follows :
814930cef6SMatthias Ringwald
824930cef6SMatthias Ringwald```sh
834930cef6SMatthias Ringwald$ make tools
844930cef6SMatthias Ringwald```
854930cef6SMatthias Ringwald
864930cef6SMatthias RingwaldThe standalone encoder `elc3` take a `wave` file as input and encode it
874930cef6SMatthias Ringwaldaccording given parameter. The LC3 binary file format used is the non
884930cef6SMatthias Ringwaldstandard format described by the reference encoder / decoder tools.
894930cef6SMatthias RingwaldThe standalone decoder `dlc3` do the inverse operation.
904930cef6SMatthias Ringwald
914930cef6SMatthias RingwaldRefer to `elc3 -h` or `dlc3 -h` for options.
924930cef6SMatthias Ringwald
934930cef6SMatthias RingwaldNote that `elc3` output bitstream to standard output when output file is
944930cef6SMatthias Ringwaldomitted. On the other side `dlc3` read from standard input when input output
954930cef6SMatthias Ringwaldfile are omitted.
964930cef6SMatthias RingwaldIn such way you can easly test encoding / decoding loop with :
974930cef6SMatthias Ringwald
984930cef6SMatthias Ringwald```sh
99*6897da5cSDirk Helbig$ alias elc3="LD_LIBRARY_PATH=`pwd`/bin `pwd`/bin/elc3"
100*6897da5cSDirk Helbig$ alias dlc3="LD_LIBRARY_PATH=`pwd`/bin `pwd`/bin/dlc3"
101*6897da5cSDirk Helbig$ elc3 <in.wav> -b <bitrate> | dlc3 > <out.wav>
1024930cef6SMatthias Ringwald```
1034930cef6SMatthias Ringwald
1044930cef6SMatthias RingwaldAdding Linux `aplay` tools, you will be able to instant hear the result :
1054930cef6SMatthias Ringwald
1064930cef6SMatthias Ringwald```sh
107*6897da5cSDirk Helbig$ alias elc3="LD_LIBRARY_PATH=`pwd`/bin `pwd`/bin/elc3"
108*6897da5cSDirk Helbig$ alias dlc3="LD_LIBRARY_PATH=`pwd`/bin `pwd`/bin/dlc3"
109*6897da5cSDirk Helbig$ elc3 <in.wav> -b <bitrate> | dlc3 | aplay -D pipewire
1104930cef6SMatthias Ringwald```
1114930cef6SMatthias Ringwald
1124930cef6SMatthias Ringwald## Test
1134930cef6SMatthias Ringwald
1144930cef6SMatthias RingwaldA python implementation of the encoder is provided in `test` diretory.
1154930cef6SMatthias RingwaldThe C implementation is unitary validated against this implementation and
116*6897da5cSDirk Helbigintermediate values given in Appendix C of the LC3 specification.
1174930cef6SMatthias Ringwald
1184930cef6SMatthias Ringwald#### Prerequisite
1194930cef6SMatthias Ringwald
1204930cef6SMatthias Ringwald```sh
1214930cef6SMatthias Ringwald# apt install python3 python3-dev python3-pip
1224930cef6SMatthias Ringwald$ pip3 install scipy numpy
1234930cef6SMatthias Ringwald```
1244930cef6SMatthias Ringwald
1254930cef6SMatthias Ringwald#### Running test suite
1264930cef6SMatthias Ringwald
1274930cef6SMatthias Ringwald```sh
1284930cef6SMatthias Ringwald$ make test
1294930cef6SMatthias Ringwald```
1304930cef6SMatthias Ringwald
131*6897da5cSDirk Helbig## Fuzzing
1324930cef6SMatthias Ringwald
133*6897da5cSDirk HelbigRoundtrip fuzz testing harness is available in `fuzz` directory.
134*6897da5cSDirk HelbigLLVM `clang` and `clang++` compilers are needed to run fuzzing.
1354930cef6SMatthias Ringwald
136*6897da5cSDirk HelbigThe encoder and decoder fuzzers can be run, for 1 million iterations, using
137*6897da5cSDirk Helbigtarget respectively `dfuzz` and `efuzz`. The `fuzz` target runs both.
138*6897da5cSDirk Helbig
139*6897da5cSDirk Helbig```sh
140*6897da5cSDirk Helbig$ make efuzz    # Run encoder fuzzer for 1M iteration
141*6897da5cSDirk Helbig$ make dfuzz    # Run decoder fuzzer for 1M iteration
142*6897da5cSDirk Helbig$ make fuzz -j  # Run encoder and decoder fuzzers in parallel
143*6897da5cSDirk Helbig```
144*6897da5cSDirk Helbig
145*6897da5cSDirk Helbig## Qualification / Conformance
146*6897da5cSDirk Helbig
147*6897da5cSDirk HelbigThe implementation is qualified under the [_QDID 194161_](https://launchstudio.bluetooth.com/ListingDetails/160904) as part of Google Fluoride 1.5.
148*6897da5cSDirk Helbig
149*6897da5cSDirk HelbigThe conformance reports can be found [here](conformance/README.md)
1504930cef6SMatthias Ringwald
1514c4eb519SMatthias Ringwald## Listening Test
1524c4eb519SMatthias Ringwald
1534c4eb519SMatthias RingwaldThe codec was [_here_](https://hydrogenaud.io/index.php/topic,122575.0.html)
1544c4eb519SMatthias Ringwaldsubjectively evaluated in a blind listening test.
1554c4eb519SMatthias Ringwald
156*6897da5cSDirk Helbig
1574c4eb519SMatthias Ringwald## Meson build system
1584c4eb519SMatthias Ringwald
1594c4eb519SMatthias RingwaldMeson build system is also available to build and install lc3 codec in Linux
1604c4eb519SMatthias Ringwaldenvironment.
1614c4eb519SMatthias Ringwald
1624c4eb519SMatthias Ringwald```sh
163*6897da5cSDirk Helbig$ meson setup build
164*6897da5cSDirk Helbig$ cd build && meson install
1654c4eb519SMatthias Ringwald```
1664c4eb519SMatthias Ringwald
167*6897da5cSDirk Helbig## Python wrapper
168*6897da5cSDirk Helbig
169*6897da5cSDirk HelbigA python wrapper, installed as follows, is available in the `python` directory.
170*6897da5cSDirk Helbig
171*6897da5cSDirk Helbig```sh
172*6897da5cSDirk Helbig$ python3 -m pip install .
173*6897da5cSDirk Helbig```
174*6897da5cSDirk Helbig
175*6897da5cSDirk HelbigDecoding and encoding tools are provided in `python/tools`, like C tools,
176*6897da5cSDirk Helbigyou can easly test encoding / decoding loop with :
177*6897da5cSDirk Helbig
178*6897da5cSDirk Helbig```sh
179*6897da5cSDirk Helbig$ python3 ./python/tools/encoder.py <in.wav> --bitrate <bitrate> | \
180*6897da5cSDirk Helbig  python3 ./python/tools/decoder.py > <out.wav>
181*6897da5cSDirk Helbig```
182