Skip to content

Commit 6e8ad0b

Browse files
committed
First sneak peek of the EHIMA LC3 codec
Snapshot of embdrv/lc3 605f0f76186708371c5d117ecdc036d69384090a Signed-off-by: Alberto Escolar Piedras <[email protected]> Signed-off-by: Bjarne Klemmensen <[email protected]>
0 parents  commit 6e8ad0b

File tree

108 files changed

+17484
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+17484
-0
lines changed

Android.bp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
cc_library_static {
2+
name: "liblc3codec",
3+
apex_available: [
4+
5+
"//apex_available:platform",
6+
"com.android.bluetooth.updatable"
7+
],
8+
defaults: ["fluoride_defaults"],
9+
srcs: [
10+
"Common/*.cpp",
11+
"Common/Tables/*.cpp",
12+
"Encoder/*.cpp",
13+
"Decoder/*.cpp",
14+
"TestSupport/DatapointsAndroid.cpp",
15+
],
16+
cflags: [
17+
"-Werror",
18+
"-Wmissing-braces",
19+
"-Wno-unused-parameter",
20+
"-Wno-#warnings",
21+
"-Wuninitialized",
22+
"-Wno-self-assign",
23+
"-Wno-implicit-fallthrough",
24+
],
25+
sanitize: {
26+
misc_undefined:[
27+
"unsigned-integer-overflow",
28+
"signed-integer-overflow",
29+
"bounds",
30+
],
31+
cfi: true,
32+
},
33+
shared_libs: [
34+
"liblog",
35+
],
36+
export_include_dirs: [
37+
"Api",
38+
"Common",
39+
"Common/Tables",
40+
"Common/KissFft",
41+
"TestSupport",
42+
],
43+
}

