Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lc3 Plus features #40

Merged
merged 6 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ LD := $(if $(LD)=ld,$(CC),$(LD))
CFLAGS := $(if $(DEBUG),-O0 -g,-O3)
CFLAGS += -std=c11 -Wall -Wextra -Wdouble-promotion -Wvla -pedantic

ifneq ($(LC3_PLUS),)
DEFINE += LC3_PLUS=$(LC3_PLUS)
endif

ifneq ($(LC3_PLUS_HR),)
DEFINE += LC3_PLUS_HR=$(LC3_PLUS_HR)
endif


#
# Declarations
Expand Down
25 changes: 21 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
# Low Complexity Communication Codec (LC3)

The LC3 is an efficient low latency audio codec.
LC3 and LC3 Plus are audio codecs designed for low-latency audio transport.

[_Low Complexity Communication Codec_](https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=502107&vId=542963)
- LC3 is specified by [_the Bluetooth Special Interset Group for the LE Audio
protocol_](https://www.bluetooth.org/DocMan/handlers/DownloadDoc.ashx?doc_id=502107&vId=542963)

- 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)

In addition to LC3, following features of LC3 Plus are proposed:
- Frame duration of 2.5 and 5ms.
- High-Resolution mode, 48 KHz, and 96 kHz sampling rates.

## Overview

The directory layout is as follows :
- include: Library interface
- src: Source files
- tools: Standalone encoder/decoder tools
- test: Python implentation, used as reference for unit testing
- test: Unit testing framework
- fuzz: Roundtrip fuzz testing harness
- build: Building outputs
- bin: Compilation output
Expand All @@ -25,6 +32,16 @@ $ make -j

Compiled library `liblc3.a` will be found in `bin` directory.

LC3 Plus features can be selectively disabled :
- `LC3_PLUS=0` disable the support of 2.5ms and 5ms frame durations.
- `LC3_PLUS_HR=0` turns off the support of the High-Resolution mode.

Only Bluetooth LC3 features will be included using the following command:

```sh
$ make LC3_PLUS=0 LC3_PLUS_HR=0 -j
```

#### Cross compilation

The cc, as, ld and ar can be selected with respective Makefile variables `CC`,
Expand Down Expand Up @@ -77,7 +94,7 @@ $ ./elc3 <in.wav> -b <bitrate> | ./dlc3 | aplay

A python implementation of the encoder is provided in `test` diretory.
The C implementation is unitary validated against this implementation and
intermediate values given in Appendix C of the specification.
intermediate values given in Appendix C of the LC3 specification.

#### Prerequisite

Expand Down
9 changes: 6 additions & 3 deletions fuzz/dfuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,21 @@ using namespace lc3;

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
const int dt_list[] = { 7500, 10000 };
const int sr_list[] = { 8000, 16000, 24000, 32000, 48000 };
const int dt_list[] = { 2500, 5000, 7500, 10000 };
const int sr_list[] = { 8000, 16000, 24000, 32000, 48000, 96000 };

FuzzedDataProvider fdp(data, size);

int dt_us = fdp.PickValueInArray(dt_list);
int sr_hz = fdp.PickValueInArray(sr_list);
int nchannels =fdp.PickValueInArray({1, 2});
bool hrmode = fdp.ConsumeBool();

int sr_pcm_hz = fdp.PickValueInArray(sr_list);
if (sr_pcm_hz < sr_hz)
sr_pcm_hz = 0;

Decoder dec(dt_us, sr_hz, sr_pcm_hz, nchannels);
Decoder dec(dt_us, sr_hz, sr_pcm_hz, nchannels, hrmode);

int frame_size = fdp.ConsumeIntegralInRange(
LC3_MIN_FRAME_BYTES, LC3_MAX_FRAME_BYTES);
Expand All @@ -46,6 +47,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
PcmFormat::kS24In3Le, PcmFormat::kF32 });

int frame_samples = dec.GetFrameSamples();
if (frame_samples < 0)
return -1;

int sample_bytes =
fmt == PcmFormat::kS16 ? sizeof(int16_t) :
Expand Down
5 changes: 3 additions & 2 deletions fuzz/efuzz.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,20 +70,21 @@ int encode(Encoder &e, int frame_size, int nchannels,

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
{
const int dt_list[] = { 7500, 10000 };
const int dt_list[] = { 2500, 5000, 7500, 10000 };
const int sr_list[] = { 8000, 16000, 24000, 32000, 48000 };

FuzzedDataProvider fdp(data, size);

int dt_us = fdp.PickValueInArray(dt_list);
int sr_hz = fdp.PickValueInArray(sr_list);
int nchannels = fdp.PickValueInArray({1, 2});
bool hrmode = fdp.ConsumeBool();

int sr_pcm_hz = fdp.PickValueInArray(sr_list);
if (sr_pcm_hz < sr_hz)
sr_pcm_hz = 0;

Encoder enc(dt_us, sr_hz, sr_pcm_hz, nchannels);
Encoder enc(dt_us, sr_hz, sr_pcm_hz, nchannels, hrmode);

PcmFormat fmt = fdp.PickValueInArray(
{ PcmFormat::kS16, PcmFormat::kS24,
Expand Down
Loading