mirror of
https://github.com/google/liblc3.git
synced 2026-04-24 00:04:48 +00:00
feature: Add High-Resolution LC3 plus mode
Duplicate interfaces for HR mode spec: Remove intermediate quantized table fix: legacy lc3_frame_bytes() and lc3_resolve_bitrate() Cosmetic: rename fast_xxx math function to lc3_xxx
This commit is contained in:
@@ -50,11 +50,12 @@ enum class PcmFormat {
|
||||
template <typename T>
|
||||
class Base {
|
||||
protected:
|
||||
Base(int dt_us, int sr_hz, int sr_pcm_hz, size_t nchannels)
|
||||
Base(int dt_us, int sr_hz, int sr_pcm_hz, size_t nchannels, bool hrmode)
|
||||
: dt_us_(dt_us),
|
||||
sr_hz_(sr_hz),
|
||||
sr_pcm_hz_(sr_pcm_hz == 0 ? sr_hz : sr_pcm_hz),
|
||||
nchannels_(nchannels) {
|
||||
nchannels_(nchannels),
|
||||
hrmode_(hrmode) {
|
||||
states.reserve(nchannels_);
|
||||
}
|
||||
|
||||
@@ -63,22 +64,27 @@ class Base {
|
||||
int dt_us_, sr_hz_;
|
||||
int sr_pcm_hz_;
|
||||
size_t nchannels_;
|
||||
bool hrmode_;
|
||||
|
||||
using state_ptr = std::unique_ptr<T, decltype(&free)>;
|
||||
std::vector<state_ptr> states;
|
||||
|
||||
public:
|
||||
// Return the number of PCM samples in a frame
|
||||
int GetFrameSamples() { return lc3_frame_samples(dt_us_, sr_pcm_hz_); }
|
||||
int GetFrameSamples() {
|
||||
return lc3_hr_frame_samples(hrmode_, dt_us_, sr_pcm_hz_); }
|
||||
|
||||
// Return the size of frames, from bitrate
|
||||
int GetFrameBytes(int bitrate) { return lc3_frame_bytes(dt_us_, bitrate); }
|
||||
int GetFrameBytes(int bitrate) {
|
||||
return lc3_hr_frame_bytes(hrmode_, dt_us_, sr_hz_, bitrate); }
|
||||
|
||||
// Resolve the bitrate, from the size of frames
|
||||
int ResolveBitrate(int nbytes) { return lc3_resolve_bitrate(dt_us_, nbytes); }
|
||||
int ResolveBitrate(int nbytes) {
|
||||
return lc3_hr_resolve_bitrate(hrmode_, dt_us_, sr_hz_, nbytes); }
|
||||
|
||||
// Return algorithmic delay, as a number of samples
|
||||
int GetDelaySamples() { return lc3_delay_samples(dt_us_, sr_pcm_hz_); }
|
||||
int GetDelaySamples() {
|
||||
return lc3_hr_delay_samples(hrmode_, dt_us_, sr_pcm_hz_); }
|
||||
|
||||
}; // class Base
|
||||
|
||||
@@ -101,21 +107,24 @@ class Encoder : public Base<struct lc3_encoder> {
|
||||
public:
|
||||
// Encoder construction / destruction
|
||||
//
|
||||
// The frame duration `dt_us` is 7500 or 10000 us.
|
||||
// The frame duration `dt_us` is 2500, 5000, 7500 or 10000 us.
|
||||
// The samplerate `sr_hz` is 8000, 16000, 24000, 32000 or 48000 Hz.
|
||||
// The `hrmode` flag enables the high-resolution mode, in which case
|
||||
// the sample rate is 48000 or 96000 Hz.
|
||||
//
|
||||
// The `sr_pcm_hz` parameter is a downsampling option of PCM input,
|
||||
// the value 0 fallback to the samplerate of the encoded stream `sr_hz`.
|
||||
// When used, `sr_pcm_hz` is intended to be higher or equal to the encoder
|
||||
// samplerate `sr_hz`.
|
||||
|
||||
Encoder(int dt_us, int sr_hz, int sr_pcm_hz = 0, size_t nchannels = 1)
|
||||
: Base(dt_us, sr_hz, sr_pcm_hz, nchannels) {
|
||||
Encoder(int dt_us, int sr_hz, int sr_pcm_hz = 0,
|
||||
size_t nchannels = 1, bool hrmode = false)
|
||||
: Base(dt_us, sr_hz, sr_pcm_hz, nchannels, hrmode) {
|
||||
for (size_t ich = 0; ich < nchannels_; ich++) {
|
||||
auto s = state_ptr(
|
||||
(lc3_encoder_t)malloc(lc3_encoder_size(dt_us_, sr_pcm_hz_)), free);
|
||||
auto s = state_ptr((lc3_encoder_t)
|
||||
malloc(lc3_hr_encoder_size(hrmode_, dt_us_, sr_pcm_hz_)), free);
|
||||
|
||||
if (lc3_setup_encoder(dt_us_, sr_hz_, sr_pcm_hz_, s.get()))
|
||||
if (lc3_setup_hr_encoder(hrmode_, dt_us_, sr_hz_, sr_pcm_hz_, s.get()))
|
||||
states.push_back(std::move(s));
|
||||
}
|
||||
}
|
||||
@@ -126,7 +135,7 @@ class Encoder : public Base<struct lc3_encoder> {
|
||||
|
||||
void Reset() {
|
||||
for (auto &s : states)
|
||||
lc3_setup_encoder(dt_us_, sr_hz_, sr_pcm_hz_, s.get());
|
||||
lc3_setup_hr_encoder(hrmode_, dt_us_, sr_hz_, sr_pcm_hz_, s.get());
|
||||
}
|
||||
|
||||
// Encode
|
||||
@@ -199,21 +208,24 @@ class Decoder : public Base<struct lc3_decoder> {
|
||||
public:
|
||||
// Decoder construction / destruction
|
||||
//
|
||||
// The frame duration `dt_us` is 7500 or 10000 us.
|
||||
// The frame duration `dt_us` is 2500, 5000, 7500 or 10000 us.
|
||||
// The samplerate `sr_hz` is 8000, 16000, 24000, 32000 or 48000 Hz.
|
||||
// The `hrmode` flag enables the high-resolution mode, in which case
|
||||
// the sample rate is 48000 or 96000 Hz.
|
||||
//
|
||||
// The `sr_pcm_hz` parameter is an downsampling option of PCM output,
|
||||
// the value 0 fallback to the samplerate of the decoded stream `sr_hz`.
|
||||
// When used, `sr_pcm_hz` is intended to be higher or equal to the decoder
|
||||
// samplerate `sr_hz`.
|
||||
|
||||
Decoder(int dt_us, int sr_hz, int sr_pcm_hz = 0, size_t nchannels = 1)
|
||||
: Base(dt_us, sr_hz, sr_pcm_hz, nchannels) {
|
||||
Decoder(int dt_us, int sr_hz, int sr_pcm_hz = 0,
|
||||
size_t nchannels = 1, bool hrmode = false)
|
||||
: Base(dt_us, sr_hz, sr_pcm_hz, nchannels, hrmode) {
|
||||
for (size_t i = 0; i < nchannels_; i++) {
|
||||
auto s = state_ptr(
|
||||
(lc3_decoder_t)malloc(lc3_decoder_size(dt_us_, sr_pcm_hz_)), free);
|
||||
auto s = state_ptr((lc3_decoder_t)
|
||||
malloc(lc3_hr_decoder_size(hrmode_, dt_us_, sr_pcm_hz_)), free);
|
||||
|
||||
if (lc3_setup_decoder(dt_us_, sr_hz_, sr_pcm_hz_, s.get()))
|
||||
if (lc3_setup_hr_decoder(hrmode_, dt_us_, sr_hz_, sr_pcm_hz_, s.get()))
|
||||
states.push_back(std::move(s));
|
||||
}
|
||||
}
|
||||
@@ -224,7 +236,7 @@ class Decoder : public Base<struct lc3_decoder> {
|
||||
|
||||
void Reset() {
|
||||
for (auto &s : states)
|
||||
lc3_setup_decoder(dt_us_, sr_hz_, sr_pcm_hz_, s.get());
|
||||
lc3_setup_hr_decoder(hrmode_, dt_us_, sr_hz_, sr_pcm_hz_, s.get());
|
||||
}
|
||||
|
||||
// Decode
|
||||
|
||||
Reference in New Issue
Block a user