Api/Lc3Config.hpp

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
/*
2+
* Lc3Config.hpp
3+
*
4+
* Copyright 2019 HIMSA II K/S - www.himsa.com. Represented by EHIMA - www.ehima.com
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#ifndef __LC3_CONFIG_HPP_
20+
#define __LC3_CONFIG_HPP_
21+
22+
#include <cstdint>
23+
24+
/*
25+
* The LC3 encoder and decoder have a common set of essential session
26+
* configuration parameters - see LC3 specification Sections 2.2 "Encoder interfaces"
27+
* and Section 2.4 "Decoder interfaces" (dr09r07).
28+
* The set of common session configuration parameters is represented
29+
* by an instance of class Lc3Config.
30+
*
31+
* Lc3Config is designed such that all parameters need to be
32+
* providing when constructing an instance. Afterwards, success of creation,
33+
* the actual parameter values, and derived parameter values are provided
34+
* by corresponding const getter methods or public const fields.
35+
*
36+
* When parameters need to be changes, a new instance of Lc3Config has to be
37+
* created.
38+
*
39+
* Instances of Lc3Config are provided to instances of Lc3Encoder and Lc3Decoder
40+
* when constructing them.
41+
*
42+
* The main purpose of Lc3Config is to verify and handle common LC3 session
43+
* configuration parameters in a consistent way.
44+
*
45+
*/
46+
class Lc3Config
47+
{
48+
public:
49+
/*
50+
* Enumeration of supported frame durations N_ms = 7.5ms and N_ms = 10ms.
51+
*
52+
* Note: although the LC3 specification describes frame duration N_ms as
53+
* a parameter with floating point values 7.5 and 10.0, we decided
54+
* to make this parameter a discrete enumeration of supported
55+
* frame durations. There are too many codec parts that need
56+
* specifically listed constants dependent on the configured
57+
* frame duration, so that it never will be possible to chose from a
58+
* larger set of floating point values for N_ms.
59+
* Making the data type of N_ms an enumeration supports
60+
* straight forwards verification that meaningful parameters are given.
61+
*/
62+
enum class FrameDuration
63+
{
64+
d10ms,
65+
d7p5ms
66+
};
67+
68+
// configuration error (see "getErrorStatus")
69+
static const uint8_t ERROR_FREE = 0x00;
70+
static const uint8_t INVALID_SAMPLING_RATE = 0x01;
71+
static const uint8_t INVALID_FRAME_DURATION = 0x02;
72+
static const uint8_t INVALID_NUMBER_OF_CHANNELS = 0x04;
73+
74+
/*
75+
* Constructor of an instance of Lc3Config
76+
* Parameters:
77+
* (see also see LC3 specification Sections 2.2 "Encoder interfaces"
78+
* and Section 2.4 "Decoder interfaces" (dr09r07) )
79+
*
80+
* Fs_ : Sampling frequency in Hz -> defines public constant Fs
81+
* Supported values are
82+
* 8000 Hz
83+
* 16000 Hz
84+
* 24000 Hz
85+
* 32000 Hz
86+
* 44100 Hz
87+
* 48000 Hz
88+
*
89+
* N_ms_ : Frame duration given by value from enumeration FrameDuration (see above)
90+
* -> defines public constant N_ms
91+
* Supported values see enumeration FrameDuration.
92+
*
93+
* Nc_ : Number of channels -> defines public constant Nc
94+
* Supported values are Nc > 0 and Nc < 256 such that device resources are not exhausted.
95+
* Notes:
96+
* - Exhausting device resources can mean that there is not enough memory
97+
* to instantiate the corresponding number of encoders and/or decoders, but
98+
* also that computing the encoders and/or decoders in real-time is not possible.
99+
* - The parameter N_c_max described in the LC3 specifciation is not given here,
100+
* since there is too little knowledge on the target devices where this code
101+
* may be used.
102+
*
103+
*/
104+
Lc3Config(uint16_t Fs_, FrameDuration N_ms_, uint8_t Nc_);
105+
106+
// no default constructor supported
107+
Lc3Config() = delete;
108+
109+
// Destructor
110+
virtual ~Lc3Config();
111+
112+
/*
113+
* Getter "isValid" provides a convenience function that returns true when an instance of Lc3Config
114+
* could be created without error.
115+
*/
116+
bool isValid() const;
117+
118+
/*
119+
* Getter "getErrorStatus" provides details on the success of instantiating Lc3Config.
120+
* The possible return values are listed as constants in this class (see configuration error constants above)
121+
*/
122+
uint8_t getErrorStatus() const;
123+
124+
/*
125+
* Getter "getByteCountFromBitrate" provides the number of bytes available in one encoded frame
126+
* of one channel (see "nbytes" as described in Section 3.2.5 "Bit budget and bitrate" (dr09r07) )
127+
*
128+
* The number of bytes "nbytes" to use for encoding a single channel is a required external input to
129+
* each single channel LC3 encoder. The same number of bytes (now to be used for decoding) is also
130+
* a required external input to each single channel LC3 decoder. The corresponding number of bits
131+
* available in one frame is thus "nbits 8*nbytes".
132+
* The codec works on a byte boundary, i.e. the variable "nbytes" shall be an integer number.
133+
* A certain "bitrate" can be converted to a number of bytes "nbytes" where the number of bytes is
134+
* rounded towards the nearest lower integer.
135+
*
136+
* The algorithm is verified from the bitrate corresponding to
137+
* nbytes = 20 up to the bitrate corresponding to
138+
* nbytes = 400 per channel for all sampling rates.
139+
* The LC3 specification does not specify or recommend what bitrate to use for encoding a frame of
140+
* audio samples. This is specified by the profiles making use of the LC3.
141+
*/
142+
uint16_t getByteCountFromBitrate(uint32_t bitrate) const; // meant for a single channel
143+
144+
/*
145+
* Getter "getBitrateFromByteCount" provides the bitrate of the codec in bits per second
146+
* of one channel (see Section 3.2.5 "Bit budget and bitrate" (dr1.0r03) )
147+
*
148+
* This is a convenience utility and not directly used by the LC3 implementation.
149+
*
150+
* The bitrate of the codec in bits per second is
151+
* "bitrate = ceil(nbits / frame_duration) = ceil(nbits*Fs/NF) = ceil(8*nbytes*Fs/NF)".
152+
*
153+
* The LC3 specification does not specify or recommend what bitrate to use for encoding a frame of
154+
* audio samples. This is specified by the profiles making use of the LC3.
155+
*/
156+
uint32_t getBitrateFromByteCount(uint16_t nbytes) const;
157+
158+
/*
159+
* Getter "getFscal" provides a utility used within the LC3 implementation
160+
* for easier parameter mapping when Fs == 44100
161+
* (see Section 3.2.2 "Sampling rates" (dr1.0r03) )
162+
*/
163+
double getFscal() const;
164+
165+
166+
/*
167+
* Getter "getNmsValue" provides a utility used within the LC3 implementation
168+
* that converts FrameDuration N_ms enumeration values to duration values in milliseconds.
169+
*/
170+
double getNmsValue() const;
171+
172+
private:
173+
// internal utilities used for verifying the given input parameters and computing derived parameters
174+
uint8_t getFs_ind(uint16_t Fs);
175+
uint16_t getNF(uint16_t Fs, FrameDuration N_ms);
176+
uint16_t getNE(uint16_t NF, FrameDuration N_ms);
177+
178+
// errors status set during construction and returned by getErrorStatus()
179+
uint8_t errorStatus;
180+
181+
public:
182+
// configuration details -> see also Section 3.1.2 "Mathematical symbols" (dr09r07)
183+
const uint16_t Fs; // Sampling rate (in Hz)
184+
const uint8_t Fs_ind; // Sampling rate index (see also Section 3.2.2 "Sampling rates" (dr09r07)
185+
const FrameDuration N_ms; // Frame duration -> see Lc3Config constructor documentation
186+
// Note: that the actual frame duration is longer by a factor of 480/441
187+
// if the sampling rate is 44100 Hz
188+
const uint16_t NF; // Number of samples processed in one frame of one channel (also known as frame size)
189+
const uint16_t NE; // Number of encoded spectral lines (per frame and channel)
190+
const uint16_t Z; // Number of leading zeros in MDCT window
191+
const uint8_t Nc; // Number of channels
192+
const uint8_t N_b; // Number of bands
193+
};
194+
195+
#endif // __LC3_CONFIG_HPP_

0 commit comments

Comments
 (0)