1*49fe348cSAndroid Build Coastguard Worker# Low Complexity Communication Codec (LC3) 2*49fe348cSAndroid Build Coastguard Worker 3*49fe348cSAndroid Build Coastguard WorkerLC3 and LC3 Plus are audio codecs designed for low-latency audio transport. 4*49fe348cSAndroid Build Coastguard Worker 5*49fe348cSAndroid Build Coastguard Worker- LC3 is specified by [_the Bluetooth Special Interset Group for the LE Audio 6*49fe348cSAndroid Build Coastguard Worker protocol_](https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=502107&vId=542963) 7*49fe348cSAndroid Build Coastguard Worker 8*49fe348cSAndroid Build Coastguard Worker- 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*49fe348cSAndroid Build Coastguard Worker 10*49fe348cSAndroid Build Coastguard WorkerIn addition to LC3, following features of LC3 Plus are proposed: 11*49fe348cSAndroid Build Coastguard Worker- Frame duration of 2.5 and 5ms. 12*49fe348cSAndroid Build Coastguard Worker- High-Resolution mode, 48 KHz, and 96 kHz sampling rates. 13*49fe348cSAndroid Build Coastguard Worker 14*49fe348cSAndroid Build Coastguard Worker## Overview 15*49fe348cSAndroid Build Coastguard Worker 16*49fe348cSAndroid Build Coastguard WorkerThe directory layout is as follows : 17*49fe348cSAndroid Build Coastguard Worker- include: Library interface 18*49fe348cSAndroid Build Coastguard Worker- src: Source files 19*49fe348cSAndroid Build Coastguard Worker- tools: Standalone encoder/decoder tools 20*49fe348cSAndroid Build Coastguard Worker- python: Python wrapper 21*49fe348cSAndroid Build Coastguard Worker- test: Unit testing framework 22*49fe348cSAndroid Build Coastguard Worker- fuzz: Roundtrip fuzz testing harness 23*49fe348cSAndroid Build Coastguard Worker- build: Building outputs 24*49fe348cSAndroid Build Coastguard Worker- bin: Compilation output 25*49fe348cSAndroid Build Coastguard Worker 26*49fe348cSAndroid Build Coastguard Worker## How to build 27*49fe348cSAndroid Build Coastguard Worker 28*49fe348cSAndroid Build Coastguard WorkerThe default toolchain used is GCC. Invoke `make` to build the library. 29*49fe348cSAndroid Build Coastguard Worker 30*49fe348cSAndroid Build Coastguard Worker```sh 31*49fe348cSAndroid Build Coastguard Worker$ make -j 32*49fe348cSAndroid Build Coastguard Worker``` 33*49fe348cSAndroid Build Coastguard Worker 34*49fe348cSAndroid Build Coastguard WorkerCompiled library `liblc3.so` will be found in `bin` directory. 35*49fe348cSAndroid Build Coastguard Worker 36*49fe348cSAndroid Build Coastguard WorkerLC3 Plus features can be selectively disabled : 37*49fe348cSAndroid Build Coastguard Worker- `LC3_PLUS=0` disable the support of 2.5ms and 5ms frame durations. 38*49fe348cSAndroid Build Coastguard Worker- `LC3_PLUS_HR=0` turns off the support of the High-Resolution mode. 39*49fe348cSAndroid Build Coastguard Worker 40*49fe348cSAndroid Build Coastguard WorkerOnly Bluetooth LC3 features will be included using the following command: 41*49fe348cSAndroid Build Coastguard Worker 42*49fe348cSAndroid Build Coastguard Worker```sh 43*49fe348cSAndroid Build Coastguard Worker$ make LC3_PLUS=0 LC3_PLUS_HR=0 -j 44*49fe348cSAndroid Build Coastguard Worker``` 45*49fe348cSAndroid Build Coastguard Worker 46*49fe348cSAndroid Build Coastguard Worker#### Cross compilation 47*49fe348cSAndroid Build Coastguard Worker 48*49fe348cSAndroid Build Coastguard WorkerThe cc, as, ld and ar can be selected with respective Makefile variables `CC`, 49*49fe348cSAndroid Build Coastguard Worker`AS`, `LD` and `AR`. The `AS` and `LD` selections are optionnal, and fallback 50*49fe348cSAndroid Build Coastguard Workerto `CC` selection when not defined. 51*49fe348cSAndroid Build Coastguard Worker 52*49fe348cSAndroid Build Coastguard WorkerThe `LIBC` must be set to `bionic` for android cross-compilation. This switch 53*49fe348cSAndroid Build Coastguard Workerprevent link with `pthread` and `rt` libraries, that is included in the 54*49fe348cSAndroid Build Coastguard Workerbionic libc. 55*49fe348cSAndroid Build Coastguard Worker 56*49fe348cSAndroid Build Coastguard WorkerFollowing example build for android, using NDK toolset. 57*49fe348cSAndroid Build Coastguard Worker 58*49fe348cSAndroid Build Coastguard Worker```sh 59*49fe348cSAndroid Build Coastguard Worker$ make -j CC=path_to_android_ndk_prebuilt/toolchain-prefix-clang LIBC=bionic 60*49fe348cSAndroid Build Coastguard Worker``` 61*49fe348cSAndroid Build Coastguard Worker 62*49fe348cSAndroid Build Coastguard WorkerCompiled library will be found in `bin` directory. 63*49fe348cSAndroid Build Coastguard Worker 64*49fe348cSAndroid Build Coastguard Worker#### Web Assembly (WASM) 65*49fe348cSAndroid Build Coastguard Worker 66*49fe348cSAndroid Build Coastguard WorkerWeb assembly compilation is supported using LLVM WebAssembly backend. 67*49fe348cSAndroid Build Coastguard WorkerInstallation of LLVM compiler and linker is needed: 68*49fe348cSAndroid Build Coastguard Worker 69*49fe348cSAndroid Build Coastguard Worker```sh 70*49fe348cSAndroid Build Coastguard Worker# apt install clang lld 71*49fe348cSAndroid Build Coastguard Worker``` 72*49fe348cSAndroid Build Coastguard Worker 73*49fe348cSAndroid Build Coastguard WorkerThe webasm object is compiled using: 74*49fe348cSAndroid Build Coastguard Worker```sh 75*49fe348cSAndroid Build Coastguard Worker$ make CC="clang --target=wasm32" 76*49fe348cSAndroid Build Coastguard Worker``` 77*49fe348cSAndroid Build Coastguard Worker 78*49fe348cSAndroid Build Coastguard Worker## Tools 79*49fe348cSAndroid Build Coastguard Worker 80*49fe348cSAndroid Build Coastguard WorkerTools can be all compiled, while invoking `make` as follows : 81*49fe348cSAndroid Build Coastguard Worker 82*49fe348cSAndroid Build Coastguard Worker```sh 83*49fe348cSAndroid Build Coastguard Worker$ make tools 84*49fe348cSAndroid Build Coastguard Worker``` 85*49fe348cSAndroid Build Coastguard Worker 86*49fe348cSAndroid Build Coastguard WorkerThe standalone encoder `elc3` take a `wave` file as input and encode it 87*49fe348cSAndroid Build Coastguard Workeraccording given parameter. The LC3 binary file format used is the non 88*49fe348cSAndroid Build Coastguard Workerstandard format described by the reference encoder / decoder tools. 89*49fe348cSAndroid Build Coastguard WorkerThe standalone decoder `dlc3` do the inverse operation. 90*49fe348cSAndroid Build Coastguard Worker 91*49fe348cSAndroid Build Coastguard WorkerRefer to `elc3 -h` or `dlc3 -h` for options. 92*49fe348cSAndroid Build Coastguard Worker 93*49fe348cSAndroid Build Coastguard WorkerNote that `elc3` output bitstream to standard output when output file is 94*49fe348cSAndroid Build Coastguard Workeromitted. On the other side `dlc3` read from standard input when input output 95*49fe348cSAndroid Build Coastguard Workerfile are omitted. 96*49fe348cSAndroid Build Coastguard WorkerIn such way you can easly test encoding / decoding loop with : 97*49fe348cSAndroid Build Coastguard Worker 98*49fe348cSAndroid Build Coastguard Worker```sh 99*49fe348cSAndroid Build Coastguard Worker$ alias elc3="LD_LIBRARY_PATH=`pwd`/bin `pwd`/bin/elc3" 100*49fe348cSAndroid Build Coastguard Worker$ alias dlc3="LD_LIBRARY_PATH=`pwd`/bin `pwd`/bin/dlc3" 101*49fe348cSAndroid Build Coastguard Worker$ elc3 <in.wav> -b <bitrate> | dlc3 > <out.wav> 102*49fe348cSAndroid Build Coastguard Worker``` 103*49fe348cSAndroid Build Coastguard Worker 104*49fe348cSAndroid Build Coastguard WorkerAdding Linux `aplay` tools, you will be able to instant hear the result : 105*49fe348cSAndroid Build Coastguard Worker 106*49fe348cSAndroid Build Coastguard Worker```sh 107*49fe348cSAndroid Build Coastguard Worker$ alias elc3="LD_LIBRARY_PATH=`pwd`/bin `pwd`/bin/elc3" 108*49fe348cSAndroid Build Coastguard Worker$ alias dlc3="LD_LIBRARY_PATH=`pwd`/bin `pwd`/bin/dlc3" 109*49fe348cSAndroid Build Coastguard Worker$ elc3 <in.wav> -b <bitrate> | dlc3 | aplay -D pipewire 110*49fe348cSAndroid Build Coastguard Worker``` 111*49fe348cSAndroid Build Coastguard Worker 112*49fe348cSAndroid Build Coastguard Worker## Test 113*49fe348cSAndroid Build Coastguard Worker 114*49fe348cSAndroid Build Coastguard WorkerA python implementation of the encoder is provided in `test` diretory. 115*49fe348cSAndroid Build Coastguard WorkerThe C implementation is unitary validated against this implementation and 116*49fe348cSAndroid Build Coastguard Workerintermediate values given in Appendix C of the LC3 specification. 117*49fe348cSAndroid Build Coastguard Worker 118*49fe348cSAndroid Build Coastguard Worker#### Prerequisite 119*49fe348cSAndroid Build Coastguard Worker 120*49fe348cSAndroid Build Coastguard Worker```sh 121*49fe348cSAndroid Build Coastguard Worker# apt install python3 python3-dev python3-pip 122*49fe348cSAndroid Build Coastguard Worker$ pip3 install scipy numpy 123*49fe348cSAndroid Build Coastguard Worker``` 124*49fe348cSAndroid Build Coastguard Worker 125*49fe348cSAndroid Build Coastguard Worker#### Running test suite 126*49fe348cSAndroid Build Coastguard Worker 127*49fe348cSAndroid Build Coastguard Worker```sh 128*49fe348cSAndroid Build Coastguard Worker$ make test 129*49fe348cSAndroid Build Coastguard Worker``` 130*49fe348cSAndroid Build Coastguard Worker 131*49fe348cSAndroid Build Coastguard Worker## Fuzzing 132*49fe348cSAndroid Build Coastguard Worker 133*49fe348cSAndroid Build Coastguard WorkerRoundtrip fuzz testing harness is available in `fuzz` directory. 134*49fe348cSAndroid Build Coastguard WorkerLLVM `clang` and `clang++` compilers are needed to run fuzzing. 135*49fe348cSAndroid Build Coastguard Worker 136*49fe348cSAndroid Build Coastguard WorkerThe encoder and decoder fuzzers can be run, for 1 million iterations, using 137*49fe348cSAndroid Build Coastguard Workertarget respectively `dfuzz` and `efuzz`. The `fuzz` target runs both. 138*49fe348cSAndroid Build Coastguard Worker 139*49fe348cSAndroid Build Coastguard Worker```sh 140*49fe348cSAndroid Build Coastguard Worker$ make efuzz # Run encoder fuzzer for 1M iteration 141*49fe348cSAndroid Build Coastguard Worker$ make dfuzz # Run decoder fuzzer for 1M iteration 142*49fe348cSAndroid Build Coastguard Worker$ make fuzz -j # Run encoder and decoder fuzzers in parallel 143*49fe348cSAndroid Build Coastguard Worker``` 144*49fe348cSAndroid Build Coastguard Worker 145*49fe348cSAndroid Build Coastguard Worker## Qualification / Conformance 146*49fe348cSAndroid Build Coastguard Worker 147*49fe348cSAndroid Build Coastguard WorkerThe implementation is qualified under the [_QDID 194161_](https://launchstudio.bluetooth.com/ListingDetails/160904) as part of Google Fluoride 1.5. 148*49fe348cSAndroid Build Coastguard Worker 149*49fe348cSAndroid Build Coastguard WorkerThe conformance reports can be found [here](conformance/README.md) 150*49fe348cSAndroid Build Coastguard Worker 151*49fe348cSAndroid Build Coastguard Worker## Listening Test 152*49fe348cSAndroid Build Coastguard Worker 153*49fe348cSAndroid Build Coastguard WorkerThe codec was [_here_](https://hydrogenaud.io/index.php/topic,122575.0.html) 154*49fe348cSAndroid Build Coastguard Workersubjectively evaluated in a blind listening test. 155*49fe348cSAndroid Build Coastguard Worker 156*49fe348cSAndroid Build Coastguard Worker 157*49fe348cSAndroid Build Coastguard Worker## Meson build system 158*49fe348cSAndroid Build Coastguard Worker 159*49fe348cSAndroid Build Coastguard WorkerMeson build system is also available to build and install lc3 codec in Linux 160*49fe348cSAndroid Build Coastguard Workerenvironment. 161*49fe348cSAndroid Build Coastguard Worker 162*49fe348cSAndroid Build Coastguard Worker```sh 163*49fe348cSAndroid Build Coastguard Worker$ meson setup build 164*49fe348cSAndroid Build Coastguard Worker$ cd build && meson install 165*49fe348cSAndroid Build Coastguard Worker``` 166*49fe348cSAndroid Build Coastguard Worker 167*49fe348cSAndroid Build Coastguard Worker## Python wrapper 168*49fe348cSAndroid Build Coastguard Worker 169*49fe348cSAndroid Build Coastguard WorkerA python wrapper, installed as follows, is available in the `python` directory. 170*49fe348cSAndroid Build Coastguard Worker 171*49fe348cSAndroid Build Coastguard Worker```sh 172*49fe348cSAndroid Build Coastguard Worker$ python3 -m pip install . 173*49fe348cSAndroid Build Coastguard Worker``` 174*49fe348cSAndroid Build Coastguard Worker 175*49fe348cSAndroid Build Coastguard WorkerDecoding and encoding tools are provided in `python/tools`, like C tools, 176*49fe348cSAndroid Build Coastguard Workeryou can easly test encoding / decoding loop with : 177*49fe348cSAndroid Build Coastguard Worker 178*49fe348cSAndroid Build Coastguard Worker```sh 179*49fe348cSAndroid Build Coastguard Worker$ python3 ./python/tools/encoder.py <in.wav> --bitrate <bitrate> | \ 180*49fe348cSAndroid Build Coastguard Worker python3 ./python/tools/decoder.py > <out.wav> 181*49fe348cSAndroid Build Coastguard Worker``` 182