diff --git a/3rd-party/README.md b/3rd-party/README.md index ca6abbee8..3e5a47306 100644 --- a/3rd-party/README.md +++ b/3rd-party/README.md @@ -8,6 +8,7 @@ Library [hxcmod-player](https://github.com/jfdelnero/HxCModPlayer) | 03d495c8 | Public Domain | A2DP Source Demo | mod music player [kiss-fft](https://github.com/mborgerding/kissfft) | 131.1.0 | BSD 2-Clause | LE Audio | FFT library [EHIMA LC3 Codec](https://github.com/zephyrproject-rtos/liblc3codec) | 6e8ad0bd | Apache 2.0 | LE Audio | audio codec +[Google LC3 Codec](https://android.googlesource.com/platform/packages/modules/Bluetooth) | 49b925f1 | Apache 2.0 | LE Audio | audio codec [lwIP](http://savannah.nongnu.org/projects/lwip/) | b3a93941 | BSD 3-Clause | PAN Demo | complete network stack [md5](http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5) | 1.0 | Public Domain | PBAP | cryptographic hash function [micro-ecc](https://github.com/kmackay/micro-ecc) | e4d264b5 | BSD 2-Clause | LE SC, Mesh | elliptic curve library @@ -15,3 +16,4 @@ Library [segger-rtt](https://www.segger.com/products/debug-probes/j-link/technology/about-real-time-transfer/) | v6.20d | BSD 3-Clause | HCI PacketLog | high-speed logging with SEGGER J-Link debug probes (development) [tinydir](https://github.com/cxong/tinydir) | 677733da | BSD 2-Clause | GAP Bonding | get a directory listing on POSIX + Windwows systems [Yxml](https://dev.yorhel.nl/yxml) | 10f968b0 | MIT | PBAP | minimal stream XML parser + \ No newline at end of file diff --git a/3rd-party/lc3-google/Android.bp b/3rd-party/lc3-google/Android.bp new file mode 100644 index 000000000..8219ccf83 --- /dev/null +++ b/3rd-party/lc3-google/Android.bp @@ -0,0 +1,61 @@ +package { + // See: http://go/android-license-faq + // A large-scale-change added 'default_applicable_licenses' to import + // all of the 'license_kinds' from "system_bt_license" + // to get the below license kinds: + // SPDX-license-identifier-Apache-2.0 + default_applicable_licenses: ["system_bt_license"], +} + +cc_library_static { + name: "liblc3", + host_supported: true, + apex_available: [ + + "//apex_available:platform", + "com.android.bluetooth" + ], + defaults: ["fluoride_defaults"], + srcs: [ + "src/*.c", + ], + cflags: [ + "-O3", + "-ffast-math", + "-Werror", + "-Wmissing-braces", + "-Wno-unused-parameter", + "-Wno-#warnings", + "-Wuninitialized", + "-Wno-self-assign", + "-Wno-implicit-fallthrough", + ], + target: { + android: { + sanitize: { + misc_undefined:[ + "unsigned-integer-overflow", + "signed-integer-overflow", + "bounds", + ], + cfi: true, + }, + }, + }, + export_include_dirs: [ + "include", + ], +} + +cc_fuzz { + name: "liblc3_fuzzer", + + srcs: [ + "fuzzer/liblc3_fuzzer.cpp", + ], + + static_libs: [ + "liblc3", + ], +} + diff --git a/3rd-party/lc3-google/fuzzer/liblc3_fuzzer.cpp b/3rd-party/lc3-google/fuzzer/liblc3_fuzzer.cpp new file mode 100644 index 000000000..88577bd40 --- /dev/null +++ b/3rd-party/lc3-google/fuzzer/liblc3_fuzzer.cpp @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include "include/lc3.h" + +void TestEncoder(FuzzedDataProvider& fdp) { + enum lc3_pcm_format pcm_format = + fdp.PickValueInArray({LC3_PCM_FORMAT_S16, LC3_PCM_FORMAT_S24}); + int dt_us = fdp.PickValueInArray({10000, 7500}); + int sr_hz = + fdp.PickValueInArray({8000, 16000, 24000, 32000, /*44100,*/ 48000}); + unsigned enc_size = lc3_encoder_size(dt_us, sr_hz); + uint16_t output_byte_count = fdp.ConsumeIntegralInRange(20, 400); + uint16_t num_frames = lc3_frame_samples(dt_us, sr_hz); + uint8_t bytes_per_frame = (pcm_format == LC3_PCM_FORMAT_S16 ? 2 : 4); + + if (fdp.remaining_bytes() < num_frames * bytes_per_frame) { + return; + } + + std::vector input_frames( + num_frames / (pcm_format == LC3_PCM_FORMAT_S16 ? 2 : 1)); + fdp.ConsumeData(input_frames.data(), num_frames * bytes_per_frame); + + void* lc3_encoder_mem = nullptr; + lc3_encoder_mem = malloc(enc_size); + lc3_encoder_t lc3_encoder = + lc3_setup_encoder(dt_us, sr_hz, 0, lc3_encoder_mem); + + std::vector output(output_byte_count); + lc3_encode(lc3_encoder, pcm_format, (const int16_t*)input_frames.data(), 1, + output.size(), output.data()); + + free(lc3_encoder_mem); + lc3_encoder_mem = nullptr; + return; +} + +void TestDecoder(FuzzedDataProvider& fdp) { + enum lc3_pcm_format pcm_format = + fdp.PickValueInArray({LC3_PCM_FORMAT_S16, LC3_PCM_FORMAT_S24}); + int dt_us = fdp.PickValueInArray({10000, 7500}); + int sr_hz = + fdp.PickValueInArray({8000, 16000, 24000, 32000, /*44100,*/ 48000}); + unsigned dec_size = lc3_decoder_size(dt_us, sr_hz); + uint16_t input_byte_count = fdp.ConsumeIntegralInRange(20, 400); + uint16_t num_frames = lc3_frame_samples(dt_us, sr_hz); + + if (fdp.remaining_bytes() < input_byte_count) { + return; + } + + std::vector input(input_byte_count); + fdp.ConsumeData(input.data(), input.size()); + + void* lc3_decoder_mem = nullptr; + lc3_decoder_mem = malloc(dec_size); + lc3_decoder_t lc3_decoder = + lc3_setup_decoder(dt_us, sr_hz, 0, lc3_decoder_mem); + + std::vector output(num_frames / + (pcm_format == LC3_PCM_FORMAT_S16 ? 2 : 1)); + lc3_decode(lc3_decoder, input.data(), input.size(), pcm_format, + (int16_t*)output.data(), 1); + + /* Empty input performs PLC (packet loss concealment) */ + lc3_decode(lc3_decoder, nullptr, 0, pcm_format, (int16_t*)output.data(), 1); + + free(lc3_decoder_mem); + lc3_decoder_mem = nullptr; + return; +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { + FuzzedDataProvider fdp(data, size); + TestEncoder(fdp); + TestDecoder(fdp); + return 0; +} \ No newline at end of file diff --git a/3rd-party/lc3-google/include/lc3.h b/3rd-party/lc3-google/include/lc3.h new file mode 100644 index 000000000..652d69469 --- /dev/null +++ b/3rd-party/lc3-google/include/lc3.h @@ -0,0 +1,300 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * Low Complexity Communication Codec (LC3) + * + * This implementation conforms to : + * Low Complexity Communication Codec (LC3) + * Bluetooth Specification v1.0 + * + * + * The LC3 is an efficient low latency audio codec. + * + * - Unlike most other codecs, the LC3 codec is focused on audio streaming + * in constrained (on packet sizes and interval) tranport layer. + * In this way, the LC3 does not handle : + * VBR (Variable Bitrate), based on input signal complexity + * ABR (Adaptative Bitrate). It does not rely on any bit reservoir, + * a frame will be strictly encoded in the bytes budget given by + * the user (or transport layer). + * + * However, the bitrate (bytes budget for encoding a frame) can be + * freely changed at any time. But will not rely on signal complexity, + * it can follow a temporary bandwidth increase or reduction. + * + * - Unlike classic codecs, the LC3 codecs does not run on fixed amount + * of samples as input. It operate only on fixed frame duration, for + * any supported samplerates (8 to 48 KHz). Two frame duration are + * available 7.5ms and 10ms. + * + * + * --- About 44.1 KHz samplerate --- + * + * The Bluetooth specification oddly add the 44.1 KHz samplerate. Although + * there is NO SUPPORT in the core algorithm of the codec of 44.1 KHz. + * We can summarize the 44.1 KHz support by "you can put any samplerate + * around the base defined samplerates". But be concerned by : + * + * 1. The frame size will not be 7.5 ms or 10 ms, but is scaled + * by 'supported samplerate' / 'input samplerate' + * + * 2. The bandwidth will be hard limited (to 20 KHz) if you select 48 KHz. + * The encoded bandwidth will also be affected by the above inverse + * factor of 20 KHz. + * + * Applied to 44.1 KHz, we get : + * + * 1. About 8.16 ms frame duration, instead of 7.5 ms + * About 10.88 ms frame duration, instead of 10 ms + * + * 2. The bandwidth becomes limited to 18.375 KHz + * + * + * --- How to encode / decode --- + * + * An encoder / decoder context need to be setup. This context keep states + * on the current stream to proceed, and samples that overlapped across + * frames. + * + * You have two ways to setup the encoder / decoder : + * + * - Using static memory allocation (this module does not rely on + * any dynamic memory allocation). The types `lc3_xxcoder_mem_16k_t`, + * and `lc3_xxcoder_mem_48k_t` have size of the memory needed for + * encoding up to 16 KHz or 48 KHz. + * + * - Using dynamic memory allocation. The `lc3_xxcoder_size()` procedure + * returns the needed memory size, for a given configuration. The memory + * space must be aligned to a pointer size. As an example, you can setup + * encoder like this : + * + * | enc = lc3_setup_encoder(frame_us, samplerate, + * | malloc(lc3_encoder_size(frame_us, samplerate))); + * | ... + * | free(enc); + * + * Note : + * - A NULL memory adress as input, will return a NULL encoder context. + * - The returned encoder handle is set at the address of the allocated + * memory space, you can directly free the handle. + * + * Next, call the `lc3_encode()` encoding procedure, for each frames. + * To handle multichannel streams (Stereo or more), you can proceed with + * inerleaved channels PCM stream like this : + * + * | for(int ich = 0; ich < nch: ich++) + * | lc3_encode(encoder[ich], pcm + ich, nch, ...); + * + * with `nch` as the number of channels in the PCM stream + */ + +#ifndef __LC3_H +#define __LC3_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include "lc3_private.h" + + +/** + * Limitations + * - On the bitrate, in bps, of a stream + * - On the size of the frames in bytes + */ + +#define LC3_MIN_BITRATE 16000 +#define LC3_MAX_BITRATE 320000 + +#define LC3_MIN_FRAME_BYTES 20 +#define LC3_MAX_FRAME_BYTES 400 + + +/** + * Parameters check + * LC3_CHECK_DT_US(us) True when frame duration in us is suitable + * LC3_CHECK_SR_HZ(sr) True when samplerate in Hz is suitable + */ + +#define LC3_CHECK_DT_US(us) \ + ( ((us) == 7500) || ((us) == 10000) ) + +#define LC3_CHECK_SR_HZ(sr) \ + ( ((sr) == 8000) || ((sr) == 16000) || ((sr) == 24000) || \ + ((sr) == 32000) || ((sr) == 48000) ) + + +/** + * PCM Sample Format + * S16 Signed 16 bits, in 16 bits words (int16_t) + * S24 Signed 24 bits, using low three bytes of 32 bits words (int32_t). + * The high byte sign extends the sample value (bits 31..24 set to b23). + */ + +enum lc3_pcm_format { + LC3_PCM_FORMAT_S16, + LC3_PCM_FORMAT_S24, +}; + + +/** + * Handle + */ + +typedef struct lc3_encoder *lc3_encoder_t; +typedef struct lc3_decoder *lc3_decoder_t; + + +/** + * Static memory of encoder context + * + * Propose types suitable for static memory allocation, supporting + * any frame duration, and maximum samplerates 16k and 48k respectively + * You can customize your type using the `LC3_ENCODER_MEM_T` or + * `LC3_DECODER_MEM_T` macro. + */ + +typedef LC3_ENCODER_MEM_T(10000, 16000) lc3_encoder_mem_16k_t; +typedef LC3_ENCODER_MEM_T(10000, 48000) lc3_encoder_mem_48k_t; + +typedef LC3_DECODER_MEM_T(10000, 16000) lc3_decoder_mem_16k_t; +typedef LC3_DECODER_MEM_T(10000, 48000) lc3_decoder_mem_48k_t; + + +/** + * Return the number of PCM samples in a frame + * dt_us Frame duration in us, 7500 or 10000 + * sr_hz Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000 + * return Number of PCM samples, -1 on bad parameters + */ +int lc3_frame_samples(int dt_us, int sr_hz); + +/** + * Return the size of frames, from bitrate + * dt_us Frame duration in us, 7500 or 10000 + * bitrate Target bitrate in bit per seconds + * return The floor size in bytes of the frames, -1 on bad parameters + */ +int lc3_frame_bytes(int dt_us, int bitrate); + +/** + * Resolve the bitrate, from the size of frames + * dt_us Frame duration in us, 7500 or 10000 + * nbytes Size in bytes of the frames + * return The according bitrate in bps, -1 on bad parameters + */ +int lc3_resolve_bitrate(int dt_us, int nbytes); + +/** + * Return algorithmic delay, as a number of samples + * dt_us Frame duration in us, 7500 or 10000 + * sr_hz Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000 + * return Number of algorithmic delay samples, -1 on bad parameters + */ +int lc3_delay_samples(int dt_us, int sr_hz); + +/** + * Return size needed for an encoder + * dt_us Frame duration in us, 7500 or 10000 + * sr_hz Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000 + * return Size of then encoder in bytes, 0 on bad parameters + * + * The `sr_hz` parameter is the samplerate of the PCM input stream, + * and will match `sr_pcm_hz` of `lc3_setup_encoder()`. + */ +unsigned lc3_encoder_size(int dt_us, int sr_hz); + +/** + * Setup encoder + * dt_us Frame duration in us, 7500 or 10000 + * sr_hz Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000 + * sr_pcm_hz Input samplerate, downsampling option of input, or 0 + * mem Encoder memory space, aligned to pointer type + * return Encoder as an handle, NULL on bad parameters + * + * 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`. The size of the context needed, given by + * `lc3_encoder_size()` will be set accordingly to `sr_pcm_hz`. + */ +lc3_encoder_t lc3_setup_encoder( + int dt_us, int sr_hz, int sr_pcm_hz, void *mem); + +/** + * Encode a frame + * encoder Handle of the encoder + * fmt PCM input format + * pcm, stride Input PCM samples, and count between two consecutives + * nbytes Target size, in bytes, of the frame (20 to 400) + * out Output buffer of `nbytes` size + * return 0: On success -1: Wrong parameters + */ +int lc3_encode(lc3_encoder_t encoder, enum lc3_pcm_format fmt, + const void *pcm, int stride, int nbytes, void *out); + +/** + * Return size needed for an decoder + * dt_us Frame duration in us, 7500 or 10000 + * sr_hz Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000 + * return Size of then decoder in bytes, 0 on bad parameters + * + * The `sr_hz` parameter is the samplerate of the PCM output stream, + * and will match `sr_pcm_hz` of `lc3_setup_decoder()`. + */ +unsigned lc3_decoder_size(int dt_us, int sr_hz); + +/** + * Setup decoder + * dt_us Frame duration in us, 7500 or 10000 + * sr_hz Samplerate in Hz, 8000, 16000, 24000, 32000 or 48000 + * sr_pcm_hz Output samplerate, upsampling option of output (or 0) + * mem Decoder memory space, aligned to pointer type + * return Decoder as an handle, NULL on bad parameters + * + * The `sr_pcm_hz` parameter is an upsampling 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`. The size of the context needed, given by + * `lc3_decoder_size()` will be set accordingly to `sr_pcm_hz`. + */ +lc3_decoder_t lc3_setup_decoder( + int dt_us, int sr_hz, int sr_pcm_hz, void *mem); + +/** + * Decode a frame + * decoder Handle of the decoder + * in, nbytes Input bitstream, and size in bytes, NULL performs PLC + * fmt PCM output format + * pcm, stride Output PCM samples, and count between two consecutives + * return 0: On success 1: PLC operated -1: Wrong parameters + */ +int lc3_decode(lc3_decoder_t decoder, const void *in, int nbytes, + enum lc3_pcm_format fmt, void *pcm, int stride); + + +#ifdef __cplusplus +} +#endif + +#endif /* __LC3_H */ diff --git a/3rd-party/lc3-google/include/lc3_private.h b/3rd-party/lc3-google/include/lc3_private.h new file mode 100644 index 000000000..c59ff53d4 --- /dev/null +++ b/3rd-party/lc3-google/include/lc3_private.h @@ -0,0 +1,156 @@ +/****************************************************************************** + * + * Copyright 2015 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#ifndef __LC3_PRIVATE_H +#define __LC3_PRIVATE_H + +#include +#include + + +/** + * Return number of samples, delayed samples and + * encoded spectrum coefficients within a frame + * For decoding, add number of samples of 18 ms history + */ + +#define __LC3_NS(dt_us, sr_hz) \ + ((dt_us * sr_hz) / 1000 / 1000) + +#define __LC3_ND(dt_us, sr_hz) \ + ( (dt_us) == 7500 ? 23 * __LC3_NS(dt_us, sr_hz) / 30 \ + : 5 * __LC3_NS(dt_us, sr_hz) / 8 ) + +#define __LC3_NH(sr_hz) \ + ( (18 * sr_hz) / 1000 ) + + +/** + * Frame duration 7.5ms or 10ms + */ + +enum lc3_dt { + LC3_DT_7M5, + LC3_DT_10M, + + LC3_NUM_DT +}; + +/** + * Sampling frequency + */ + +enum lc3_srate { + LC3_SRATE_8K, + LC3_SRATE_16K, + LC3_SRATE_24K, + LC3_SRATE_32K, + LC3_SRATE_48K, + + LC3_NUM_SRATE, +}; + + +/** + * Encoder state and memory + */ + +typedef struct lc3_attdet_analysis { + float en1, an1; + int p_att; +} lc3_attdet_analysis_t; + +struct lc3_ltpf_hp50_state { + float s1, s2; +}; + +typedef struct lc3_ltpf_analysis { + bool active; + int pitch; + float nc[2]; + + struct lc3_ltpf_hp50_state hp50; + float x_12k8[384]; + float x_6k4[178]; + int tc; +} lc3_ltpf_analysis_t; + +typedef struct lc3_spec_analysis { + float nbits_off; + int nbits_spare; +} lc3_spec_analysis_t; + +struct lc3_encoder { + enum lc3_dt dt; + enum lc3_srate sr, sr_pcm; + + lc3_attdet_analysis_t attdet; + lc3_ltpf_analysis_t ltpf; + lc3_spec_analysis_t spec; + + float *xs, *xf, s[0]; +}; + +#define LC3_ENCODER_BUFFER_COUNT(dt_us, sr_hz) \ + ( 2*__LC3_NS(dt_us, sr_hz) + __LC3_ND(dt_us, sr_hz) ) + +#define LC3_ENCODER_MEM_T(dt_us, sr_hz) \ + struct { \ + struct lc3_encoder __e; \ + float __s[LC3_ENCODER_BUFFER_COUNT(dt_us, sr_hz)]; \ + } + + +/** + * Decoder state and memory + */ + +typedef struct lc3_ltpf_synthesis { + bool active; + int pitch; + float c[12][2], x[12]; +} lc3_ltpf_synthesis_t; + +typedef struct lc3_plc_state { + uint16_t seed; + int count; + float alpha; +} lc3_plc_state_t; + +struct lc3_decoder { + enum lc3_dt dt; + enum lc3_srate sr, sr_pcm; + + lc3_ltpf_synthesis_t ltpf; + lc3_plc_state_t plc; + + float *xs, *xd, *xg, s[0]; +}; + +#define LC3_DECODER_BUFFER_COUNT(dt_us, sr_hz) \ + ( __LC3_NH(sr_hz) + __LC3_NS(dt_us, sr_hz) + \ + __LC3_ND(dt_us, sr_hz) + __LC3_NS(dt_us, sr_hz) ) + +#define LC3_DECODER_MEM_T(dt_us, sr_hz) \ + struct { \ + struct lc3_decoder __d; \ + float __s[LC3_DECODER_BUFFER_COUNT(dt_us, sr_hz)]; \ + } + + +#endif /* __LC3_PRIVATE_H */ diff --git a/3rd-party/lc3-google/src/attdet.c b/3rd-party/lc3-google/src/attdet.c new file mode 100644 index 000000000..6f07ed4bd --- /dev/null +++ b/3rd-party/lc3-google/src/attdet.c @@ -0,0 +1,92 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "attdet.h" + + +/** + * Time domain attack detector + */ +bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr, + int nbytes, struct lc3_attdet_analysis *attdet, const float *x) +{ + /* --- Check enabling --- */ + + const int nbytes_ranges[LC3_NUM_DT][LC3_NUM_SRATE - LC3_SRATE_32K][2] = { + [LC3_DT_7M5] = { { 61, 149 }, { 75, 149 } }, + [LC3_DT_10M] = { { 81, INT_MAX }, { 100, INT_MAX } }, + }; + + if (sr < LC3_SRATE_32K || + nbytes < nbytes_ranges[dt][sr - LC3_SRATE_32K][0] || + nbytes > nbytes_ranges[dt][sr - LC3_SRATE_32K][1] ) + return 0; + + /* --- Filtering & Energy calculation --- */ + + int nblk = 4 - (dt == LC3_DT_7M5); + float e[4]; + + for (int i = 0; i < nblk; i++) { + e[i] = 0; + + if (sr == LC3_SRATE_32K) { + float xn2 = x[-4] + x[-3]; + float xn1 = x[-2] + x[-1]; + float xn, xf; + + for (int j = 0; j < 40; j++, x += 2, xn2 = xn1, xn1 = xn) { + xn = x[0] + x[1]; + xf = 0.375 * xn - 0.5 * xn1 + 0.125 * xn2; + e[i] += xf * xf; + } + } + + else { + float xn2 = x[-6] + x[-5] + x[-4]; + float xn1 = x[-3] + x[-2] + x[-1]; + float xn, xf; + + for (int j = 0; j < 40; j++, x += 3, xn2 = xn1, xn1 = xn) { + xn = x[0] + x[1] + x[2]; + xf = 0.375 * xn - 0.5 * xn1 + 0.125 * xn2; + e[i] += xf * xf; + } + } + } + + /* --- Attack detection --- + * The attack block `p_att` is defined as the normative value + 1, + * in such way, it will be initialized to 0 */ + + int p_att = 0; + float a[4]; + + for (int i = 0; i < nblk; i++) { + a[i] = fmaxf(0.25 * attdet->an1, attdet->en1); + attdet->en1 = e[i], attdet->an1 = a[i]; + + if (e[i] > 8.5 * a[i]) + p_att = i + 1; + } + + int att = attdet->p_att >= 1 + (nblk >> 1) || p_att > 0; + attdet->p_att = p_att; + + return att; +} diff --git a/3rd-party/lc3-google/src/attdet.h b/3rd-party/lc3-google/src/attdet.h new file mode 100644 index 000000000..487537261 --- /dev/null +++ b/3rd-party/lc3-google/src/attdet.h @@ -0,0 +1,44 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * LC3 - Time domain attack detector + * + * Reference : Low Complexity Communication Codec (LC3) + * Bluetooth Specification v1.0 + */ + +#ifndef __LC3_ATTDET_H +#define __LC3_ATTDET_H + +#include "common.h" + + +/** + * Time domain attack detector + * dt, sr Duration and samplerate of the frame + * nbytes Size in bytes of the frame + * attdet Context of the Attack Detector + * x [-6..-1] Previous, [0..ns-1] Current samples + * return 1: Attack detected 0: Otherwise + */ +bool lc3_attdet_run(enum lc3_dt dt, enum lc3_srate sr, + int nbytes, lc3_attdet_analysis_t *attdet, const float *x); + + +#endif /* __LC3_ATTDET_H */ diff --git a/3rd-party/lc3-google/src/bits.c b/3rd-party/lc3-google/src/bits.c new file mode 100644 index 000000000..90b2a197b --- /dev/null +++ b/3rd-party/lc3-google/src/bits.c @@ -0,0 +1,375 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "bits.h" +#include "common.h" + + +/* ---------------------------------------------------------------------------- + * Common + * -------------------------------------------------------------------------- */ + +static inline int ac_get(struct lc3_bits_buffer *); +static inline void accu_load(struct lc3_bits_accu *, struct lc3_bits_buffer *); + +/** + * Arithmetic coder return range bits + * ac Arithmetic coder + * return 1 + log2(ac->range) + */ +static int ac_get_range_bits(const struct lc3_bits_ac *ac) +{ + int nbits = 0; + + for (unsigned r = ac->range; r; r >>= 1, nbits++); + + return nbits; +} + +/** + * Arithmetic coder return pending bits + * ac Arithmetic coder + * return Pending bits + */ +static int ac_get_pending_bits(const struct lc3_bits_ac *ac) +{ + return 26 - ac_get_range_bits(ac) + + ((ac->cache >= 0) + ac->carry_count) * 8; +} + +/** + * Return number of bits left in the bitstream + * bits Bitstream context + * return >= 0: Number of bits left < 0: Overflow + */ +static int get_bits_left(const struct lc3_bits *bits) +{ + const struct lc3_bits_buffer *buffer = &bits->buffer; + const struct lc3_bits_accu *accu = &bits->accu; + const struct lc3_bits_ac *ac = &bits->ac; + + uintptr_t end = (uintptr_t)buffer->p_bw + + (bits->mode == LC3_BITS_MODE_READ ? LC3_ACCU_BITS/8 : 0); + + uintptr_t start = (uintptr_t)buffer->p_fw - + (bits->mode == LC3_BITS_MODE_READ ? LC3_AC_BITS/8 : 0); + + int n = end > start ? (int)(end - start) : -(int)(start - end); + + return 8 * n - (accu->n + accu->nover + ac_get_pending_bits(ac)); +} + +/** + * Setup bitstream writing + */ +void lc3_setup_bits(struct lc3_bits *bits, + enum lc3_bits_mode mode, void *buffer, int len) +{ + *bits = (struct lc3_bits){ + .mode = mode, + .accu = { + .n = mode == LC3_BITS_MODE_READ ? LC3_ACCU_BITS : 0, + }, + .ac = { + .range = 0xffffff, + .cache = -1 + }, + .buffer = { + .start = (uint8_t *)buffer, .end = (uint8_t *)buffer + len, + .p_fw = (uint8_t *)buffer, .p_bw = (uint8_t *)buffer + len, + } + }; + + if (mode == LC3_BITS_MODE_READ) { + struct lc3_bits_ac *ac = &bits->ac; + struct lc3_bits_accu *accu = &bits->accu; + struct lc3_bits_buffer *buffer = &bits->buffer; + + ac->low = ac_get(buffer) << 16; + ac->low |= ac_get(buffer) << 8; + ac->low |= ac_get(buffer); + + accu_load(accu, buffer); + } +} + +/** + * Return number of bits left in the bitstream + */ +int lc3_get_bits_left(const struct lc3_bits *bits) +{ + return LC3_MAX(get_bits_left(bits), 0); +} + +/** + * Return number of bits left in the bitstream + */ +int lc3_check_bits(const struct lc3_bits *bits) +{ + const struct lc3_bits_ac *ac = &bits->ac; + + return -(get_bits_left(bits) < 0 || ac->error); +} + + +/* ---------------------------------------------------------------------------- + * Writing + * -------------------------------------------------------------------------- */ + +/** + * Flush the bits accumulator + * accu Bitstream accumulator + * buffer Bitstream buffer + */ +static inline void accu_flush( + struct lc3_bits_accu *accu, struct lc3_bits_buffer *buffer) +{ + int nbytes = LC3_MIN(accu->n >> 3, + LC3_MAX(buffer->p_bw - buffer->p_fw, 0)); + + accu->n -= 8 * nbytes; + + for ( ; nbytes; accu->v >>= 8, nbytes--) + *(--buffer->p_bw) = accu->v & 0xff; + + if (accu->n >= 8) + accu->n = 0; +} + +/** + * Arithmetic coder put byte + * buffer Bitstream buffer + * byte Byte to output + */ +static inline void ac_put(struct lc3_bits_buffer *buffer, int byte) +{ + if (buffer->p_fw < buffer->end) + *(buffer->p_fw++) = byte; +} + +/** + * Arithmetic coder range shift + * ac Arithmetic coder + * buffer Bitstream buffer + */ +static inline void ac_shift( + struct lc3_bits_ac *ac, struct lc3_bits_buffer *buffer) +{ + if (ac->low < 0xff0000 || ac->carry) + { + if (ac->cache >= 0) + ac_put(buffer, ac->cache + ac->carry); + + for ( ; ac->carry_count > 0; ac->carry_count--) + ac_put(buffer, ac->carry ? 0x00 : 0xff); + + ac->cache = ac->low >> 16; + ac->carry = 0; + } + else + ac->carry_count++; + + ac->low = (ac->low << 8) & 0xffffff; +} + +/** + * Arithmetic coder termination + * ac Arithmetic coder + * buffer Bitstream buffer + * end_val/nbits End value and count of bits to terminate (1 to 8) + */ +static void ac_terminate(struct lc3_bits_ac *ac, + struct lc3_bits_buffer *buffer) +{ + int nbits = 25 - ac_get_range_bits(ac); + unsigned mask = 0xffffff >> nbits; + unsigned val = ac->low + mask; + unsigned high = ac->low + ac->range; + + bool over_val = val >> 24; + bool over_high = high >> 24; + + val = (val & 0xffffff) & ~mask; + high = (high & 0xffffff); + + if (over_val == over_high) { + + if (val + mask >= high) { + nbits++; + mask >>= 1; + val = ((ac->low + mask) & 0xffffff) & ~mask; + } + + ac->carry |= val < ac->low; + } + + ac->low = val; + + for (; nbits > 8; nbits -= 8) + ac_shift(ac, buffer); + ac_shift(ac, buffer); + + int end_val = ac->cache >> (8 - nbits); + + if (ac->carry_count) { + ac_put(buffer, ac->cache); + for ( ; ac->carry_count > 1; ac->carry_count--) + ac_put(buffer, 0xff); + + end_val = nbits < 8 ? 0 : 0xff; + } + + if (buffer->p_fw < buffer->end) { + *buffer->p_fw &= 0xff >> nbits; + *buffer->p_fw |= end_val << (8 - nbits); + } +} + +/** + * Flush and terminate bitstream + */ +void lc3_flush_bits(struct lc3_bits *bits) +{ + struct lc3_bits_ac *ac = &bits->ac; + struct lc3_bits_accu *accu = &bits->accu; + struct lc3_bits_buffer *buffer = &bits->buffer; + + int nleft = buffer->p_bw - buffer->p_fw; + for (int n = 8 * nleft - accu->n; n > 0; n -= 32) + lc3_put_bits(bits, 0, LC3_MIN(n, 32)); + + accu_flush(accu, buffer); + + ac_terminate(ac, buffer); +} + +/** + * Write from 1 to 32 bits, + * exceeding the capacity of the accumulator + */ +void lc3_put_bits_generic(struct lc3_bits *bits, unsigned v, int n) +{ + struct lc3_bits_accu *accu = &bits->accu; + + /* --- Fulfill accumulator and flush -- */ + + int n1 = LC3_MIN(LC3_ACCU_BITS - accu->n, n); + if (n1) { + accu->v |= v << accu->n; + accu->n = LC3_ACCU_BITS; + } + + accu_flush(accu, &bits->buffer); + + /* --- Accumulate remaining bits -- */ + + accu->v = v >> n1; + accu->n = n - n1; +} + +/** + * Arithmetic coder renormalization + */ +void lc3_ac_write_renorm(struct lc3_bits *bits) +{ + struct lc3_bits_ac *ac = &bits->ac; + + for ( ; ac->range < 0x10000; ac->range <<= 8) + ac_shift(ac, &bits->buffer); +} + + +/* ---------------------------------------------------------------------------- + * Reading + * -------------------------------------------------------------------------- */ + +/** + * Arithmetic coder get byte + * buffer Bitstream buffer + * return Byte read, 0 on overflow + */ +static inline int ac_get(struct lc3_bits_buffer *buffer) +{ + return buffer->p_fw < buffer->end ? *(buffer->p_fw++) : 0; +} + +/** + * Load the accumulator + * accu Bitstream accumulator + * buffer Bitstream buffer + */ +static inline void accu_load(struct lc3_bits_accu *accu, + struct lc3_bits_buffer *buffer) +{ + int nbytes = LC3_MIN(accu->n >> 3, buffer->p_bw - buffer->start); + + accu->n -= 8 * nbytes; + + for ( ; nbytes; nbytes--) { + accu->v >>= 8; + accu->v |= *(--buffer->p_bw) << (LC3_ACCU_BITS - 8); + } + + if (accu->n >= 8) { + accu->nover = LC3_MIN(accu->nover + accu->n, LC3_ACCU_BITS); + accu->v >>= accu->n; + accu->n = 0; + } +} + +/** + * Read from 1 to 32 bits, + * exceeding the capacity of the accumulator + */ +unsigned lc3_get_bits_generic(struct lc3_bits *bits, int n) +{ + struct lc3_bits_accu *accu = &bits->accu; + struct lc3_bits_buffer *buffer = &bits->buffer; + + /* --- Fulfill accumulator and read -- */ + + accu_load(accu, buffer); + + int n1 = LC3_MIN(LC3_ACCU_BITS - accu->n, n); + unsigned v = (accu->v >> accu->n) & ((1u << n1) - 1); + accu->n += n1; + + /* --- Second round --- */ + + int n2 = n - n1; + + if (n2) { + accu_load(accu, buffer); + + v |= ((accu->v >> accu->n) & ((1u << n2) - 1)) << n1; + accu->n += n2; + } + + return v; +} + +/** + * Arithmetic coder renormalization + */ +void lc3_ac_read_renorm(struct lc3_bits *bits) +{ + struct lc3_bits_ac *ac = &bits->ac; + + for ( ; ac->range < 0x10000; ac->range <<= 8) + ac->low = ((ac->low << 8) | ac_get(&bits->buffer)) & 0xffffff; +} diff --git a/3rd-party/lc3-google/src/bits.h b/3rd-party/lc3-google/src/bits.h new file mode 100644 index 000000000..faef3370b --- /dev/null +++ b/3rd-party/lc3-google/src/bits.h @@ -0,0 +1,314 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * LC3 - Bitstream management + * + * The bitstream is written by the 2 ends of the buffer : + * + * - Arthmetic coder put bits while increasing memory addresses + * in the buffer (forward) + * + * - Plain bits are puts starting the end of the buffer, with memeory + * addresses decreasing (backward) + * + * .---------------------------------------------------. + * | > > > > > > > > > > : : < < < < < < < < < | + * '---------------------------------------------------' + * |---------------------> - - - - - - - - - - - - - ->| + * |< - - - <-------------------| + * Arithmetic coding Plain bits + * `lc3_put_symbol()` `lc3_put_bits()` + * + * - The forward writing is protected against buffer overflow, it cannot + * write after the buffer, but can overwrite plain bits previously + * written in the buffer. + * + * - The backward writing is protected against overwrite of the arithmetic + * coder bitstream. In such way, the backward bitstream is always limited + * by the aritmetic coder bitstream, and can be overwritten by him. + * + * .---------------------------------------------------. + * | > > > > > > > > > > : : < < < < < < < < < | + * '---------------------------------------------------' + * |---------------------> - - - - - - - - - - - - - ->| + * |< - - - - - - - - - - - - - - <-------------------| + * Arithmetic coding Plain bits + * `lc3_get_symbol()` `lc3_get_bits()` + * + * - Reading is limited to read of the complementary end of the buffer. + * + * - The procedure `lc3_check_bits()` returns indication that read has been + * made crossing the other bit plane. + * + * + * Reference : Low Complexity Communication Codec (LC3) + * Bluetooth Specification v1.0 + * + */ + +#ifndef __LC3_BITS_H +#define __LC3_BITS_H + +#include "common.h" + + +/** + * Bitstream mode + */ + +enum lc3_bits_mode { + LC3_BITS_MODE_READ, + LC3_BITS_MODE_WRITE, +}; + +/** + * Arithmetic coder symbol interval + * The model split the interval in 17 symbols + */ + +struct lc3_ac_symbol { + uint16_t low : 16; + uint16_t range : 16; +}; + +struct lc3_ac_model { + struct lc3_ac_symbol s[17]; +}; + +/** + * Bitstream context + */ + +#define LC3_ACCU_BITS (int)(8 * sizeof(unsigned)) + +struct lc3_bits_accu { + unsigned v; + int n, nover; +}; + +#define LC3_AC_BITS (int)(24) + +struct lc3_bits_ac { + unsigned low, range; + int cache, carry, carry_count; + bool error; +}; + +struct lc3_bits_buffer { + const uint8_t *start, *end; + uint8_t *p_fw, *p_bw; +}; + +typedef struct lc3_bits { + enum lc3_bits_mode mode; + struct lc3_bits_ac ac; + struct lc3_bits_accu accu; + struct lc3_bits_buffer buffer; +} lc3_bits_t; + + +/** + * Setup bitstream reading/writing + * bits Bitstream context + * mode Either READ or WRITE mode + * buffer, len Output buffer and length (in bytes) + */ +void lc3_setup_bits(lc3_bits_t *bits, + enum lc3_bits_mode mode, void *buffer, int len); + +/** + * Return number of bits left in the bitstream + * bits Bitstream context + * return Number of bits left + */ +int lc3_get_bits_left(const lc3_bits_t *bits); + +/** + * Check if error occured on bitstream reading/writing + * bits Bitstream context + * return 0: Ok -1: Bitstream overflow or AC reading error + */ +int lc3_check_bits(const lc3_bits_t *bits); + +/** + * Put a bit + * bits Bitstream context + * v Bit value, 0 or 1 + */ +static inline void lc3_put_bit(lc3_bits_t *bits, int v); + +/** + * Put from 1 to 32 bits + * bits Bitstream context + * v, n Value, in range 0 to 2^n - 1, and bits count (1 to 32) + */ +static inline void lc3_put_bits(lc3_bits_t *bits, unsigned v, int n); + +/** + * Put arithmetic coder symbol + * bits Bitstream context + * model, s Model distribution and symbol value + */ +static inline void lc3_put_symbol(lc3_bits_t *bits, + const struct lc3_ac_model *model, unsigned s); + +/** + * Flush and terminate bitstream writing + * bits Bitstream context + */ +void lc3_flush_bits(lc3_bits_t *bits); + +/** + * Get a bit + * bits Bitstream context + */ +static inline int lc3_get_bit(lc3_bits_t *bits); + +/** + * Get from 1 to 32 bits + * bits Bitstream context + * n Number of bits to read (1 to 32) + * return The value read + */ +static inline unsigned lc3_get_bits(lc3_bits_t *bits, int n); + +/** + * Get arithmetic coder symbol + * bits Bitstream context + * model Model distribution + * return The value read + */ +static inline unsigned lc3_get_symbol(lc3_bits_t *bits, + const struct lc3_ac_model *model); + + + +/* ---------------------------------------------------------------------------- + * Inline implementations + * -------------------------------------------------------------------------- */ + +void lc3_put_bits_generic(lc3_bits_t *bits, unsigned v, int n); +unsigned lc3_get_bits_generic(struct lc3_bits *bits, int n); + +void lc3_ac_read_renorm(lc3_bits_t *bits); +void lc3_ac_write_renorm(lc3_bits_t *bits); + + +/** + * Put a bit + */ +static inline void lc3_put_bit(lc3_bits_t *bits, int v) +{ + lc3_put_bits(bits, v, 1); +} + +/** + * Put from 1 to 32 bits + */ +static inline void lc3_put_bits(struct lc3_bits *bits, unsigned v, int n) +{ + struct lc3_bits_accu *accu = &bits->accu; + + if (accu->n + n <= LC3_ACCU_BITS) { + accu->v |= v << accu->n; + accu->n += n; + } else { + lc3_put_bits_generic(bits, v, n); + } +} + +/** + * Get a bit + */ +static inline int lc3_get_bit(lc3_bits_t *bits) +{ + return lc3_get_bits(bits, 1); +} + +/** + * Get from 1 to 32 bits + */ +static inline unsigned lc3_get_bits(struct lc3_bits *bits, int n) +{ + struct lc3_bits_accu *accu = &bits->accu; + + if (accu->n + n <= LC3_ACCU_BITS) { + int v = (accu->v >> accu->n) & ((1u << n) - 1); + return (accu->n += n), v; + } + else { + return lc3_get_bits_generic(bits, n); + } +} + +/** + * Put arithmetic coder symbol + */ +static inline void lc3_put_symbol( + struct lc3_bits *bits, const struct lc3_ac_model *model, unsigned s) +{ + const struct lc3_ac_symbol *symbols = model->s; + struct lc3_bits_ac *ac = &bits->ac; + unsigned range = ac->range >> 10; + + ac->low += range * symbols[s].low; + ac->range = range * symbols[s].range; + + ac->carry |= ac->low >> 24; + ac->low &= 0xffffff; + + if (ac->range < 0x10000) + lc3_ac_write_renorm(bits); +} + +/** + * Get arithmetic coder symbol + */ +static inline unsigned lc3_get_symbol( + lc3_bits_t *bits, const struct lc3_ac_model *model) +{ + const struct lc3_ac_symbol *symbols = model->s; + struct lc3_bits_ac *ac = &bits->ac; + + unsigned range = (ac->range >> 10) & 0xffff; + + ac->error |= (ac->low >= (range << 10)); + if (ac->error) + ac->low = 0; + + int s = 16; + + if (ac->low < range * symbols[s].low) { + s >>= 1; + s -= ac->low < range * symbols[s].low ? 4 : -4; + s -= ac->low < range * symbols[s].low ? 2 : -2; + s -= ac->low < range * symbols[s].low ? 1 : -1; + s -= ac->low < range * symbols[s].low; + } + + ac->low -= range * symbols[s].low; + ac->range = range * symbols[s].range; + + if (ac->range < 0x10000) + lc3_ac_read_renorm(bits); + + return s; +} + +#endif /* __LC3_BITS_H */ diff --git a/3rd-party/lc3-google/src/bwdet.c b/3rd-party/lc3-google/src/bwdet.c new file mode 100644 index 000000000..a8e0b0e75 --- /dev/null +++ b/3rd-party/lc3-google/src/bwdet.c @@ -0,0 +1,129 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "bwdet.h" + + +/** + * Bandwidth detector + */ +enum lc3_bandwidth lc3_bwdet_run( + enum lc3_dt dt, enum lc3_srate sr, const float *e) +{ + /* Bandwidth regions (Table 3.6) */ + + struct region { int is : 8; int ie : 8; }; + + static const struct region bws_table[LC3_NUM_DT] + [LC3_NUM_BANDWIDTH-1][LC3_NUM_BANDWIDTH-1] = { + + [LC3_DT_7M5] = { + { { 51, 63+1 } }, + { { 45, 55+1 }, { 58, 63+1 } }, + { { 42, 51+1 }, { 53, 58+1 }, { 60, 63+1 } }, + { { 40, 48+1 }, { 51, 55+1 }, { 57, 60+1 }, { 61, 63+1 } }, + }, + + [LC3_DT_10M] = { + { { 53, 63+1 } }, + { { 47, 56+1 }, { 59, 63+1 } }, + { { 44, 52+1 }, { 54, 59+1 }, { 60, 63+1 } }, + { { 41, 49+1 }, { 51, 55+1 }, { 57, 60+1 }, { 61, 63+1 } }, + }, + }; + + static const int l_table[LC3_NUM_DT][LC3_NUM_BANDWIDTH-1] = { + [LC3_DT_7M5] = { 4, 4, 3, 2 }, + [LC3_DT_10M] = { 4, 4, 3, 1 }, + }; + + /* --- Stage 1 --- + * Determine bw0 candidate */ + + enum lc3_bandwidth bw0 = LC3_BANDWIDTH_NB; + enum lc3_bandwidth bwn = (enum lc3_bandwidth)sr; + + if (bwn <= bw0) + return bwn; + + const struct region *bwr = bws_table[dt][bwn-1]; + + for (enum lc3_bandwidth bw = bw0; bw < bwn; bw++) { + int i = bwr[bw].is, ie = bwr[bw].ie; + int n = ie - i; + + float se = e[i]; + for (i++; i < ie; i++) + se += e[i]; + + if (se >= (10 << (bw == LC3_BANDWIDTH_NB)) * n) + bw0 = bw + 1; + } + + /* --- Stage 2 --- + * Detect drop above cut-off frequency. + * The Tc condition (13) is precalculated, as + * Tc[] = 10 ^ (n / 10) , n = { 15, 23, 20, 20 } */ + + int hold = bw0 >= bwn; + + if (!hold) { + int i0 = bwr[bw0].is, l = l_table[dt][bw0]; + float tc = (const float []){ + 31.62277660, 199.52623150, 100, 100 }[bw0]; + + for (int i = i0 - l + 1; !hold && i <= i0 + 1; i++) { + hold = e[i-l] > tc * e[i]; + } + + } + + return hold ? bw0 : bwn; +} + +/** + * Return number of bits coding the bandwidth value + */ +int lc3_bwdet_get_nbits(enum lc3_srate sr) +{ + return (sr > 0) + (sr > 1) + (sr > 3); +} + +/** + * Put bandwidth indication + */ +void lc3_bwdet_put_bw(lc3_bits_t *bits, + enum lc3_srate sr, enum lc3_bandwidth bw) +{ + int nbits_bw = lc3_bwdet_get_nbits(sr); + if (nbits_bw > 0) + lc3_put_bits(bits, bw, nbits_bw); +} + +/** + * Get bandwidth indication + */ +int lc3_bwdet_get_bw(lc3_bits_t *bits, + enum lc3_srate sr, enum lc3_bandwidth *bw) +{ + enum lc3_bandwidth max_bw = (enum lc3_bandwidth)sr; + int nbits_bw = lc3_bwdet_get_nbits(sr); + + *bw = nbits_bw > 0 ? lc3_get_bits(bits, nbits_bw) : LC3_BANDWIDTH_NB; + return *bw > max_bw ? (*bw = max_bw), -1 : 0; +} diff --git a/3rd-party/lc3-google/src/bwdet.h b/3rd-party/lc3-google/src/bwdet.h new file mode 100644 index 000000000..ba9240e72 --- /dev/null +++ b/3rd-party/lc3-google/src/bwdet.h @@ -0,0 +1,69 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * LC3 - Bandwidth detector + * + * Reference : Low Complexity Communication Codec (LC3) + * Bluetooth Specification v1.0 + */ + +#ifndef __LC3_BWDET_H +#define __LC3_BWDET_H + +#include "common.h" +#include "bits.h" + + +/** + * Bandwidth detector (cf. 3.3.5) + * dt, sr Duration and samplerate of the frame + * e Energy estimation per bands + * return Return detected bandwitdth + */ +enum lc3_bandwidth lc3_bwdet_run( + enum lc3_dt dt, enum lc3_srate sr, const float *e); + +/** + * Return number of bits coding the bandwidth value + * sr Samplerate of the frame + * return Number of bits coding the bandwidth value + */ +int lc3_bwdet_get_nbits(enum lc3_srate sr); + +/** + * Put bandwidth indication + * bits Bitstream context + * sr Samplerate of the frame + * bw Bandwidth detected + */ +void lc3_bwdet_put_bw(lc3_bits_t *bits, + enum lc3_srate sr, enum lc3_bandwidth bw); + +/** + * Get bandwidth indication + * bits Bitstream context + * sr Samplerate of the frame + * bw Return bandwidth indication + * return 0: Ok -1: Invalid bandwidth indication + */ +int lc3_bwdet_get_bw(lc3_bits_t *bits, + enum lc3_srate sr, enum lc3_bandwidth *bw); + + +#endif /* __LC3_BWDET_H */ diff --git a/3rd-party/lc3-google/src/common.h b/3rd-party/lc3-google/src/common.h new file mode 100644 index 000000000..b19d7a6ed --- /dev/null +++ b/3rd-party/lc3-google/src/common.h @@ -0,0 +1,105 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * LC3 - Common constants and types + */ + +#ifndef __LC3_COMMON_H +#define __LC3_COMMON_H + +#include + +#include +#include +#include + + +/** + * Macros + * MIN/MAX Minimum and maximum between 2 values + * CLIP Clip a value between low and high limits + * ABS Return the absolute value + */ + +#define LC3_MIN(a, b) ( (a) < (b) ? (a) : (b) ) +#define LC3_MAX(a, b) ( (a) > (b) ? (a) : (b) ) +#define LC3_CLIP(v, min, max) LC3_MIN(LC3_MAX(v, min), max) + +#define LC3_ABS(n) ( (n) < 0 ? -(n) : (n) ) + + +/** + * Convert `dt` in us and `sr` in KHz + */ + +#define LC3_DT_US(dt) \ + ( (3 + (dt)) * 2500 ) + +#define LC3_SRATE_KHZ(sr) \ + ( (1 + (sr) + ((sr) == LC3_SRATE_48K)) * 8 ) + + +/** + * Return number of samples, delayed samples and + * encoded spectrum coefficients within a frame + * For decoding, add number of samples of 18 ms history + */ + +#define LC3_NS(dt, sr) \ + ( 20 * (3 + (dt)) * (1 + (sr) + ((sr) == LC3_SRATE_48K)) ) + +#define LC3_ND(dt, sr) \ + ( (dt) == LC3_DT_7M5 ? 23 * LC3_NS(dt, sr) / 30 \ + : 5 * LC3_NS(dt, sr) / 8 ) +#define LC3_NE(dt, sr) \ + ( 20 * (3 + (dt)) * (1 + (sr)) ) + +#define LC3_MAX_NE \ + LC3_NE(LC3_DT_10M, LC3_SRATE_48K) + +#define LC3_NH(sr) \ + (18 * LC3_SRATE_KHZ(sr)) + + +/** + * Bandwidth, mapped to Nyquist frequency of samplerates + */ + +enum lc3_bandwidth { + LC3_BANDWIDTH_NB = LC3_SRATE_8K, + LC3_BANDWIDTH_WB = LC3_SRATE_16K, + LC3_BANDWIDTH_SSWB = LC3_SRATE_24K, + LC3_BANDWIDTH_SWB = LC3_SRATE_32K, + LC3_BANDWIDTH_FB = LC3_SRATE_48K, + + LC3_NUM_BANDWIDTH, +}; + + +/** + * Complex floating point number + */ + +struct lc3_complex +{ + float re, im; +}; + + +#endif /* __LC3_COMMON_H */ diff --git a/3rd-party/lc3-google/src/energy.c b/3rd-party/lc3-google/src/energy.c new file mode 100644 index 000000000..71e97a32b --- /dev/null +++ b/3rd-party/lc3-google/src/energy.c @@ -0,0 +1,70 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "energy.h" +#include "tables.h" + + +/** + * Energy estimation per band + */ +bool lc3_energy_compute( + enum lc3_dt dt, enum lc3_srate sr, const float *x, float *e) +{ + static const int n1_table[LC3_NUM_DT][LC3_NUM_SRATE] = { + [LC3_DT_7M5] = { 56, 34, 27, 24, 22 }, + [LC3_DT_10M] = { 49, 28, 23, 20, 18 }, + }; + + /* First bands are 1 coefficient width */ + + int n1 = n1_table[dt][sr]; + float e_sum[2] = { 0, 0 }; + int iband; + + for (iband = 0; iband < n1; iband++) { + *e = x[iband] * x[iband]; + e_sum[0] += *(e++); + } + + /* Mean the square of coefficients within each band, + * note that 7.5ms 8KHz frame has more bands than samples */ + + int nb = LC3_MIN(LC3_NUM_BANDS, LC3_NS(dt, sr)); + int iband_h = nb - 2*(2 - dt); + const int *lim = lc3_band_lim[dt][sr]; + + for (int i = lim[iband]; iband < nb; iband++) { + int ie = lim[iband+1]; + int n = ie - i; + + float sx2 = x[i] * x[i]; + for (i++; i < ie; i++) + sx2 += x[i] * x[i]; + + *e = sx2 / n; + e_sum[iband >= iband_h] += *(e++); + } + + for (; iband < LC3_NUM_BANDS; iband++) + *(e++) = 0; + + /* Return the near nyquist flag */ + + return e_sum[1] > 30 * e_sum[0]; +} diff --git a/3rd-party/lc3-google/src/energy.h b/3rd-party/lc3-google/src/energy.h new file mode 100644 index 000000000..63208c886 --- /dev/null +++ b/3rd-party/lc3-google/src/energy.h @@ -0,0 +1,43 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * LC3 - Energy estimation per band + * + * Reference : Low Complexity Communication Codec (LC3) + * Bluetooth Specification v1.0 + */ + +#ifndef __LC3_ENERGY_H +#define __LC3_ENERGY_H + +#include "common.h" + + +/** + * Energy estimation per band + * dt, sr Duration and samplerate of the frame + * x Input MDCT coefficient + * e Energy estimation per bands + * return True when high energy detected near Nyquist frequency + */ +bool lc3_energy_compute( + enum lc3_dt dt, enum lc3_srate sr, const float *x, float *e); + + +#endif /* __LC3_ENERGY_H */ diff --git a/3rd-party/lc3-google/src/lc3.c b/3rd-party/lc3-google/src/lc3.c new file mode 100644 index 000000000..2f7789f9f --- /dev/null +++ b/3rd-party/lc3-google/src/lc3.c @@ -0,0 +1,570 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include + +#include "common.h" +#include "bits.h" + +#include "attdet.h" +#include "bwdet.h" +#include "ltpf.h" +#include "mdct.h" +#include "energy.h" +#include "sns.h" +#include "tns.h" +#include "spec.h" +#include "plc.h" + + +/** + * Frame side data + */ + +struct side_data { + enum lc3_bandwidth bw; + bool pitch_present; + lc3_ltpf_data_t ltpf; + lc3_sns_data_t sns; + lc3_tns_data_t tns; + lc3_spec_side_t spec; +}; + + +/* ---------------------------------------------------------------------------- + * General + * -------------------------------------------------------------------------- */ + +/** + * Resolve frame duration in us + * us Frame duration in us + * return Frame duration identifier, or LC3_NUM_DT + */ +static enum lc3_dt resolve_dt(int us) +{ + return us == 7500 ? LC3_DT_7M5 : + us == 10000 ? LC3_DT_10M : LC3_NUM_DT; +} + +/** + * Resolve samplerate in Hz + * hz Samplerate in Hz + * return Sample rate identifier, or LC3_NUM_SRATE + */ +static enum lc3_srate resolve_sr(int hz) +{ + return hz == 8000 ? LC3_SRATE_8K : hz == 16000 ? LC3_SRATE_16K : + hz == 24000 ? LC3_SRATE_24K : hz == 32000 ? LC3_SRATE_32K : + hz == 48000 ? LC3_SRATE_48K : LC3_NUM_SRATE; +} + +/** + * Return the number of PCM samples in a frame + */ +int lc3_frame_samples(int dt_us, int sr_hz) +{ + enum lc3_dt dt = resolve_dt(dt_us); + enum lc3_srate sr = resolve_sr(sr_hz); + + if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE) + return -1; + + return LC3_NS(dt, sr); +} + +/** + * Return the size of frames, from bitrate + */ +int lc3_frame_bytes(int dt_us, int bitrate) +{ + if (resolve_dt(dt_us) >= LC3_NUM_DT) + return -1; + + if (bitrate < LC3_MIN_BITRATE) + return LC3_MIN_FRAME_BYTES; + + if (bitrate > LC3_MAX_BITRATE) + return LC3_MAX_FRAME_BYTES; + + int nbytes = ((unsigned)bitrate * dt_us) / (1000*1000*8); + + return LC3_CLIP(nbytes, LC3_MIN_FRAME_BYTES, LC3_MAX_FRAME_BYTES); +} + +/** + * Resolve the bitrate, from the size of frames + */ +int lc3_resolve_bitrate(int dt_us, int nbytes) +{ + if (resolve_dt(dt_us) >= LC3_NUM_DT) + return -1; + + if (nbytes < LC3_MIN_FRAME_BYTES) + return LC3_MIN_BITRATE; + + if (nbytes > LC3_MAX_FRAME_BYTES) + return LC3_MAX_BITRATE; + + int bitrate = ((unsigned)nbytes * (1000*1000*8) + dt_us/2) / dt_us; + + return LC3_CLIP(bitrate, LC3_MIN_BITRATE, LC3_MAX_BITRATE); +} + +/** + * Return algorithmic delay, as a number of samples + */ +int lc3_delay_samples(int dt_us, int sr_hz) +{ + enum lc3_dt dt = resolve_dt(dt_us); + enum lc3_srate sr = resolve_sr(sr_hz); + + if (dt >= LC3_NUM_DT || sr >= LC3_NUM_SRATE) + return -1; + + return (dt == LC3_DT_7M5 ? 8 : 5) * (LC3_SRATE_KHZ(sr) / 2); +} + + +/* ---------------------------------------------------------------------------- + * Encoder + * -------------------------------------------------------------------------- */ + +/** + * Input PCM Samples from signed 16 bits + * encoder Encoder state + * pcm, stride Input PCM samples, and count between two consecutives + */ +static void load_s16( + struct lc3_encoder *encoder, const void *_pcm, int stride) +{ + const int16_t *pcm = _pcm; + + enum lc3_dt dt = encoder->dt; + enum lc3_srate sr = encoder->sr_pcm; + float *xs = encoder->xs; + int ns = LC3_NS(dt, sr); + + for (int i = 0; i < ns; i++) + xs[i] = pcm[i*stride]; +} + +/** + * Input PCM Samples from signed 24 bits + * encoder Encoder state + * pcm, stride Input PCM samples, and count between two consecutives + */ +static void load_s24( + struct lc3_encoder *encoder, const void *_pcm, int stride) +{ + const int32_t *pcm = _pcm; + + enum lc3_dt dt = encoder->dt; + enum lc3_srate sr = encoder->sr_pcm; + float *xs = encoder->xs; + int ns = LC3_NS(dt, sr); + + for (int i = 0; i < ns; i++) + xs[i] = ldexpf(pcm[i*stride], -8); +} + +/** + * Frame Analysis + * encoder Encoder state + * nbytes Size in bytes of the frame + * side, xq Return frame data + */ +static void analyze(struct lc3_encoder *encoder, + int nbytes, struct side_data *side, int16_t *xq) +{ + enum lc3_dt dt = encoder->dt; + enum lc3_srate sr = encoder->sr; + enum lc3_srate sr_pcm = encoder->sr_pcm; + int ns = LC3_NS(dt, sr_pcm); + int nd = LC3_ND(dt, sr_pcm); + + float *xs = encoder->xs; + float *xf = encoder->xf; + + /* --- Temporal --- */ + + bool att = lc3_attdet_run(dt, sr_pcm, nbytes, &encoder->attdet, xs); + + side->pitch_present = + lc3_ltpf_analyse(dt, sr_pcm, &encoder->ltpf, xs, &side->ltpf); + + /* --- Spectral --- */ + + float e[LC3_NUM_BANDS]; + + lc3_mdct_forward(dt, sr_pcm, sr, xs, xf); + memmove(xs - nd, xs + ns-nd, nd * sizeof(float)); + + bool nn_flag = lc3_energy_compute(dt, sr, xf, e); + if (nn_flag) + lc3_ltpf_disable(&side->ltpf); + + side->bw = lc3_bwdet_run(dt, sr, e); + + lc3_sns_analyze(dt, sr, e, att, &side->sns, xf, xf); + + lc3_tns_analyze(dt, side->bw, nn_flag, nbytes, &side->tns, xf); + + lc3_spec_analyze(dt, sr, + nbytes, side->pitch_present, &side->tns, + &encoder->spec, xf, xq, &side->spec); +} + +/** + * Encode bitstream + * encoder Encoder state + * side, xq The frame data + * nbytes Target size of the frame (20 to 400) + * buffer Output bitstream buffer of `nbytes` size + */ +static void encode(struct lc3_encoder *encoder, + const struct side_data *side, int16_t *xq, int nbytes, void *buffer) +{ + enum lc3_dt dt = encoder->dt; + enum lc3_srate sr = encoder->sr; + enum lc3_bandwidth bw = side->bw; + float *xf = encoder->xf; + + lc3_bits_t bits; + + lc3_setup_bits(&bits, LC3_BITS_MODE_WRITE, buffer, nbytes); + + lc3_bwdet_put_bw(&bits, sr, bw); + + lc3_spec_put_side(&bits, dt, sr, &side->spec); + + lc3_tns_put_data(&bits, &side->tns); + + lc3_put_bit(&bits, side->pitch_present); + + lc3_sns_put_data(&bits, &side->sns); + + if (side->pitch_present) + lc3_ltpf_put_data(&bits, &side->ltpf); + + lc3_spec_encode(&bits, + dt, sr, bw, nbytes, xq, &side->spec, xf); + + lc3_flush_bits(&bits); +} + +/** + * Return size needed for an encoder + */ +unsigned lc3_encoder_size(int dt_us, int sr_hz) +{ + if (resolve_dt(dt_us) >= LC3_NUM_DT || + resolve_sr(sr_hz) >= LC3_NUM_SRATE) + return 0; + + return sizeof(struct lc3_encoder) + + LC3_ENCODER_BUFFER_COUNT(dt_us, sr_hz) * sizeof(float); +} + +/** + * Setup encoder + */ +struct lc3_encoder *lc3_setup_encoder( + int dt_us, int sr_hz, int sr_pcm_hz, void *mem) +{ + if (sr_pcm_hz <= 0) + sr_pcm_hz = sr_hz; + + enum lc3_dt dt = resolve_dt(dt_us); + enum lc3_srate sr = resolve_sr(sr_hz); + enum lc3_srate sr_pcm = resolve_sr(sr_pcm_hz); + + if (dt >= LC3_NUM_DT || sr_pcm >= LC3_NUM_SRATE || sr > sr_pcm || !mem) + return NULL; + + struct lc3_encoder *encoder = mem; + int ns = LC3_NS(dt, sr_pcm); + int nd = LC3_ND(dt, sr_pcm); + + *encoder = (struct lc3_encoder){ + .dt = dt, .sr = sr, + .sr_pcm = sr_pcm, + .xs = encoder->s + nd, + .xf = encoder->s + nd+ns, + }; + + memset(encoder->s, 0, + LC3_ENCODER_BUFFER_COUNT(dt_us, sr_pcm_hz) * sizeof(float)); + + return encoder; +} + +/** + * Encode a frame + */ +int lc3_encode(struct lc3_encoder *encoder, enum lc3_pcm_format fmt, + const void *pcm, int stride, int nbytes, void *out) +{ + static void (* const load[])(struct lc3_encoder *, const void *, int) = { + [LC3_PCM_FORMAT_S16] = load_s16, + [LC3_PCM_FORMAT_S24] = load_s24, + }; + + /* --- Check parameters --- */ + + if (!encoder || nbytes < LC3_MIN_FRAME_BYTES + || nbytes > LC3_MAX_FRAME_BYTES) + return -1; + + /* --- Processing --- */ + + struct side_data side; + int16_t xq[LC3_NE(encoder->dt, encoder->sr)]; + + load[fmt](encoder, pcm, stride); + + analyze(encoder, nbytes, &side, xq); + + encode(encoder, &side, xq, nbytes, out); + + return 0; +} + + +/* ---------------------------------------------------------------------------- + * Decoder + * -------------------------------------------------------------------------- */ + +/** + * Output PCM Samples to signed 16 bits + * decoder Decoder state + * pcm, stride Output PCM samples, and count between two consecutives + */ +static void store_s16( + struct lc3_decoder *decoder, void *_pcm, int stride) +{ + int16_t *pcm = _pcm; + + enum lc3_dt dt = decoder->dt; + enum lc3_srate sr = decoder->sr_pcm; + float *xs = decoder->xs; + int ns = LC3_NS(dt, sr); + + for ( ; ns > 0; ns--, xs++, pcm += stride) { + int s = *xs >= 0 ? (int)(*xs + 0.5f) : (int)(*xs - 0.5f); + *pcm = LC3_CLIP(s, INT16_MIN, INT16_MAX); + } +} + +/** + * Output PCM Samples to signed 24 bits + * decoder Decoder state + * pcm, stride Output PCM samples, and count between two consecutives + */ +static void store_s24( + struct lc3_decoder *decoder, void *_pcm, int stride) +{ + int32_t *pcm = _pcm; + const int32_t int24_max = (1 << 23) - 1; + const int32_t int24_min = -(1 << 23); + + enum lc3_dt dt = decoder->dt; + enum lc3_srate sr = decoder->sr_pcm; + float *xs = decoder->xs; + int ns = LC3_NS(dt, sr); + + for ( ; ns > 0; ns--, xs++, pcm += stride) { + int32_t s = *xs >= 0 ? (int32_t)(ldexpf(*xs, 8) + 0.5f) + : (int32_t)(ldexpf(*xs, 8) - 0.5f); + *pcm = LC3_CLIP(s, int24_min, int24_max); + } +} + +/** + * Decode bitstream + * decoder Decoder state + * data, nbytes Input bitstream buffer + * side Return the side data + * return 0: Ok < 0: Bitsream error detected + */ +static int decode(struct lc3_decoder *decoder, + const void *data, int nbytes, struct side_data *side) +{ + enum lc3_dt dt = decoder->dt; + enum lc3_srate sr = decoder->sr; + float *xf = decoder->xs; + int ns = LC3_NS(dt, sr); + int ne = LC3_NE(dt, sr); + + lc3_bits_t bits; + int ret = 0; + + lc3_setup_bits(&bits, LC3_BITS_MODE_READ, (void *)data, nbytes); + + if ((ret = lc3_bwdet_get_bw(&bits, sr, &side->bw)) < 0) + return ret; + + if ((ret = lc3_spec_get_side(&bits, dt, sr, &side->spec)) < 0) + return ret; + + lc3_tns_get_data(&bits, dt, side->bw, nbytes, &side->tns); + + side->pitch_present = lc3_get_bit(&bits); + + if ((ret = lc3_sns_get_data(&bits, &side->sns)) < 0) + return ret; + + if (side->pitch_present) + lc3_ltpf_get_data(&bits, &side->ltpf); + + if ((ret = lc3_spec_decode(&bits, dt, sr, + side->bw, nbytes, &side->spec, xf)) < 0) + return ret; + + memset(xf + ne, 0, (ns - ne) * sizeof(float)); + + return lc3_check_bits(&bits); +} + +/** + * Frame synthesis + * decoder Decoder state + * side Frame data, NULL performs PLC + * nbytes Size in bytes of the frame + */ +static void synthesize(struct lc3_decoder *decoder, + const struct side_data *side, int nbytes) +{ + enum lc3_dt dt = decoder->dt; + enum lc3_srate sr = decoder->sr; + enum lc3_srate sr_pcm = decoder->sr_pcm; + int ns = LC3_NS(dt, sr_pcm); + int ne = LC3_NE(dt, sr); + int nh = LC3_NH(sr_pcm); + + float *xf = decoder->xs; + float *xg = decoder->xg; + float *xd = decoder->xd; + float *xs = xf; + + if (side) { + enum lc3_bandwidth bw = side->bw; + + lc3_plc_suspend(&decoder->plc); + + lc3_tns_synthesize(dt, bw, &side->tns, xf); + + lc3_sns_synthesize(dt, sr, &side->sns, xf, xg); + + lc3_mdct_inverse(dt, sr_pcm, sr, xg, xd, xs); + + } else { + lc3_plc_synthesize(dt, sr, &decoder->plc, xg, xf); + + memset(xf + ne, 0, (ns - ne) * sizeof(float)); + + lc3_mdct_inverse(dt, sr_pcm, sr, xf, xd, xs); + } + + lc3_ltpf_synthesize(dt, sr_pcm, nbytes, &decoder->ltpf, + side && side->pitch_present ? &side->ltpf : NULL, xs); + + memmove(xs - nh, xs - nh+ns, nh * sizeof(*xs)); +} + +/** + * Return size needed for a decoder + */ +unsigned lc3_decoder_size(int dt_us, int sr_hz) +{ + if (resolve_dt(dt_us) >= LC3_NUM_DT || + resolve_sr(sr_hz) >= LC3_NUM_SRATE) + return 0; + + return sizeof(struct lc3_decoder) + + LC3_DECODER_BUFFER_COUNT(dt_us, sr_hz) * sizeof(float); +} + +/** + * Setup decoder + */ +struct lc3_decoder *lc3_setup_decoder( + int dt_us, int sr_hz, int sr_pcm_hz, void *mem) +{ + if (sr_pcm_hz <= 0) + sr_pcm_hz = sr_hz; + + enum lc3_dt dt = resolve_dt(dt_us); + enum lc3_srate sr = resolve_sr(sr_hz); + enum lc3_srate sr_pcm = resolve_sr(sr_pcm_hz); + + if (dt >= LC3_NUM_DT || sr_pcm >= LC3_NUM_SRATE || sr > sr_pcm || !mem) + return NULL; + + struct lc3_decoder *decoder = mem; + int nh = LC3_NH(sr_pcm); + int ns = LC3_NS(dt, sr_pcm); + int nd = LC3_ND(dt, sr_pcm); + + *decoder = (struct lc3_decoder){ + .dt = dt, .sr = sr, + .sr_pcm = sr_pcm, + .xs = decoder->s + nh, + .xd = decoder->s + nh+ns, + .xg = decoder->s + nh+ns+nd, + }; + + lc3_plc_reset(&decoder->plc); + + memset(decoder->s, 0, + LC3_DECODER_BUFFER_COUNT(dt_us, sr_pcm_hz) * sizeof(float)); + + return decoder; +} + +/** + * Decode a frame + */ +int lc3_decode(struct lc3_decoder *decoder, const void *in, int nbytes, + enum lc3_pcm_format fmt, void *pcm, int stride) +{ + static void (* const store[])(struct lc3_decoder *, void *, int) = { + [LC3_PCM_FORMAT_S16] = store_s16, + [LC3_PCM_FORMAT_S24] = store_s24, + }; + + /* --- Check parameters --- */ + + if (!decoder) + return -1; + + if (in && (nbytes < LC3_MIN_FRAME_BYTES || + nbytes > LC3_MAX_FRAME_BYTES )) + return -1; + + /* --- Processing --- */ + + struct side_data side; + + int ret = !in || (decode(decoder, in, nbytes, &side) < 0); + + synthesize(decoder, ret ? NULL : &side, nbytes); + + store[fmt](decoder, pcm, stride); + + return ret; +} diff --git a/3rd-party/lc3-google/src/ltpf.c b/3rd-party/lc3-google/src/ltpf.c new file mode 100644 index 000000000..283cd9fa7 --- /dev/null +++ b/3rd-party/lc3-google/src/ltpf.c @@ -0,0 +1,621 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "ltpf.h" +#include "tables.h" + + +/* ---------------------------------------------------------------------------- + * Resampling + * -------------------------------------------------------------------------- */ + +/** + * Resample to 12.8 KHz (cf. 3.3.9.3-4) Template + * sr Samplerate source of the frame + * hp50 State of the High-Pass 50 Hz filter + * x [-d..-1] Previous, [0..ns-1] Current samples + * y, n [0..n-1] Output `n` processed samples + * + * The number of previous samples `d` accessed on `x` is : + * d: { 10, 20, 30, 40, 60 } - 1 for samplerates from 8KHz to 48KHz + */ +static inline void resample_12k8_template(const enum lc3_srate sr, + struct lc3_ltpf_hp50_state *hp50, const float *x, float *y, int n) +{ + /* --- Parameters --- + * p: Resampling factor, from 4 to 24 + * w: Half width of polyphase filter + * + * bn, an: High-Pass Biquad coefficients, + * with `bn` support of rescaling resampling factor. + * Note that it's an High-Pass filter, so we have `b0 = b2`, + * in the following steps we use `b0` as `b2`. */ + + const int p = 192 / LC3_SRATE_KHZ(sr); + const int w = 5 * LC3_SRATE_KHZ(sr) / 8; + + const int b_scale = p >> (sr == LC3_SRATE_8K); + const float a1 = -1.965293373, b1 = -1.965589417 * b_scale; + const float a2 = 0.965885461, b2 = 0.982794708 * b_scale; + + /* --- Resampling --- + * The value `15*8 * n` is divisible by all resampling factors `p`, + * integer and fractionnal position can be determined at compilation + * time while unrolling the loops by 8 samples. + * The biquad filter implementation chosen in the `Direct Form 2`. */ + + const float *h = lc3_ltpf_h12k8 + 119; + x -= w; + + for (int i = 0; i < n; i += 8, x += 120/p) + for (int j = 0; j < 15*8; j += 15) { + float un, yn; + int e, f, k; + + e = j / p, f = j % p; + for (un = 0, k = 1-w; k <= w; k++) + un += x[e+k] * h[k*p - f]; + + yn = b2 * un + hp50->s1; + hp50->s1 = b1 * un - a1 * yn + hp50->s2; + hp50->s2 = b2 * un - a2 * yn; + *(y++) = yn; + } +} + +/** + * LTPF Resample to 12.8 KHz implementations for each samplerates + */ + +static void resample_8k_12k8( + struct lc3_ltpf_hp50_state *hp50, const float *x, float *y, int n) +{ + resample_12k8_template(LC3_SRATE_8K, hp50, x, y, n); +} + +static void resample_16k_12k8( + struct lc3_ltpf_hp50_state *hp50, const float *x, float *y, int n) +{ + resample_12k8_template(LC3_SRATE_16K, hp50, x, y, n); +} + +static void resample_24k_12k8( + struct lc3_ltpf_hp50_state *hp50, const float *x, float *y, int n) +{ + resample_12k8_template(LC3_SRATE_24K, hp50, x, y, n); +} + +static void resample_32k_12k8( + struct lc3_ltpf_hp50_state *hp50, const float *x, float *y, int n) +{ + resample_12k8_template(LC3_SRATE_32K, hp50, x, y, n); +} + +static void resample_48k_12k8( + struct lc3_ltpf_hp50_state *hp50, const float *x, float *y, int n) +{ + resample_12k8_template(LC3_SRATE_48K, hp50, x, y, n); +} + +static void (* const resample_12k8[]) + (struct lc3_ltpf_hp50_state *, const float *, float *, int ) = +{ + [LC3_SRATE_8K ] = resample_8k_12k8, + [LC3_SRATE_16K] = resample_16k_12k8, + [LC3_SRATE_24K] = resample_24k_12k8, + [LC3_SRATE_32K] = resample_32k_12k8, + [LC3_SRATE_48K] = resample_48k_12k8, +}; + +/** + * Resample to 6.4 KHz (cf. 3.3.9.3-4) + * x [-3..-1] Previous, [0..n-1] Current samples + * y, n [0..n-1] Output `n` processed samples + */ +static void resample_6k4(const float *x, float *y, int n) +{ + static const float h[] = { 0.2819382921, 0.2353512128, 0.1236796411 }; + float xn2 = x[-3], xn1 = x[-2], x0 = x[-1], x1, x2; + + for (const float *ye = y + n; y < ye; xn2 = x0, xn1 = x1, x0 = x2) { + x1 = *(x++); x2 = *(x++); + + *(y++) = x0 * h[0] + (xn1 + x1) * h[1] + (xn2 + x2) * h[2]; + } +} + + +/* ---------------------------------------------------------------------------- + * Analysis + * -------------------------------------------------------------------------- */ + +/** + * Return dot product of 2 vectors + * a, b, n The 2 vectors of size `n` + * return sum( a[i] * b[i] ), i = [0..n-1] + */ +static inline float dot(const float *a, const float *b, int n) +{ + float v = 0; + + while (n--) + v += *(a++) * *(b++); + + return v; +} + +/** + * Return vector of correlations + * a, b, n The 2 vector of size `n` to correlate + * y, nc Output the correlation vector of size `nc` + * + * The size `n` of input vectors must be multiple of 16 + */ +static void correlate( + const float *a, const float *b, int n, float *y, int nc) +{ + for (const float *ye = y + nc; y < ye; ) + *(y++) = dot(a, b--, n); +} + +/** + * Search the maximum value and returns its argument + * x, n The input vector of size `n` + * x_max Return the maximum value + * return Return the argument of the maximum + */ +static int argmax(const float *x, int n, float *x_max) +{ + int arg = 0; + + *x_max = x[arg = 0]; + for (int i = 1; i < n; i++) + if (*x_max < x[i]) + *x_max = x[arg = i]; + + return arg; +} + +/** + * Search the maximum weithed value and returns its argument + * x, n The input vector of size `n` + * w_incr Increment of the weight + * x_max, xw_max Return the maximum not weighted value + * return Return the argument of the weigthed maximum + */ +static int argmax_weighted( + const float *x, int n, float w_incr, float *x_max) +{ + int arg; + + float xw_max = (*x_max = x[arg = 0]); + float w = 1 + w_incr; + + for (int i = 1; i < n; i++, w += w_incr) + if (xw_max < x[i] * w) + xw_max = (*x_max = x[arg = i]) * w; + + return arg; +} + +/** + * Interpolate from pitch detected value (3.3.9.8) + * x, n [-2..-1] Previous, [0..n] Current input + * d The phase of interpolation (0 to 3) + * return The interpolated vector + * + * The size `n` of vectors must be multiple of 4 + */ +static void interpolate(const float *x, int n, int d, float *y) +{ + static const float h4[][8] = { + { 2.09880463e-01, 5.83527575e-01, 2.09880463e-01 }, + { 1.06999186e-01, 5.50075002e-01, 3.35690625e-01, 6.69885837e-03 }, + { 3.96711478e-02, 4.59220930e-01, 4.59220930e-01, 3.96711478e-02 }, + { 6.69885837e-03, 3.35690625e-01, 5.50075002e-01, 1.06999186e-01 }, + }; + + const float *h = h4[d]; + float x3 = x[-2], x2 = x[-1], x1, x0; + + x1 = (*x++); + for (const float *ye = y + n; y < ye; ) { + *(y++) = (x0 = *(x++)) * h[0] + x1 * h[1] + x2 * h[2] + x3 * h[3]; + *(y++) = (x3 = *(x++)) * h[0] + x0 * h[1] + x1 * h[2] + x2 * h[3]; + *(y++) = (x2 = *(x++)) * h[0] + x3 * h[1] + x0 * h[2] + x1 * h[3]; + *(y++) = (x1 = *(x++)) * h[0] + x2 * h[1] + x3 * h[2] + x0 * h[3]; + } +} + +/** + * Interpolate autocorrelation (3.3.9.7) + * x [-4..-1] Previous, [0..4] Current input + * d The phase of interpolation (-3 to 3) + * return The interpolated value + */ +static float interpolate_4(const float *x, int d) +{ + static const float h4[][8] = { + { 1.53572770e-02, -4.72963246e-02, 8.35788573e-02, 8.98638285e-01, + 8.35788573e-02, -4.72963246e-02, 1.53572770e-02, }, + { 2.74547165e-03, 4.59833449e-03, -7.54404636e-02, 8.17488686e-01, + 3.30182571e-01, -1.05835916e-01, 2.86823405e-02, -2.87456116e-03 }, + { -3.00125103e-03, 2.95038503e-02, -1.30305021e-01, 6.03297008e-01, + 6.03297008e-01, -1.30305021e-01, 2.95038503e-02, -3.00125103e-03 }, + { -2.87456116e-03, 2.86823405e-02, -1.05835916e-01, 3.30182571e-01, + 8.17488686e-01, -7.54404636e-02, 4.59833449e-03, 2.74547165e-03 }, + }; + + const float *h = h4[(4+d) % 4]; + + float y = d < 0 ? x[-4] * *(h++) : + d > 0 ? x[ 4] * *(h+7) : 0; + + y += x[-3] * h[0] + x[-2] * h[1] + x[-1] * h[2] + x[0] * h[3] + + x[ 1] * h[4] + x[ 2] * h[5] + x[ 3] * h[6]; + + return y; +} + +/** + * Pitch detection algorithm (3.3.9.5-6) + * ltpf Context of analysis + * x, n [-114..-17] Previous, [0..n-1] Current 6.4KHz samples + * tc Return the pitch-lag estimation + * return True when pitch present + */ +static bool detect_pitch( + struct lc3_ltpf_analysis *ltpf, const float *x, int n, int *tc) +{ + float rm1, rm2; + float r[98]; + + const int r0 = 17, nr = 98; + int k0 = LC3_MAX( 0, ltpf->tc-4); + int nk = LC3_MIN(nr-1, ltpf->tc+4) - k0 + 1; + + correlate(x, x - r0, n, r, nr); + + int t1 = argmax_weighted(r, nr, -.5/(nr-1), &rm1); + int t2 = k0 + argmax(r + k0, nk, &rm2); + + const float *x1 = x - (r0 + t1); + const float *x2 = x - (r0 + t2); + + float nc1 = rm1 <= 0 ? 0 : + rm1 / sqrtf(dot(x, x, n) * dot(x1, x1, n)); + + float nc2 = rm2 <= 0 ? 0 : + rm2 / sqrtf(dot(x, x, n) * dot(x2, x2, n)); + + int t1sel = nc2 <= 0.85 * nc1; + ltpf->tc = (t1sel ? t1 : t2); + + *tc = r0 + ltpf->tc; + return (t1sel ? nc1 : nc2) > 0.6; +} + +/** + * Pitch-lag parameter (3.3.9.7) + * x, n [-232..-28] Previous, [0..n-1] Current 12.8KHz samples + * tc Pitch-lag estimation + * pitch The pitch value, in fixed .4 + * return The bitstream pitch index value + */ +static int refine_pitch(const float *x, int n, int tc, int *pitch) +{ + float r[17], rm; + int e, f; + + int r0 = LC3_MAX( 32, 2*tc - 4); + int nr = LC3_MIN(228, 2*tc + 4) - r0 + 1; + + correlate(x, x - (r0 - 4), n, r, nr + 8); + + e = r0 + argmax(r + 4, nr, &rm); + const float *re = r + (e - (r0 - 4)); + + float dm = interpolate_4(re, f = 0); + for (int i = 1; i <= 3; i++) { + float d; + + if (e >= 127 && ((i & 1) | (e >= 157))) + continue; + + if ((d = interpolate_4(re, i)) > dm) + dm = d, f = i; + + if (e > 32 && (d = interpolate_4(re, -i)) > dm) + dm = d, f = -i; + } + + e -= (f < 0); + f += 4*(f < 0); + + *pitch = 4*e + f; + return e < 127 ? 4*e + f - 128 : + e < 157 ? 2*e + (f >> 1) + 126 : e + 283; +} + +/** + * LTPF Analysis + */ +bool lc3_ltpf_analyse(enum lc3_dt dt, enum lc3_srate sr, + struct lc3_ltpf_analysis *ltpf, const float *x, struct lc3_ltpf_data *data) +{ + /* --- Resampling to 12.8 KHz --- */ + + int z_12k8 = sizeof(ltpf->x_12k8) / sizeof(float); + int n_12k8 = dt == LC3_DT_7M5 ? 96 : 128; + + memmove(ltpf->x_12k8, ltpf->x_12k8 + n_12k8, + (z_12k8 - n_12k8) * sizeof(float)); + + float *x_12k8 = ltpf->x_12k8 + (z_12k8 - n_12k8); + resample_12k8[sr](<pf->hp50, x, x_12k8, n_12k8); + + x_12k8 -= (dt == LC3_DT_7M5 ? 44 : 24); + + /* --- Resampling to 6.4 KHz --- */ + + int z_6k4 = sizeof(ltpf->x_6k4) / sizeof(float); + int n_6k4 = n_12k8 >> 1; + + memmove(ltpf->x_6k4, ltpf->x_6k4 + n_6k4, + (z_6k4 - n_6k4) * sizeof(float)); + + float *x_6k4 = ltpf->x_6k4 + (z_6k4 - n_6k4); + resample_6k4(x_12k8, x_6k4, n_6k4); + + /* --- Pitch detection --- */ + + int tc, pitch = 0; + float nc = 0; + + bool pitch_present = detect_pitch(ltpf, x_6k4, n_6k4, &tc); + + if (pitch_present) { + float u[n_12k8], v[n_12k8]; + + data->pitch_index = refine_pitch(x_12k8, n_12k8, tc, &pitch); + + interpolate(x_12k8, n_12k8, 0, u); + interpolate(x_12k8 - (pitch >> 2), n_12k8, pitch & 3, v); + + nc = dot(u, v, n_12k8) / sqrtf(dot(u, u, n_12k8) * dot(v, v, n_12k8)); + } + + /* --- Activation --- */ + + if (ltpf->active) { + int pitch_diff = + LC3_MAX(pitch, ltpf->pitch) - LC3_MIN(pitch, ltpf->pitch); + float nc_diff = nc - ltpf->nc[0]; + + data->active = pitch_present && + ((nc > 0.9) || (nc > 0.84 && pitch_diff < 8 && nc_diff > -0.1)); + + } else { + data->active = pitch_present && + ( (dt == LC3_DT_10M || ltpf->nc[1] > 0.94) && + (ltpf->nc[0] > 0.94 && nc > 0.94) ); + } + + ltpf->active = data->active; + ltpf->pitch = pitch; + ltpf->nc[1] = ltpf->nc[0]; + ltpf->nc[0] = nc; + + return pitch_present; +} + + +/* ---------------------------------------------------------------------------- + * Synthesis + * -------------------------------------------------------------------------- */ + +/** + * Synthesis filter template + * ym [-w/2..0] Previous, [0..w-1] Current pitch samples + * xm w-1 previous input samples + * x, n Current samples as input, filtered as output + * c, w Coefficients by pair (num, den), and count of pairs + * fade Fading mode of filter -1: Out 1: In 0: None + */ +static inline void synthesize_template(const float *ym, const float *xm, + float *x, int n, const float (*c)[2], const int w, int fade) +{ + float g = (float)(fade <= 0); + float g_incr = (float)((fade > 0) - (fade < 0)) / n; + float u[w]; + int i; + + ym -= (w >> 1); + + /* --- Load previous samples --- */ + + for (i = 1-w; i < 0; i++) { + float xi = *(xm++), yi = *(ym++); + + u[i + w-1] = 0; + for (int k = w-1; k+i >= 0; k--) + u[i+k] += xi * c[k][0] - yi * c[k][1]; + } + + u[w-1] = 0; + + /* --- Process --- */ + + for (; i < n; i += w) { + + for (int j = 0; j < w; j++, g += g_incr) { + float xi = *x, yi = *(ym++); + + for (int k = w-1; k >= 0; k--) + u[(j+k)%w] += xi * c[k][0] - yi * c[k][1]; + + *(x++) = xi - g * u[j]; + u[j] = 0; + } + } +} + +/** + * Synthesis filter for each samplerates (width of filter) + */ + +static void synthesize_4(const float *ym, const float *xm, + float *x, int n, const float (*c)[2], int fade) +{ + synthesize_template(ym, xm, x, n, c, 4, fade); +} + +static void synthesize_6(const float *ym, const float *xm, + float *x, int n, const float (*c)[2], int fade) +{ + synthesize_template(ym, xm, x, n, c, 6, fade); +} + +static void synthesize_8(const float *ym, const float *xm, + float *x, int n, const float (*c)[2], int fade) +{ + synthesize_template(ym, xm, x, n, c, 8, fade); +} + +static void synthesize_12(const float *ym, const float *xm, + float *x, int n, const float (*c)[2], int fade) +{ + synthesize_template(ym, xm, x, n, c, 12, fade); +} + +static void (* const synthesize[])( + const float *, const float *, float *, int, const float (*)[2], int) = +{ + [LC3_SRATE_8K ] = synthesize_4, + [LC3_SRATE_16K] = synthesize_4, + [LC3_SRATE_24K] = synthesize_6, + [LC3_SRATE_32K] = synthesize_8, + [LC3_SRATE_48K] = synthesize_12, +}; + +/** + * LTPF Synthesis + */ +void lc3_ltpf_synthesize(enum lc3_dt dt, enum lc3_srate sr, + int nbytes, struct lc3_ltpf_synthesis *ltpf, + const struct lc3_ltpf_data *data, float *x) +{ + int dt_us = LC3_DT_US(dt); + + /* --- Filter parameters --- */ + + int p_idx = data ? data->pitch_index : 0; + int pitch = + p_idx >= 440 ? (((p_idx ) - 283) << 2) : + p_idx >= 380 ? (((p_idx >> 1) - 63) << 2) + (((p_idx & 1)) << 1) : + (((p_idx >> 2) + 32) << 2) + (((p_idx & 3)) << 0) ; + + pitch = (pitch * LC3_SRATE_KHZ(sr) * 10 + 64) / 128; + + int nbits = (nbytes*8 * 10000 + (dt_us/2)) / dt_us; + int g_idx = LC3_MAX(nbits / 80, 3 + (int)sr) - (3 + sr); + bool active = data && data->active && g_idx < 4; + + int w = LC3_MAX(4, LC3_SRATE_KHZ(sr) / 4); + float c[w][2]; + + for (int i = 0; i < w; i++) { + float g = active ? 0.4f - 0.05f * g_idx : 0; + + c[i][0] = active ? 0.85f * g * lc3_ltpf_cnum[sr][g_idx][i] : 0; + c[i][1] = active ? g * lc3_ltpf_cden[sr][pitch & 3][i] : 0; + } + + /* --- Transition handling --- */ + + int ns = LC3_NS(dt, sr); + int nt = ns / (4 - (dt == LC3_DT_7M5)); + float xm[12]; + + if (active) + memcpy(xm, x + nt-(w-1), (w-1) * sizeof(float)); + + if (!ltpf->active && active) + synthesize[sr](x - pitch/4, ltpf->x, x, nt, c, 1); + else if (ltpf->active && !active) + synthesize[sr](x - ltpf->pitch/4, ltpf->x, x, nt, ltpf->c, -1); + else if (ltpf->active && active && ltpf->pitch == pitch) + synthesize[sr](x - pitch/4, ltpf->x, x, nt, c, 0); + else if (ltpf->active && active) { + synthesize[sr](x - ltpf->pitch/4, ltpf->x, x, nt, ltpf->c, -1); + synthesize[sr](x - pitch/4, x - (w-1), x, nt, c, 1); + } + + /* --- Remainder --- */ + + memcpy(ltpf->x, x + ns-(w-1), (w-1) * sizeof(float)); + + if (active) + synthesize[sr](x - pitch/4 + nt, xm, x + nt, ns-nt, c, 0); + + /* --- Update state --- */ + + ltpf->active = active; + ltpf->pitch = pitch; + memcpy(ltpf->c, c, w * sizeof(ltpf->c[0])); +} + + +/* ---------------------------------------------------------------------------- + * Bitstream data + * -------------------------------------------------------------------------- */ + +/** + * LTPF disable + */ +void lc3_ltpf_disable(struct lc3_ltpf_data *data) +{ + data->active = false; +} + +/** + * Return number of bits coding the bitstream data + */ +int lc3_ltpf_get_nbits(bool pitch) +{ + return 1 + 10 * pitch; +} + +/** + * Put bitstream data + */ +void lc3_ltpf_put_data(lc3_bits_t *bits, + const struct lc3_ltpf_data *data) +{ + lc3_put_bit(bits, data->active); + lc3_put_bits(bits, data->pitch_index, 9); +} + +/** + * Get bitstream data + */ +void lc3_ltpf_get_data(lc3_bits_t *bits, struct lc3_ltpf_data *data) +{ + data->active = lc3_get_bit(bits); + data->pitch_index = lc3_get_bits(bits, 9); +} diff --git a/3rd-party/lc3-google/src/ltpf.h b/3rd-party/lc3-google/src/ltpf.h new file mode 100644 index 000000000..f27861ac4 --- /dev/null +++ b/3rd-party/lc3-google/src/ltpf.h @@ -0,0 +1,107 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * LC3 - Long Term Postfilter + * + * Reference : Low Complexity Communication Codec (LC3) + * Bluetooth Specification v1.0 + */ + +#ifndef __LC3_LTPF_H +#define __LC3_LTPF_H + +#include "common.h" +#include "bits.h" + + +/** + * LTPF data + */ + +typedef struct lc3_ltpf_data { + bool active; + int pitch_index; +} lc3_ltpf_data_t; + + +/* ---------------------------------------------------------------------------- + * Encoding + * -------------------------------------------------------------------------- */ + +/** + * LTPF analysis + * dt, sr Duration and samplerate of the frame + * ltpf Context of analysis + * allowed True when activation of LTPF is allowed + * x [-d..-1] Previous, [0..ns-1] Current samples + * data Return bitstream data + * return True when pitch present, False otherwise + * + * The number of previous samples `d` accessed on `x` is : + * d: { 10, 20, 30, 40, 60 } - 1 for samplerates from 8KHz to 48KHz + */ +bool lc3_ltpf_analyse(enum lc3_dt dt, enum lc3_srate sr, + lc3_ltpf_analysis_t *ltpf, const float *x, lc3_ltpf_data_t *data); + +/** + * LTPF disable + * data LTPF data, disabled activation on return + */ +void lc3_ltpf_disable(lc3_ltpf_data_t *data); + +/** + * Return number of bits coding the bitstream data + * pitch True when pitch present, False otherwise + * return Bit consumption, including the pitch present flag + */ +int lc3_ltpf_get_nbits(bool pitch); + +/** + * Put bitstream data + * bits Bitstream context + * data LTPF data + */ +void lc3_ltpf_put_data(lc3_bits_t *bits, const lc3_ltpf_data_t *data); + + +/* ---------------------------------------------------------------------------- + * Decoding + * -------------------------------------------------------------------------- */ +/** + * Get bitstream data + * bits Bitstream context + * data Return bitstream data + */ +void lc3_ltpf_get_data(lc3_bits_t *bits, lc3_ltpf_data_t *data); + +/** + * LTPF synthesis + * dt, sr Duration and samplerate of the frame + * nbytes Size in bytes of the frame + * ltpf Context of synthesis + * data Bitstream data, NULL when pitch not present + * x [-d..-1] Previous, [0..ns-1] Current, filtered as output + * + * The number of previous samples `d` accessed on `x` is about 18 ms + */ +void lc3_ltpf_synthesize(enum lc3_dt dt, enum lc3_srate sr, int nbytes, + lc3_ltpf_synthesis_t *ltpf, const lc3_ltpf_data_t *data, float *x); + + +#endif /* __LC3_LTPF_H */ diff --git a/3rd-party/lc3-google/src/mdct.c b/3rd-party/lc3-google/src/mdct.c new file mode 100644 index 000000000..c02904a1b --- /dev/null +++ b/3rd-party/lc3-google/src/mdct.c @@ -0,0 +1,502 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "tables.h" + + +/* ---------------------------------------------------------------------------- + * FFT processing + * -------------------------------------------------------------------------- */ + +/** + * FFT 5 Points template + * s -1: Forward 1: Inverse + * x, y Input and output coefficients, of size 5xn + * n Number of interleaved transform to perform + */ +static inline void xfft_5(const float s, + const struct lc3_complex *x, struct lc3_complex *y, int n) +{ + static const float cos1 = 0.3090169944; /* cos(-2Pi 1/5) */ + static const float cos2 = -0.8090169944; /* cos(-2Pi 2/5) */ + + static const float sin1 = -0.9510565163; /* sin(-2Pi 1/5) */ + static const float sin2 = -0.5877852523; /* sin(-2Pi 2/5) */ + + for (int i = 0; i < n; i++, x++, y+= 5) { + + struct lc3_complex s14 = + { x[1*n].re + x[4*n].re, x[1*n].im + x[4*n].im }; + struct lc3_complex d14 = + { x[1*n].re - x[4*n].re, x[1*n].im - x[4*n].im }; + + struct lc3_complex s23 = + { x[2*n].re + x[3*n].re, x[2*n].im + x[3*n].im }; + struct lc3_complex d23 = + { x[2*n].re - x[3*n].re, x[2*n].im - x[3*n].im }; + + y[0].re = x[0].re + s14.re + s23.re; + y[0].im = x[0].im + s14.im + s23.im; + + y[1].re = x[0].re + s14.re * cos1 + s * d14.im * sin1 + + s23.re * cos2 + s * d23.im * sin2; + + y[1].im = x[0].im + s14.im * cos1 - s * d14.re * sin1 + + s23.im * cos2 - s * d23.re * sin2; + + y[2].re = x[0].re + s14.re * cos2 + s * d14.im * sin2 + + s23.re * cos1 - s * d23.im * sin1; + + y[2].im = x[0].im + s14.im * cos2 - s * d14.re * sin2 + + s23.im * cos1 + s * d23.re * sin1; + + y[3].re = x[0].re + s14.re * cos2 - s * d14.im * sin2 + + s23.re * cos1 + s * d23.im * sin1; + + y[3].im = x[0].im + s14.im * cos2 + s * d14.re * sin2 + + s23.im * cos1 - s * d23.re * sin1; + + y[4].re = x[0].re + s14.re * cos1 - s * d14.im * sin1 + + s23.re * cos2 - s * d23.im * sin2; + + y[4].im = x[0].im + s14.im * cos1 + s * d14.re * sin1 + + s23.im * cos2 + s * d23.re * sin2; + } +} + +/** + * FFT Butterfly 3 Points template + * s -1: Forward 1: Inverse + * x, y Input and output coefficients + * twiddles Twiddles factors, determine size of transform + * n Number of interleaved transforms + */ +static inline void xfft_bf3( + const float s, const struct lc3_fft_bf3_twiddles *twiddles, + const struct lc3_complex *x, struct lc3_complex *y, int n) +{ + int n3 = twiddles->n3; + const struct lc3_complex (*w0)[2] = twiddles->t; + const struct lc3_complex (*w1)[2] = w0 + n3, (*w2)[2] = w1 + n3; + + const struct lc3_complex *x0 = x, *x1 = x0 + n*n3, *x2 = x1 + n*n3; + struct lc3_complex *y0 = y, *y1 = y0 + n3, *y2 = y1 + n3; + + for (int i = 0; i < n; i++, y0 += 3*n3, y1 += 3*n3, y2 += 3*n3) { + + for (int j = 0; j < n3; j++, x0++, x1++, x2++) { + + y0[j].re = x0->re + x1->re * w0[j][0].re + s * x1->im * w0[j][0].im + + x2->re * w0[j][1].re + s * x2->im * w0[j][1].im; + + y0[j].im = x0->im + x1->im * w0[j][0].re - s * x1->re * w0[j][0].im + + x2->im * w0[j][1].re - s * x2->re * w0[j][1].im; + + y1[j].re = x0->re + x1->re * w1[j][0].re + s * x1->im * w1[j][0].im + + x2->re * w1[j][1].re + s * x2->im * w1[j][1].im; + + y1[j].im = x0->im + x1->im * w1[j][0].re - s * x1->re * w1[j][0].im + + x2->im * w1[j][1].re - s * x2->re * w1[j][1].im; + + y2[j].re = x0->re + x1->re * w2[j][0].re + s * x1->im * w2[j][0].im + + x2->re * w2[j][1].re + s * x2->im * w2[j][1].im; + + y2[j].im = x0->im + x1->im * w2[j][0].re - s * x1->re * w2[j][0].im + + x2->im * w2[j][1].re - s * x2->re * w2[j][1].im; + } + } +} + +/** + * FFT Butterfly 2 Points template + * s -1: Forward 1: Inverse + * twiddles Twiddles factors, determine size of transform + * x, y Input and output coefficients + * n Number of interleaved transforms + */ +static inline void xfft_bf2( + const float s, const struct lc3_fft_bf2_twiddles *twiddles, + const struct lc3_complex *x, struct lc3_complex *y, int n) +{ + int n2 = twiddles->n2; + const struct lc3_complex *w = twiddles->t; + + const struct lc3_complex *x0 = x, *x1 = x0 + n*n2; + struct lc3_complex *y0 = y, *y1 = y0 + n2; + + for (int i = 0; i < n; i++, y0 += 2*n2, y1 += 2*n2) { + + for (int j = 0; j < n2; j++, x0++, x1++) { + + y0[j].re = x0->re + x1->re * w[j].re + s * x1->im * w[j].im; + y0[j].im = x0->im + x1->im * w[j].re - s * x1->re * w[j].im; + + y1[j].re = x0->re - x1->re * w[j].re - s * x1->im * w[j].im; + y1[j].im = x0->im - x1->im * w[j].re + s * x1->re * w[j].im; + } + } +} + +/** + * Forward FFT 5 Points + * x, y Input and output coefficients, of size 5xn + * n Number of interleaved transform to perform + */ +static void ffft_5(const struct lc3_complex *x, struct lc3_complex *y, int n) +{ + xfft_5(-1, x, y, n); +} + +/** + * Inverse FFT 5 Points + * x, y Input and output coefficients, of size 5xn + * n Number of interleaved transform to perform + */ +static void ifft_5(const struct lc3_complex *x, struct lc3_complex *y, int n) +{ + xfft_5(1, x, y, n); +} + +/** + * Forward FFT Butterfly 3 Points + * twiddles Twiddles factors, determine size of transform + * x, y Input and output coefficients + * n Number of interleaved transforms + */ +static void ffft_bf3(const struct lc3_fft_bf3_twiddles *twiddles, + const struct lc3_complex *x, struct lc3_complex *y, int n) +{ + xfft_bf3(-1, twiddles, x, y, n); +} + +/** + * Inverse FFT Butterfly 3 Points + * twiddles Twiddles factors, determine size of transform + * x, y Input and output coefficients + * n Number of interleaved transforms + */ +static void ifft_bf3(const struct lc3_fft_bf3_twiddles *twiddles, + const struct lc3_complex *x, struct lc3_complex *y, int n) +{ + xfft_bf3(1, twiddles, x, y, n); +} + +/** + * Forward FFT Butterfly 2 Points + * twiddles Twiddles factors, determine size of transform + * x, y Input and output coefficients + * n Number of interleaved transforms + */ +static void ffft_bf2(const struct lc3_fft_bf2_twiddles *twiddles, + const struct lc3_complex *x, struct lc3_complex *y, int n) +{ + xfft_bf2(-1, twiddles, x, y, n); +} + +/** + * InverseIFFT Butterfly 2 Points + * twiddles Twiddles factors, determine size of transform + * x, y Input and output coefficients + * n Number of interleaved transforms + */ +static void ifft_bf2(const struct lc3_fft_bf2_twiddles *twiddles, + const struct lc3_complex *x, struct lc3_complex *y, int n) +{ + xfft_bf2(1, twiddles, x, y, n); +} + +/** + * Perform FFT + * inverse True on inverse transform else forward + * x, y0, y1 Input, and 2 scratch buffers of size `n` + * n Number of points 30, 40, 60, 80, 90, 120, 160, 180, 240 + * return The buffer `y0` or `y1` that hold the result + * + * Input `x` can be the same as the `y0` second scratch buffer + */ +static struct lc3_complex *fft( + bool inverse, const struct lc3_complex *x, int n, + struct lc3_complex *y0, struct lc3_complex *y1) +{ + struct lc3_complex *y[2] = { y1, y0 }; + int i2, i3, is = 0; + + /* The number of points `n` can be decomposed as : + * + * n = 5^1 * 3^n3 * 2^n2 + * + * for n = 40, 80, 160 n3 = 0, n2 = [3..5] + * n = 30, 60, 120, 240 n3 = 1, n2 = [1..4] + * n = 90, 180 n3 = 2, n2 = [1..2] + * + * Note that the expression `n & (n-1) == 0` is equivalent + * to the check that `n` is a power of 2. */ + + (inverse ? ifft_5 : ffft_5)(x, y[is], n /= 5); + + for (i3 = 0; n & (n-1); i3++, is ^= 1) + (inverse ? ifft_bf3 : ffft_bf3) + (lc3_fft_twiddles_bf3[i3], y[is], y[is ^ 1], n /= 3); + + for (i2 = 0; n > 1; i2++, is ^= 1) + (inverse ? ifft_bf2 : ffft_bf2) + (lc3_fft_twiddles_bf2[i2][i3], y[is], y[is ^ 1], n >>= 1); + + return y[is]; +} + + +/* ---------------------------------------------------------------------------- + * MDCT processing + * -------------------------------------------------------------------------- */ + +/** + * Windowing of samples before MDCT + * dt, sr Duration and samplerate (size of the transform) + * x [-nd..-1] Previous, [0..ns-1] Current samples + * y Output `ns` windowed samples + * + * The number of previous samples `nd` accessed on `x` is : + * nd: `ns` * 23/30 for 7.5ms frame duration + * nd: `ns` * 5/ 8 for 10ms frame duration + */ +static void mdct_window( + enum lc3_dt dt, enum lc3_srate sr, const float *x, float *y) +{ + int ns = LC3_NS(dt, sr), nd = LC3_ND(dt, sr); + + const float *w0 = lc3_mdct_win[dt][sr], *w1 = w0 + ns; + const float *w2 = w1, *w3 = w2 + nd; + + const float *x0 = x - nd, *x1 = x0 + ns; + const float *x2 = x1, *x3 = x2 + nd; + + float *y0 = y + ns/2, *y1 = y0; + + while (x0 < x1) + *(--y0) = *(x0++) * *(w0++) - *(--x1) * *(--w1); + + for (const float *xe = x2 + ns-nd; x2 < xe; ) + *(y1++) = *(x2++) * *(w2++); + + while (x2 < x3) + *(y1++) = *(x2++) * *(w2++) + *(--x3) * *(--w3); +} + +/** + * Pre-rotate MDCT coefficients of N/2 points, before FFT N/4 points FFT + * def Size and twiddles factors + * x, y Input and output coefficients + * + * `x` and y` can be the same buffer + */ +static void mdct_pre_fft(const struct lc3_mdct_rot_def *def, + const float *x, struct lc3_complex *y) +{ + int n4 = def->n4; + + const float *x0 = x, *x1 = x0 + 2*n4; + const struct lc3_complex *w0 = def->w, *w1 = w0 + n4; + struct lc3_complex *y0 = y, *y1 = y0 + n4; + + while (x0 < x1) { + struct lc3_complex u, uw = *(w0++); + u.re = - *(--x1) * uw.re + *x0 * uw.im; + u.im = *(x0++) * uw.re + *x1 * uw.im; + + struct lc3_complex v, vw = *(--w1); + v.re = - *(--x1) * vw.im + *x0 * vw.re; + v.im = - *(x0++) * vw.im - *x1 * vw.re; + + *(y0++) = u; + *(--y1) = v; + } +} + +/** + * Post-rotate FFT N/4 points coefficients, resulting MDCT N points + * def Size and twiddles factors + * x, y Input and output coefficients + * scale Scale on output coefficients + * + * `x` and y` can be the same buffer + */ +static void mdct_post_fft(const struct lc3_mdct_rot_def *def, + const struct lc3_complex *x, float *y, float scale) +{ + int n4 = def->n4, n8 = n4 >> 1; + + const struct lc3_complex *w0 = def->w + n8, *w1 = w0 - 1; + const struct lc3_complex *x0 = x + n8, *x1 = x0 - 1; + + float *y0 = y + n4, *y1 = y0; + + for ( ; y1 > y; x0++, x1--, w0++, w1--) { + + float u0 = (x0->im * w0->im + x0->re * w0->re) * scale; + float u1 = (x1->re * w1->im - x1->im * w1->re) * scale; + + float v0 = (x0->re * w0->im - x0->im * w0->re) * scale; + float v1 = (x1->im * w1->im + x1->re * w1->re) * scale; + + *(y0++) = u0; *(y0++) = u1; + *(--y1) = v0; *(--y1) = v1; + } +} + +/** + * Pre-rotate IMDCT coefficients of N points, before FFT N/4 points FFT + * def Size and twiddles factors + * x, y Input and output coefficients + * + * `x` and y` can be the same buffer + */ +static void imdct_pre_fft(const struct lc3_mdct_rot_def *def, + const float *x, struct lc3_complex *y) +{ + int n4 = def->n4; + + const float *x0 = x, *x1 = x0 + 2*n4; + + const struct lc3_complex *w0 = def->w, *w1 = w0 + n4; + struct lc3_complex *y0 = y, *y1 = y0 + n4; + + while (x0 < x1) { + float u0 = *(x0++), u1 = *(--x1); + float v0 = *(x0++), v1 = *(--x1); + struct lc3_complex uw = *(w0++), vw = *(--w1); + + (y0 )->re = - u1 * uw.re + u0 * uw.im; + (y0++)->im = - u0 * uw.re - u1 * uw.im; + + (--y1)->re = - v0 * vw.re + v1 * vw.im; + ( y1)->im = - v1 * vw.re - v0 * vw.im; + } +} + +/** + * Post-rotate FFT N/4 points coefficients, resulting IMDCT N points + * def Size and twiddles factors + * x, y Input and output coefficients + * scale Scale on output coefficients + * + * `x` and y` can be the same buffer + */ +static void imdct_post_fft(const struct lc3_mdct_rot_def *def, + const struct lc3_complex *x, float *y, float scale) +{ + int n4 = def->n4; + + const struct lc3_complex *w0 = def->w, *w1 = w0 + n4; + const struct lc3_complex *x0 = x, *x1 = x0 + n4; + + float *y0 = y, *y1 = y0 + 2*n4; + + while (x0 < x1) { + struct lc3_complex uz = *(x0++), vz = *(--x1); + struct lc3_complex uw = *(w0++), vw = *(--w1); + + *(y0++) = (uz.im * uw.im - uz.re * uw.re) * scale; + *(--y1) = (uz.im * uw.re + uz.re * uw.im) * scale; + + *(--y1) = (vz.im * vw.im - vz.re * vw.re) * scale; + *(y0++) = (vz.im * vw.re + vz.re * vw.im) * scale; + } +} + +/** + * Apply windowing of samples + * dt, sr Duration and samplerate + * x, d Middle half of IMDCT coefficients and delayed samples + * y, d Output samples and delayed ones + */ +static void imdct_window(enum lc3_dt dt, enum lc3_srate sr, + const float *x, float *d, float *y) +{ + /* The full MDCT coefficients is given by symmetry : + * T[ 0 .. n/4-1] = -half[n/4-1 .. 0 ] + * T[ n/4 .. n/2-1] = half[0 .. n/4-1] + * T[ n/2 .. 3n/4-1] = half[n/4 .. n/2-1] + * T[3n/4 .. n-1] = half[n/2-1 .. n/4 ] */ + + int n4 = LC3_NS(dt, sr) >> 1, nd = LC3_ND(dt, sr); + const float *w2 = lc3_mdct_win[dt][sr], *w0 = w2 + 3*n4, *w1 = w0; + + const float *x0 = d + nd-n4, *x1 = x0; + float *y0 = y + nd-n4, *y1 = y0, *y2 = d + nd, *y3 = d; + + while (y0 > y) { + *(--y0) = *(--x0) - *(x ) * *(w1++); + *(y1++) = *(x1++) + *(x++) * *(--w0); + } + + while (y1 < y + nd) { + *(y1++) = *(x1++) + *(x++) * *(--w0); + } + + while (y1 < y + 2*n4) { + *(y1++) = *(x ) * *(--w0); + *(--y2) = *(x++) * *(w2++); + } + + while (y2 > y3) { + *(y3++) = *(x ) * *(--w0); + *(--y2) = *(x++) * *(w2++); + } +} + +/** + * Forward MDCT transformation + */ +void lc3_mdct_forward(enum lc3_dt dt, enum lc3_srate sr, + enum lc3_srate sr_dst, const float *x, float *y) +{ + const struct lc3_mdct_rot_def *rot = lc3_mdct_rot[dt][sr]; + int nf = LC3_NS(dt, sr_dst); + int ns = LC3_NS(dt, sr); + + union { float *f; struct lc3_complex *z; } u = { .f = y }; + struct lc3_complex z[ns/2]; + + mdct_window(dt, sr, x, u.f); + + mdct_pre_fft(rot, u.f, u.z); + u.z = fft(false, u.z, ns/2, u.z, z); + mdct_post_fft(rot, u.z, y, sqrtf( (2.f*nf) / (ns*ns) )); +} + +/** + * Inverse MDCT transformation + */ +void lc3_mdct_inverse(enum lc3_dt dt, enum lc3_srate sr, + enum lc3_srate sr_src, const float *x, float *d, float *y) +{ + const struct lc3_mdct_rot_def *rot = lc3_mdct_rot[dt][sr]; + int nf = LC3_NS(dt, sr_src); + int ns = LC3_NS(dt, sr); + + struct lc3_complex buffer[ns/2]; + struct lc3_complex *z = (struct lc3_complex *)y; + union { float *f; struct lc3_complex *z; } u = { .z = buffer }; + + imdct_pre_fft(rot, x, z); + z = fft(true, z, ns/2, z, u.z); + imdct_post_fft(rot, z, u.f, sqrtf(2.f / nf)); + + imdct_window(dt, sr, u.f, d, y); +} diff --git a/3rd-party/lc3-google/src/mdct.h b/3rd-party/lc3-google/src/mdct.h new file mode 100644 index 000000000..27e48f40e --- /dev/null +++ b/3rd-party/lc3-google/src/mdct.h @@ -0,0 +1,59 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * LC3 - Compute LD-MDCT (Low Delay Modified Discret Cosinus Transform) + * + * Reference : Low Complexity Communication Codec (LC3) + * Bluetooth Specification v1.0 + */ + +#ifndef __LC3_MDCT_H +#define __LC3_MDCT_H + +#include "common.h" + + +/** + * Forward MDCT transformation + * dt, sr Duration and samplerate (size of the transform) + * sr_dst Samplerate destination, scale transforam accordingly + * x [-nd..-1] Previous, [0..ns-1] Current samples + * y Output `ns` frequency coefficients + * + * The number of previous samples `nd` accessed on `x` is : + * nd: `ns` * 23/30 for 7.5ms frame duration + * nd: `ns` * 5/ 8 for 10ms frame duration + */ +void lc3_mdct_forward(enum lc3_dt dt, enum lc3_srate sr, + enum lc3_srate sr_dst, const float *x, float *y); + +/** + * Inverse MDCT transformation + * dt, sr Duration and samplerate (size of the transform) + * sr_src Samplerate source, scale transforam accordingly + * x, d Frequency coefficients and delayed buffer + * y, d Output `ns` samples and `nd` delayed ones + * + * `x` and `y` can be the same buffer + */ +void lc3_mdct_inverse(enum lc3_dt dt, enum lc3_srate sr, + enum lc3_srate sr_src, const float *x, float *d, float *y); + + +#endif /* __LC3_MDCT_H */ diff --git a/3rd-party/lc3-google/src/plc.c b/3rd-party/lc3-google/src/plc.c new file mode 100644 index 000000000..b8dfef458 --- /dev/null +++ b/3rd-party/lc3-google/src/plc.c @@ -0,0 +1,61 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "plc.h" + + +/** + * Reset Packet Loss Concealment state + */ +void lc3_plc_reset(struct lc3_plc_state *plc) +{ + plc->seed = 24607; + lc3_plc_suspend(plc); +} + +/** + * Suspend PLC execution (Good frame received) + */ +void lc3_plc_suspend(struct lc3_plc_state *plc) +{ + plc->count = 1; + plc->alpha = 1.0f; +} + +/** + * Synthesis of a PLC frame + */ +void lc3_plc_synthesize(enum lc3_dt dt, enum lc3_srate sr, + struct lc3_plc_state *plc, const float *x, float *y) +{ + uint16_t seed = plc->seed; + float alpha = plc->alpha; + int ne = LC3_NE(dt, sr); + + alpha *= (plc->count < 4 ? 1.0f : + plc->count < 8 ? 0.9f : 0.85f); + + for (int i = 0; i < ne; i++) { + seed = (16831 + seed * 12821) & 0xffff; + y[i] = alpha * (seed & 0x8000 ? -x[i] : x[i]); + } + + plc->seed = seed; + plc->alpha = alpha; + plc->count++; +} diff --git a/3rd-party/lc3-google/src/plc.h b/3rd-party/lc3-google/src/plc.h new file mode 100644 index 000000000..86b797c56 --- /dev/null +++ b/3rd-party/lc3-google/src/plc.h @@ -0,0 +1,57 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * LC3 - Packet Loss Concealment + * + * Reference : Low Complexity Communication Codec (LC3) + * Bluetooth Specification v1.0 + */ + +#ifndef __LC3_PLC_H +#define __LC3_PLC_H + +#include "common.h" + + +/** + * Reset PLC state + * plc PLC State to reset + */ +void lc3_plc_reset(lc3_plc_state_t *plc); + +/** + * Suspend PLC synthesis (Error-free frame decoded) + * plc PLC State + */ +void lc3_plc_suspend(lc3_plc_state_t *plc); + +/** + * Synthesis of a PLC frame + * dt, sr Duration and samplerate of the frame + * plc PLC State + * x Last good spectral coefficients + * y Return emulated ones + * + * `x` and `y` can be the same buffer + */ +void lc3_plc_synthesize(enum lc3_dt dt, enum lc3_srate sr, + lc3_plc_state_t *plc, const float *x, float *y); + + +#endif /* __LC3_PLC_H */ diff --git a/3rd-party/lc3-google/src/sns.c b/3rd-party/lc3-google/src/sns.c new file mode 100644 index 000000000..56643056e --- /dev/null +++ b/3rd-party/lc3-google/src/sns.c @@ -0,0 +1,878 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "sns.h" +#include "tables.h" + + +/* ---------------------------------------------------------------------------- + * DCT-16 + * -------------------------------------------------------------------------- */ + +/** + * Matrix of DCT-16 coefficients + * + * M[n][k] = 2f cos( Pi k (2n + 1) / 2N ) + * + * k = [0..N-1], n = [0..N-1], N = 16 + * f = sqrt(1/4N) for k=0, sqrt(1/2N) otherwise + */ +static const float dct16_m[16][16] = { + + { 2.50000000e-01, 3.51850934e-01, 3.46759961e-01, 3.38329500e-01, + 3.26640741e-01, 3.11806253e-01, 2.93968901e-01, 2.73300467e-01, + 2.50000000e-01, 2.24291897e-01, 1.96423740e-01, 1.66663915e-01, + 1.35299025e-01, 1.02631132e-01, 6.89748448e-02, 3.46542923e-02 }, + + { 2.50000000e-01, 3.38329500e-01, 2.93968901e-01, 2.24291897e-01, + 1.35299025e-01, 3.46542923e-02, -6.89748448e-02, -1.66663915e-01, + -2.50000000e-01, -3.11806253e-01, -3.46759961e-01, -3.51850934e-01, + -3.26640741e-01, -2.73300467e-01, -1.96423740e-01, -1.02631132e-01 }, + + { 2.50000000e-01, 3.11806253e-01, 1.96423740e-01, 3.46542923e-02, + -1.35299025e-01, -2.73300467e-01, -3.46759961e-01, -3.38329500e-01, + -2.50000000e-01, -1.02631132e-01, 6.89748448e-02, 2.24291897e-01, + 3.26640741e-01, 3.51850934e-01, 2.93968901e-01, 1.66663915e-01 }, + + { 2.50000000e-01, 2.73300467e-01, 6.89748448e-02, -1.66663915e-01, + -3.26640741e-01, -3.38329500e-01, -1.96423740e-01, 3.46542923e-02, + 2.50000000e-01, 3.51850934e-01, 2.93968901e-01, 1.02631132e-01, + -1.35299025e-01, -3.11806253e-01, -3.46759961e-01, -2.24291897e-01 }, + + { 2.50000000e-01, 2.24291897e-01, -6.89748448e-02, -3.11806253e-01, + -3.26640741e-01, -1.02631132e-01, 1.96423740e-01, 3.51850934e-01, + 2.50000000e-01, -3.46542923e-02, -2.93968901e-01, -3.38329500e-01, + -1.35299025e-01, 1.66663915e-01, 3.46759961e-01, 2.73300467e-01 }, + + { 2.50000000e-01, 1.66663915e-01, -1.96423740e-01, -3.51850934e-01, + -1.35299025e-01, 2.24291897e-01, 3.46759961e-01, 1.02631132e-01, + -2.50000000e-01, -3.38329500e-01, -6.89748448e-02, 2.73300467e-01, + 3.26640741e-01, 3.46542923e-02, -2.93968901e-01, -3.11806253e-01 }, + + { 2.50000000e-01, 1.02631132e-01, -2.93968901e-01, -2.73300467e-01, + 1.35299025e-01, 3.51850934e-01, 6.89748448e-02, -3.11806253e-01, + -2.50000000e-01, 1.66663915e-01, 3.46759961e-01, 3.46542923e-02, + -3.26640741e-01, -2.24291897e-01, 1.96423740e-01, 3.38329500e-01 }, + + { 2.50000000e-01, 3.46542923e-02, -3.46759961e-01, -1.02631132e-01, + 3.26640741e-01, 1.66663915e-01, -2.93968901e-01, -2.24291897e-01, + 2.50000000e-01, 2.73300467e-01, -1.96423740e-01, -3.11806253e-01, + 1.35299025e-01, 3.38329500e-01, -6.89748448e-02, -3.51850934e-01 }, + + { 2.50000000e-01, -3.46542923e-02, -3.46759961e-01, 1.02631132e-01, + 3.26640741e-01, -1.66663915e-01, -2.93968901e-01, 2.24291897e-01, + 2.50000000e-01, -2.73300467e-01, -1.96423740e-01, 3.11806253e-01, + 1.35299025e-01, -3.38329500e-01, -6.89748448e-02, 3.51850934e-01 }, + + { 2.50000000e-01, -1.02631132e-01, -2.93968901e-01, 2.73300467e-01, + 1.35299025e-01, -3.51850934e-01, 6.89748448e-02, 3.11806253e-01, + -2.50000000e-01, -1.66663915e-01, 3.46759961e-01, -3.46542923e-02, + -3.26640741e-01, 2.24291897e-01, 1.96423740e-01, -3.38329500e-01 }, + + { 2.50000000e-01, -1.66663915e-01, -1.96423740e-01, 3.51850934e-01, + -1.35299025e-01, -2.24291897e-01, 3.46759961e-01, -1.02631132e-01, + -2.50000000e-01, 3.38329500e-01, -6.89748448e-02, -2.73300467e-01, + 3.26640741e-01, -3.46542923e-02, -2.93968901e-01, 3.11806253e-01 }, + + { 2.50000000e-01, -2.24291897e-01, -6.89748448e-02, 3.11806253e-01, + -3.26640741e-01, 1.02631132e-01, 1.96423740e-01, -3.51850934e-01, + 2.50000000e-01, 3.46542923e-02, -2.93968901e-01, 3.38329500e-01, + -1.35299025e-01, -1.66663915e-01, 3.46759961e-01, -2.73300467e-01 }, + + { 2.50000000e-01, -2.73300467e-01, 6.89748448e-02, 1.66663915e-01, + -3.26640741e-01, 3.38329500e-01, -1.96423740e-01, -3.46542923e-02, + 2.50000000e-01, -3.51850934e-01, 2.93968901e-01, -1.02631132e-01, + -1.35299025e-01, 3.11806253e-01, -3.46759961e-01, 2.24291897e-01 }, + + { 2.50000000e-01, -3.11806253e-01, 1.96423740e-01, -3.46542923e-02, + -1.35299025e-01, 2.73300467e-01, -3.46759961e-01, 3.38329500e-01, + -2.50000000e-01, 1.02631132e-01, 6.89748448e-02, -2.24291897e-01, + 3.26640741e-01, -3.51850934e-01, 2.93968901e-01, -1.66663915e-01 }, + + { 2.50000000e-01, -3.38329500e-01, 2.93968901e-01, -2.24291897e-01, + 1.35299025e-01, -3.46542923e-02, -6.89748448e-02, 1.66663915e-01, + -2.50000000e-01, 3.11806253e-01, -3.46759961e-01, 3.51850934e-01, + -3.26640741e-01, 2.73300467e-01, -1.96423740e-01, 1.02631132e-01 }, + + { 2.50000000e-01, -3.51850934e-01, 3.46759961e-01, -3.38329500e-01, + 3.26640741e-01, -3.11806253e-01, 2.93968901e-01, -2.73300467e-01, + 2.50000000e-01, -2.24291897e-01, 1.96423740e-01, -1.66663915e-01, + 1.35299025e-01, -1.02631132e-01, 6.89748448e-02, -3.46542923e-02 }, + +}; + +/** + * Forward DCT-16 transformation + * x, y Input and output 16 values + */ +static void dct16_forward(const float *x, float *y) +{ + for (int i = 0, j; i < 16; i++) + for (y[i] = 0, j = 0; j < 16; j++) + y[i] += x[j] * dct16_m[j][i]; +} + +/** + * Inverse DCT-16 transformation + * x, y Input and output 16 values + */ +static void dct16_inverse(const float *x, float *y) +{ + for (int i = 0, j; i < 16; i++) + for (y[i] = 0, j = 0; j < 16; j++) + y[i] += x[j] * dct16_m[i][j]; +} + + +/* ---------------------------------------------------------------------------- + * Scale factors + * -------------------------------------------------------------------------- */ + +/** + * Scale factors + * dt, sr Duration and samplerate of the frame + * eb Energy estimation per bands + * att 1: Attack detected 0: Otherwise + * scf Output 16 scale factors + */ +static void compute_scale_factors(enum lc3_dt dt, enum lc3_srate sr, + const float *eb, bool att, float *scf) +{ + /* Pre-emphasis gain table : + * Ge[b] = 10 ^ (b * g_tilt) / 630 , b = [0..63] */ + + static const float ge_table[LC3_NUM_SRATE][LC3_NUM_BANDS] = { + + [LC3_SRATE_8K] = { /* g_tilt = 14 */ + 1.00000000e+00, 1.05250029e+00, 1.10775685e+00, 1.16591440e+00, + 1.22712524e+00, 1.29154967e+00, 1.35935639e+00, 1.43072299e+00, + 1.50583635e+00, 1.58489319e+00, 1.66810054e+00, 1.75567629e+00, + 1.84784980e+00, 1.94486244e+00, 2.04696827e+00, 2.15443469e+00, + 2.26754313e+00, 2.38658979e+00, 2.51188643e+00, 2.64376119e+00, + 2.78255940e+00, 2.92864456e+00, 3.08239924e+00, 3.24422608e+00, + 3.41454887e+00, 3.59381366e+00, 3.78248991e+00, 3.98107171e+00, + 4.19007911e+00, 4.41005945e+00, 4.64158883e+00, 4.88527357e+00, + 5.14175183e+00, 5.41169527e+00, 5.69581081e+00, 5.99484250e+00, + 6.30957344e+00, 6.64082785e+00, 6.98947321e+00, 7.35642254e+00, + 7.74263683e+00, 8.14912747e+00, 8.57695899e+00, 9.02725178e+00, + 9.50118507e+00, 1.00000000e+01, 1.05250029e+01, 1.10775685e+01, + 1.16591440e+01, 1.22712524e+01, 1.29154967e+01, 1.35935639e+01, + 1.43072299e+01, 1.50583635e+01, 1.58489319e+01, 1.66810054e+01, + 1.75567629e+01, 1.84784980e+01, 1.94486244e+01, 2.04696827e+01, + 2.15443469e+01, 2.26754313e+01, 2.38658979e+01, 2.51188643e+01 }, + + [LC3_SRATE_16K] = { /* g_tilt = 18 */ + 1.00000000e+00, 1.06800043e+00, 1.14062492e+00, 1.21818791e+00, + 1.30102522e+00, 1.38949549e+00, 1.48398179e+00, 1.58489319e+00, + 1.69266662e+00, 1.80776868e+00, 1.93069773e+00, 2.06198601e+00, + 2.20220195e+00, 2.35195264e+00, 2.51188643e+00, 2.68269580e+00, + 2.86512027e+00, 3.05994969e+00, 3.26802759e+00, 3.49025488e+00, + 3.72759372e+00, 3.98107171e+00, 4.25178630e+00, 4.54090961e+00, + 4.84969343e+00, 5.17947468e+00, 5.53168120e+00, 5.90783791e+00, + 6.30957344e+00, 6.73862717e+00, 7.19685673e+00, 7.68624610e+00, + 8.20891416e+00, 8.76712387e+00, 9.36329209e+00, 1.00000000e+01, + 1.06800043e+01, 1.14062492e+01, 1.21818791e+01, 1.30102522e+01, + 1.38949549e+01, 1.48398179e+01, 1.58489319e+01, 1.69266662e+01, + 1.80776868e+01, 1.93069773e+01, 2.06198601e+01, 2.20220195e+01, + 2.35195264e+01, 2.51188643e+01, 2.68269580e+01, 2.86512027e+01, + 3.05994969e+01, 3.26802759e+01, 3.49025488e+01, 3.72759372e+01, + 3.98107171e+01, 4.25178630e+01, 4.54090961e+01, 4.84969343e+01, + 5.17947468e+01, 5.53168120e+01, 5.90783791e+01, 6.30957344e+01 }, + + [LC3_SRATE_24K] = { /* g_tilt = 22 */ + 1.00000000e+00, 1.08372885e+00, 1.17446822e+00, 1.27280509e+00, + 1.37937560e+00, 1.49486913e+00, 1.62003281e+00, 1.75567629e+00, + 1.90267705e+00, 2.06198601e+00, 2.23463373e+00, 2.42173704e+00, + 2.62450630e+00, 2.84425319e+00, 3.08239924e+00, 3.34048498e+00, + 3.62017995e+00, 3.92329345e+00, 4.25178630e+00, 4.60778348e+00, + 4.99358789e+00, 5.41169527e+00, 5.86481029e+00, 6.35586411e+00, + 6.88803330e+00, 7.46476041e+00, 8.08977621e+00, 8.76712387e+00, + 9.50118507e+00, 1.02967084e+01, 1.11588399e+01, 1.20931568e+01, + 1.31057029e+01, 1.42030283e+01, 1.53922315e+01, 1.66810054e+01, + 1.80776868e+01, 1.95913107e+01, 2.12316686e+01, 2.30093718e+01, + 2.49359200e+01, 2.70237760e+01, 2.92864456e+01, 3.17385661e+01, + 3.43959997e+01, 3.72759372e+01, 4.03970086e+01, 4.37794036e+01, + 4.74450028e+01, 5.14175183e+01, 5.57226480e+01, 6.03882412e+01, + 6.54444792e+01, 7.09240702e+01, 7.68624610e+01, 8.32980665e+01, + 9.02725178e+01, 9.78309319e+01, 1.06022203e+02, 1.14899320e+02, + 1.24519708e+02, 1.34945600e+02, 1.46244440e+02, 1.58489319e+02 }, + + [LC3_SRATE_32K] = { /* g_tilt = 26 */ + 1.00000000e+00, 1.09968890e+00, 1.20931568e+00, 1.32987103e+00, + 1.46244440e+00, 1.60823388e+00, 1.76855694e+00, 1.94486244e+00, + 2.13874364e+00, 2.35195264e+00, 2.58641621e+00, 2.84425319e+00, + 3.12779366e+00, 3.43959997e+00, 3.78248991e+00, 4.15956216e+00, + 4.57422434e+00, 5.03022373e+00, 5.53168120e+00, 6.08312841e+00, + 6.68954879e+00, 7.35642254e+00, 8.08977621e+00, 8.89623710e+00, + 9.78309319e+00, 1.07583590e+01, 1.18308480e+01, 1.30102522e+01, + 1.43072299e+01, 1.57335019e+01, 1.73019574e+01, 1.90267705e+01, + 2.09235283e+01, 2.30093718e+01, 2.53031508e+01, 2.78255940e+01, + 3.05994969e+01, 3.36499270e+01, 3.70044512e+01, 4.06933843e+01, + 4.47500630e+01, 4.92111475e+01, 5.41169527e+01, 5.95118121e+01, + 6.54444792e+01, 7.19685673e+01, 7.91430346e+01, 8.70327166e+01, + 9.57089124e+01, 1.05250029e+02, 1.15742288e+02, 1.27280509e+02, + 1.39968963e+02, 1.53922315e+02, 1.69266662e+02, 1.86140669e+02, + 2.04696827e+02, 2.25102829e+02, 2.47543082e+02, 2.72220379e+02, + 2.99357729e+02, 3.29200372e+02, 3.62017995e+02, 3.98107171e+02 }, + + [LC3_SRATE_48K] = { /* g_tilt = 30 */ + 1.00000000e+00, 1.11588399e+00, 1.24519708e+00, 1.38949549e+00, + 1.55051578e+00, 1.73019574e+00, 1.93069773e+00, 2.15443469e+00, + 2.40409918e+00, 2.68269580e+00, 2.99357729e+00, 3.34048498e+00, + 3.72759372e+00, 4.15956216e+00, 4.64158883e+00, 5.17947468e+00, + 5.77969288e+00, 6.44946677e+00, 7.19685673e+00, 8.03085722e+00, + 8.96150502e+00, 1.00000000e+01, 1.11588399e+01, 1.24519708e+01, + 1.38949549e+01, 1.55051578e+01, 1.73019574e+01, 1.93069773e+01, + 2.15443469e+01, 2.40409918e+01, 2.68269580e+01, 2.99357729e+01, + 3.34048498e+01, 3.72759372e+01, 4.15956216e+01, 4.64158883e+01, + 5.17947468e+01, 5.77969288e+01, 6.44946677e+01, 7.19685673e+01, + 8.03085722e+01, 8.96150502e+01, 1.00000000e+02, 1.11588399e+02, + 1.24519708e+02, 1.38949549e+02, 1.55051578e+02, 1.73019574e+02, + 1.93069773e+02, 2.15443469e+02, 2.40409918e+02, 2.68269580e+02, + 2.99357729e+02, 3.34048498e+02, 3.72759372e+02, 4.15956216e+02, + 4.64158883e+02, 5.17947468e+02, 5.77969288e+02, 6.44946677e+02, + 7.19685673e+02, 8.03085722e+02, 8.96150502e+02, 1.00000000e+03 }, + }; + + float e[LC3_NUM_BANDS]; + + /* --- Copy and padding --- */ + + int nb = LC3_MIN(lc3_band_lim[dt][sr][LC3_NUM_BANDS], LC3_NUM_BANDS); + int n2 = LC3_NUM_BANDS - nb; + + for (int i2 = 0; i2 < n2; i2++) + e[2*i2 + 0] = e[2*i2 + 1] = eb[i2]; + + memcpy(e + 2*n2, eb + n2, (nb - n2) * sizeof(float)); + + /* --- Smoothing, pre-emphasis and logarithm --- */ + + const float *ge = ge_table[sr]; + + float e0 = e[0], e1 = e[0], e2; + float e_sum = 0; + + for (int i = 0; i < LC3_NUM_BANDS-1; ) { + e[i] = (e0 * 0.25 + e1 * 0.5 + (e2 = e[i+1]) * 0.25) * ge[i]; + e_sum += e[i++]; + + e[i] = (e1 * 0.25 + e2 * 0.5 + (e0 = e[i+1]) * 0.25) * ge[i]; + e_sum += e[i++]; + + e[i] = (e2 * 0.25 + e0 * 0.5 + (e1 = e[i+1]) * 0.25) * ge[i]; + e_sum += e[i++]; + } + + e[LC3_NUM_BANDS-1] = (e0 * 0.25 + e1 * 0.75) * ge[LC3_NUM_BANDS-1]; + e_sum += e[LC3_NUM_BANDS-1]; + + float noise_floor = fmaxf(e_sum * (1e-4 / 64), 0x1p-32); + + for (int i = 0; i < LC3_NUM_BANDS; i++) + e[i] = log2f(fmaxf(e[i], noise_floor)) * 0.5; + + /* --- Grouping & scaling --- */ + + float scf_sum; + + scf[0] = (e[0] + e[4]) * 1./12 + + (e[0] + e[3]) * 2./12 + + (e[1] + e[2]) * 3./12 ; + scf_sum = scf[0]; + + for (int i = 1; i < 15; i++) { + scf[i] = (e[4*i-1] + e[4*i+4]) * 1./12 + + (e[4*i ] + e[4*i+3]) * 2./12 + + (e[4*i+1] + e[4*i+2]) * 3./12 ; + scf_sum += scf[i]; + } + + scf[15] = (e[59] + e[63]) * 1./12 + + (e[60] + e[63]) * 2./12 + + (e[61] + e[62]) * 3./12 ; + scf_sum += scf[15]; + + for (int i = 0; i < 16; i++) + scf[i] = 0.85 * (scf[i] - scf_sum * 1./16); + + /* --- Attack handling --- */ + + if (!att) + return; + + float s0, s1 = scf[0], s2 = scf[1], s3 = scf[2], s4 = scf[3]; + float sn = s1 + s2; + + scf[0] = (sn += s3) * 1./3; + scf[1] = (sn += s4) * 1./4; + scf_sum = scf[0] + scf[1]; + + for (int i = 2; i < 14; i++, sn -= s0) { + s0 = s1, s1 = s2, s2 = s3, s3 = s4, s4 = scf[i+2]; + scf[i] = (sn += s4) * 1./5; + scf_sum += scf[i]; + } + + scf[14] = (sn ) * 1./4; + scf[15] = (sn -= s1) * 1./3; + scf_sum += scf[14] + scf[15]; + + for (int i = 0; i < 16; i++) + scf[i] = (dt == LC3_DT_7M5 ? 0.3 : 0.5) * + (scf[i] - scf_sum * 1./16); +} + +/** + * Codebooks + * scf Input 16 scale factors + * lf/hfcb_idx Output the low and high frequency codebooks index + */ +static void resolve_codebooks(const float *scf, int *lfcb_idx, int *hfcb_idx) +{ + float dlfcb_max = 0, dhfcb_max = 0; + *lfcb_idx = *hfcb_idx = 0; + + for (int icb = 0; icb < 32; icb++) { + const float *lfcb = lc3_sns_lfcb[icb]; + const float *hfcb = lc3_sns_hfcb[icb]; + float dlfcb = 0, dhfcb = 0; + + for (int i = 0; i < 8; i++) { + dlfcb += (scf[ i] - lfcb[i]) * (scf[ i] - lfcb[i]); + dhfcb += (scf[8+i] - hfcb[i]) * (scf[8+i] - hfcb[i]); + } + + if (icb == 0 || dlfcb < dlfcb_max) + *lfcb_idx = icb, dlfcb_max = dlfcb; + + if (icb == 0 || dhfcb < dhfcb_max) + *hfcb_idx = icb, dhfcb_max = dhfcb; + } +} + +/** + * Unit energy normalize pulse configuration + * c Pulse configuration + * cn Normalized pulse configuration + */ +static void normalize(const int *c, float *cn) +{ + int c2_sum = 0; + for (int i = 0; i < 16; i++) + c2_sum += c[i] * c[i]; + + float c_norm = 1.f / sqrtf(c2_sum); + + for (int i = 0; i < 16; i++) + cn[i] = c[i] * c_norm; +} + +/** + * Sub-procedure of `quantize()`, add unit pulse + * x, y, n Transformed residual, and vector of pulses with length + * start, end Current number of pulses, limit to reach + * corr, energy Correlation (x,y) and y energy, updated at output + */ +static void add_pulse(const float *x, int *y, int n, + int start, int end, float *corr, float *energy) +{ + for (int k = start; k < end; k++) { + float best_c2 = (*corr + x[0]) * (*corr + x[0]); + float best_e = *energy + 2*y[0] + 1; + int nbest = 0; + + for (int i = 1; i < n; i++) { + float c2 = (*corr + x[i]) * (*corr + x[i]); + float e = *energy + 2*y[i] + 1; + + if (c2 * best_e > e * best_c2) + best_c2 = c2, best_e = e, nbest = i; + } + + *corr += x[nbest]; + *energy += 2*y[nbest] + 1; + y[nbest]++; + } +} + +/** + * Quantization of codebooks residual + * scf Input 16 scale factors, output quantized version + * lf/hfcb_idx Codebooks index + * c, cn Output 4 pulse configurations candidates, normalized + * shape/gain_idx Output selected shape/gain indexes + */ +static void quantize(const float *scf, int lfcb_idx, int hfcb_idx, + int (*c)[16], float (*cn)[16], int *shape_idx, int *gain_idx) +{ + /* --- Residual --- */ + + const float *lfcb = lc3_sns_lfcb[lfcb_idx]; + const float *hfcb = lc3_sns_hfcb[hfcb_idx]; + float r[16], x[16]; + + for (int i = 0; i < 8; i++) { + r[ i] = scf[ i] - lfcb[i]; + r[8+i] = scf[8+i] - hfcb[i]; + } + + dct16_forward(r, x); + + /* --- Shape 3 candidate --- + * Project to or below pyramid N = 16, K = 6, + * then add unit pulses until you reach K = 6, over N = 16 */ + + float xm[16]; + float xm_sum = 0; + + for (int i = 0; i < 16; i++) { + xm[i] = fabsf(x[i]); + xm_sum += xm[i]; + } + + float proj_factor = (6 - 1) / fmaxf(xm_sum, 1e-31); + float corr = 0, energy = 0; + int npulses = 0; + + for (int i = 0; i < 16; i++) { + c[3][i] = floorf(xm[i] * proj_factor); + npulses += c[3][i]; + corr += c[3][i] * xm[i]; + energy += c[3][i] * c[3][i]; + } + + add_pulse(xm, c[3], 16, npulses, 6, &corr, &energy); + npulses = 6; + + /* --- Shape 2 candidate --- + * Add unit pulses until you reach K = 8 on shape 3 */ + + memcpy(c[2], c[3], sizeof(c[2])); + + add_pulse(xm, c[2], 16, npulses, 8, &corr, &energy); + npulses = 8; + + /* --- Shape 1 candidate --- + * Remove any unit pulses from shape 2 that are not part of 0 to 9 + * Update energy and correlation terms accordingly + * Add unit pulses until you reach K = 10, over N = 10 */ + + memcpy(c[1], c[2], sizeof(c[1])); + + for (int i = 10; i < 16; i++) { + c[1][i] = 0; + npulses -= c[2][i]; + corr -= c[2][i] * xm[i]; + energy -= c[2][i] * c[2][i]; + } + + add_pulse(xm, c[1], 10, npulses, 10, &corr, &energy); + npulses = 10; + + /* --- Shape 0 candidate --- + * Add unit pulses until you reach K = 1, on shape 1 */ + + memcpy(c[0], c[1], sizeof(c[0])); + + add_pulse(xm + 10, c[0] + 10, 6, 0, 1, &corr, &energy); + + /* --- Add sign and unit energy normalize --- */ + + for (int j = 0; j < 16; j++) + for (int i = 0; i < 4; i++) + c[i][j] = x[j] < 0 ? -c[i][j] : c[i][j]; + + for (int i = 0; i < 4; i++) + normalize(c[i], cn[i]); + + /* --- Determe shape & gain index --- + * Search the Mean Square Error, within (shape, gain) combinations */ + + float mse_min = INFINITY; + *shape_idx = *gain_idx = 0; + + for (int ic = 0; ic < 4; ic++) { + const struct lc3_sns_vq_gains *cgains = lc3_sns_vq_gains + ic; + float cmse_min = INFINITY; + int cgain_idx = 0; + + for (int ig = 0; ig < cgains->count; ig++) { + float g = cgains->v[ig]; + + float mse = 0; + for (int i = 0; i < 16; i++) + mse += (x[i] - g * cn[ic][i]) * (x[i] - g * cn[ic][i]); + + if (mse < cmse_min) { + cgain_idx = ig, + cmse_min = mse; + } + } + + if (cmse_min < mse_min) { + *shape_idx = ic, *gain_idx = cgain_idx; + mse_min = cmse_min; + } + } +} + +/** + * Unquantization of codebooks residual + * lf/hfcb_idx Low and high frequency codebooks index + * c Table of normalized pulse configuration + * shape/gain Selected shape/gain indexes + * scf Return unquantized scale factors + */ +static void unquantize(int lfcb_idx, int hfcb_idx, + const float *c, int shape, int gain, float *scf) +{ + const float *lfcb = lc3_sns_lfcb[lfcb_idx]; + const float *hfcb = lc3_sns_hfcb[hfcb_idx]; + float g = lc3_sns_vq_gains[shape].v[gain]; + + dct16_inverse(c, scf); + + for (int i = 0; i < 8; i++) + scf[i] = lfcb[i] + g * scf[i]; + + for (int i = 8; i < 16; i++) + scf[i] = hfcb[i-8] + g * scf[i]; +} + +/** + * Sub-procedure of `sns_enumerate()`, enumeration of a vector + * c, n Table of pulse configuration, and length + * idx, ls Return enumeration set + */ +static void enum_mvpq(const int *c, int n, int *idx, bool *ls) +{ + int ci, i, j; + + /* --- Scan for 1st significant coeff --- */ + + for (i = 0, c += n; (ci = *(--c)) == 0 ; i++); + + *idx = 0; + *ls = ci < 0; + + /* --- Scan remaining coefficients --- */ + + for (i++, j = LC3_ABS(ci); i < n; i++, j += LC3_ABS(ci)) { + + if ((ci = *(--c)) != 0) { + *idx = (*idx << 1) | *ls; + *ls = ci < 0; + } + + *idx += lc3_sns_mpvq_offsets[i][j]; + } +} + +/** + * Sub-procedure of `sns_deenumerate()`, deenumeration of a vector + * idx, ls Enumeration set + * npulses Number of pulses in the set + * c, n Table of pulses configuration, and length + */ +static void deenum_mvpq(int idx, bool ls, int npulses, int *c, int n) +{ + int i; + + /* --- Scan for coefficients --- */ + + for (i = n-1; i >= 0 && idx; i--) { + + int ci = 0; + + for (ci = 0; idx < lc3_sns_mpvq_offsets[i][npulses - ci]; ci++); + idx -= lc3_sns_mpvq_offsets[i][npulses - ci]; + + *(c++) = ls ? -ci : ci; + npulses -= ci; + if (ci > 0) { + ls = idx & 1; + idx >>= 1; + } + } + + /* --- Set last significant --- */ + + int ci = npulses; + + if (i-- >= 0) + *(c++) = ls ? -ci : ci; + + while (i-- >= 0) + *(c++) = 0; +} + +/** + * SNS Enumeration of PVQ configuration + * shape Selected shape index + * c Selected pulse configuration + * idx_a, ls_a Return enumeration set A + * idx_b, ls_b Return enumeration set B (shape = 0) + */ +static void enumerate(int shape, const int *c, + int *idx_a, bool *ls_a, int *idx_b, bool *ls_b) +{ + enum_mvpq(c, shape < 2 ? 10 : 16, idx_a, ls_a); + + if (shape == 0) + enum_mvpq(c + 10, 6, idx_b, ls_b); +} + +/** + * SNS Deenumeration of PVQ configuration + * shape Selected shape index + * idx_a, ls_a enumeration set A + * idx_b, ls_b enumeration set B (shape = 0) + * c Return pulse configuration + */ +static void deenumerate(int shape, + int idx_a, bool ls_a, int idx_b, bool ls_b, int *c) +{ + int npulses_a = (const int []){ 10, 10, 8, 6 }[shape]; + + deenum_mvpq(idx_a, ls_a, npulses_a, c, shape < 2 ? 10 : 16); + + if (shape == 0) + deenum_mvpq(idx_b, ls_b, 1, c + 10, 6); + else if (shape == 1) + memset(c + 10, 0, 6 * sizeof(*c)); +} + + +/* ---------------------------------------------------------------------------- + * Filtering + * -------------------------------------------------------------------------- */ + +/** + * Spectral shaping + * dt, sr Duration and samplerate of the frame + * scf_q Quantized scale factors + * inv True on inverse shaping, False otherwise + * x Spectral coefficients + * y Return shapped coefficients + * + * `x` and `y` can be the same buffer + */ +static void spectral_shaping(enum lc3_dt dt, enum lc3_srate sr, + const float *scf_q, bool inv, const float *x, float *y) +{ + /* --- Interpolate scale factors --- */ + + float scf[LC3_NUM_BANDS]; + float s0, s1 = inv ? -scf_q[0] : scf_q[0]; + + scf[0] = scf[1] = s1; + for (int i = 0; i < 15; i++) { + s0 = s1, s1 = inv ? -scf_q[i+1] : scf_q[i+1]; + scf[4*i+2] = s0 + 0.125 * (s1 - s0); + scf[4*i+3] = s0 + 0.375 * (s1 - s0); + scf[4*i+4] = s0 + 0.625 * (s1 - s0); + scf[4*i+5] = s0 + 0.875 * (s1 - s0); + } + scf[62] = s1 + 0.125 * (s1 - s0); + scf[63] = s1 + 0.375 * (s1 - s0); + + int nb = LC3_MIN(lc3_band_lim[dt][sr][LC3_NUM_BANDS], LC3_NUM_BANDS); + int n2 = LC3_NUM_BANDS - nb; + + for (int i2 = 0; i2 < n2; i2++) + scf[i2] = 0.5 * (scf[2*i2] + scf[2*i2+1]); + + if (n2 > 0) + memmove(scf + n2, scf + 2*n2, (nb - n2) * sizeof(float)); + + /* --- Spectral shaping --- */ + + const int *lim = lc3_band_lim[dt][sr]; + + for (int i = 0, ib = 0; ib < nb; ib++) { + float g_sns = powf(2, -scf[ib]); + + for ( ; i < lim[ib+1]; i++) + y[i] = x[i] * g_sns; + } +} + + +/* ---------------------------------------------------------------------------- + * Interface + * -------------------------------------------------------------------------- */ + +/** + * SNS analysis + */ +void lc3_sns_analyze(enum lc3_dt dt, enum lc3_srate sr, + const float *eb, bool att, struct lc3_sns_data *data, + const float *x, float *y) +{ + /* Processing steps : + * - Determine 16 scale factors from bands energy estimation + * - Get codebooks indexes that match thoses scale factors + * - Quantize the residual with the selected codebook + * - The pulse configuration `c[]` is enumerated + * - Finally shape the spectrum coefficients accordingly */ + + float scf[16], cn[4][16]; + int c[4][16]; + + compute_scale_factors(dt, sr, eb, att, scf); + + resolve_codebooks(scf, &data->lfcb, &data->hfcb); + + quantize(scf, data->lfcb, data->hfcb, + c, cn, &data->shape, &data->gain); + + unquantize(data->lfcb, data->hfcb, + cn[data->shape], data->shape, data->gain, scf); + + enumerate(data->shape, c[data->shape], + &data->idx_a, &data->ls_a, &data->idx_b, &data->ls_b); + + spectral_shaping(dt, sr, scf, false, x, y); +} + +/** + * SNS synthesis + */ +void lc3_sns_synthesize(enum lc3_dt dt, enum lc3_srate sr, + const lc3_sns_data_t *data, const float *x, float *y) +{ + float scf[16], cn[16]; + int c[16]; + + deenumerate(data->shape, + data->idx_a, data->ls_a, data->idx_b, data->ls_b, c); + + normalize(c, cn); + + unquantize(data->lfcb, data->hfcb, cn, data->shape, data->gain, scf); + + spectral_shaping(dt, sr, scf, true, x, y); +} + +/** + * Return number of bits coding the bitstream data + */ +int lc3_sns_get_nbits(void) +{ + return 38; +} + +/** + * Put bitstream data + */ +void lc3_sns_put_data(lc3_bits_t *bits, const struct lc3_sns_data *data) +{ + /* --- Codebooks --- */ + + lc3_put_bits(bits, data->lfcb, 5); + lc3_put_bits(bits, data->hfcb, 5); + + /* --- Shape, gain and vectors --- * + * Write MSB bit of shape index, next LSB bits of shape and gain, + * and MVPQ vectors indexes are muxed */ + + int shape_msb = data->shape >> 1; + lc3_put_bit(bits, shape_msb); + + if (shape_msb == 0) { + const int size_a = 2390004; + int submode = data->shape & 1; + + int mux_high = submode == 0 ? + 2 * (data->idx_b + 1) + data->ls_b : data->gain & 1; + int mux_code = mux_high * size_a + data->idx_a; + + lc3_put_bits(bits, data->gain >> submode, 1); + lc3_put_bits(bits, data->ls_a, 1); + lc3_put_bits(bits, mux_code, 25); + + } else { + const int size_a = 15158272; + int submode = data->shape & 1; + + int mux_code = submode == 0 ? + data->idx_a : size_a + 2 * data->idx_a + (data->gain & 1); + + lc3_put_bits(bits, data->gain >> submode, 2); + lc3_put_bits(bits, data->ls_a, 1); + lc3_put_bits(bits, mux_code, 24); + } +} + +/** + * Get bitstream data + */ +int lc3_sns_get_data(lc3_bits_t *bits, struct lc3_sns_data *data) +{ + /* --- Codebooks --- */ + + *data = (struct lc3_sns_data){ + .lfcb = lc3_get_bits(bits, 5), + .hfcb = lc3_get_bits(bits, 5) + }; + + /* --- Shape, gain and vectors --- */ + + int shape_msb = lc3_get_bit(bits); + data->gain = lc3_get_bits(bits, 1 + shape_msb); + data->ls_a = lc3_get_bit(bits); + + int mux_code = lc3_get_bits(bits, 25 - shape_msb); + + if (shape_msb == 0) { + const int size_a = 2390004; + + if (mux_code >= size_a * 14) + return -1; + + data->idx_a = mux_code % size_a; + mux_code = mux_code / size_a; + + data->shape = (mux_code < 2); + + if (data->shape == 0) { + data->idx_b = (mux_code - 2) / 2; + data->ls_b = (mux_code - 2) % 2; + } else { + data->gain = (data->gain << 1) + (mux_code % 2); + } + + } else { + const int size_a = 15158272; + + if (mux_code >= size_a + 1549824) + return -1; + + data->shape = 2 + (mux_code >= size_a); + if (data->shape == 2) { + data->idx_a = mux_code; + } else { + mux_code -= size_a; + data->idx_a = mux_code / 2; + data->gain = (data->gain << 1) + (mux_code % 2); + } + } + + return 0; +} diff --git a/3rd-party/lc3-google/src/sns.h b/3rd-party/lc3-google/src/sns.h new file mode 100644 index 000000000..dc3f3f725 --- /dev/null +++ b/3rd-party/lc3-google/src/sns.h @@ -0,0 +1,103 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * LC3 - Spectral Noise Shaping + * + * Reference : Low Complexity Communication Codec (LC3) + * Bluetooth Specification v1.0 + */ + +#ifndef __LC3_SNS_H +#define __LC3_SNS_H + +#include "common.h" +#include "bits.h" + + +/** + * Bitstream data + */ + +typedef struct lc3_sns_data { + int lfcb, hfcb; + int shape, gain; + int idx_a, idx_b; + bool ls_a, ls_b; +} lc3_sns_data_t; + + +/* ---------------------------------------------------------------------------- + * Encoding + * -------------------------------------------------------------------------- */ + +/** + * SNS analysis + * dt, sr Duration and samplerate of the frame + * eb Energy estimation per bands, and count of bands + * att 1: Attack detected 0: Otherwise + * data Return bitstream data + * x Spectral coefficients + * y Return shapped coefficients + * + * `x` and `y` can be the same buffer + */ +void lc3_sns_analyze(enum lc3_dt dt, enum lc3_srate sr, + const float *eb, bool att, lc3_sns_data_t *data, + const float *x, float *y); + +/** + * Return number of bits coding the bitstream data + * return Bit consumption + */ +int lc3_sns_get_nbits(void); + +/** + * Put bitstream data + * bits Bitstream context + * data Bitstream data + */ +void lc3_sns_put_data(lc3_bits_t *bits, const lc3_sns_data_t *data); + + +/* ---------------------------------------------------------------------------- + * Decoding + * -------------------------------------------------------------------------- */ + +/** + * Get bitstream data + * bits Bitstream context + * data Return SNS data + * return 0: Ok -1: Invalid SNS data + */ +int lc3_sns_get_data(lc3_bits_t *bits, lc3_sns_data_t *data); + +/** + * SNS synthesis + * dt, sr Duration and samplerate of the frame + * data Bitstream data + * x Spectral coefficients + * y Return shapped coefficients + * + * `x` and `y` can be the same buffer + */ +void lc3_sns_synthesize(enum lc3_dt dt, enum lc3_srate sr, + const lc3_sns_data_t *data, const float *x, float *y); + + +#endif /* __LC3_SNS_H */ diff --git a/3rd-party/lc3-google/src/spec.c b/3rd-party/lc3-google/src/spec.c new file mode 100644 index 000000000..1518cf7ad --- /dev/null +++ b/3rd-party/lc3-google/src/spec.c @@ -0,0 +1,877 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "spec.h" +#include "bits.h" +#include "tables.h" + + +/* ---------------------------------------------------------------------------- + * Global Gain / Quantization + * -------------------------------------------------------------------------- */ + +/** + * Resolve quantized gain index offset + * sr, nbytes Samplerate and size of the frame + * return Gain index offset + */ +static int resolve_gain_offset(enum lc3_srate sr, int nbytes) +{ + int g_off = (nbytes * 8) / (10 * (1 + sr)); + return 105 + 5*(1 + sr) + LC3_MIN(g_off, 115); +} + +/** + * Global Gain Estimation + * dt, sr Duration and samplerate of the frame + * x Spectral coefficients + * nbits_budget Number of bits available coding the spectrum + * nbits_off Offset on the available bits, temporarily smoothed + * g_off Gain index offset + * reset_off Return True when the nbits_off must be reset + * return The quantized gain value + */ +static int estimate_gain( + enum lc3_dt dt, enum lc3_srate sr, const float *x, + int nbits_budget, float nbits_off, int g_off, bool *reset_off) +{ + int ne = LC3_NE(dt, sr) >> 2; + float e[ne]; + + /* --- Energy (dB) by 4 NDCT blocks --- + * For the next steps, add energy offset 28/20 dB, + * and compute the maximum magnitude */ + + float x_max = 0; + + for (int i = 0; i < ne; i++, x += 4) { + float x0 = fabsf(x[0]), x1 = fabsf(x[1]); + float x2 = fabsf(x[2]), x3 = fabsf(x[3]); + + x_max = fmaxf(x_max, x0); + x_max = fmaxf(x_max, x1); + x_max = fmaxf(x_max, x2); + x_max = fmaxf(x_max, x3); + + float s2 = x0*x0 + x1*x1 + x2*x2 + x3*x3; + e[i] = 28.f/20 * 10 * (s2 > 0 ? log10f(s2) : -10); + } + + /* --- Determine gain index --- */ + + int nbits = nbits_budget + nbits_off + 0.5f; + int g_int = 255 - g_off; + + for (int i = 128; i > 0; i >>= 1) { + const float *e_ptr = e + ne-1; + float v = 0; + + g_int -= i; + + for ( ; e_ptr >= e && *e_ptr < g_int; e_ptr--); + + while (e_ptr >= e) { + float e_diff = *(e_ptr--) - g_int; + + if (e_diff < 0) { + v += 2.7f * 28.f/20; + } else { + v += e_diff + 7 * 28.f/20; + if (e_diff > 43 * 28.f/20) + v += e_diff - 43 * 28.f/20; + } + } + + if (v > nbits * 1.4 * 28./20) + g_int += i; + } + + /* --- Limit gain index --- */ + + int g_min = x_max == 0 ? -g_off : + ceilf(28 * log10f(x_max / (32768 - 0.375f))); + + *reset_off = g_int < g_min || x_max == 0; + if (*reset_off) + g_int = g_min; + + return g_int; +} + +/** + * Global Gain Adjustment + * sr Samplerate of the frame + * g_idx The estimated quantized gain index + * nbits Computed number of bits coding the spectrum + * nbits_budget Number of bits available for coding the spectrum + * return Gain adjust value (-1 to 2) + */ +static int adjust_gain(enum lc3_srate sr, + int g_idx, int nbits, int nbits_budget) +{ + /* --- Compute delta threshold --- */ + + const int *t = (const int [LC3_NUM_SRATE][3]){ + { 80, 500, 850 }, { 230, 1025, 1700 }, { 380, 1550, 2550 }, + { 530, 2075, 3400 }, { 680, 2600, 4250 } + }[sr]; + + int delta, den = 48; + + if (nbits < t[0]) { + delta = 3*(nbits + 48); + + } else if (nbits < t[1]) { + int n0 = 3*(t[0] + 48), range = t[1] - t[0]; + delta = n0 * range + (nbits - t[0]) * (t[1] - n0); + den *= range; + + } else { + delta = LC3_MIN(nbits, t[2]); + } + + delta = (delta + den/2) / den; + + /* --- Adjust gain --- */ + + if (nbits < nbits_budget - (delta + 2)) + return -(g_idx > 0); + + if (nbits > nbits_budget) + return (g_idx < 255) + (g_idx < 254 && nbits >= nbits_budget + delta); + + return 0; +} + +/** + * Unquantize gain + * g_int Quantization gain value + * return Unquantized gain value + */ +static float unquantize_gain(int g_int) +{ + /* Unquantization gain table : + * G[i] = 10 ^ (i / 28) , i = [0..64] */ + + static const float iq_table[] = { + 1.00000000e+00, 1.08571112e+00, 1.17876863e+00, 1.27980221e+00, + 1.38949549e+00, 1.50859071e+00, 1.63789371e+00, 1.77827941e+00, + 1.93069773e+00, 2.09617999e+00, 2.27584593e+00, 2.47091123e+00, + 2.68269580e+00, 2.91263265e+00, 3.16227766e+00, 3.43332002e+00, + 3.72759372e+00, 4.04708995e+00, 4.39397056e+00, 4.77058270e+00, + 5.17947468e+00, 5.62341325e+00, 6.10540230e+00, 6.62870316e+00, + 7.19685673e+00, 7.81370738e+00, 8.48342898e+00, 9.21055318e+00, + 1.00000000e+01, 1.08571112e+01, 1.17876863e+01, 1.27980221e+01, + 1.38949549e+01, 1.50859071e+01, 1.63789371e+01, 1.77827941e+01, + 1.93069773e+01, 2.09617999e+01, 2.27584593e+01, 2.47091123e+01, + 2.68269580e+01, 2.91263265e+01, 3.16227766e+01, 3.43332002e+01, + 3.72759372e+01, 4.04708995e+01, 4.39397056e+01, 4.77058270e+01, + 5.17947468e+01, 5.62341325e+01, 6.10540230e+01, 6.62870316e+01, + 7.19685673e+01, 7.81370738e+01, 8.48342898e+01, 9.21055318e+01, + 1.00000000e+02, 1.08571112e+02, 1.17876863e+02, 1.27980221e+02, + 1.38949549e+02, 1.50859071e+02, 1.63789371e+02, 1.77827941e+02, + 1.93069773e+02 + }; + + float g = iq_table[LC3_ABS(g_int) & 0x3f]; + for(int n64 = LC3_ABS(g_int) >> 6; n64--; ) + g *= iq_table[64]; + + return g_int >= 0 ? g : 1 / g; +} + +/** + * Spectrum quantization + * dt, sr Duration and samplerate of the frame + * g_int Quantization gain value + * x Spectral coefficients, scaled as output + * xq, nq Output spectral quantized coefficients, and count + */ +static void quantize(enum lc3_dt dt, enum lc3_srate sr, + int g_int, float *x, int16_t *xq, int *nq) +{ + float g_inv = 1 / unquantize_gain(g_int); + int ne = LC3_NE(dt, sr); + + *nq = ne; + + for (int i = 0; i < ne; i += 2) { + int16_t x0, x1; + + x[i+0] *= g_inv; + x0 = fminf(floorf(fabsf(x[i+0]) + 6.f/16), INT16_MAX); + xq[i+0] = x[i+0] < 0 ? -x0 : x0; + + x[i+1] *= g_inv; + x1 = fminf(floorf(fabsf(x[i+1]) + 6.f/16), INT16_MAX); + xq[i+1] = x[i+1] < 0 ? -x1 : x1; + + *nq = x0 || x1 ? ne : *nq - 2; + } +} + +/** + * Spectrum quantization inverse + * dt, sr Duration and samplerate of the frame + * g_int Quantization gain value + * x, nq Spectral quantized, and count of significants + * return Unquantized gain value + */ +static float unquantize(enum lc3_dt dt, enum lc3_srate sr, + int g_int, float *x, int nq) +{ + float g = unquantize_gain(g_int); + int i, ne = LC3_NE(dt, sr); + + for (i = 0; i < nq; i++) + x[i] = x[i] * g; + + for ( ; i < ne; i++) + x[i] = 0; + + return g; +} + + +/* ---------------------------------------------------------------------------- + * Spectrum coding + * -------------------------------------------------------------------------- */ + +/** + * Resolve High-bitrate mode according size of the frame + * sr, nbytes Samplerate and size of the frame + * return True when High-Rate mode enabled + */ +static int resolve_high_rate(enum lc3_srate sr, int nbytes) +{ + return nbytes > 20 * (1 + (int)sr); +} + +/** + * Bit consumption + * dt, sr, nbytes Duration, samplerate and size of the frame + * x Spectral quantized coefficients + * n Count of significant coefficients, updated on truncation + * nbits_budget Truncate to stay in budget, when not zero + * p_lsb_mode Return True when LSB's are not AC coded, or NULL + * return The number of bits coding the spectrum + */ +static int compute_nbits( + enum lc3_dt dt, enum lc3_srate sr, int nbytes, + const int16_t *x, int *n, int nbits_budget, bool *p_lsb_mode) +{ + int ne = LC3_NE(dt, sr); + + /* --- Mode and rate --- */ + + bool lsb_mode = nbytes >= 20 * (3 + (int)sr); + bool high_rate = resolve_high_rate(sr, nbytes); + + /* --- Loop on quantized coefficients --- */ + + int nbits = 0, nbits_lsb = 0; + uint8_t state = 0; + + int nbits_end = 0; + int n_end = 0; + + nbits_budget = nbits_budget ? nbits_budget * 2048 : INT_MAX; + + for (int i = 0, h = 0; h < 2; h++) { + const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h]; + + for ( ; i < LC3_MIN(*n, (ne + 2) >> (1 - h)) + && nbits <= nbits_budget; i += 2) { + + const uint8_t *lut = lut_coeff[state]; + int a = LC3_ABS(x[i]), b = LC3_ABS(x[i+1]); + + /* --- Sign values --- */ + + int s = (a != 0) + (b != 0); + nbits += s * 2048; + + /* --- LSB values Reduce to 2*2 bits MSB values --- + * Reduce to 2x2 bits MSB values. The LSB's pair are arithmetic + * coded with an escape code followed by 1 bit for each values. + * The LSB mode does not arthmetic code the first LSB, + * add the sign of the LSB when one of pair was at value 1 */ + + int k = 0; + int m = (a | b) >> 2; + + if (m) { + if (lsb_mode) { + nbits += lc3_spectrum_bits[lut[k++]][16] - 2*2048; + nbits_lsb += 2 + (a == 1) + (b == 1); + } + + for (m >>= lsb_mode; m; m >>= 1, k++) + nbits += lc3_spectrum_bits[lut[LC3_MIN(k, 3)]][16]; + + nbits += k * 2*2048; + a >>= k; + b >>= k; + + k = LC3_MIN(k, 3); + } + + /* --- MSB values --- */ + + nbits += lc3_spectrum_bits[lut[k]][a + 4*b]; + + /* --- Update state --- */ + + if (s && nbits <= nbits_budget) { + n_end = i + 2; + nbits_end = nbits; + } + + state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1)); + } + } + + /* --- Return --- */ + + *n = n_end; + + if (p_lsb_mode) + *p_lsb_mode = lsb_mode && + nbits_end + nbits_lsb * 2048 > nbits_budget; + + if (nbits_budget >= INT_MAX) + nbits_end += nbits_lsb * 2048; + + return (nbits_end + 2047) / 2048; +} + +/** + * Put quantized spectrum + * bits Bitstream context + * dt, sr, nbytes Duration, samplerate and size of the frame + * x Spectral quantized + * nq, lsb_mode Count of significants, and LSB discard indication + */ +static void put_quantized(lc3_bits_t *bits, + enum lc3_dt dt, enum lc3_srate sr, int nbytes, + const int16_t *x, int nq, bool lsb_mode) +{ + int ne = LC3_NE(dt, sr); + bool high_rate = resolve_high_rate(sr, nbytes); + + /* --- Loop on quantized coefficients --- */ + + uint8_t state = 0; + + for (int i = 0, h = 0; h < 2; h++) { + const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h]; + + for ( ; i < LC3_MIN(nq, (ne + 2) >> (1 - h)); i += 2) { + + const uint8_t *lut = lut_coeff[state]; + bool a_neg = x[i] < 0, b_neg = x[i+1] < 0; + int a = LC3_ABS(x[i]), b = LC3_ABS(x[i+1]); + + /* --- LSB values Reduce to 2*2 bits MSB values --- + * Reduce to 2x2 bits MSB values. The LSB's pair are arithmetic + * coded with an escape code and 1 bits for each values. + * The LSB mode discard the first LSB (at this step) */ + + int m = (a | b) >> 2; + int k = 0, shr = 0; + + if (m) { + + if (lsb_mode) + lc3_put_symbol(bits, + lc3_spectrum_models + lut[k++], 16); + + for (m >>= lsb_mode; m; m >>= 1, k++) { + lc3_put_bit(bits, (a >> k) & 1); + lc3_put_bit(bits, (b >> k) & 1); + lc3_put_symbol(bits, + lc3_spectrum_models + lut[LC3_MIN(k, 3)], 16); + } + + a >>= lsb_mode; + b >>= lsb_mode; + + shr = k - lsb_mode; + k = LC3_MIN(k, 3); + } + + /* --- Sign values --- */ + + if (a) lc3_put_bit(bits, a_neg); + if (b) lc3_put_bit(bits, b_neg); + + /* --- MSB values --- */ + + a >>= shr; + b >>= shr; + + lc3_put_symbol(bits, lc3_spectrum_models + lut[k], a + 4*b); + + /* --- Update state --- */ + + state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1)); + } + } +} + +/** + * Get quantized spectrum + * bits Bitstream context + * dt, sr, nbytes Duration, samplerate and size of the frame + * nq, lsb_mode Count of significants, and LSB discard indication + * xq Return `nq` spectral quantized coefficients + * nf_seed Return the noise factor seed associated + * return 0: Ok -1: Invalid bitstream data + */ +static int get_quantized(lc3_bits_t *bits, + enum lc3_dt dt, enum lc3_srate sr, int nbytes, + int nq, bool lsb_mode, float *xq, uint16_t *nf_seed) +{ + int ne = LC3_NE(dt, sr); + bool high_rate = resolve_high_rate(sr, nbytes); + + *nf_seed = 0; + + /* --- Loop on quantized coefficients --- */ + + uint8_t state = 0; + + for (int i = 0, h = 0; h < 2; h++) { + const uint8_t (*lut_coeff)[4] = lc3_spectrum_lookup[high_rate][h]; + + for ( ; i < LC3_MIN(nq, (ne + 2) >> (1 - h)); i += 2) { + + const uint8_t *lut = lut_coeff[state]; + + /* --- LSB values --- + * Until the symbol read indicates the escape value 16, + * read an LSB bit for each values. + * The LSB mode discard the first LSB (at this step) */ + + int u = 0, v = 0; + int k = 0, shl = 0; + + unsigned s = lc3_get_symbol(bits, lc3_spectrum_models + lut[k]); + + if (lsb_mode && s >= 16) { + s = lc3_get_symbol(bits, lc3_spectrum_models + lut[++k]); + shl++; + } + + for ( ; s >= 16 && shl < 14; shl++) { + u |= lc3_get_bit(bits) << shl; + v |= lc3_get_bit(bits) << shl; + + k += (k < 3); + s = lc3_get_symbol(bits, lc3_spectrum_models + lut[k]); + } + + if (s >= 16) + return -1; + + /* --- MSB & sign values --- */ + + int a = s % 4; + int b = s / 4; + + u |= a << shl; + v |= b << shl; + + xq[i ] = u && lc3_get_bit(bits) ? -u : u; + xq[i+1] = v && lc3_get_bit(bits) ? -v : v; + + *nf_seed = (*nf_seed + u * i + v * (i+1)) & 0xffff; + + /* --- Update state --- */ + + state = (state << 4) + (k > 1 ? 12 + k : 1 + (a + b) * (k + 1)); + } + } + + return 0; +} + +/** + * Put residual bits of quantization + * bits Bitstream context + * nbits Maximum number of bits to output + * xq, n Spectral quantized, and count of significants + * xf Scaled spectral coefficients + */ +static void put_residual(lc3_bits_t *bits, int nbits, + const int16_t *xq, int n, const float *xf) +{ + for (int i = 0; i < n && nbits > 0; i++) { + + if (xq[i] == 0) + continue; + + lc3_put_bit(bits, xf[i] >= xq[i]); + nbits--; + } +} + +/** + * Get residual bits of quantization + * bits Bitstream context + * nbits Maximum number of bits to output + * x, nq Spectral quantized, and count of significants + */ +static void get_residual(lc3_bits_t *bits, int nbits, float *x, int nq) +{ + for (int i = 0; i < nq && nbits > 0; i++) { + + if (x[i] == 0) + continue; + + if (lc3_get_bit(bits) == 0) + x[i] -= x[i] < 0 ? 5.f/16 : 3.f/16; + else + x[i] += x[i] > 0 ? 5.f/16 : 3.f/16; + + nbits--; + } +} + +/** + * Put LSB values of quantized spectrum values + * bits Bitstream context + * nbits Maximum number of bits to output + * x, n Spectral quantized, and count of significants + */ +static void put_lsb(lc3_bits_t *bits, int nbits, const int16_t *x, int n) +{ + for (int i = 0; i < n && nbits > 0; i += 2) { + + bool a_neg = x[i] < 0, b_neg = x[i+1] < 0; + int a = LC3_ABS(x[i]), b = LC3_ABS(x[i+1]); + + if ((a | b) >> 2 == 0) + continue; + + if (nbits-- > 0) + lc3_put_bit(bits, a & 1); + + if (a == 1 && nbits-- > 0) + lc3_put_bit(bits, a_neg); + + if (nbits-- > 0) + lc3_put_bit(bits, b & 1); + + if (b == 1 && nbits-- > 0) + lc3_put_bit(bits, b_neg); + } +} + +/** + * Get LSB values of quantized spectrum values + * bits Bitstream context + * nbits Maximum number of bits to output + * x, nq Spectral quantized, and count of significants + * nf_seed Update the noise factor seed according + */ +static void get_lsb(lc3_bits_t *bits, + int nbits, float *x, int nq, uint16_t *nf_seed) +{ + for (int i = 0; i < nq && nbits > 0; i += 2) { + + float a = fabsf(x[i]), b = fabsf(x[i+1]); + + if (fmaxf(a, b) < 4) + continue; + + if (nbits-- > 0 && lc3_get_bit(bits)) { + if (a) { + x[i] += x[i] < 0 ? -1 : 1; + *nf_seed = (*nf_seed + i) & 0xffff; + } else if (nbits-- > 0) { + x[i] = lc3_get_bit(bits) ? -1 : 1; + *nf_seed = (*nf_seed + i) & 0xffff; + } + } + + if (nbits-- > 0 && lc3_get_bit(bits)) { + if (b) { + x[i+1] += x[i+1] < 0 ? -1 : 1; + *nf_seed = (*nf_seed + i+1) & 0xffff; + } else if (nbits-- > 0) { + x[i+1] = lc3_get_bit(bits) ? -1 : 1; + *nf_seed = (*nf_seed + i+1) & 0xffff; + } + } + } +} + + +/* ---------------------------------------------------------------------------- + * Noise coding + * -------------------------------------------------------------------------- */ + +/** + * Estimate noise level + * dt, bw Duration and bandwidth of the frame + * xq, nq Quantized spectral coefficients + * x Quantization scaled spectrum coefficients + * return Noise factor (0 to 7) + */ +static int estimate_noise(enum lc3_dt dt, enum lc3_bandwidth bw, + const int16_t *xq, int nq, const float *x) +{ + int bw_stop = (dt == LC3_DT_7M5 ? 60 : 80) * (1 + bw); + int w = 2 + dt; + + float sum = 0; + int i, n = 0, z = 0; + + for (i = 6*(3 + dt) - w; i < LC3_MIN(nq, bw_stop); i++) { + z = xq[i] ? 0 : z + 1; + if (z > 2*w) + sum += fabs(x[i - w]), n++; + } + + for ( ; i < bw_stop + w; i++) + if (++z > 2*w) + sum += fabs(x[i - w]), n++; + + int nf = n ? 8 - (int)((16 * sum) / n + 0.5f) : 0; + + return LC3_CLIP(nf, 0, 7); +} + +/** + * Noise filling + * dt, bw Duration and bandwidth of the frame + * nf, nf_seed The noise factor and pseudo-random seed + * g Quantization gain + * x, nq Spectral quantized, and count of significants + */ +static void fill_noise(enum lc3_dt dt, enum lc3_bandwidth bw, + int nf, uint16_t nf_seed, float g, float *x, int nq) +{ + int bw_stop = (dt == LC3_DT_7M5 ? 60 : 80) * (1 + bw); + int w = 2 + dt; + + float s = g * (float)(8 - nf) / 16; + int i, z = 0; + + for (i = 6*(3 + dt) - w; i < LC3_MIN(nq, bw_stop); i++) { + z = x[i] ? 0 : z + 1; + if (z > 2*w) { + nf_seed = (13849 + nf_seed*31821) & 0xffff; + x[i - w] = nf_seed & 0x8000 ? -s : s; + } + } + + for ( ; i < bw_stop + w; i++) + if (++z > 2*w) { + nf_seed = (13849 + nf_seed*31821) & 0xffff; + x[i - w] = nf_seed & 0x8000 ? -s : s; + } +} + +/** + * Put noise factor + * bits Bitstream context + * nf Noise factor (0 to 7) + */ +static void put_noise_factor(lc3_bits_t *bits, int nf) +{ + lc3_put_bits(bits, nf, 3); +} + +/** + * Get noise factor + * bits Bitstream context + * return Noise factor (0 to 7) + */ +static int get_noise_factor(lc3_bits_t *bits) +{ + return lc3_get_bits(bits, 3); +} + + +/* ---------------------------------------------------------------------------- + * Encoding + * -------------------------------------------------------------------------- */ + +/** + * Bit consumption of the number of coded coefficients + * dt, sr Duration, samplerate of the frame + * return Bit consumpution of the number of coded coefficients + */ +static int get_nbits_nq(enum lc3_dt dt, enum lc3_srate sr) +{ + int ne = LC3_NE(dt, sr); + return 4 + (ne > 32) + (ne > 64) + (ne > 128) + (ne > 256); +} + +/** + * Bit consumption of the arithmetic coder + * dt, sr, nbytes Duration, samplerate and size of the frame + * return Bit consumption of bitstream data + */ +static int get_nbits_ac(enum lc3_dt dt, enum lc3_srate sr, int nbytes) +{ + return get_nbits_nq(dt, sr) + 3 + LC3_MIN((nbytes-1) / 160, 2); +} + +/** + * Spectrum analysis + */ +void lc3_spec_analyze(enum lc3_dt dt, enum lc3_srate sr, + int nbytes, bool pitch, const lc3_tns_data_t *tns, + struct lc3_spec_analysis *spec, float *x, + int16_t *xq, struct lc3_spec_side *side) +{ + bool reset_off; + + /* --- Bit budget --- */ + + const int nbits_gain = 8; + const int nbits_nf = 3; + + int nbits_budget = 8*nbytes - get_nbits_ac(dt, sr, nbytes) - + lc3_bwdet_get_nbits(sr) - lc3_ltpf_get_nbits(pitch) - + lc3_sns_get_nbits() - lc3_tns_get_nbits(tns) - nbits_gain - nbits_nf; + + /* --- Global gain --- */ + + float nbits_off = spec->nbits_off + spec->nbits_spare; + nbits_off = fminf(fmaxf(nbits_off, -40), 40); + nbits_off = 0.8 * spec->nbits_off + 0.2 * nbits_off; + + int g_off = resolve_gain_offset(sr, nbytes); + + int g_int = estimate_gain(dt, sr, + x, nbits_budget, nbits_off, g_off, &reset_off); + + /* --- Quantization --- */ + + quantize(dt, sr, g_int, x, xq, &side->nq); + + int nbits = compute_nbits(dt, sr, nbytes, xq, &side->nq, 0, NULL); + + spec->nbits_off = reset_off ? 0 : nbits_off; + spec->nbits_spare = reset_off ? 0 : nbits_budget - nbits; + + /* --- Adjust gain and requantize --- */ + + int g_adj = adjust_gain(sr, g_int + g_off, nbits, nbits_budget); + + if (g_adj) + quantize(dt, sr, g_adj, x, xq, &side->nq); + + side->g_idx = g_int + g_adj + g_off; + nbits = compute_nbits(dt, sr, nbytes, + xq, &side->nq, nbits_budget, &side->lsb_mode); +} + +/** + * Put spectral quantization side data + */ +void lc3_spec_put_side(lc3_bits_t *bits, + enum lc3_dt dt, enum lc3_srate sr, const struct lc3_spec_side *side) +{ + int nbits_nq = get_nbits_nq(dt, sr); + + lc3_put_bits(bits, LC3_MAX(side->nq >> 1, 1) - 1, nbits_nq); + lc3_put_bits(bits, side->lsb_mode, 1); + lc3_put_bits(bits, side->g_idx, 8); +} + +/** + * Encode spectral coefficients + */ +void lc3_spec_encode(lc3_bits_t *bits, + enum lc3_dt dt, enum lc3_srate sr, enum lc3_bandwidth bw, int nbytes, + const int16_t *xq, const lc3_spec_side_t *side, const float *x) +{ + bool lsb_mode = side->lsb_mode; + int nq = side->nq; + + put_noise_factor(bits, estimate_noise(dt, bw, xq, nq, x)); + + put_quantized(bits, dt, sr, nbytes, xq, nq, lsb_mode); + + int nbits_left = lc3_get_bits_left(bits); + + if (lsb_mode) + put_lsb(bits, nbits_left, xq, nq); + else + put_residual(bits, nbits_left, xq, nq, x); +} + + +/* ---------------------------------------------------------------------------- + * Decoding + * -------------------------------------------------------------------------- */ + +/** + * Get spectral quantization side data + */ +int lc3_spec_get_side(lc3_bits_t *bits, + enum lc3_dt dt, enum lc3_srate sr, struct lc3_spec_side *side) +{ + int nbits_nq = get_nbits_nq(dt, sr); + int ne = LC3_NE(dt, sr); + + side->nq = (lc3_get_bits(bits, nbits_nq) + 1) << 1; + side->lsb_mode = lc3_get_bit(bits); + side->g_idx = lc3_get_bits(bits, 8); + + return side->nq > ne ? (side->nq = ne), -1 : 0; +} + +/** + * Decode spectral coefficients + */ +int lc3_spec_decode(lc3_bits_t *bits, + enum lc3_dt dt, enum lc3_srate sr, enum lc3_bandwidth bw, + int nbytes, const lc3_spec_side_t *side, float *x) +{ + bool lsb_mode = side->lsb_mode; + int nq = side->nq; + int ret = 0; + + int nf = get_noise_factor(bits); + uint16_t nf_seed; + + if ((ret = get_quantized(bits, dt, sr, nbytes, + nq, lsb_mode, x, &nf_seed)) < 0) + return ret; + + int nbits_left = lc3_get_bits_left(bits); + + if (lsb_mode) + get_lsb(bits, nbits_left, x, nq, &nf_seed); + else + get_residual(bits, nbits_left, x, nq); + + int g_int = side->g_idx - resolve_gain_offset(sr, nbytes); + float g = unquantize(dt, sr, g_int, x, nq); + + if (nq > 2 || x[0] || x[1] || side->g_idx > 0 || nf < 7) + fill_noise(dt, bw, nf, nf_seed, g, x, nq); + + return 0; +} diff --git a/3rd-party/lc3-google/src/spec.h b/3rd-party/lc3-google/src/spec.h new file mode 100644 index 000000000..3c45058a0 --- /dev/null +++ b/3rd-party/lc3-google/src/spec.h @@ -0,0 +1,111 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * LC3 - Spectral coefficients encoding/decoding + * + * Reference : Low Complexity Communication Codec (LC3) + * Bluetooth Specification v1.0 + */ + +#ifndef __LC3_SPEC_H +#define __LC3_SPEC_H + +#include "common.h" +#include "tables.h" +#include "bwdet.h" +#include "ltpf.h" +#include "tns.h" +#include "sns.h" + + +/** + * Spectral quantization side data + */ +typedef struct lc3_spec_side { + int g_idx, nq; + bool lsb_mode; +} lc3_spec_side_t; + + +/* ---------------------------------------------------------------------------- + * Encoding + * -------------------------------------------------------------------------- */ + +/** + * Spectrum analysis + * dt, sr, nbytes Duration, samplerate and size of the frame + * pitch, tns Pitch present indication and TNS bistream data + * spec Context of analysis + * x Spectral coefficients, scaled as output + * xq, side Return quantization data + */ +void lc3_spec_analyze(enum lc3_dt dt, enum lc3_srate sr, + int nbytes, bool pitch, const lc3_tns_data_t *tns, + lc3_spec_analysis_t *spec, float *x, int16_t *xq, lc3_spec_side_t *side); + +/** + * Put spectral quantization side data + * bits Bitstream context + * dt, sr Duration and samplerate of the frame + * side Spectral quantization side data + */ +void lc3_spec_put_side(lc3_bits_t *bits, + enum lc3_dt dt, enum lc3_srate sr, const lc3_spec_side_t *side); + +/** + * Encode spectral coefficients + * bits Bitstream context + * dt, sr, bw Duration, samplerate, bandwidth + * nbytes and size of the frame + * xq, side Quantization data + * x Scaled spectral coefficients + */ +void lc3_spec_encode(lc3_bits_t *bits, + enum lc3_dt dt, enum lc3_srate sr, enum lc3_bandwidth bw, int nbytes, + const int16_t *xq, const lc3_spec_side_t *side, const float *x); + + +/* ---------------------------------------------------------------------------- + * Decoding + * -------------------------------------------------------------------------- */ + +/** + * Get spectral quantization side data + * bits Bitstream context + * dt, sr Duration and samplerate of the frame + * side Return quantization side data + * return 0: Ok -1: Invalid bandwidth indication + */ +int lc3_spec_get_side(lc3_bits_t *bits, + enum lc3_dt dt, enum lc3_srate sr, lc3_spec_side_t *side); + +/** + * Decode spectral coefficients + * bits Bitstream context + * dt, sr, bw Duration, samplerate, bandwidth + * nbytes and size of the frame + * side Quantization side data + * x Spectral coefficients + * return 0: Ok -1: Invalid bitstream data + */ +int lc3_spec_decode(lc3_bits_t *bits, enum lc3_dt dt, enum lc3_srate sr, + enum lc3_bandwidth bw, int nbytes, const lc3_spec_side_t *side, float *x); + + +#endif /* __LC3_SPEC_H */ diff --git a/3rd-party/lc3-google/src/tables.c b/3rd-party/lc3-google/src/tables.c new file mode 100644 index 000000000..9e7d5dde3 --- /dev/null +++ b/3rd-party/lc3-google/src/tables.c @@ -0,0 +1,3526 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "tables.h" + + +/** + * Twiddles FFT 3 points + * + * T[0..N-1] = + * { cos(-2Pi * i/N) + j sin(-2Pi * i/N), + * cos(-2Pi * 2i/N) + j sin(-2Pi * 2i/N) } , N=15, 45 + */ + +static const struct lc3_fft_bf3_twiddles fft_twiddles_15 = { + .n3 = 15/3, .t = (const struct lc3_complex [][2]){ + { { 1.0000000e+0, -0.0000000e+0 }, { 1.0000000e+0, -0.0000000e+0 } }, + { { 9.1354546e-1, -4.0673664e-1 }, { 6.6913061e-1, -7.4314483e-1 } }, + { { 6.6913061e-1, -7.4314483e-1 }, { -1.0452846e-1, -9.9452190e-1 } }, + { { 3.0901699e-1, -9.5105652e-1 }, { -8.0901699e-1, -5.8778525e-1 } }, + { { -1.0452846e-1, -9.9452190e-1 }, { -9.7814760e-1, 2.0791169e-1 } }, + { { -5.0000000e-1, -8.6602540e-1 }, { -5.0000000e-1, 8.6602540e-1 } }, + { { -8.0901699e-1, -5.8778525e-1 }, { 3.0901699e-1, 9.5105652e-1 } }, + { { -9.7814760e-1, -2.0791169e-1 }, { 9.1354546e-1, 4.0673664e-1 } }, + { { -9.7814760e-1, 2.0791169e-1 }, { 9.1354546e-1, -4.0673664e-1 } }, + { { -8.0901699e-1, 5.8778525e-1 }, { 3.0901699e-1, -9.5105652e-1 } }, + { { -5.0000000e-1, 8.6602540e-1 }, { -5.0000000e-1, -8.6602540e-1 } }, + { { -1.0452846e-1, 9.9452190e-1 }, { -9.7814760e-1, -2.0791169e-1 } }, + { { 3.0901699e-1, 9.5105652e-1 }, { -8.0901699e-1, 5.8778525e-1 } }, + { { 6.6913061e-1, 7.4314483e-1 }, { -1.0452846e-1, 9.9452190e-1 } }, + { { 9.1354546e-1, 4.0673664e-1 }, { 6.6913061e-1, 7.4314483e-1 } }, + } +}; + +static const struct lc3_fft_bf3_twiddles fft_twiddles_45 = { + .n3 = 45/3, .t = (const struct lc3_complex [][2]){ + { { 1.0000000e+0, -0.0000000e+0 }, { 1.0000000e+0, -0.0000000e+0 } }, + { { 9.9026807e-1, -1.3917310e-1 }, { 9.6126170e-1, -2.7563736e-1 } }, + { { 9.6126170e-1, -2.7563736e-1 }, { 8.4804810e-1, -5.2991926e-1 } }, + { { 9.1354546e-1, -4.0673664e-1 }, { 6.6913061e-1, -7.4314483e-1 } }, + { { 8.4804810e-1, -5.2991926e-1 }, { 4.3837115e-1, -8.9879405e-1 } }, + { { 7.6604444e-1, -6.4278761e-1 }, { 1.7364818e-1, -9.8480775e-1 } }, + { { 6.6913061e-1, -7.4314483e-1 }, { -1.0452846e-1, -9.9452190e-1 } }, + { { 5.5919290e-1, -8.2903757e-1 }, { -3.7460659e-1, -9.2718385e-1 } }, + { { 4.3837115e-1, -8.9879405e-1 }, { -6.1566148e-1, -7.8801075e-1 } }, + { { 3.0901699e-1, -9.5105652e-1 }, { -8.0901699e-1, -5.8778525e-1 } }, + { { 1.7364818e-1, -9.8480775e-1 }, { -9.3969262e-1, -3.4202014e-1 } }, + { { 3.4899497e-2, -9.9939083e-1 }, { -9.9756405e-1, -6.9756474e-2 } }, + { { -1.0452846e-1, -9.9452190e-1 }, { -9.7814760e-1, 2.0791169e-1 } }, + { { -2.4192190e-1, -9.7029573e-1 }, { -8.8294759e-1, 4.6947156e-1 } }, + { { -3.7460659e-1, -9.2718385e-1 }, { -7.1933980e-1, 6.9465837e-1 } }, + { { -5.0000000e-1, -8.6602540e-1 }, { -5.0000000e-1, 8.6602540e-1 } }, + { { -6.1566148e-1, -7.8801075e-1 }, { -2.4192190e-1, 9.7029573e-1 } }, + { { -7.1933980e-1, -6.9465837e-1 }, { 3.4899497e-2, 9.9939083e-1 } }, + { { -8.0901699e-1, -5.8778525e-1 }, { 3.0901699e-1, 9.5105652e-1 } }, + { { -8.8294759e-1, -4.6947156e-1 }, { 5.5919290e-1, 8.2903757e-1 } }, + { { -9.3969262e-1, -3.4202014e-1 }, { 7.6604444e-1, 6.4278761e-1 } }, + { { -9.7814760e-1, -2.0791169e-1 }, { 9.1354546e-1, 4.0673664e-1 } }, + { { -9.9756405e-1, -6.9756474e-2 }, { 9.9026807e-1, 1.3917310e-1 } }, + { { -9.9756405e-1, 6.9756474e-2 }, { 9.9026807e-1, -1.3917310e-1 } }, + { { -9.7814760e-1, 2.0791169e-1 }, { 9.1354546e-1, -4.0673664e-1 } }, + { { -9.3969262e-1, 3.4202014e-1 }, { 7.6604444e-1, -6.4278761e-1 } }, + { { -8.8294759e-1, 4.6947156e-1 }, { 5.5919290e-1, -8.2903757e-1 } }, + { { -8.0901699e-1, 5.8778525e-1 }, { 3.0901699e-1, -9.5105652e-1 } }, + { { -7.1933980e-1, 6.9465837e-1 }, { 3.4899497e-2, -9.9939083e-1 } }, + { { -6.1566148e-1, 7.8801075e-1 }, { -2.4192190e-1, -9.7029573e-1 } }, + { { -5.0000000e-1, 8.6602540e-1 }, { -5.0000000e-1, -8.6602540e-1 } }, + { { -3.7460659e-1, 9.2718385e-1 }, { -7.1933980e-1, -6.9465837e-1 } }, + { { -2.4192190e-1, 9.7029573e-1 }, { -8.8294759e-1, -4.6947156e-1 } }, + { { -1.0452846e-1, 9.9452190e-1 }, { -9.7814760e-1, -2.0791169e-1 } }, + { { 3.4899497e-2, 9.9939083e-1 }, { -9.9756405e-1, 6.9756474e-2 } }, + { { 1.7364818e-1, 9.8480775e-1 }, { -9.3969262e-1, 3.4202014e-1 } }, + { { 3.0901699e-1, 9.5105652e-1 }, { -8.0901699e-1, 5.8778525e-1 } }, + { { 4.3837115e-1, 8.9879405e-1 }, { -6.1566148e-1, 7.8801075e-1 } }, + { { 5.5919290e-1, 8.2903757e-1 }, { -3.7460659e-1, 9.2718385e-1 } }, + { { 6.6913061e-1, 7.4314483e-1 }, { -1.0452846e-1, 9.9452190e-1 } }, + { { 7.6604444e-1, 6.4278761e-1 }, { 1.7364818e-1, 9.8480775e-1 } }, + { { 8.4804810e-1, 5.2991926e-1 }, { 4.3837115e-1, 8.9879405e-1 } }, + { { 9.1354546e-1, 4.0673664e-1 }, { 6.6913061e-1, 7.4314483e-1 } }, + { { 9.6126170e-1, 2.7563736e-1 }, { 8.4804810e-1, 5.2991926e-1 } }, + { { 9.9026807e-1, 1.3917310e-1 }, { 9.6126170e-1, 2.7563736e-1 } }, + } +}; + +const struct lc3_fft_bf3_twiddles *lc3_fft_twiddles_bf3[] = + { &fft_twiddles_15, &fft_twiddles_45 }; + + +/** + * Twiddles FFT 2 points + * + * T[0..N/2-1] = + * cos(-2Pi * i/N) + j sin(-2Pi * i/N) , N=10, 20, ... + */ + +static const struct lc3_fft_bf2_twiddles fft_twiddles_10 = { + .n2 = 10/2, .t = (const struct lc3_complex []){ + { 1.0000000e+00, -0.0000000e+00 }, { 8.0901699e-01, -5.8778525e-01 }, + { 3.0901699e-01, -9.5105652e-01 }, { -3.0901699e-01, -9.5105652e-01 }, + { -8.0901699e-01, -5.8778525e-01 }, + } +}; + +static const struct lc3_fft_bf2_twiddles fft_twiddles_20 = { + .n2 = 20/2, .t = (const struct lc3_complex []){ + { 1.0000000e+00, -0.0000000e+00 }, { 9.5105652e-01, -3.0901699e-01 }, + { 8.0901699e-01, -5.8778525e-01 }, { 5.8778525e-01, -8.0901699e-01 }, + { 3.0901699e-01, -9.5105652e-01 }, { 6.1232340e-17, -1.0000000e+00 }, + { -3.0901699e-01, -9.5105652e-01 }, { -5.8778525e-01, -8.0901699e-01 }, + { -8.0901699e-01, -5.8778525e-01 }, { -9.5105652e-01, -3.0901699e-01 }, + } +}; + +static const struct lc3_fft_bf2_twiddles fft_twiddles_30 = { + .n2 = 30/2, .t = (const struct lc3_complex []){ + { 1.0000000e+00, -0.0000000e+00 }, { 9.7814760e-01, -2.0791169e-01 }, + { 9.1354546e-01, -4.0673664e-01 }, { 8.0901699e-01, -5.8778525e-01 }, + { 6.6913061e-01, -7.4314483e-01 }, { 5.0000000e-01, -8.6602540e-01 }, + { 3.0901699e-01, -9.5105652e-01 }, { 1.0452846e-01, -9.9452190e-01 }, + { -1.0452846e-01, -9.9452190e-01 }, { -3.0901699e-01, -9.5105652e-01 }, + { -5.0000000e-01, -8.6602540e-01 }, { -6.6913061e-01, -7.4314483e-01 }, + { -8.0901699e-01, -5.8778525e-01 }, { -9.1354546e-01, -4.0673664e-01 }, + { -9.7814760e-01, -2.0791169e-01 }, + } +}; + +static const struct lc3_fft_bf2_twiddles fft_twiddles_40 = { + .n2 = 40/2, .t = (const struct lc3_complex []){ + { 1.0000000e+00, -0.0000000e+00 }, { 9.8768834e-01, -1.5643447e-01 }, + { 9.5105652e-01, -3.0901699e-01 }, { 8.9100652e-01, -4.5399050e-01 }, + { 8.0901699e-01, -5.8778525e-01 }, { 7.0710678e-01, -7.0710678e-01 }, + { 5.8778525e-01, -8.0901699e-01 }, { 4.5399050e-01, -8.9100652e-01 }, + { 3.0901699e-01, -9.5105652e-01 }, { 1.5643447e-01, -9.8768834e-01 }, + { 6.1232340e-17, -1.0000000e+00 }, { -1.5643447e-01, -9.8768834e-01 }, + { -3.0901699e-01, -9.5105652e-01 }, { -4.5399050e-01, -8.9100652e-01 }, + { -5.8778525e-01, -8.0901699e-01 }, { -7.0710678e-01, -7.0710678e-01 }, + { -8.0901699e-01, -5.8778525e-01 }, { -8.9100652e-01, -4.5399050e-01 }, + { -9.5105652e-01, -3.0901699e-01 }, { -9.8768834e-01, -1.5643447e-01 }, + } +}; + +static const struct lc3_fft_bf2_twiddles fft_twiddles_60 = { + .n2 = 60/2, .t = (const struct lc3_complex []){ + { 1.0000000e+00, -0.0000000e+00 }, { 9.9452190e-01, -1.0452846e-01 }, + { 9.7814760e-01, -2.0791169e-01 }, { 9.5105652e-01, -3.0901699e-01 }, + { 9.1354546e-01, -4.0673664e-01 }, { 8.6602540e-01, -5.0000000e-01 }, + { 8.0901699e-01, -5.8778525e-01 }, { 7.4314483e-01, -6.6913061e-01 }, + { 6.6913061e-01, -7.4314483e-01 }, { 5.8778525e-01, -8.0901699e-01 }, + { 5.0000000e-01, -8.6602540e-01 }, { 4.0673664e-01, -9.1354546e-01 }, + { 3.0901699e-01, -9.5105652e-01 }, { 2.0791169e-01, -9.7814760e-01 }, + { 1.0452846e-01, -9.9452190e-01 }, { 2.8327694e-16, -1.0000000e+00 }, + { -1.0452846e-01, -9.9452190e-01 }, { -2.0791169e-01, -9.7814760e-01 }, + { -3.0901699e-01, -9.5105652e-01 }, { -4.0673664e-01, -9.1354546e-01 }, + { -5.0000000e-01, -8.6602540e-01 }, { -5.8778525e-01, -8.0901699e-01 }, + { -6.6913061e-01, -7.4314483e-01 }, { -7.4314483e-01, -6.6913061e-01 }, + { -8.0901699e-01, -5.8778525e-01 }, { -8.6602540e-01, -5.0000000e-01 }, + { -9.1354546e-01, -4.0673664e-01 }, { -9.5105652e-01, -3.0901699e-01 }, + { -9.7814760e-01, -2.0791169e-01 }, { -9.9452190e-01, -1.0452846e-01 }, + } +}; + +static const struct lc3_fft_bf2_twiddles fft_twiddles_80 = { + .n2 = 80/2, .t = (const struct lc3_complex []){ + { 1.0000000e+00, -0.0000000e+00 }, { 9.9691733e-01, -7.8459096e-02 }, + { 9.8768834e-01, -1.5643447e-01 }, { 9.7236992e-01, -2.3344536e-01 }, + { 9.5105652e-01, -3.0901699e-01 }, { 9.2387953e-01, -3.8268343e-01 }, + { 8.9100652e-01, -4.5399050e-01 }, { 8.5264016e-01, -5.2249856e-01 }, + { 8.0901699e-01, -5.8778525e-01 }, { 7.6040597e-01, -6.4944805e-01 }, + { 7.0710678e-01, -7.0710678e-01 }, { 6.4944805e-01, -7.6040597e-01 }, + { 5.8778525e-01, -8.0901699e-01 }, { 5.2249856e-01, -8.5264016e-01 }, + { 4.5399050e-01, -8.9100652e-01 }, { 3.8268343e-01, -9.2387953e-01 }, + { 3.0901699e-01, -9.5105652e-01 }, { 2.3344536e-01, -9.7236992e-01 }, + { 1.5643447e-01, -9.8768834e-01 }, { 7.8459096e-02, -9.9691733e-01 }, + { 6.1232340e-17, -1.0000000e+00 }, { -7.8459096e-02, -9.9691733e-01 }, + { -1.5643447e-01, -9.8768834e-01 }, { -2.3344536e-01, -9.7236992e-01 }, + { -3.0901699e-01, -9.5105652e-01 }, { -3.8268343e-01, -9.2387953e-01 }, + { -4.5399050e-01, -8.9100652e-01 }, { -5.2249856e-01, -8.5264016e-01 }, + { -5.8778525e-01, -8.0901699e-01 }, { -6.4944805e-01, -7.6040597e-01 }, + { -7.0710678e-01, -7.0710678e-01 }, { -7.6040597e-01, -6.4944805e-01 }, + { -8.0901699e-01, -5.8778525e-01 }, { -8.5264016e-01, -5.2249856e-01 }, + { -8.9100652e-01, -4.5399050e-01 }, { -9.2387953e-01, -3.8268343e-01 }, + { -9.5105652e-01, -3.0901699e-01 }, { -9.7236992e-01, -2.3344536e-01 }, + { -9.8768834e-01, -1.5643447e-01 }, { -9.9691733e-01, -7.8459096e-02 }, + } +}; + +static const struct lc3_fft_bf2_twiddles fft_twiddles_90 = { + .n2 = 90/2, .t = (const struct lc3_complex []){ + { 1.0000000e+00, -0.0000000e+00 }, { 9.9756405e-01, -6.9756474e-02 }, + { 9.9026807e-01, -1.3917310e-01 }, { 9.7814760e-01, -2.0791169e-01 }, + { 9.6126170e-01, -2.7563736e-01 }, { 9.3969262e-01, -3.4202014e-01 }, + { 9.1354546e-01, -4.0673664e-01 }, { 8.8294759e-01, -4.6947156e-01 }, + { 8.4804810e-01, -5.2991926e-01 }, { 8.0901699e-01, -5.8778525e-01 }, + { 7.6604444e-01, -6.4278761e-01 }, { 7.1933980e-01, -6.9465837e-01 }, + { 6.6913061e-01, -7.4314483e-01 }, { 6.1566148e-01, -7.8801075e-01 }, + { 5.5919290e-01, -8.2903757e-01 }, { 5.0000000e-01, -8.6602540e-01 }, + { 4.3837115e-01, -8.9879405e-01 }, { 3.7460659e-01, -9.2718385e-01 }, + { 3.0901699e-01, -9.5105652e-01 }, { 2.4192190e-01, -9.7029573e-01 }, + { 1.7364818e-01, -9.8480775e-01 }, { 1.0452846e-01, -9.9452190e-01 }, + { 3.4899497e-02, -9.9939083e-01 }, { -3.4899497e-02, -9.9939083e-01 }, + { -1.0452846e-01, -9.9452190e-01 }, { -1.7364818e-01, -9.8480775e-01 }, + { -2.4192190e-01, -9.7029573e-01 }, { -3.0901699e-01, -9.5105652e-01 }, + { -3.7460659e-01, -9.2718385e-01 }, { -4.3837115e-01, -8.9879405e-01 }, + { -5.0000000e-01, -8.6602540e-01 }, { -5.5919290e-01, -8.2903757e-01 }, + { -6.1566148e-01, -7.8801075e-01 }, { -6.6913061e-01, -7.4314483e-01 }, + { -7.1933980e-01, -6.9465837e-01 }, { -7.6604444e-01, -6.4278761e-01 }, + { -8.0901699e-01, -5.8778525e-01 }, { -8.4804810e-01, -5.2991926e-01 }, + { -8.8294759e-01, -4.6947156e-01 }, { -9.1354546e-01, -4.0673664e-01 }, + { -9.3969262e-01, -3.4202014e-01 }, { -9.6126170e-01, -2.7563736e-01 }, + { -9.7814760e-01, -2.0791169e-01 }, { -9.9026807e-01, -1.3917310e-01 }, + { -9.9756405e-01, -6.9756474e-02 }, + } +}; + +static const struct lc3_fft_bf2_twiddles fft_twiddles_120 = { + .n2 = 120/2, .t = (const struct lc3_complex []){ + { 1.0000000e+00, -0.0000000e+00 }, { 9.9862953e-01, -5.2335956e-02 }, + { 9.9452190e-01, -1.0452846e-01 }, { 9.8768834e-01, -1.5643447e-01 }, + { 9.7814760e-01, -2.0791169e-01 }, { 9.6592583e-01, -2.5881905e-01 }, + { 9.5105652e-01, -3.0901699e-01 }, { 9.3358043e-01, -3.5836795e-01 }, + { 9.1354546e-01, -4.0673664e-01 }, { 8.9100652e-01, -4.5399050e-01 }, + { 8.6602540e-01, -5.0000000e-01 }, { 8.3867057e-01, -5.4463904e-01 }, + { 8.0901699e-01, -5.8778525e-01 }, { 7.7714596e-01, -6.2932039e-01 }, + { 7.4314483e-01, -6.6913061e-01 }, { 7.0710678e-01, -7.0710678e-01 }, + { 6.6913061e-01, -7.4314483e-01 }, { 6.2932039e-01, -7.7714596e-01 }, + { 5.8778525e-01, -8.0901699e-01 }, { 5.4463904e-01, -8.3867057e-01 }, + { 5.0000000e-01, -8.6602540e-01 }, { 4.5399050e-01, -8.9100652e-01 }, + { 4.0673664e-01, -9.1354546e-01 }, { 3.5836795e-01, -9.3358043e-01 }, + { 3.0901699e-01, -9.5105652e-01 }, { 2.5881905e-01, -9.6592583e-01 }, + { 2.0791169e-01, -9.7814760e-01 }, { 1.5643447e-01, -9.8768834e-01 }, + { 1.0452846e-01, -9.9452190e-01 }, { 5.2335956e-02, -9.9862953e-01 }, + { 2.8327694e-16, -1.0000000e+00 }, { -5.2335956e-02, -9.9862953e-01 }, + { -1.0452846e-01, -9.9452190e-01 }, { -1.5643447e-01, -9.8768834e-01 }, + { -2.0791169e-01, -9.7814760e-01 }, { -2.5881905e-01, -9.6592583e-01 }, + { -3.0901699e-01, -9.5105652e-01 }, { -3.5836795e-01, -9.3358043e-01 }, + { -4.0673664e-01, -9.1354546e-01 }, { -4.5399050e-01, -8.9100652e-01 }, + { -5.0000000e-01, -8.6602540e-01 }, { -5.4463904e-01, -8.3867057e-01 }, + { -5.8778525e-01, -8.0901699e-01 }, { -6.2932039e-01, -7.7714596e-01 }, + { -6.6913061e-01, -7.4314483e-01 }, { -7.0710678e-01, -7.0710678e-01 }, + { -7.4314483e-01, -6.6913061e-01 }, { -7.7714596e-01, -6.2932039e-01 }, + { -8.0901699e-01, -5.8778525e-01 }, { -8.3867057e-01, -5.4463904e-01 }, + { -8.6602540e-01, -5.0000000e-01 }, { -8.9100652e-01, -4.5399050e-01 }, + { -9.1354546e-01, -4.0673664e-01 }, { -9.3358043e-01, -3.5836795e-01 }, + { -9.5105652e-01, -3.0901699e-01 }, { -9.6592583e-01, -2.5881905e-01 }, + { -9.7814760e-01, -2.0791169e-01 }, { -9.8768834e-01, -1.5643447e-01 }, + { -9.9452190e-01, -1.0452846e-01 }, { -9.9862953e-01, -5.2335956e-02 }, + } +}; + +static const struct lc3_fft_bf2_twiddles fft_twiddles_160 = { + .n2 = 160/2, .t = (const struct lc3_complex []){ + { 1.0000000e+00, -0.0000000e+00 }, { 9.9922904e-01, -3.9259816e-02 }, + { 9.9691733e-01, -7.8459096e-02 }, { 9.9306846e-01, -1.1753740e-01 }, + { 9.8768834e-01, -1.5643447e-01 }, { 9.8078528e-01, -1.9509032e-01 }, + { 9.7236992e-01, -2.3344536e-01 }, { 9.6245524e-01, -2.7144045e-01 }, + { 9.5105652e-01, -3.0901699e-01 }, { 9.3819134e-01, -3.4611706e-01 }, + { 9.2387953e-01, -3.8268343e-01 }, { 9.0814317e-01, -4.1865974e-01 }, + { 8.9100652e-01, -4.5399050e-01 }, { 8.7249601e-01, -4.8862124e-01 }, + { 8.5264016e-01, -5.2249856e-01 }, { 8.3146961e-01, -5.5557023e-01 }, + { 8.0901699e-01, -5.8778525e-01 }, { 7.8531693e-01, -6.1909395e-01 }, + { 7.6040597e-01, -6.4944805e-01 }, { 7.3432251e-01, -6.7880075e-01 }, + { 7.0710678e-01, -7.0710678e-01 }, { 6.7880075e-01, -7.3432251e-01 }, + { 6.4944805e-01, -7.6040597e-01 }, { 6.1909395e-01, -7.8531693e-01 }, + { 5.8778525e-01, -8.0901699e-01 }, { 5.5557023e-01, -8.3146961e-01 }, + { 5.2249856e-01, -8.5264016e-01 }, { 4.8862124e-01, -8.7249601e-01 }, + { 4.5399050e-01, -8.9100652e-01 }, { 4.1865974e-01, -9.0814317e-01 }, + { 3.8268343e-01, -9.2387953e-01 }, { 3.4611706e-01, -9.3819134e-01 }, + { 3.0901699e-01, -9.5105652e-01 }, { 2.7144045e-01, -9.6245524e-01 }, + { 2.3344536e-01, -9.7236992e-01 }, { 1.9509032e-01, -9.8078528e-01 }, + { 1.5643447e-01, -9.8768834e-01 }, { 1.1753740e-01, -9.9306846e-01 }, + { 7.8459096e-02, -9.9691733e-01 }, { 3.9259816e-02, -9.9922904e-01 }, + { 6.1232340e-17, -1.0000000e+00 }, { -3.9259816e-02, -9.9922904e-01 }, + { -7.8459096e-02, -9.9691733e-01 }, { -1.1753740e-01, -9.9306846e-01 }, + { -1.5643447e-01, -9.8768834e-01 }, { -1.9509032e-01, -9.8078528e-01 }, + { -2.3344536e-01, -9.7236992e-01 }, { -2.7144045e-01, -9.6245524e-01 }, + { -3.0901699e-01, -9.5105652e-01 }, { -3.4611706e-01, -9.3819134e-01 }, + { -3.8268343e-01, -9.2387953e-01 }, { -4.1865974e-01, -9.0814317e-01 }, + { -4.5399050e-01, -8.9100652e-01 }, { -4.8862124e-01, -8.7249601e-01 }, + { -5.2249856e-01, -8.5264016e-01 }, { -5.5557023e-01, -8.3146961e-01 }, + { -5.8778525e-01, -8.0901699e-01 }, { -6.1909395e-01, -7.8531693e-01 }, + { -6.4944805e-01, -7.6040597e-01 }, { -6.7880075e-01, -7.3432251e-01 }, + { -7.0710678e-01, -7.0710678e-01 }, { -7.3432251e-01, -6.7880075e-01 }, + { -7.6040597e-01, -6.4944805e-01 }, { -7.8531693e-01, -6.1909395e-01 }, + { -8.0901699e-01, -5.8778525e-01 }, { -8.3146961e-01, -5.5557023e-01 }, + { -8.5264016e-01, -5.2249856e-01 }, { -8.7249601e-01, -4.8862124e-01 }, + { -8.9100652e-01, -4.5399050e-01 }, { -9.0814317e-01, -4.1865974e-01 }, + { -9.2387953e-01, -3.8268343e-01 }, { -9.3819134e-01, -3.4611706e-01 }, + { -9.5105652e-01, -3.0901699e-01 }, { -9.6245524e-01, -2.7144045e-01 }, + { -9.7236992e-01, -2.3344536e-01 }, { -9.8078528e-01, -1.9509032e-01 }, + { -9.8768834e-01, -1.5643447e-01 }, { -9.9306846e-01, -1.1753740e-01 }, + { -9.9691733e-01, -7.8459096e-02 }, { -9.9922904e-01, -3.9259816e-02 }, + } +}; + +static const struct lc3_fft_bf2_twiddles fft_twiddles_180 = { + .n2 = 180/2, .t = (const struct lc3_complex []){ + { 1.0000000e+00, -0.0000000e+00 }, { 9.9939083e-01, -3.4899497e-02 }, + { 9.9756405e-01, -6.9756474e-02 }, { 9.9452190e-01, -1.0452846e-01 }, + { 9.9026807e-01, -1.3917310e-01 }, { 9.8480775e-01, -1.7364818e-01 }, + { 9.7814760e-01, -2.0791169e-01 }, { 9.7029573e-01, -2.4192190e-01 }, + { 9.6126170e-01, -2.7563736e-01 }, { 9.5105652e-01, -3.0901699e-01 }, + { 9.3969262e-01, -3.4202014e-01 }, { 9.2718385e-01, -3.7460659e-01 }, + { 9.1354546e-01, -4.0673664e-01 }, { 8.9879405e-01, -4.3837115e-01 }, + { 8.8294759e-01, -4.6947156e-01 }, { 8.6602540e-01, -5.0000000e-01 }, + { 8.4804810e-01, -5.2991926e-01 }, { 8.2903757e-01, -5.5919290e-01 }, + { 8.0901699e-01, -5.8778525e-01 }, { 7.8801075e-01, -6.1566148e-01 }, + { 7.6604444e-01, -6.4278761e-01 }, { 7.4314483e-01, -6.6913061e-01 }, + { 7.1933980e-01, -6.9465837e-01 }, { 6.9465837e-01, -7.1933980e-01 }, + { 6.6913061e-01, -7.4314483e-01 }, { 6.4278761e-01, -7.6604444e-01 }, + { 6.1566148e-01, -7.8801075e-01 }, { 5.8778525e-01, -8.0901699e-01 }, + { 5.5919290e-01, -8.2903757e-01 }, { 5.2991926e-01, -8.4804810e-01 }, + { 5.0000000e-01, -8.6602540e-01 }, { 4.6947156e-01, -8.8294759e-01 }, + { 4.3837115e-01, -8.9879405e-01 }, { 4.0673664e-01, -9.1354546e-01 }, + { 3.7460659e-01, -9.2718385e-01 }, { 3.4202014e-01, -9.3969262e-01 }, + { 3.0901699e-01, -9.5105652e-01 }, { 2.7563736e-01, -9.6126170e-01 }, + { 2.4192190e-01, -9.7029573e-01 }, { 2.0791169e-01, -9.7814760e-01 }, + { 1.7364818e-01, -9.8480775e-01 }, { 1.3917310e-01, -9.9026807e-01 }, + { 1.0452846e-01, -9.9452190e-01 }, { 6.9756474e-02, -9.9756405e-01 }, + { 3.4899497e-02, -9.9939083e-01 }, { 6.1232340e-17, -1.0000000e+00 }, + { -3.4899497e-02, -9.9939083e-01 }, { -6.9756474e-02, -9.9756405e-01 }, + { -1.0452846e-01, -9.9452190e-01 }, { -1.3917310e-01, -9.9026807e-01 }, + { -1.7364818e-01, -9.8480775e-01 }, { -2.0791169e-01, -9.7814760e-01 }, + { -2.4192190e-01, -9.7029573e-01 }, { -2.7563736e-01, -9.6126170e-01 }, + { -3.0901699e-01, -9.5105652e-01 }, { -3.4202014e-01, -9.3969262e-01 }, + { -3.7460659e-01, -9.2718385e-01 }, { -4.0673664e-01, -9.1354546e-01 }, + { -4.3837115e-01, -8.9879405e-01 }, { -4.6947156e-01, -8.8294759e-01 }, + { -5.0000000e-01, -8.6602540e-01 }, { -5.2991926e-01, -8.4804810e-01 }, + { -5.5919290e-01, -8.2903757e-01 }, { -5.8778525e-01, -8.0901699e-01 }, + { -6.1566148e-01, -7.8801075e-01 }, { -6.4278761e-01, -7.6604444e-01 }, + { -6.6913061e-01, -7.4314483e-01 }, { -6.9465837e-01, -7.1933980e-01 }, + { -7.1933980e-01, -6.9465837e-01 }, { -7.4314483e-01, -6.6913061e-01 }, + { -7.6604444e-01, -6.4278761e-01 }, { -7.8801075e-01, -6.1566148e-01 }, + { -8.0901699e-01, -5.8778525e-01 }, { -8.2903757e-01, -5.5919290e-01 }, + { -8.4804810e-01, -5.2991926e-01 }, { -8.6602540e-01, -5.0000000e-01 }, + { -8.8294759e-01, -4.6947156e-01 }, { -8.9879405e-01, -4.3837115e-01 }, + { -9.1354546e-01, -4.0673664e-01 }, { -9.2718385e-01, -3.7460659e-01 }, + { -9.3969262e-01, -3.4202014e-01 }, { -9.5105652e-01, -3.0901699e-01 }, + { -9.6126170e-01, -2.7563736e-01 }, { -9.7029573e-01, -2.4192190e-01 }, + { -9.7814760e-01, -2.0791169e-01 }, { -9.8480775e-01, -1.7364818e-01 }, + { -9.9026807e-01, -1.3917310e-01 }, { -9.9452190e-01, -1.0452846e-01 }, + { -9.9756405e-01, -6.9756474e-02 }, { -9.9939083e-01, -3.4899497e-02 }, + } +}; + +static const struct lc3_fft_bf2_twiddles fft_twiddles_240 = { + .n2 = 240/2, .t = (const struct lc3_complex []){ + { 1.0000000e+00, -0.0000000e+00 }, { 9.9965732e-01, -2.6176948e-02 }, + { 9.9862953e-01, -5.2335956e-02 }, { 9.9691733e-01, -7.8459096e-02 }, + { 9.9452190e-01, -1.0452846e-01 }, { 9.9144486e-01, -1.3052619e-01 }, + { 9.8768834e-01, -1.5643447e-01 }, { 9.8325491e-01, -1.8223553e-01 }, + { 9.7814760e-01, -2.0791169e-01 }, { 9.7236992e-01, -2.3344536e-01 }, + { 9.6592583e-01, -2.5881905e-01 }, { 9.5881973e-01, -2.8401534e-01 }, + { 9.5105652e-01, -3.0901699e-01 }, { 9.4264149e-01, -3.3380686e-01 }, + { 9.3358043e-01, -3.5836795e-01 }, { 9.2387953e-01, -3.8268343e-01 }, + { 9.1354546e-01, -4.0673664e-01 }, { 9.0258528e-01, -4.3051110e-01 }, + { 8.9100652e-01, -4.5399050e-01 }, { 8.7881711e-01, -4.7715876e-01 }, + { 8.6602540e-01, -5.0000000e-01 }, { 8.5264016e-01, -5.2249856e-01 }, + { 8.3867057e-01, -5.4463904e-01 }, { 8.2412619e-01, -5.6640624e-01 }, + { 8.0901699e-01, -5.8778525e-01 }, { 7.9335334e-01, -6.0876143e-01 }, + { 7.7714596e-01, -6.2932039e-01 }, { 7.6040597e-01, -6.4944805e-01 }, + { 7.4314483e-01, -6.6913061e-01 }, { 7.2537437e-01, -6.8835458e-01 }, + { 7.0710678e-01, -7.0710678e-01 }, { 6.8835458e-01, -7.2537437e-01 }, + { 6.6913061e-01, -7.4314483e-01 }, { 6.4944805e-01, -7.6040597e-01 }, + { 6.2932039e-01, -7.7714596e-01 }, { 6.0876143e-01, -7.9335334e-01 }, + { 5.8778525e-01, -8.0901699e-01 }, { 5.6640624e-01, -8.2412619e-01 }, + { 5.4463904e-01, -8.3867057e-01 }, { 5.2249856e-01, -8.5264016e-01 }, + { 5.0000000e-01, -8.6602540e-01 }, { 4.7715876e-01, -8.7881711e-01 }, + { 4.5399050e-01, -8.9100652e-01 }, { 4.3051110e-01, -9.0258528e-01 }, + { 4.0673664e-01, -9.1354546e-01 }, { 3.8268343e-01, -9.2387953e-01 }, + { 3.5836795e-01, -9.3358043e-01 }, { 3.3380686e-01, -9.4264149e-01 }, + { 3.0901699e-01, -9.5105652e-01 }, { 2.8401534e-01, -9.5881973e-01 }, + { 2.5881905e-01, -9.6592583e-01 }, { 2.3344536e-01, -9.7236992e-01 }, + { 2.0791169e-01, -9.7814760e-01 }, { 1.8223553e-01, -9.8325491e-01 }, + { 1.5643447e-01, -9.8768834e-01 }, { 1.3052619e-01, -9.9144486e-01 }, + { 1.0452846e-01, -9.9452190e-01 }, { 7.8459096e-02, -9.9691733e-01 }, + { 5.2335956e-02, -9.9862953e-01 }, { 2.6176948e-02, -9.9965732e-01 }, + { 2.8327694e-16, -1.0000000e+00 }, { -2.6176948e-02, -9.9965732e-01 }, + { -5.2335956e-02, -9.9862953e-01 }, { -7.8459096e-02, -9.9691733e-01 }, + { -1.0452846e-01, -9.9452190e-01 }, { -1.3052619e-01, -9.9144486e-01 }, + { -1.5643447e-01, -9.8768834e-01 }, { -1.8223553e-01, -9.8325491e-01 }, + { -2.0791169e-01, -9.7814760e-01 }, { -2.3344536e-01, -9.7236992e-01 }, + { -2.5881905e-01, -9.6592583e-01 }, { -2.8401534e-01, -9.5881973e-01 }, + { -3.0901699e-01, -9.5105652e-01 }, { -3.3380686e-01, -9.4264149e-01 }, + { -3.5836795e-01, -9.3358043e-01 }, { -3.8268343e-01, -9.2387953e-01 }, + { -4.0673664e-01, -9.1354546e-01 }, { -4.3051110e-01, -9.0258528e-01 }, + { -4.5399050e-01, -8.9100652e-01 }, { -4.7715876e-01, -8.7881711e-01 }, + { -5.0000000e-01, -8.6602540e-01 }, { -5.2249856e-01, -8.5264016e-01 }, + { -5.4463904e-01, -8.3867057e-01 }, { -5.6640624e-01, -8.2412619e-01 }, + { -5.8778525e-01, -8.0901699e-01 }, { -6.0876143e-01, -7.9335334e-01 }, + { -6.2932039e-01, -7.7714596e-01 }, { -6.4944805e-01, -7.6040597e-01 }, + { -6.6913061e-01, -7.4314483e-01 }, { -6.8835458e-01, -7.2537437e-01 }, + { -7.0710678e-01, -7.0710678e-01 }, { -7.2537437e-01, -6.8835458e-01 }, + { -7.4314483e-01, -6.6913061e-01 }, { -7.6040597e-01, -6.4944805e-01 }, + { -7.7714596e-01, -6.2932039e-01 }, { -7.9335334e-01, -6.0876143e-01 }, + { -8.0901699e-01, -5.8778525e-01 }, { -8.2412619e-01, -5.6640624e-01 }, + { -8.3867057e-01, -5.4463904e-01 }, { -8.5264016e-01, -5.2249856e-01 }, + { -8.6602540e-01, -5.0000000e-01 }, { -8.7881711e-01, -4.7715876e-01 }, + { -8.9100652e-01, -4.5399050e-01 }, { -9.0258528e-01, -4.3051110e-01 }, + { -9.1354546e-01, -4.0673664e-01 }, { -9.2387953e-01, -3.8268343e-01 }, + { -9.3358043e-01, -3.5836795e-01 }, { -9.4264149e-01, -3.3380686e-01 }, + { -9.5105652e-01, -3.0901699e-01 }, { -9.5881973e-01, -2.8401534e-01 }, + { -9.6592583e-01, -2.5881905e-01 }, { -9.7236992e-01, -2.3344536e-01 }, + { -9.7814760e-01, -2.0791169e-01 }, { -9.8325491e-01, -1.8223553e-01 }, + { -9.8768834e-01, -1.5643447e-01 }, { -9.9144486e-01, -1.3052619e-01 }, + { -9.9452190e-01, -1.0452846e-01 }, { -9.9691733e-01, -7.8459096e-02 }, + { -9.9862953e-01, -5.2335956e-02 }, { -9.9965732e-01, -2.6176948e-02 }, + } +}; + +const struct lc3_fft_bf2_twiddles *lc3_fft_twiddles_bf2[][3] = { + { &fft_twiddles_10 , &fft_twiddles_30 , &fft_twiddles_90 }, + { &fft_twiddles_20 , &fft_twiddles_60 , &fft_twiddles_180 }, + { &fft_twiddles_40 , &fft_twiddles_120 }, + { &fft_twiddles_80 , &fft_twiddles_240 }, + { &fft_twiddles_160 } +}; + + +/** + * MDCT Rotation twiddles + * + * 2Pi (n + 1/8) / N + * W[n] = e , n = [0..N/4-1] + */ + +static const struct lc3_mdct_rot_def mdct_rot_120 = { + .n4 = 120/4, .w = (const struct lc3_complex []){ + { 9.9997858e-01, 6.5449380e-03 }, { 9.9826561e-01, 5.8870804e-02 }, + { 9.9381646e-01, 1.1103531e-01 }, { 9.8664333e-01, 1.6289547e-01 }, + { 9.7676588e-01, 2.1430915e-01 }, { 9.6421118e-01, 2.6513543e-01 }, + { 9.4901365e-01, 3.1523498e-01 }, { 9.3121493e-01, 3.6447050e-01 }, + { 9.1086382e-01, 4.1270703e-01 }, { 8.8801610e-01, 4.5981236e-01 }, + { 8.6273439e-01, 5.0565737e-01 }, { 8.3508798e-01, 5.5011642e-01 }, + { 8.0515265e-01, 5.9306763e-01 }, { 7.7301045e-01, 6.3439328e-01 }, + { 7.3874949e-01, 6.7398011e-01 }, { 7.0246367e-01, 7.1171961e-01 }, + { 6.6425244e-01, 7.4750833e-01 }, { 6.2422054e-01, 7.8124818e-01 }, + { 5.8247770e-01, 8.1284668e-01 }, { 5.3913832e-01, 8.4221723e-01 }, + { 4.9432121e-01, 8.6927932e-01 }, { 4.4814919e-01, 8.9395878e-01 }, + { 4.0074883e-01, 9.1618796e-01 }, { 3.5225005e-01, 9.3590593e-01 }, + { 3.0278577e-01, 9.5305864e-01 }, { 2.5249158e-01, 9.6759909e-01 }, + { 2.0150532e-01, 9.7948742e-01 }, { 1.4996676e-01, 9.8869104e-01 }, + { 9.8017140e-02, 9.9518473e-01 }, { 4.5798867e-02, 9.9895068e-01 }, + } +}; + +static const struct lc3_mdct_rot_def mdct_rot_160 = { + .n4 = 160/4, .w = (const struct lc3_complex []){ + { 9.9998795e-01, 4.9087188e-03 }, { 9.9902428e-01, 4.4164277e-02 }, + { 9.9652019e-01, 8.3351737e-02 }, { 9.9247953e-01, 1.2241068e-01 }, + { 9.8690855e-01, 1.6128086e-01 }, { 9.7981582e-01, 1.9990237e-01 }, + { 9.7121229e-01, 2.3821564e-01 }, { 9.6111122e-01, 2.7616160e-01 }, + { 9.4952818e-01, 3.1368174e-01 }, { 9.3648104e-01, 3.5071820e-01 }, + { 9.2198992e-01, 3.8721389e-01 }, { 9.0607715e-01, 4.2311251e-01 }, + { 8.8876728e-01, 4.5835873e-01 }, { 8.7008699e-01, 4.9289819e-01 }, + { 8.5006509e-01, 5.2667764e-01 }, { 8.2873246e-01, 5.5964499e-01 }, + { 8.0612197e-01, 5.9174941e-01 }, { 7.8226851e-01, 6.2294139e-01 }, + { 7.5720885e-01, 6.5317284e-01 }, { 7.3098162e-01, 6.8239715e-01 }, + { 7.0362727e-01, 7.1056925e-01 }, { 6.7518798e-01, 7.3764570e-01 }, + { 6.4570760e-01, 7.6358476e-01 }, { 6.1523159e-01, 7.8834643e-01 }, + { 5.8380693e-01, 8.1189252e-01 }, { 5.5148209e-01, 8.3418673e-01 }, + { 5.1830690e-01, 8.5519469e-01 }, { 4.8433252e-01, 8.7488400e-01 }, + { 4.4961133e-01, 8.9322430e-01 }, { 4.1419687e-01, 9.1018732e-01 }, + { 3.7814376e-01, 9.2574689e-01 }, { 3.4150757e-01, 9.3987902e-01 }, + { 3.0434480e-01, 9.5256194e-01 }, { 2.6671276e-01, 9.6377607e-01 }, + { 2.2866946e-01, 9.7350412e-01 }, { 1.9027357e-01, 9.8173111e-01 }, + { 1.5158430e-01, 9.8844433e-01 }, { 1.1266129e-01, 9.9363345e-01 }, + { 7.3564564e-02, 9.9729046e-01 }, { 3.4354408e-02, 9.9940971e-01 }, + } +}; + +static const struct lc3_mdct_rot_def mdct_rot_240 = { + .n4 = 240/4, .w = (const struct lc3_complex []){ + { 9.9999465e-01, 3.2724865e-03 }, { 9.9956631e-01, 2.9448173e-02 }, + { 9.9845292e-01, 5.5603678e-02 }, { 9.9665524e-01, 8.1721074e-02 }, + { 9.9417450e-01, 1.0778246e-01 }, { 9.9101241e-01, 1.3376998e-01 }, + { 9.8717112e-01, 1.5966582e-01 }, { 9.8265328e-01, 1.8545224e-01 }, + { 9.7746197e-01, 2.1111155e-01 }, { 9.7160077e-01, 2.3662618e-01 }, + { 9.6507367e-01, 2.6197864e-01 }, { 9.5788516e-01, 2.8715155e-01 }, + { 9.5004017e-01, 3.1212766e-01 }, { 9.4154407e-01, 3.3688985e-01 }, + { 9.3240267e-01, 3.6142116e-01 }, { 9.2262226e-01, 3.8570477e-01 }, + { 9.1220953e-01, 4.0972403e-01 }, { 9.0117161e-01, 4.3346249e-01 }, + { 8.8951608e-01, 4.5690388e-01 }, { 8.7725091e-01, 4.8003212e-01 }, + { 8.6438452e-01, 5.0283138e-01 }, { 8.5092573e-01, 5.2528602e-01 }, + { 8.3688375e-01, 5.4738066e-01 }, { 8.2226822e-01, 5.6910015e-01 }, + { 8.0708914e-01, 5.9042960e-01 }, { 7.9135693e-01, 6.1135441e-01 }, + { 7.7508236e-01, 6.3186022e-01 }, { 7.5827658e-01, 6.5193299e-01 }, + { 7.4095113e-01, 6.7155895e-01 }, { 7.2311786e-01, 6.9072467e-01 }, + { 7.0478900e-01, 7.0941699e-01 }, { 6.8597711e-01, 7.2762312e-01 }, + { 6.6669509e-01, 7.4533057e-01 }, { 6.4695615e-01, 7.6252720e-01 }, + { 6.2677382e-01, 7.7920124e-01 }, { 6.0616193e-01, 7.9534126e-01 }, + { 5.8513461e-01, 8.1093618e-01 }, { 5.6370626e-01, 8.2597533e-01 }, + { 5.4189158e-01, 8.4044840e-01 }, { 5.1970551e-01, 8.5434547e-01 }, + { 4.9716327e-01, 8.6765701e-01 }, { 4.7428029e-01, 8.8037390e-01 }, + { 4.5107226e-01, 8.9248743e-01 }, { 4.2755509e-01, 9.0398929e-01 }, + { 4.0374490e-01, 9.1487161e-01 }, { 3.7965800e-01, 9.2512691e-01 }, + { 3.5531090e-01, 9.3474818e-01 }, { 3.3072029e-01, 9.4372882e-01 }, + { 3.0590302e-01, 9.5206268e-01 }, { 2.8087610e-01, 9.5974404e-01 }, + { 2.5565668e-01, 9.6676764e-01 }, { 2.3026205e-01, 9.7312866e-01 }, + { 2.0470960e-01, 9.7882275e-01 }, { 1.7901686e-01, 9.8384601e-01 }, + { 1.5320143e-01, 9.8819498e-01 }, { 1.2728100e-01, 9.9186670e-01 }, + { 1.0127334e-01, 9.9485864e-01 }, { 7.5196277e-02, 9.9716875e-01 }, + { 4.9067674e-02, 9.9879546e-01 }, { 2.2905443e-02, 9.9973764e-01 }, + } +}; + +static const struct lc3_mdct_rot_def mdct_rot_320 = { + .n4 = 320/4, .w = (const struct lc3_complex []){ + { 9.9999699e-01, 2.4543668e-03 }, { 9.9975604e-01, 2.2087527e-02 }, + { 9.9912967e-01, 4.1712172e-02 }, { 9.9811811e-01, 6.1320736e-02 }, + { 9.9672176e-01, 8.0905660e-02 }, { 9.9494116e-01, 1.0045939e-01 }, + { 9.9277699e-01, 1.1997440e-01 }, { 9.9023008e-01, 1.3944315e-01 }, + { 9.8730142e-01, 1.5885814e-01 }, { 9.8399213e-01, 1.7821189e-01 }, + { 9.8030350e-01, 1.9749694e-01 }, { 9.7623695e-01, 2.1670585e-01 }, + { 9.7179403e-01, 2.3583121e-01 }, { 9.6697647e-01, 2.5486566e-01 }, + { 9.6178612e-01, 2.7380185e-01 }, { 9.5622499e-01, 2.9263249e-01 }, + { 9.5029521e-01, 3.1135031e-01 }, { 9.4399908e-01, 3.2994809e-01 }, + { 9.3733901e-01, 3.4841868e-01 }, { 9.3031759e-01, 3.6675495e-01 }, + { 9.2293750e-01, 3.8494982e-01 }, { 9.1520161e-01, 4.0299629e-01 }, + { 9.0711289e-01, 4.2088739e-01 }, { 8.9867447e-01, 4.3861624e-01 }, + { 8.8988958e-01, 4.5617599e-01 }, { 8.8076163e-01, 4.7355988e-01 }, + { 8.7129412e-01, 4.9076120e-01 }, { 8.6149072e-01, 5.0777332e-01 }, + { 8.5135519e-01, 5.2458968e-01 }, { 8.4089145e-01, 5.4120381e-01 }, + { 8.3010353e-01, 5.5760929e-01 }, { 8.1899560e-01, 5.7379980e-01 }, + { 8.0757192e-01, 5.8976911e-01 }, { 7.9583690e-01, 6.0551104e-01 }, + { 7.8379508e-01, 6.2101954e-01 }, { 7.7145109e-01, 6.3628862e-01 }, + { 7.5880969e-01, 6.5131241e-01 }, { 7.4587576e-01, 6.6608510e-01 }, + { 7.3265427e-01, 6.8060100e-01 }, { 7.1915033e-01, 6.9485451e-01 }, + { 7.0536915e-01, 7.0884015e-01 }, { 6.9131604e-01, 7.2255252e-01 }, + { 6.7699640e-01, 7.3598632e-01 }, { 6.6241578e-01, 7.4913639e-01 }, + { 6.4757978e-01, 7.6199766e-01 }, { 6.3249412e-01, 7.7456516e-01 }, + { 6.1716463e-01, 7.8683405e-01 }, { 6.0159721e-01, 7.9879960e-01 }, + { 5.8579786e-01, 8.1045720e-01 }, { 5.6977267e-01, 8.2180235e-01 }, + { 5.5352783e-01, 8.3283068e-01 }, { 5.3706959e-01, 8.4353794e-01 }, + { 5.2040430e-01, 8.5392000e-01 }, { 5.0353838e-01, 8.6397286e-01 }, + { 4.8647834e-01, 8.7369263e-01 }, { 4.6923076e-01, 8.8307559e-01 }, + { 4.5180228e-01, 8.9211810e-01 }, { 4.3419961e-01, 9.0081668e-01 }, + { 4.1642956e-01, 9.0916798e-01 }, { 3.9849896e-01, 9.1716878e-01 }, + { 3.8041474e-01, 9.2481600e-01 }, { 3.6218386e-01, 9.3210667e-01 }, + { 3.4381335e-01, 9.3903801e-01 }, { 3.2531029e-01, 9.4560733e-01 }, + { 3.0668182e-01, 9.5181209e-01 }, { 2.8793512e-01, 9.5764992e-01 }, + { 2.6907741e-01, 9.6311855e-01 }, { 2.5011597e-01, 9.6821588e-01 }, + { 2.3105811e-01, 9.7293995e-01 }, { 2.1191117e-01, 9.7728893e-01 }, + { 1.9268253e-01, 9.8126115e-01 }, { 1.7337961e-01, 9.8485507e-01 }, + { 1.5400984e-01, 9.8806931e-01 }, { 1.3458071e-01, 9.9090264e-01 }, + { 1.1509969e-01, 9.9335395e-01 }, { 9.5574297e-02, 9.9542230e-01 }, + { 7.6012059e-02, 9.9710690e-01 }, { 5.6420516e-02, 9.9840709e-01 }, + { 3.6807223e-02, 9.9932238e-01 }, { 1.7179740e-02, 9.9985242e-01 }, + } +}; + +static const struct lc3_mdct_rot_def mdct_rot_360 = { + .n4 = 360/4, .w = (const struct lc3_complex []){ + { 9.9999762e-01, 2.1816598e-03 }, { 9.9980724e-01, 1.9633692e-02 }, + { 9.9931231e-01, 3.7079744e-02 }, { 9.9851298e-01, 5.4514502e-02 }, + { 9.9740949e-01, 7.1932653e-02 }, { 9.9600218e-01, 8.9328893e-02 }, + { 9.9429148e-01, 1.0669792e-01 }, { 9.9227791e-01, 1.2403445e-01 }, + { 9.8996208e-01, 1.4133320e-01 }, { 9.8734470e-01, 1.5858889e-01 }, + { 9.8442657e-01, 1.7579628e-01 }, { 9.8120857e-01, 1.9295012e-01 }, + { 9.7769168e-01, 2.1004518e-01 }, { 9.7387698e-01, 2.2707626e-01 }, + { 9.6976563e-01, 2.4403818e-01 }, { 9.6535887e-01, 2.6092575e-01 }, + { 9.6065806e-01, 2.7773385e-01 }, { 9.5566462e-01, 2.9445734e-01 }, + { 9.5038008e-01, 3.1109114e-01 }, { 9.4480605e-01, 3.2763018e-01 }, + { 9.3894421e-01, 3.4406942e-01 }, { 9.3279637e-01, 3.6040385e-01 }, + { 9.2636438e-01, 3.7662850e-01 }, { 9.1965022e-01, 3.9273843e-01 }, + { 9.1265592e-01, 4.0872872e-01 }, { 9.0538362e-01, 4.2459451e-01 }, + { 8.9783553e-01, 4.4033097e-01 }, { 8.9001395e-01, 4.5593329e-01 }, + { 8.8192126e-01, 4.7139674e-01 }, { 8.7355994e-01, 4.8671659e-01 }, + { 8.6493251e-01, 5.0188818e-01 }, { 8.5604162e-01, 5.1690690e-01 }, + { 8.4688997e-01, 5.3176816e-01 }, { 8.3748035e-01, 5.4646743e-01 }, + { 8.2781563e-01, 5.6100025e-01 }, { 8.1789875e-01, 5.7536218e-01 }, + { 8.0773272e-01, 5.8954885e-01 }, { 7.9732065e-01, 6.0355594e-01 }, + { 7.8666571e-01, 6.1737918e-01 }, { 7.7577115e-01, 6.3101436e-01 }, + { 7.6464028e-01, 6.4445733e-01 }, { 7.5327649e-01, 6.5770399e-01 }, + { 7.4168324e-01, 6.7075030e-01 }, { 7.2986407e-01, 6.8359230e-01 }, + { 7.1782258e-01, 6.9622607e-01 }, { 7.0556243e-01, 7.0864776e-01 }, + { 6.9308736e-01, 7.2085360e-01 }, { 6.8040117e-01, 7.3283985e-01 }, + { 6.6750772e-01, 7.4460287e-01 }, { 6.5441095e-01, 7.5613908e-01 }, + { 6.4111483e-01, 7.6744496e-01 }, { 6.2762343e-01, 7.7851708e-01 }, + { 6.1394084e-01, 7.8935204e-01 }, { 6.0007124e-01, 7.9994657e-01 }, + { 5.8601885e-01, 8.1029742e-01 }, { 5.7178796e-01, 8.2040144e-01 }, + { 5.5738289e-01, 8.3025557e-01 }, { 5.4280804e-01, 8.3985679e-01 }, + { 5.2806785e-01, 8.4920218e-01 }, { 5.1316680e-01, 8.5828890e-01 }, + { 4.9810944e-01, 8.6711417e-01 }, { 4.8290034e-01, 8.7567532e-01 }, + { 4.6754415e-01, 8.8396972e-01 }, { 4.5204555e-01, 8.9199486e-01 }, + { 4.3640924e-01, 8.9974828e-01 }, { 4.2064000e-01, 9.0722764e-01 }, + { 4.0474263e-01, 9.1443064e-01 }, { 3.8872197e-01, 9.2135511e-01 }, + { 3.7258290e-01, 9.2799891e-01 }, { 3.5633034e-01, 9.3436004e-01 }, + { 3.3996924e-01, 9.4043656e-01 }, { 3.2350458e-01, 9.4622660e-01 }, + { 3.0694138e-01, 9.5172842e-01 }, { 2.9028468e-01, 9.5694034e-01 }, + { 2.7353955e-01, 9.6186076e-01 }, { 2.5671111e-01, 9.6648818e-01 }, + { 2.3980446e-01, 9.7082121e-01 }, { 2.2282477e-01, 9.7485851e-01 }, + { 2.0577721e-01, 9.7859887e-01 }, { 1.8866696e-01, 9.8204113e-01 }, + { 1.7149925e-01, 9.8518425e-01 }, { 1.5427929e-01, 9.8802728e-01 }, + { 1.3701234e-01, 9.9056934e-01 }, { 1.1970366e-01, 9.9280967e-01 }, + { 1.0235851e-01, 9.9474757e-01 }, { 8.4982177e-02, 9.9638247e-01 }, + { 6.7579962e-02, 9.9771386e-01 }, { 5.0157162e-02, 9.9874134e-01 }, + { 3.2719083e-02, 9.9946459e-01 }, { 1.5271037e-02, 9.9988339e-01 }, + } +}; + +static const struct lc3_mdct_rot_def mdct_rot_480 = { + .n4 = 480/4, .w = (const struct lc3_complex []){ + { 9.9999866e-01, 1.6362454e-03 }, { 9.9989157e-01, 1.4725683e-02 }, + { 9.9961315e-01, 2.7812598e-02 }, { 9.9916346e-01, 4.0894747e-02 }, + { 9.9854256e-01, 5.3969889e-02 }, { 9.9775057e-01, 6.7035784e-02 }, + { 9.9678762e-01, 8.0090192e-02 }, { 9.9565388e-01, 9.3130877e-02 }, + { 9.9434953e-01, 1.0615561e-01 }, { 9.9287481e-01, 1.1916214e-01 }, + { 9.9122996e-01, 1.3214826e-01 }, { 9.8941527e-01, 1.4511174e-01 }, + { 9.8743105e-01, 1.5805036e-01 }, { 9.8527764e-01, 1.7096189e-01 }, + { 9.8295541e-01, 1.8384413e-01 }, { 9.8046475e-01, 1.9669487e-01 }, + { 9.7780610e-01, 2.0951190e-01 }, { 9.7497990e-01, 2.2229304e-01 }, + { 9.7198664e-01, 2.3503609e-01 }, { 9.6882685e-01, 2.4773886e-01 }, + { 9.6550104e-01, 2.6039919e-01 }, { 9.6200980e-01, 2.7301490e-01 }, + { 9.5835373e-01, 2.8558383e-01 }, { 9.5453345e-01, 2.9810383e-01 }, + { 9.5054962e-01, 3.1057274e-01 }, { 9.4640291e-01, 3.2298845e-01 }, + { 9.4209404e-01, 3.3534881e-01 }, { 9.3762375e-01, 3.4765171e-01 }, + { 9.3299280e-01, 3.5989504e-01 }, { 9.2820199e-01, 3.7207670e-01 }, + { 9.2325213e-01, 3.8419461e-01 }, { 9.1814408e-01, 3.9624670e-01 }, + { 9.1287871e-01, 4.0823088e-01 }, { 9.0745693e-01, 4.2014512e-01 }, + { 9.0187965e-01, 4.3198737e-01 }, { 8.9614785e-01, 4.4375560e-01 }, + { 8.9026249e-01, 4.5544780e-01 }, { 8.8422459e-01, 4.6706195e-01 }, + { 8.7803519e-01, 4.7859608e-01 }, { 8.7169533e-01, 4.9004821e-01 }, + { 8.6520612e-01, 5.0141636e-01 }, { 8.5856866e-01, 5.1269860e-01 }, + { 8.5178409e-01, 5.2389299e-01 }, { 8.4485357e-01, 5.3499762e-01 }, + { 8.3777828e-01, 5.4601058e-01 }, { 8.3055945e-01, 5.5692998e-01 }, + { 8.2319831e-01, 5.6775395e-01 }, { 8.1569611e-01, 5.7848064e-01 }, + { 8.0805415e-01, 5.8910822e-01 }, { 8.0027373e-01, 5.9963485e-01 }, + { 7.9235620e-01, 6.1005873e-01 }, { 7.8430289e-01, 6.2037809e-01 }, + { 7.7611520e-01, 6.3059115e-01 }, { 7.6779452e-01, 6.4069616e-01 }, + { 7.5934229e-01, 6.5069139e-01 }, { 7.5075995e-01, 6.6057513e-01 }, + { 7.4204897e-01, 6.7034568e-01 }, { 7.3321084e-01, 6.8000137e-01 }, + { 7.2424708e-01, 6.8954054e-01 }, { 7.1515923e-01, 6.9896157e-01 }, + { 7.0594883e-01, 7.0826283e-01 }, { 6.9661748e-01, 7.1744274e-01 }, + { 6.8716676e-01, 7.2649972e-01 }, { 6.7759830e-01, 7.3543221e-01 }, + { 6.6791374e-01, 7.4423869e-01 }, { 6.5811474e-01, 7.5291765e-01 }, + { 6.4820297e-01, 7.6146760e-01 }, { 6.3818013e-01, 7.6988708e-01 }, + { 6.2804795e-01, 7.7817464e-01 }, { 6.1780815e-01, 7.8632887e-01 }, + { 6.0746249e-01, 7.9434836e-01 }, { 5.9701275e-01, 8.0223175e-01 }, + { 5.8646072e-01, 8.0997767e-01 }, { 5.7580819e-01, 8.1758481e-01 }, + { 5.6505701e-01, 8.2505187e-01 }, { 5.5420900e-01, 8.3237755e-01 }, + { 5.4326604e-01, 8.3956061e-01 }, { 5.3222998e-01, 8.4659981e-01 }, + { 5.2110274e-01, 8.5349396e-01 }, { 5.0988620e-01, 8.6024186e-01 }, + { 4.9858230e-01, 8.6684237e-01 }, { 4.8719297e-01, 8.7329434e-01 }, + { 4.7572016e-01, 8.7959669e-01 }, { 4.6416584e-01, 8.8574831e-01 }, + { 4.5253199e-01, 8.9174817e-01 }, { 4.4082059e-01, 8.9759523e-01 }, + { 4.2903367e-01, 9.0328850e-01 }, { 4.1717323e-01, 9.0882699e-01 }, + { 4.0524131e-01, 9.1420976e-01 }, { 3.9323996e-01, 9.1943588e-01 }, + { 3.8117123e-01, 9.2450446e-01 }, { 3.6903718e-01, 9.2941463e-01 }, + { 3.5683990e-01, 9.3416555e-01 }, { 3.4458148e-01, 9.3875641e-01 }, + { 3.3226402e-01, 9.4318642e-01 }, { 3.1988962e-01, 9.4745482e-01 }, + { 3.0746042e-01, 9.5156087e-01 }, { 2.9497853e-01, 9.5550388e-01 }, + { 2.8244610e-01, 9.5928317e-01 }, { 2.6986527e-01, 9.6289809e-01 }, + { 2.5723821e-01, 9.6634802e-01 }, { 2.4456706e-01, 9.6963238e-01 }, + { 2.3185402e-01, 9.7275059e-01 }, { 2.1910124e-01, 9.7570213e-01 }, + { 2.0631092e-01, 9.7848649e-01 }, { 1.9348526e-01, 9.8110318e-01 }, + { 1.8062644e-01, 9.8355177e-01 }, { 1.6773667e-01, 9.8583184e-01 }, + { 1.5481816e-01, 9.8794298e-01 }, { 1.4187312e-01, 9.8988485e-01 }, + { 1.2890377e-01, 9.9165711e-01 }, { 1.1591234e-01, 9.9325945e-01 }, + { 1.0290104e-01, 9.9469160e-01 }, { 8.9872115e-02, 9.9595331e-01 }, + { 7.6827789e-02, 9.9704438e-01 }, { 6.3770300e-02, 9.9796460e-01 }, + { 5.0701883e-02, 9.9871383e-01 }, { 3.7624779e-02, 9.9929194e-01 }, + { 2.4541229e-02, 9.9969882e-01 }, { 1.1453473e-02, 9.9993441e-01 }, + } +}; + +static const struct lc3_mdct_rot_def mdct_rot_640 = { + .n4 = 640/4, .w = (const struct lc3_complex []){ + { 9.9999925e-01, 1.2271843e-03 }, { 9.9993901e-01, 1.1044437e-02 }, + { 9.9978239e-01, 2.0860625e-02 }, { 9.9952942e-01, 3.0674803e-02 }, + { 9.9918010e-01, 4.0486024e-02 }, { 9.9873449e-01, 5.0293344e-02 }, + { 9.9819261e-01, 6.0095815e-02 }, { 9.9755453e-01, 6.9892495e-02 }, + { 9.9682030e-01, 7.9682438e-02 }, { 9.9598999e-01, 8.9464701e-02 }, + { 9.9506369e-01, 9.9238342e-02 }, { 9.9404148e-01, 1.0900242e-01 }, + { 9.9292347e-01, 1.1875599e-01 }, { 9.9170975e-01, 1.2849811e-01 }, + { 9.9040046e-01, 1.3822785e-01 }, { 9.8899570e-01, 1.4794427e-01 }, + { 9.8749562e-01, 1.5764642e-01 }, { 9.8590037e-01, 1.6733339e-01 }, + { 9.8421009e-01, 1.7700422e-01 }, { 9.8242496e-01, 1.8665800e-01 }, + { 9.8054513e-01, 1.9629378e-01 }, { 9.7857080e-01, 2.0591064e-01 }, + { 9.7650215e-01, 2.1550766e-01 }, { 9.7433938e-01, 2.2508391e-01 }, + { 9.7208271e-01, 2.3463847e-01 }, { 9.6973234e-01, 2.4417040e-01 }, + { 9.6728851e-01, 2.5367881e-01 }, { 9.6475145e-01, 2.6316276e-01 }, + { 9.6212140e-01, 2.7262136e-01 }, { 9.5939863e-01, 2.8205367e-01 }, + { 9.5658338e-01, 2.9145880e-01 }, { 9.5367594e-01, 3.0083584e-01 }, + { 9.5067658e-01, 3.1018388e-01 }, { 9.4758559e-01, 3.1950203e-01 }, + { 9.4440327e-01, 3.2878938e-01 }, { 9.4112993e-01, 3.3804505e-01 }, + { 9.3776588e-01, 3.4726813e-01 }, { 9.3431145e-01, 3.5645774e-01 }, + { 9.3076696e-01, 3.6561300e-01 }, { 9.2713277e-01, 3.7473302e-01 }, + { 9.2340921e-01, 3.8381691e-01 }, { 9.1959666e-01, 3.9286382e-01 }, + { 9.1569547e-01, 4.0187286e-01 }, { 9.1170603e-01, 4.1084317e-01 }, + { 9.0762872e-01, 4.1977388e-01 }, { 9.0346392e-01, 4.2866413e-01 }, + { 8.9921205e-01, 4.3751307e-01 }, { 8.9487351e-01, 4.4631984e-01 }, + { 8.9044872e-01, 4.5508359e-01 }, { 8.8593811e-01, 4.6380348e-01 }, + { 8.8134211e-01, 4.7247866e-01 }, { 8.7666116e-01, 4.8110831e-01 }, + { 8.7189572e-01, 4.8969159e-01 }, { 8.6704625e-01, 4.9822767e-01 }, + { 8.6211320e-01, 5.0671573e-01 }, { 8.5709707e-01, 5.1515495e-01 }, + { 8.5199832e-01, 5.2354452e-01 }, { 8.4681746e-01, 5.3188363e-01 }, + { 8.4155498e-01, 5.4017147e-01 }, { 8.3621139e-01, 5.4840726e-01 }, + { 8.3078720e-01, 5.5659018e-01 }, { 8.2528294e-01, 5.6471946e-01 }, + { 8.1969914e-01, 5.7279431e-01 }, { 8.1403633e-01, 5.8081396e-01 }, + { 8.0829506e-01, 5.8877762e-01 }, { 8.0247589e-01, 5.9668454e-01 }, + { 7.9657938e-01, 6.0453395e-01 }, { 7.9060609e-01, 6.1232509e-01 }, + { 7.8455660e-01, 6.2005721e-01 }, { 7.7843149e-01, 6.2772957e-01 }, + { 7.7223135e-01, 6.3534143e-01 }, { 7.6595679e-01, 6.4289206e-01 }, + { 7.5960840e-01, 6.5038072e-01 }, { 7.5318680e-01, 6.5780669e-01 }, + { 7.4669260e-01, 6.6516927e-01 }, { 7.4012644e-01, 6.7246773e-01 }, + { 7.3348894e-01, 6.7970138e-01 }, { 7.2678075e-01, 6.8686952e-01 }, + { 7.2000251e-01, 6.9397146e-01 }, { 7.1315487e-01, 7.0100651e-01 }, + { 7.0623850e-01, 7.0797400e-01 }, { 6.9925406e-01, 7.1487325e-01 }, + { 6.9220222e-01, 7.2170360e-01 }, { 6.8508367e-01, 7.2846439e-01 }, + { 6.7789909e-01, 7.3515497e-01 }, { 6.7064917e-01, 7.4177469e-01 }, + { 6.6333461e-01, 7.4832292e-01 }, { 6.5595612e-01, 7.5479903e-01 }, + { 6.4851440e-01, 7.6120239e-01 }, { 6.4101018e-01, 7.6753238e-01 }, + { 6.3344418e-01, 7.7378839e-01 }, { 6.2581713e-01, 7.7996982e-01 }, + { 6.1812975e-01, 7.8607608e-01 }, { 6.1038281e-01, 7.9210658e-01 }, + { 6.0257703e-01, 7.9806073e-01 }, { 5.9471317e-01, 8.0393796e-01 }, + { 5.8679200e-01, 8.0973771e-01 }, { 5.7881426e-01, 8.1545941e-01 }, + { 5.7078075e-01, 8.2110251e-01 }, { 5.6269221e-01, 8.2666648e-01 }, + { 5.5454945e-01, 8.3215077e-01 }, { 5.4635323e-01, 8.3755486e-01 }, + { 5.3810436e-01, 8.4287822e-01 }, { 5.2980362e-01, 8.4812034e-01 }, + { 5.2145182e-01, 8.5328072e-01 }, { 5.1304977e-01, 8.5835886e-01 }, + { 5.0459826e-01, 8.6335427e-01 }, { 4.9609812e-01, 8.6826647e-01 }, + { 4.8755016e-01, 8.7309498e-01 }, { 4.7895521e-01, 8.7783934e-01 }, + { 4.7031410e-01, 8.8249909e-01 }, { 4.6162766e-01, 8.8707379e-01 }, + { 4.5289673e-01, 8.9156298e-01 }, { 4.4412214e-01, 8.9596625e-01 }, + { 4.3530476e-01, 9.0028316e-01 }, { 4.2644541e-01, 9.0451330e-01 }, + { 4.1754496e-01, 9.0865626e-01 }, { 4.0860427e-01, 9.1271165e-01 }, + { 3.9962420e-01, 9.1667906e-01 }, { 3.9060561e-01, 9.2055812e-01 }, + { 3.8154937e-01, 9.2434846e-01 }, { 3.7245636e-01, 9.2804971e-01 }, + { 3.6332745e-01, 9.3166151e-01 }, { 3.5416353e-01, 9.3518351e-01 }, + { 3.4496546e-01, 9.3861538e-01 }, { 3.3573415e-01, 9.4195678e-01 }, + { 3.2647048e-01, 9.4520740e-01 }, { 3.1717535e-01, 9.4836691e-01 }, + { 3.0784964e-01, 9.5143502e-01 }, { 2.9849426e-01, 9.5441143e-01 }, + { 2.8911012e-01, 9.5729585e-01 }, { 2.7969810e-01, 9.6008800e-01 }, + { 2.7025914e-01, 9.6278762e-01 }, { 2.6079412e-01, 9.6539444e-01 }, + { 2.5130396e-01, 9.6790822e-01 }, { 2.4178959e-01, 9.7032870e-01 }, + { 2.3225191e-01, 9.7265567e-01 }, { 2.2269185e-01, 9.7488889e-01 }, + { 2.1311032e-01, 9.7702814e-01 }, { 2.0350825e-01, 9.7907323e-01 }, + { 1.9388657e-01, 9.8102395e-01 }, { 1.8424620e-01, 9.8288012e-01 }, + { 1.7458807e-01, 9.8464156e-01 }, { 1.6491312e-01, 9.8630810e-01 }, + { 1.5522227e-01, 9.8787957e-01 }, { 1.4551646e-01, 9.8935583e-01 }, + { 1.3579663e-01, 9.9073673e-01 }, { 1.2606370e-01, 9.9202215e-01 }, + { 1.1631863e-01, 9.9321195e-01 }, { 1.0656235e-01, 9.9430602e-01 }, + { 9.6795791e-02, 9.9530426e-01 }, { 8.7019907e-02, 9.9620657e-01 }, + { 7.7235635e-02, 9.9701287e-01 }, { 6.7443920e-02, 9.9772307e-01 }, + { 5.7645703e-02, 9.9833710e-01 }, { 4.7841931e-02, 9.9885492e-01 }, + { 3.8033548e-02, 9.9927646e-01 }, { 2.8221499e-02, 9.9960169e-01 }, + { 1.8406730e-02, 9.9983058e-01 }, { 8.5901868e-03, 9.9996310e-01 }, + } +}; + +static const struct lc3_mdct_rot_def mdct_rot_720 = { + .n4 = 720/4, .w = (const struct lc3_complex []){ + { 9.9999941e-01, 1.0908306e-03 }, { 9.9995181e-01, 9.8173193e-03 }, + { 9.9982806e-01, 1.8543060e-02 }, { 9.9962818e-01, 2.7267389e-02 }, + { 9.9935216e-01, 3.5989642e-02 }, { 9.9900005e-01, 4.4709154e-02 }, + { 9.9857185e-01, 5.3425261e-02 }, { 9.9806761e-01, 6.2137299e-02 }, + { 9.9748736e-01, 7.0844606e-02 }, { 9.9683116e-01, 7.9546517e-02 }, + { 9.9609903e-01, 8.8242371e-02 }, { 9.9529105e-01, 9.6931504e-02 }, + { 9.9440728e-01, 1.0561326e-01 }, { 9.9344778e-01, 1.1428696e-01 }, + { 9.9241262e-01, 1.2295197e-01 }, { 9.9130189e-01, 1.3160761e-01 }, + { 9.9011567e-01, 1.4025323e-01 }, { 9.8885404e-01, 1.4888817e-01 }, + { 9.8751711e-01, 1.5751177e-01 }, { 9.8610498e-01, 1.6612338e-01 }, + { 9.8461775e-01, 1.7472233e-01 }, { 9.8305553e-01, 1.8330798e-01 }, + { 9.8141846e-01, 1.9187967e-01 }, { 9.7970664e-01, 2.0043675e-01 }, + { 9.7792022e-01, 2.0897856e-01 }, { 9.7605933e-01, 2.1750446e-01 }, + { 9.7412410e-01, 2.2601379e-01 }, { 9.7211469e-01, 2.3450592e-01 }, + { 9.7003125e-01, 2.4298018e-01 }, { 9.6787394e-01, 2.5143594e-01 }, + { 9.6564292e-01, 2.5987255e-01 }, { 9.6333837e-01, 2.6828937e-01 }, + { 9.6096045e-01, 2.7668577e-01 }, { 9.5850935e-01, 2.8506109e-01 }, + { 9.5598526e-01, 2.9341470e-01 }, { 9.5338836e-01, 3.0174596e-01 }, + { 9.5071887e-01, 3.1005425e-01 }, { 9.4797697e-01, 3.1833893e-01 }, + { 9.4516287e-01, 3.2659936e-01 }, { 9.4227680e-01, 3.3483492e-01 }, + { 9.3931898e-01, 3.4304499e-01 }, { 9.3628962e-01, 3.5122892e-01 }, + { 9.3318895e-01, 3.5938611e-01 }, { 9.3001722e-01, 3.6751594e-01 }, + { 9.2677467e-01, 3.7561777e-01 }, { 9.2346154e-01, 3.8369100e-01 }, + { 9.2007808e-01, 3.9173501e-01 }, { 9.1662456e-01, 3.9974919e-01 }, + { 9.1310123e-01, 4.0773292e-01 }, { 9.0950837e-01, 4.1568561e-01 }, + { 9.0584624e-01, 4.2360664e-01 }, { 9.0211513e-01, 4.3149541e-01 }, + { 8.9831532e-01, 4.3935132e-01 }, { 8.9444710e-01, 4.4717377e-01 }, + { 8.9051077e-01, 4.5496217e-01 }, { 8.8650662e-01, 4.6271592e-01 }, + { 8.8243495e-01, 4.7043443e-01 }, { 8.7829609e-01, 4.7811712e-01 }, + { 8.7409034e-01, 4.8576339e-01 }, { 8.6981803e-01, 4.9337268e-01 }, + { 8.6547947e-01, 5.0094439e-01 }, { 8.6107501e-01, 5.0847795e-01 }, + { 8.5660497e-01, 5.1597279e-01 }, { 8.5206970e-01, 5.2342834e-01 }, + { 8.4746954e-01, 5.3084403e-01 }, { 8.4280484e-01, 5.3821929e-01 }, + { 8.3807596e-01, 5.4555356e-01 }, { 8.3328326e-01, 5.5284629e-01 }, + { 8.2842709e-01, 5.6009691e-01 }, { 8.2350785e-01, 5.6730488e-01 }, + { 8.1852588e-01, 5.7446965e-01 }, { 8.1348159e-01, 5.8159067e-01 }, + { 8.0837534e-01, 5.8866740e-01 }, { 8.0320753e-01, 5.9569930e-01 }, + { 7.9797856e-01, 6.0268584e-01 }, { 7.9268881e-01, 6.0962648e-01 }, + { 7.8733870e-01, 6.1652070e-01 }, { 7.8192863e-01, 6.2336796e-01 }, + { 7.7645902e-01, 6.3016775e-01 }, { 7.7093027e-01, 6.3691955e-01 }, + { 7.6534281e-01, 6.4362285e-01 }, { 7.5969708e-01, 6.5027714e-01 }, + { 7.5399348e-01, 6.5688190e-01 }, { 7.4823247e-01, 6.6343664e-01 }, + { 7.4241448e-01, 6.6994085e-01 }, { 7.3653994e-01, 6.7639405e-01 }, + { 7.3060932e-01, 6.8279574e-01 }, { 7.2462306e-01, 6.8914543e-01 }, + { 7.1858162e-01, 6.9544264e-01 }, { 7.1248545e-01, 7.0168688e-01 }, + { 7.0633503e-01, 7.0787769e-01 }, { 7.0013081e-01, 7.1401460e-01 }, + { 6.9387328e-01, 7.2009713e-01 }, { 6.8756291e-01, 7.2612482e-01 }, + { 6.8120017e-01, 7.3209721e-01 }, { 6.7478556e-01, 7.3801385e-01 }, + { 6.6831956e-01, 7.4387429e-01 }, { 6.6180267e-01, 7.4967808e-01 }, + { 6.5523538e-01, 7.5542478e-01 }, { 6.4861819e-01, 7.6111395e-01 }, + { 6.4195160e-01, 7.6674516e-01 }, { 6.3523613e-01, 7.7231798e-01 }, + { 6.2847228e-01, 7.7783198e-01 }, { 6.2166057e-01, 7.8328675e-01 }, + { 6.1480152e-01, 7.8868187e-01 }, { 6.0789565e-01, 7.9401692e-01 }, + { 6.0094349e-01, 7.9929151e-01 }, { 5.9394556e-01, 8.0450523e-01 }, + { 5.8690240e-01, 8.0965769e-01 }, { 5.7981455e-01, 8.1474848e-01 }, + { 5.7268254e-01, 8.1977723e-01 }, { 5.6550692e-01, 8.2474355e-01 }, + { 5.5828823e-01, 8.2964706e-01 }, { 5.5102703e-01, 8.3448740e-01 }, + { 5.4372386e-01, 8.3926418e-01 }, { 5.3637929e-01, 8.4397705e-01 }, + { 5.2899387e-01, 8.4862564e-01 }, { 5.2156817e-01, 8.5320961e-01 }, + { 5.1410274e-01, 8.5772861e-01 }, { 5.0659817e-01, 8.6218229e-01 }, + { 4.9905502e-01, 8.6657030e-01 }, { 4.9147386e-01, 8.7089233e-01 }, + { 4.8385527e-01, 8.7514803e-01 }, { 4.7619984e-01, 8.7933709e-01 }, + { 4.6850814e-01, 8.8345918e-01 }, { 4.6078076e-01, 8.8751399e-01 }, + { 4.5301829e-01, 8.9150122e-01 }, { 4.4522133e-01, 8.9542056e-01 }, + { 4.3739045e-01, 8.9927170e-01 }, { 4.2952627e-01, 9.0305436e-01 }, + { 4.2162938e-01, 9.0676825e-01 }, { 4.1370038e-01, 9.1041309e-01 }, + { 4.0573988e-01, 9.1398859e-01 }, { 3.9774847e-01, 9.1749450e-01 }, + { 3.8972678e-01, 9.2093053e-01 }, { 3.8167541e-01, 9.2429643e-01 }, + { 3.7359497e-01, 9.2759194e-01 }, { 3.6548608e-01, 9.3081681e-01 }, + { 3.5734936e-01, 9.3397079e-01 }, { 3.4918542e-01, 9.3705365e-01 }, + { 3.4099489e-01, 9.4006515e-01 }, { 3.3277840e-01, 9.4300506e-01 }, + { 3.2453656e-01, 9.4587315e-01 }, { 3.1627001e-01, 9.4866922e-01 }, + { 3.0797937e-01, 9.5139304e-01 }, { 2.9966528e-01, 9.5404440e-01 }, + { 2.9132836e-01, 9.5662311e-01 }, { 2.8296927e-01, 9.5912898e-01 }, + { 2.7458862e-01, 9.6156180e-01 }, { 2.6618706e-01, 9.6392139e-01 }, + { 2.5776523e-01, 9.6620758e-01 }, { 2.4932377e-01, 9.6842019e-01 }, + { 2.4086332e-01, 9.7055904e-01 }, { 2.3238453e-01, 9.7262399e-01 }, + { 2.2388805e-01, 9.7461487e-01 }, { 2.1537451e-01, 9.7653153e-01 }, + { 2.0684457e-01, 9.7837382e-01 }, { 1.9829888e-01, 9.8014160e-01 }, + { 1.8973809e-01, 9.8183474e-01 }, { 1.8116285e-01, 9.8345311e-01 }, + { 1.7257382e-01, 9.8499659e-01 }, { 1.6397164e-01, 9.8646505e-01 }, + { 1.5535697e-01, 9.8785840e-01 }, { 1.4673047e-01, 9.8917651e-01 }, + { 1.3809280e-01, 9.9041929e-01 }, { 1.2944462e-01, 9.9158665e-01 }, + { 1.2078657e-01, 9.9267850e-01 }, { 1.1211933e-01, 9.9369475e-01 }, + { 1.0344355e-01, 9.9463533e-01 }, { 9.4759887e-02, 9.9550016e-01 }, + { 8.6069011e-02, 9.9628918e-01 }, { 7.7371581e-02, 9.9700233e-01 }, + { 6.8668259e-02, 9.9763955e-01 }, { 5.9959707e-02, 9.9820080e-01 }, + { 5.1246589e-02, 9.9868603e-01 }, { 4.2529569e-02, 9.9909521e-01 }, + { 3.3809310e-02, 9.9942830e-01 }, { 2.5086476e-02, 9.9968528e-01 }, + { 1.6361732e-02, 9.9986614e-01 }, { 7.6357413e-03, 9.9997085e-01 }, + } +}; + +static const struct lc3_mdct_rot_def mdct_rot_960 = { + .n4 = 960/4, .w = (const struct lc3_complex []){ + { 9.9999967e-01, 8.1812300e-04 }, { 9.9997289e-01, 7.3630412e-03 }, + { 9.9990328e-01, 1.3907644e-02 }, { 9.9979084e-01, 2.0451651e-02 }, + { 9.9963557e-01, 2.6994782e-02 }, { 9.9943748e-01, 3.3536757e-02 }, + { 9.9919658e-01, 4.0077295e-02 }, { 9.9891288e-01, 4.6616116e-02 }, + { 9.9858638e-01, 5.3152941e-02 }, { 9.9821711e-01, 5.9687488e-02 }, + { 9.9780508e-01, 6.6219479e-02 }, { 9.9735031e-01, 7.2748633e-02 }, + { 9.9685281e-01, 7.9274670e-02 }, { 9.9631261e-01, 8.5797312e-02 }, + { 9.9572973e-01, 9.2316279e-02 }, { 9.9510420e-01, 9.8831291e-02 }, + { 9.9443605e-01, 1.0534207e-01 }, { 9.9372529e-01, 1.1184834e-01 }, + { 9.9297196e-01, 1.1834981e-01 }, { 9.9217610e-01, 1.2484622e-01 }, + { 9.9133774e-01, 1.3133727e-01 }, { 9.9045692e-01, 1.3782270e-01 }, + { 9.8953366e-01, 1.4430223e-01 }, { 9.8856802e-01, 1.5077558e-01 }, + { 9.8756003e-01, 1.5724246e-01 }, { 9.8650973e-01, 1.6370261e-01 }, + { 9.8541718e-01, 1.7015575e-01 }, { 9.8428242e-01, 1.7660160e-01 }, + { 9.8310549e-01, 1.8303989e-01 }, { 9.8188645e-01, 1.8947033e-01 }, + { 9.8062534e-01, 1.9589266e-01 }, { 9.7932224e-01, 2.0230660e-01 }, + { 9.7797718e-01, 2.0871187e-01 }, { 9.7659022e-01, 2.1510820e-01 }, + { 9.7516144e-01, 2.2149531e-01 }, { 9.7369088e-01, 2.2787294e-01 }, + { 9.7217861e-01, 2.3424080e-01 }, { 9.7062469e-01, 2.4059864e-01 }, + { 9.6902920e-01, 2.4694616e-01 }, { 9.6739220e-01, 2.5328311e-01 }, + { 9.6571376e-01, 2.5960920e-01 }, { 9.6399395e-01, 2.6592418e-01 }, + { 9.6223284e-01, 2.7222777e-01 }, { 9.6043052e-01, 2.7851969e-01 }, + { 9.5858705e-01, 2.8479968e-01 }, { 9.5670253e-01, 2.9106748e-01 }, + { 9.5477702e-01, 2.9732280e-01 }, { 9.5281061e-01, 3.0356539e-01 }, + { 9.5080338e-01, 3.0979497e-01 }, { 9.4875543e-01, 3.1601129e-01 }, + { 9.4666684e-01, 3.2221406e-01 }, { 9.4453769e-01, 3.2840304e-01 }, + { 9.4236808e-01, 3.3457794e-01 }, { 9.4015810e-01, 3.4073852e-01 }, + { 9.3790786e-01, 3.4688450e-01 }, { 9.3561743e-01, 3.5301562e-01 }, + { 9.3328693e-01, 3.5913161e-01 }, { 9.3091644e-01, 3.6523223e-01 }, + { 9.2850608e-01, 3.7131719e-01 }, { 9.2605595e-01, 3.7738626e-01 }, + { 9.2356614e-01, 3.8343915e-01 }, { 9.2103677e-01, 3.8947562e-01 }, + { 9.1846795e-01, 3.9549541e-01 }, { 9.1585979e-01, 4.0149825e-01 }, + { 9.1321239e-01, 4.0748390e-01 }, { 9.1052587e-01, 4.1345209e-01 }, + { 9.0780035e-01, 4.1940257e-01 }, { 9.0503595e-01, 4.2533508e-01 }, + { 9.0223277e-01, 4.3124938e-01 }, { 8.9939095e-01, 4.3714520e-01 }, + { 8.9651059e-01, 4.4302229e-01 }, { 8.9359184e-01, 4.4888041e-01 }, + { 8.9063481e-01, 4.5471930e-01 }, { 8.8763962e-01, 4.6053871e-01 }, + { 8.8460641e-01, 4.6633839e-01 }, { 8.8153531e-01, 4.7211810e-01 }, + { 8.7842644e-01, 4.7787758e-01 }, { 8.7527995e-01, 4.8361659e-01 }, + { 8.7209596e-01, 4.8933489e-01 }, { 8.6887462e-01, 4.9503222e-01 }, + { 8.6561605e-01, 5.0070835e-01 }, { 8.6232041e-01, 5.0636303e-01 }, + { 8.5898782e-01, 5.1199602e-01 }, { 8.5561844e-01, 5.1760707e-01 }, + { 8.5221241e-01, 5.2319595e-01 }, { 8.4876987e-01, 5.2876243e-01 }, + { 8.4529098e-01, 5.3430625e-01 }, { 8.4177587e-01, 5.3982718e-01 }, + { 8.3822471e-01, 5.4532499e-01 }, { 8.3463763e-01, 5.5079944e-01 }, + { 8.3101481e-01, 5.5625029e-01 }, { 8.2735639e-01, 5.6167732e-01 }, + { 8.2366252e-01, 5.6708028e-01 }, { 8.1993338e-01, 5.7245896e-01 }, + { 8.1616911e-01, 5.7781311e-01 }, { 8.1236987e-01, 5.8314251e-01 }, + { 8.0853584e-01, 5.8844693e-01 }, { 8.0466718e-01, 5.9372614e-01 }, + { 8.0076404e-01, 5.9897992e-01 }, { 7.9682660e-01, 6.0420805e-01 }, + { 7.9285503e-01, 6.0941029e-01 }, { 7.8884950e-01, 6.1458642e-01 }, + { 7.8481017e-01, 6.1973623e-01 }, { 7.8073723e-01, 6.2485949e-01 }, + { 7.7663084e-01, 6.2995598e-01 }, { 7.7249118e-01, 6.3502549e-01 }, + { 7.6831844e-01, 6.4006780e-01 }, { 7.6411277e-01, 6.4508268e-01 }, + { 7.5987438e-01, 6.5006994e-01 }, { 7.5560344e-01, 6.5502934e-01 }, + { 7.5130013e-01, 6.5996069e-01 }, { 7.4696464e-01, 6.6486377e-01 }, + { 7.4259715e-01, 6.6973837e-01 }, { 7.3819784e-01, 6.7458427e-01 }, + { 7.3376692e-01, 6.7940128e-01 }, { 7.2930457e-01, 6.8418919e-01 }, + { 7.2481097e-01, 6.8894779e-01 }, { 7.2028632e-01, 6.9367688e-01 }, + { 7.1573083e-01, 6.9837625e-01 }, { 7.1114467e-01, 7.0304571e-01 }, + { 7.0652804e-01, 7.0768504e-01 }, { 7.0188116e-01, 7.1229407e-01 }, + { 6.9720420e-01, 7.1687258e-01 }, { 6.9249738e-01, 7.2142039e-01 }, + { 6.8776090e-01, 7.2593729e-01 }, { 6.8299495e-01, 7.3042309e-01 }, + { 6.7819975e-01, 7.3487761e-01 }, { 6.7337550e-01, 7.3930064e-01 }, + { 6.6852240e-01, 7.4369201e-01 }, { 6.6364066e-01, 7.4805152e-01 }, + { 6.5873050e-01, 7.5237898e-01 }, { 6.5379211e-01, 7.5667422e-01 }, + { 6.4882573e-01, 7.6093704e-01 }, { 6.4383154e-01, 7.6516727e-01 }, + { 6.3880978e-01, 7.6936471e-01 }, { 6.3376065e-01, 7.7352921e-01 }, + { 6.2868438e-01, 7.7766056e-01 }, { 6.2358117e-01, 7.8175861e-01 }, + { 6.1845126e-01, 7.8582316e-01 }, { 6.1329485e-01, 7.8985406e-01 }, + { 6.0811216e-01, 7.9385112e-01 }, { 6.0290343e-01, 7.9781417e-01 }, + { 5.9766888e-01, 8.0174305e-01 }, { 5.9240872e-01, 8.0563758e-01 }, + { 5.8712318e-01, 8.0949760e-01 }, { 5.8181249e-01, 8.1332295e-01 }, + { 5.7647688e-01, 8.1711346e-01 }, { 5.7111658e-01, 8.2086896e-01 }, + { 5.6573181e-01, 8.2458930e-01 }, { 5.6032281e-01, 8.2827432e-01 }, + { 5.5488980e-01, 8.3192386e-01 }, { 5.4943303e-01, 8.3553776e-01 }, + { 5.4395272e-01, 8.3911587e-01 }, { 5.3844911e-01, 8.4265803e-01 }, + { 5.3292243e-01, 8.4616410e-01 }, { 5.2737292e-01, 8.4963392e-01 }, + { 5.2180083e-01, 8.5306735e-01 }, { 5.1620638e-01, 8.5646423e-01 }, + { 5.1058981e-01, 8.5982442e-01 }, { 5.0495138e-01, 8.6314779e-01 }, + { 4.9929132e-01, 8.6643418e-01 }, { 4.9360987e-01, 8.6968345e-01 }, + { 4.8790727e-01, 8.7289547e-01 }, { 4.8218377e-01, 8.7607009e-01 }, + { 4.7643962e-01, 8.7920719e-01 }, { 4.7067506e-01, 8.8230663e-01 }, + { 4.6489034e-01, 8.8536827e-01 }, { 4.5908570e-01, 8.8839199e-01 }, + { 4.5326139e-01, 8.9137765e-01 }, { 4.4741768e-01, 8.9432512e-01 }, + { 4.4155479e-01, 8.9723429e-01 }, { 4.3567299e-01, 9.0010502e-01 }, + { 4.2977253e-01, 9.0293719e-01 }, { 4.2385365e-01, 9.0573069e-01 }, + { 4.1791662e-01, 9.0848539e-01 }, { 4.1196169e-01, 9.1120117e-01 }, + { 4.0598911e-01, 9.1387791e-01 }, { 3.9999914e-01, 9.1651551e-01 }, + { 3.9399204e-01, 9.1911385e-01 }, { 3.8796806e-01, 9.2167282e-01 }, + { 3.8192746e-01, 9.2419231e-01 }, { 3.7587050e-01, 9.2667220e-01 }, + { 3.6979743e-01, 9.2911240e-01 }, { 3.6370853e-01, 9.3151280e-01 }, + { 3.5760405e-01, 9.3387330e-01 }, { 3.5148424e-01, 9.3619380e-01 }, + { 3.4534939e-01, 9.3847419e-01 }, { 3.3919973e-01, 9.4071438e-01 }, + { 3.3303555e-01, 9.4291427e-01 }, { 3.2685710e-01, 9.4507377e-01 }, + { 3.2066465e-01, 9.4719279e-01 }, { 3.1445847e-01, 9.4927123e-01 }, + { 3.0823881e-01, 9.5130901e-01 }, { 3.0200595e-01, 9.5330604e-01 }, + { 2.9576015e-01, 9.5526223e-01 }, { 2.8950169e-01, 9.5717750e-01 }, + { 2.8323082e-01, 9.5905177e-01 }, { 2.7694782e-01, 9.6088496e-01 }, + { 2.7065295e-01, 9.6267699e-01 }, { 2.6434649e-01, 9.6442777e-01 }, + { 2.5802871e-01, 9.6613725e-01 }, { 2.5169988e-01, 9.6780534e-01 }, + { 2.4536026e-01, 9.6943197e-01 }, { 2.3901013e-01, 9.7101707e-01 }, + { 2.3264977e-01, 9.7256058e-01 }, { 2.2627944e-01, 9.7406243e-01 }, + { 2.1989941e-01, 9.7552255e-01 }, { 2.1350997e-01, 9.7694089e-01 }, + { 2.0711138e-01, 9.7831737e-01 }, { 2.0070391e-01, 9.7965195e-01 }, + { 1.9428785e-01, 9.8094456e-01 }, { 1.8786347e-01, 9.8219515e-01 }, + { 1.8143104e-01, 9.8340367e-01 }, { 1.7499084e-01, 9.8457006e-01 }, + { 1.6854314e-01, 9.8569428e-01 }, { 1.6208822e-01, 9.8677627e-01 }, + { 1.5562636e-01, 9.8781599e-01 }, { 1.4915783e-01, 9.8881340e-01 }, + { 1.4268292e-01, 9.8976845e-01 }, { 1.3620189e-01, 9.9068110e-01 }, + { 1.2971502e-01, 9.9155132e-01 }, { 1.2322260e-01, 9.9237906e-01 }, + { 1.1672491e-01, 9.9316428e-01 }, { 1.1022221e-01, 9.9390697e-01 }, + { 1.0371479e-01, 9.9460708e-01 }, { 9.7202924e-02, 9.9526458e-01 }, + { 9.0686897e-02, 9.9587945e-01 }, { 8.4166986e-02, 9.9645166e-01 }, + { 7.7643468e-02, 9.9698119e-01 }, { 7.1116625e-02, 9.9746801e-01 }, + { 6.4586736e-02, 9.9791210e-01 }, { 5.8054080e-02, 9.9831344e-01 }, + { 5.1518937e-02, 9.9867202e-01 }, { 4.4981587e-02, 9.9898782e-01 }, + { 3.8442310e-02, 9.9926082e-01 }, { 3.1901387e-02, 9.9949102e-01 }, + { 2.5359097e-02, 9.9967841e-01 }, { 1.8815721e-02, 9.9982297e-01 }, + { 1.2271538e-02, 9.9992470e-01 }, { 5.7268303e-03, 9.9998360e-01 }, + } +}; + +const struct lc3_mdct_rot_def * lc3_mdct_rot[LC3_NUM_DT][LC3_NUM_SRATE] = { + [LC3_DT_7M5] = { &mdct_rot_120, &mdct_rot_240, &mdct_rot_360, + &mdct_rot_480, &mdct_rot_720 }, + [LC3_DT_10M] = { &mdct_rot_160, &mdct_rot_320, &mdct_rot_480, + &mdct_rot_640, &mdct_rot_960 } +}; + + +/** + * Low delay MDCT windows (cf. 3.7.3) + */ + +static const float mdct_win_10m_80[80+50] = { + -7.07854671e-04, -2.09819773e-03, -4.52519808e-03, -8.23397633e-03, + -1.33771310e-02, -1.99972156e-02, -2.80090946e-02, -3.72150208e-02, + -4.73176826e-02, -5.79465483e-02, -6.86760675e-02, -7.90464744e-02, + -8.85970547e-02, -9.68830362e-02, -1.03496124e-01, -1.08076646e-01, + -1.10324226e-01, -1.09980985e-01, -1.06817214e-01, -1.00619042e-01, + -9.11645251e-02, -7.82061748e-02, -6.14668812e-02, -4.06336286e-02, + -1.53632952e-02, 1.47015507e-02, 4.98973651e-02, 9.05036926e-02, + 1.36691102e-01, 1.88468639e-01, 2.45645680e-01, 3.07778908e-01, + 3.74164237e-01, 4.43811480e-01, 5.15473546e-01, 5.87666172e-01, + 6.58761977e-01, 7.27057670e-01, 7.90875299e-01, 8.48664336e-01, + 8.99132024e-01, 9.41334815e-01, 9.74763483e-01, 9.99411473e-01, + 1.01576037e+00, 1.02473616e+00, 1.02763429e+00, 1.02599149e+00, + 1.02142721e+00, 1.01543986e+00, 1.00936693e+00, 1.00350816e+00, + 9.98889821e-01, 9.95313390e-01, 9.92594392e-01, 9.90577196e-01, + 9.89137162e-01, 9.88179075e-01, 9.87624927e-01, 9.87405628e-01, + 9.87452485e-01, 9.87695113e-01, 9.88064062e-01, 9.88492687e-01, + 9.88923003e-01, 9.89307497e-01, 9.89614633e-01, 9.89831927e-01, + 9.89969310e-01, 9.90060335e-01, 9.90157502e-01, 9.90325529e-01, + 9.90630379e-01, 9.91129889e-01, 9.91866549e-01, 9.92861973e-01, + 9.94115607e-01, 9.95603378e-01, 9.97279311e-01, 9.99078484e-01, + 1.00092237e+00, 1.00272811e+00, 1.00441604e+00, 1.00591922e+00, + 1.00718935e+00, 1.00820015e+00, 1.00894949e+00, 1.00945824e+00, + 1.00976898e+00, 1.00994034e+00, 1.01003945e+00, 1.01013232e+00, + 1.01027252e+00, 1.01049435e+00, 1.01080807e+00, 1.01120107e+00, + 1.01164127e+00, 1.01208013e+00, 1.01245818e+00, 1.01270696e+00, + 1.01275501e+00, 1.01253013e+00, 1.01196233e+00, 1.01098214e+00, + 1.00951244e+00, 1.00746086e+00, 1.00470868e+00, 1.00111141e+00, + 9.96504102e-01, 9.90720000e-01, 9.82376587e-01, 9.70882175e-01, + 9.54673298e-01, 9.32155386e-01, 9.01800368e-01, 8.62398408e-01, + 8.13281737e-01, 7.54455197e-01, 6.86658072e-01, 6.11348804e-01, + 5.30618165e-01, 4.47130985e-01, 3.63911468e-01, 2.84164703e-01, + 2.11020945e-01, 1.47228797e-01, 9.48266535e-02, 5.48243661e-02, + 2.70146141e-02, 9.99674359e-03, +}; + +static const float mdct_win_10m_160[160+100] = { + -4.61989875e-04, -9.74716672e-04, -1.66447310e-03, -2.59710692e-03, + -3.80628516e-03, -5.32460872e-03, -7.17588528e-03, -9.38248086e-03, + -1.19527030e-02, -1.48952816e-02, -1.82066640e-02, -2.18757093e-02, + -2.58847194e-02, -3.02086274e-02, -3.48159779e-02, -3.96706799e-02, + -4.47269805e-02, -4.99422586e-02, -5.52633479e-02, -6.06371724e-02, + -6.60096152e-02, -7.13196627e-02, -7.65117823e-02, -8.15296401e-02, + -8.63113754e-02, -9.08041129e-02, -9.49537776e-02, -9.87073651e-02, + -1.02020268e-01, -1.04843883e-01, -1.07138231e-01, -1.08869014e-01, + -1.09996966e-01, -1.10489847e-01, -1.10322584e-01, -1.09462175e-01, + -1.07883429e-01, -1.05561251e-01, -1.02465016e-01, -9.85701457e-02, + -9.38468492e-02, -8.82630999e-02, -8.17879272e-02, -7.43878560e-02, + -6.60218980e-02, -5.66565564e-02, -4.62445689e-02, -3.47458578e-02, + -2.21158161e-02, -8.31042570e-03, 6.71769764e-03, 2.30064206e-02, + 4.06010646e-02, 5.95323909e-02, 7.98335419e-02, 1.01523314e-01, + 1.24617139e-01, 1.49115252e-01, 1.75006740e-01, 2.02269985e-01, + 2.30865538e-01, 2.60736512e-01, 2.91814469e-01, 3.24009570e-01, + 3.57217518e-01, 3.91314689e-01, 4.26157164e-01, 4.61592545e-01, + 4.97447159e-01, 5.33532682e-01, 5.69654673e-01, 6.05608382e-01, + 6.41183084e-01, 6.76165350e-01, 7.10340055e-01, 7.43494372e-01, + 7.75428189e-01, 8.05943723e-01, 8.34858937e-01, 8.62010834e-01, + 8.87259971e-01, 9.10486312e-01, 9.31596250e-01, 9.50522086e-01, + 9.67236671e-01, 9.81739750e-01, 9.94055718e-01, 1.00424751e+00, + 1.01240743e+00, 1.01865099e+00, 1.02311884e+00, 1.02597245e+00, + 1.02739752e+00, 1.02758583e+00, 1.02673867e+00, 1.02506178e+00, + 1.02275651e+00, 1.02000914e+00, 1.01699650e+00, 1.01391595e+00, + 1.01104487e+00, 1.00777386e+00, 1.00484875e+00, 1.00224501e+00, + 9.99939317e-01, 9.97905542e-01, 9.96120338e-01, 9.94559753e-01, + 9.93203161e-01, 9.92029727e-01, 9.91023065e-01, 9.90166895e-01, + 9.89448837e-01, 9.88855636e-01, 9.88377852e-01, 9.88005163e-01, + 9.87729546e-01, 9.87541274e-01, 9.87432981e-01, 9.87394992e-01, + 9.87419705e-01, 9.87497321e-01, 9.87620124e-01, 9.87778192e-01, + 9.87963798e-01, 9.88167801e-01, 9.88383520e-01, 9.88602222e-01, + 9.88818277e-01, 9.89024798e-01, 9.89217866e-01, 9.89392368e-01, + 9.89546334e-01, 9.89677201e-01, 9.89785920e-01, 9.89872536e-01, + 9.89941079e-01, 9.89994556e-01, 9.90039402e-01, 9.90081472e-01, + 9.90129379e-01, 9.90190227e-01, 9.90273445e-01, 9.90386228e-01, + 9.90537983e-01, 9.90734883e-01, 9.90984259e-01, 9.91290512e-01, + 9.91658694e-01, 9.92090615e-01, 9.92588721e-01, 9.93151653e-01, + 9.93779087e-01, 9.94466818e-01, 9.95211663e-01, 9.96006862e-01, + 9.96846133e-01, 9.97720337e-01, 9.98621352e-01, 9.99538258e-01, + 1.00046196e+00, 1.00138055e+00, 1.00228487e+00, 1.00316385e+00, + 1.00400915e+00, 1.00481138e+00, 1.00556397e+00, 1.00625986e+00, + 1.00689557e+00, 1.00746662e+00, 1.00797244e+00, 1.00841147e+00, + 1.00878601e+00, 1.00909776e+00, 1.00935176e+00, 1.00955240e+00, + 1.00970709e+00, 1.00982209e+00, 1.00990696e+00, 1.00996902e+00, + 1.01001789e+00, 1.01006081e+00, 1.01010656e+00, 1.01016113e+00, + 1.01023108e+00, 1.01031948e+00, 1.01043047e+00, 1.01056410e+00, + 1.01072136e+00, 1.01089966e+00, 1.01109699e+00, 1.01130817e+00, + 1.01152919e+00, 1.01175301e+00, 1.01197388e+00, 1.01218284e+00, + 1.01237303e+00, 1.01253506e+00, 1.01266098e+00, 1.01274058e+00, + 1.01276592e+00, 1.01272696e+00, 1.01261590e+00, 1.01242289e+00, + 1.01214046e+00, 1.01175881e+00, 1.01126996e+00, 1.01066368e+00, + 1.00993075e+00, 1.00905825e+00, 1.00803431e+00, 1.00684335e+00, + 1.00547001e+00, 1.00389477e+00, 1.00209885e+00, 1.00006069e+00, + 9.97760020e-01, 9.95174643e-01, 9.92286108e-01, 9.89075787e-01, + 9.84736245e-01, 9.79861353e-01, 9.74137862e-01, 9.67333198e-01, + 9.59253976e-01, 9.49698408e-01, 9.38463416e-01, 9.25356797e-01, + 9.10198679e-01, 8.92833832e-01, 8.73143784e-01, 8.51042044e-01, + 8.26483991e-01, 7.99468149e-01, 7.70043128e-01, 7.38302860e-01, + 7.04381434e-01, 6.68461648e-01, 6.30775533e-01, 5.91579959e-01, + 5.51170316e-01, 5.09891542e-01, 4.68101711e-01, 4.26177297e-01, + 3.84517234e-01, 3.43522867e-01, 3.03600465e-01, 2.65143468e-01, + 2.28528397e-01, 1.94102191e-01, 1.62173542e-01, 1.33001524e-01, + 1.06784043e-01, 8.36505724e-02, 6.36518811e-02, 4.67653841e-02, + 3.28807275e-02, 2.18305756e-02, 1.33638143e-02, 6.75812489e-03, +}; + +static const float mdct_win_10m_240[240+150] = { + -3.61349642e-04, -7.07854671e-04, -1.07444364e-03, -1.53347854e-03, + -2.09819773e-03, -2.77842087e-03, -3.58412992e-03, -4.52519808e-03, + -5.60932724e-03, -6.84323454e-03, -8.23397633e-03, -9.78531476e-03, + -1.14988030e-02, -1.33771310e-02, -1.54218168e-02, -1.76297991e-02, + -1.99972156e-02, -2.25208056e-02, -2.51940630e-02, -2.80090946e-02, + -3.09576509e-02, -3.40299627e-02, -3.72150208e-02, -4.05005325e-02, + -4.38721922e-02, -4.73176826e-02, -5.08232534e-02, -5.43716664e-02, + -5.79465483e-02, -6.15342620e-02, -6.51170816e-02, -6.86760675e-02, + -7.21944781e-02, -7.56569598e-02, -7.90464744e-02, -8.23444256e-02, + -8.55332458e-02, -8.85970547e-02, -9.15209110e-02, -9.42884745e-02, + -9.68830362e-02, -9.92912326e-02, -1.01500847e-01, -1.03496124e-01, + -1.05263700e-01, -1.06793998e-01, -1.08076646e-01, -1.09099730e-01, + -1.09852449e-01, -1.10324226e-01, -1.10508462e-01, -1.10397741e-01, + -1.09980985e-01, -1.09249277e-01, -1.08197423e-01, -1.06817214e-01, + -1.05099580e-01, -1.03036011e-01, -1.00619042e-01, -9.78412002e-02, + -9.46930422e-02, -9.11645251e-02, -8.72464453e-02, -8.29304391e-02, + -7.82061748e-02, -7.30614243e-02, -6.74846818e-02, -6.14668812e-02, + -5.49949726e-02, -4.80544442e-02, -4.06336286e-02, -3.27204559e-02, + -2.43012258e-02, -1.53632952e-02, -5.89143427e-03, 4.12659586e-03, + 1.47015507e-02, 2.58473819e-02, 3.75765277e-02, 4.98973651e-02, + 6.28203403e-02, 7.63539773e-02, 9.05036926e-02, 1.05274712e-01, + 1.20670347e-01, 1.36691102e-01, 1.53334389e-01, 1.70595471e-01, + 1.88468639e-01, 2.06944996e-01, 2.26009300e-01, 2.45645680e-01, + 2.65834602e-01, 2.86554381e-01, 3.07778908e-01, 3.29476944e-01, + 3.51617148e-01, 3.74164237e-01, 3.97073959e-01, 4.20304305e-01, + 4.43811480e-01, 4.67544229e-01, 4.91449863e-01, 5.15473546e-01, + 5.39555764e-01, 5.63639982e-01, 5.87666172e-01, 6.11569531e-01, + 6.35289059e-01, 6.58761977e-01, 6.81923097e-01, 7.04709282e-01, + 7.27057670e-01, 7.48906896e-01, 7.70199019e-01, 7.90875299e-01, + 8.10878869e-01, 8.30157914e-01, 8.48664336e-01, 8.66354816e-01, + 8.83189685e-01, 8.99132024e-01, 9.14154056e-01, 9.28228255e-01, + 9.41334815e-01, 9.53461939e-01, 9.64604825e-01, 9.74763483e-01, + 9.83943539e-01, 9.92152910e-01, 9.99411473e-01, 1.00574608e+00, + 1.01118397e+00, 1.01576037e+00, 1.01951507e+00, 1.02249094e+00, + 1.02473616e+00, 1.02630410e+00, 1.02725098e+00, 1.02763429e+00, + 1.02751106e+00, 1.02694280e+00, 1.02599149e+00, 1.02471615e+00, + 1.02317598e+00, 1.02142721e+00, 1.01952157e+00, 1.01751012e+00, + 1.01543986e+00, 1.01346092e+00, 1.01165490e+00, 1.00936693e+00, + 1.00726318e+00, 1.00531319e+00, 1.00350816e+00, 1.00184079e+00, + 1.00030393e+00, 9.98889821e-01, 9.97591528e-01, 9.96401528e-01, + 9.95313390e-01, 9.94320108e-01, 9.93415896e-01, 9.92594392e-01, + 9.91851028e-01, 9.91179799e-01, 9.90577196e-01, 9.90038105e-01, + 9.89559439e-01, 9.89137162e-01, 9.88768437e-01, 9.88449792e-01, + 9.88179075e-01, 9.87952836e-01, 9.87769137e-01, 9.87624927e-01, + 9.87517995e-01, 9.87445813e-01, 9.87405628e-01, 9.87395112e-01, + 9.87411537e-01, 9.87452485e-01, 9.87514989e-01, 9.87596889e-01, + 9.87695113e-01, 9.87807582e-01, 9.87931200e-01, 9.88064062e-01, + 9.88203257e-01, 9.88347108e-01, 9.88492687e-01, 9.88638659e-01, + 9.88782558e-01, 9.88923003e-01, 9.89058172e-01, 9.89186767e-01, + 9.89307497e-01, 9.89419640e-01, 9.89522076e-01, 9.89614633e-01, + 9.89697035e-01, 9.89769260e-01, 9.89831927e-01, 9.89885257e-01, + 9.89930764e-01, 9.89969310e-01, 9.90002569e-01, 9.90032156e-01, + 9.90060335e-01, 9.90088981e-01, 9.90120659e-01, 9.90157502e-01, + 9.90202395e-01, 9.90257541e-01, 9.90325529e-01, 9.90408791e-01, + 9.90509649e-01, 9.90630379e-01, 9.90772711e-01, 9.90938744e-01, + 9.91129889e-01, 9.91347632e-01, 9.91592856e-01, 9.91866549e-01, + 9.92169132e-01, 9.92501085e-01, 9.92861973e-01, 9.93251918e-01, + 9.93670021e-01, 9.94115607e-01, 9.94587315e-01, 9.95083740e-01, + 9.95603378e-01, 9.96143992e-01, 9.96703453e-01, 9.97279311e-01, + 9.97869086e-01, 9.98469709e-01, 9.99078484e-01, 9.99691901e-01, + 1.00030819e+00, 1.00092237e+00, 1.00153264e+00, 1.00213546e+00, + 1.00272811e+00, 1.00330745e+00, 1.00387093e+00, 1.00441604e+00, + 1.00494055e+00, 1.00544214e+00, 1.00591922e+00, 1.00637030e+00, + 1.00679393e+00, 1.00718935e+00, 1.00755557e+00, 1.00789267e+00, + 1.00820015e+00, 1.00847842e+00, 1.00872788e+00, 1.00894949e+00, + 1.00914411e+00, 1.00931322e+00, 1.00945824e+00, 1.00958128e+00, + 1.00968409e+00, 1.00976898e+00, 1.00983831e+00, 1.00989455e+00, + 1.00994034e+00, 1.00997792e+00, 1.01001023e+00, 1.01003945e+00, + 1.01006820e+00, 1.01009839e+00, 1.01013232e+00, 1.01017166e+00, + 1.01021810e+00, 1.01027252e+00, 1.01033649e+00, 1.01041022e+00, + 1.01049435e+00, 1.01058887e+00, 1.01069350e+00, 1.01080807e+00, + 1.01093144e+00, 1.01106288e+00, 1.01120107e+00, 1.01134470e+00, + 1.01149190e+00, 1.01164127e+00, 1.01179028e+00, 1.01193757e+00, + 1.01208013e+00, 1.01221624e+00, 1.01234291e+00, 1.01245818e+00, + 1.01255888e+00, 1.01264286e+00, 1.01270696e+00, 1.01274895e+00, + 1.01276580e+00, 1.01275501e+00, 1.01271380e+00, 1.01263978e+00, + 1.01253013e+00, 1.01238231e+00, 1.01219407e+00, 1.01196233e+00, + 1.01168517e+00, 1.01135914e+00, 1.01098214e+00, 1.01055072e+00, + 1.01006213e+00, 1.00951244e+00, 1.00889869e+00, 1.00821592e+00, + 1.00746086e+00, 1.00662774e+00, 1.00571234e+00, 1.00470868e+00, + 1.00361147e+00, 1.00241429e+00, 1.00111141e+00, 9.99696165e-01, + 9.98162595e-01, 9.96504102e-01, 9.94714888e-01, 9.92789191e-01, + 9.90720000e-01, 9.88479371e-01, 9.85534766e-01, 9.82376587e-01, + 9.78974733e-01, 9.75162381e-01, 9.70882175e-01, 9.66080552e-01, + 9.60697640e-01, 9.54673298e-01, 9.47947935e-01, 9.40460905e-01, + 9.32155386e-01, 9.22977548e-01, 9.12874535e-01, 9.01800368e-01, + 8.89716328e-01, 8.76590897e-01, 8.62398408e-01, 8.47120080e-01, + 8.30747973e-01, 8.13281737e-01, 7.94729145e-01, 7.75110884e-01, + 7.54455197e-01, 7.32796355e-01, 7.10179084e-01, 6.86658072e-01, + 6.62296243e-01, 6.37168412e-01, 6.11348804e-01, 5.84920660e-01, + 5.57974743e-01, 5.30618165e-01, 5.02952396e-01, 4.75086883e-01, + 4.47130985e-01, 4.19204992e-01, 3.91425291e-01, 3.63911468e-01, + 3.36783777e-01, 3.10162784e-01, 2.84164703e-01, 2.58903371e-01, + 2.34488060e-01, 2.11020945e-01, 1.88599764e-01, 1.67310081e-01, + 1.47228797e-01, 1.28422307e-01, 1.10942255e-01, 9.48266535e-02, + 8.00991437e-02, 6.67676585e-02, 5.48243661e-02, 4.42458885e-02, + 3.49936100e-02, 2.70146141e-02, 2.02437018e-02, 1.46079676e-02, + 9.99674359e-03, 5.30523510e-03, +}; + +static const float mdct_win_10m_320[320+200] = { + -3.02115349e-04, -5.86773749e-04, -8.36650400e-04, -1.12663536e-03, + -1.47049294e-03, -1.87347339e-03, -2.33929236e-03, -2.87200807e-03, + -3.47625639e-03, -4.15596382e-03, -4.91456379e-03, -5.75517250e-03, + -6.68062338e-03, -7.69381692e-03, -8.79676075e-03, -9.99050307e-03, + -1.12757412e-02, -1.26533415e-02, -1.41243899e-02, -1.56888962e-02, + -1.73451209e-02, -1.90909737e-02, -2.09254671e-02, -2.28468479e-02, + -2.48520772e-02, -2.69374670e-02, -2.90995249e-02, -3.13350463e-02, + -3.36396073e-02, -3.60082097e-02, -3.84360174e-02, -4.09174603e-02, + -4.34465489e-02, -4.60178672e-02, -4.86259851e-02, -5.12647420e-02, + -5.39264475e-02, -5.66038431e-02, -5.92911675e-02, -6.19826820e-02, + -6.46702555e-02, -6.73454222e-02, -7.00009902e-02, -7.26305701e-02, + -7.52278496e-02, -7.77852594e-02, -8.02948025e-02, -8.27492454e-02, + -8.51412546e-02, -8.74637912e-02, -8.97106934e-02, -9.18756408e-02, + -9.39517698e-02, -9.59313774e-02, -9.78084326e-02, -9.95785130e-02, + -1.01236117e-01, -1.02774104e-01, -1.04186122e-01, -1.05468025e-01, + -1.06616088e-01, -1.07625538e-01, -1.08491230e-01, -1.09208742e-01, + -1.09773615e-01, -1.10180886e-01, -1.10427188e-01, -1.10510836e-01, + -1.10428147e-01, -1.10173922e-01, -1.09743736e-01, -1.09135313e-01, + -1.08346734e-01, -1.07373994e-01, -1.06213016e-01, -1.04860615e-01, + -1.03313240e-01, -1.01567316e-01, -9.96200551e-02, -9.74680323e-02, + -9.51072362e-02, -9.25330338e-02, -8.97412522e-02, -8.67287769e-02, + -8.34921384e-02, -8.00263990e-02, -7.63267954e-02, -7.23880616e-02, + -6.82057680e-02, -6.37761143e-02, -5.90938600e-02, -5.41531632e-02, + -4.89481272e-02, -4.34734711e-02, -3.77246130e-02, -3.16958761e-02, + -2.53817983e-02, -1.87768910e-02, -1.18746138e-02, -4.66909925e-03, + 2.84409675e-03, 1.06697612e-02, 1.88135595e-02, 2.72815601e-02, + 3.60781047e-02, 4.52070276e-02, 5.46723880e-02, 6.44786605e-02, + 7.46286220e-02, 8.51249057e-02, 9.59698399e-02, 1.07165078e-01, + 1.18711585e-01, 1.30610107e-01, 1.42859645e-01, 1.55458473e-01, + 1.68404161e-01, 1.81694789e-01, 1.95327388e-01, 2.09296321e-01, + 2.23594564e-01, 2.38216022e-01, 2.53152972e-01, 2.68396157e-01, + 2.83936139e-01, 2.99762426e-01, 3.15861908e-01, 3.32221055e-01, + 3.48826468e-01, 3.65664038e-01, 3.82715297e-01, 3.99961186e-01, + 4.17384327e-01, 4.34966962e-01, 4.52687640e-01, 4.70524201e-01, + 4.88453925e-01, 5.06454555e-01, 5.24500675e-01, 5.42567437e-01, + 5.60631204e-01, 5.78667265e-01, 5.96647704e-01, 6.14545890e-01, + 6.32336194e-01, 6.49992632e-01, 6.67487403e-01, 6.84793267e-01, + 7.01883546e-01, 7.18732254e-01, 7.35312821e-01, 7.51600199e-01, + 7.67569925e-01, 7.83197457e-01, 7.98458386e-01, 8.13329535e-01, + 8.27789227e-01, 8.41817856e-01, 8.55396130e-01, 8.68506898e-01, + 8.81133444e-01, 8.93259678e-01, 9.04874884e-01, 9.15965761e-01, + 9.26521530e-01, 9.36533999e-01, 9.45997703e-01, 9.54908841e-01, + 9.63265812e-01, 9.71068890e-01, 9.78320416e-01, 9.85022676e-01, + 9.91179208e-01, 9.96798994e-01, 1.00189402e+00, 1.00647434e+00, + 1.01055206e+00, 1.01414254e+00, 1.01726259e+00, 1.01992884e+00, + 1.02215987e+00, 1.02397632e+00, 1.02540073e+00, 1.02645534e+00, + 1.02716451e+00, 1.02755273e+00, 1.02764446e+00, 1.02746325e+00, + 1.02703590e+00, 1.02638907e+00, 1.02554820e+00, 1.02453713e+00, + 1.02338080e+00, 1.02210370e+00, 1.02072836e+00, 1.01927533e+00, + 1.01776518e+00, 1.01621736e+00, 1.01466531e+00, 1.01324907e+00, + 1.01194801e+00, 1.01018909e+00, 1.00855796e+00, 1.00701129e+00, + 1.00554876e+00, 1.00416842e+00, 1.00286727e+00, 1.00164177e+00, + 1.00048907e+00, 9.99406080e-01, 9.98389887e-01, 9.97437085e-01, + 9.96544484e-01, 9.95709855e-01, 9.94930241e-01, 9.94202405e-01, + 9.93524160e-01, 9.92893043e-01, 9.92306810e-01, 9.91763378e-01, + 9.91259764e-01, 9.90795450e-01, 9.90367789e-01, 9.89975161e-01, + 9.89616034e-01, 9.89289016e-01, 9.88992851e-01, 9.88726033e-01, + 9.88486872e-01, 9.88275104e-01, 9.88089217e-01, 9.87927711e-01, + 9.87789826e-01, 9.87674344e-01, 9.87580750e-01, 9.87507202e-01, + 9.87452945e-01, 9.87416974e-01, 9.87398469e-01, 9.87395830e-01, + 9.87408003e-01, 9.87434340e-01, 9.87473624e-01, 9.87524314e-01, + 9.87585620e-01, 9.87656379e-01, 9.87735892e-01, 9.87822558e-01, + 9.87915097e-01, 9.88013273e-01, 9.88115695e-01, 9.88221131e-01, + 9.88328903e-01, 9.88437831e-01, 9.88547679e-01, 9.88656841e-01, + 9.88764587e-01, 9.88870854e-01, 9.88974432e-01, 9.89074727e-01, + 9.89171004e-01, 9.89263102e-01, 9.89350722e-01, 9.89433065e-01, + 9.89509692e-01, 9.89581081e-01, 9.89646747e-01, 9.89706737e-01, + 9.89760693e-01, 9.89809448e-01, 9.89853013e-01, 9.89891471e-01, + 9.89925419e-01, 9.89955420e-01, 9.89982449e-01, 9.90006512e-01, + 9.90028481e-01, 9.90049748e-01, 9.90070956e-01, 9.90092836e-01, + 9.90116392e-01, 9.90142748e-01, 9.90173428e-01, 9.90208733e-01, + 9.90249864e-01, 9.90298369e-01, 9.90354850e-01, 9.90420508e-01, + 9.90495930e-01, 9.90582515e-01, 9.90681257e-01, 9.90792209e-01, + 9.90916546e-01, 9.91055074e-01, 9.91208461e-01, 9.91376861e-01, + 9.91560583e-01, 9.91760421e-01, 9.91976718e-01, 9.92209110e-01, + 9.92457914e-01, 9.92723123e-01, 9.93004954e-01, 9.93302728e-01, + 9.93616108e-01, 9.93945371e-01, 9.94289515e-01, 9.94648168e-01, + 9.95020303e-01, 9.95405817e-01, 9.95803871e-01, 9.96213027e-01, + 9.96632469e-01, 9.97061531e-01, 9.97499058e-01, 9.97943743e-01, + 9.98394057e-01, 9.98849312e-01, 9.99308343e-01, 9.99768922e-01, + 1.00023113e+00, 1.00069214e+00, 1.00115201e+00, 1.00160853e+00, + 1.00206049e+00, 1.00250721e+00, 1.00294713e+00, 1.00337891e+00, + 1.00380137e+00, 1.00421381e+00, 1.00461539e+00, 1.00500462e+00, + 1.00538063e+00, 1.00574328e+00, 1.00609151e+00, 1.00642491e+00, + 1.00674243e+00, 1.00704432e+00, 1.00733022e+00, 1.00759940e+00, + 1.00785206e+00, 1.00808818e+00, 1.00830803e+00, 1.00851125e+00, + 1.00869814e+00, 1.00886952e+00, 1.00902566e+00, 1.00916672e+00, + 1.00929336e+00, 1.00940640e+00, 1.00950702e+00, 1.00959526e+00, + 1.00967215e+00, 1.00973908e+00, 1.00979668e+00, 1.00984614e+00, + 1.00988808e+00, 1.00992409e+00, 1.00995538e+00, 1.00998227e+00, + 1.01000630e+00, 1.01002862e+00, 1.01005025e+00, 1.01007195e+00, + 1.01009437e+00, 1.01011892e+00, 1.01014650e+00, 1.01017711e+00, + 1.01021176e+00, 1.01025100e+00, 1.01029547e+00, 1.01034523e+00, + 1.01040032e+00, 1.01046156e+00, 1.01052862e+00, 1.01060152e+00, + 1.01067979e+00, 1.01076391e+00, 1.01085343e+00, 1.01094755e+00, + 1.01104595e+00, 1.01114849e+00, 1.01125440e+00, 1.01136308e+00, + 1.01147330e+00, 1.01158500e+00, 1.01169742e+00, 1.01180892e+00, + 1.01191926e+00, 1.01202724e+00, 1.01213215e+00, 1.01223273e+00, + 1.01232756e+00, 1.01241638e+00, 1.01249789e+00, 1.01257043e+00, + 1.01263330e+00, 1.01268528e+00, 1.01272556e+00, 1.01275258e+00, + 1.01276506e+00, 1.01276236e+00, 1.01274338e+00, 1.01270648e+00, + 1.01265084e+00, 1.01257543e+00, 1.01247947e+00, 1.01236111e+00, + 1.01221981e+00, 1.01205436e+00, 1.01186400e+00, 1.01164722e+00, + 1.01140252e+00, 1.01112965e+00, 1.01082695e+00, 1.01049292e+00, + 1.01012635e+00, 1.00972589e+00, 1.00929006e+00, 1.00881730e+00, + 1.00830503e+00, 1.00775283e+00, 1.00715783e+00, 1.00651805e+00, + 1.00583140e+00, 1.00509559e+00, 1.00430863e+00, 1.00346750e+00, + 1.00256950e+00, 1.00161271e+00, 1.00059427e+00, 9.99511170e-01, + 9.98360922e-01, 9.97140929e-01, 9.95848886e-01, 9.94481854e-01, + 9.93037528e-01, 9.91514656e-01, 9.89913680e-01, 9.88193062e-01, + 9.85942259e-01, 9.83566790e-01, 9.81142303e-01, 9.78521444e-01, + 9.75663604e-01, 9.72545344e-01, 9.69145663e-01, 9.65440618e-01, + 9.61404362e-01, 9.57011307e-01, 9.52236767e-01, 9.47054884e-01, + 9.41440374e-01, 9.35369161e-01, 9.28819009e-01, 9.21766289e-01, + 9.14189628e-01, 9.06069468e-01, 8.97389168e-01, 8.88133200e-01, + 8.78289389e-01, 8.67846957e-01, 8.56797064e-01, 8.45133465e-01, + 8.32854281e-01, 8.19959478e-01, 8.06451101e-01, 7.92334648e-01, + 7.77620449e-01, 7.62320618e-01, 7.46448649e-01, 7.30020573e-01, + 7.13056738e-01, 6.95580544e-01, 6.77617323e-01, 6.59195531e-01, + 6.40348643e-01, 6.21107220e-01, 6.01504928e-01, 5.81578761e-01, + 5.61367451e-01, 5.40918863e-01, 5.20273683e-01, 4.99478073e-01, + 4.78577418e-01, 4.57617260e-01, 4.36649021e-01, 4.15722146e-01, + 3.94885659e-01, 3.74190319e-01, 3.53686890e-01, 3.33426002e-01, + 3.13458647e-01, 2.93833790e-01, 2.74599264e-01, 2.55803064e-01, + 2.37490219e-01, 2.19703603e-01, 2.02485542e-01, 1.85874992e-01, + 1.69906780e-01, 1.54613227e-01, 1.40023821e-01, 1.26163740e-01, + 1.13053443e-01, 1.00708497e-01, 8.91402439e-02, 7.83561210e-02, + 6.83582123e-02, 5.91421154e-02, 5.06989301e-02, 4.30171776e-02, + 3.60802073e-02, 2.98631634e-02, 2.43372266e-02, 1.94767524e-02, + 1.52571017e-02, 1.16378749e-02, 8.43308778e-03, 4.44966900e-03, +}; + +static const float mdct_win_10m_480[480+300] = { + -2.35303215e-04, -4.61989875e-04, -6.26293154e-04, -7.92918043e-04, + -9.74716672e-04, -1.18025689e-03, -1.40920904e-03, -1.66447310e-03, + -1.94659161e-03, -2.25708173e-03, -2.59710692e-03, -2.96760762e-03, + -3.37045488e-03, -3.80628516e-03, -4.27687377e-03, -4.78246990e-03, + -5.32460872e-03, -5.90340381e-03, -6.52041973e-03, -7.17588528e-03, + -7.87142282e-03, -8.60658604e-03, -9.38248086e-03, -1.01982718e-02, + -1.10552055e-02, -1.19527030e-02, -1.28920591e-02, -1.38726348e-02, + -1.48952816e-02, -1.59585662e-02, -1.70628856e-02, -1.82066640e-02, + -1.93906598e-02, -2.06135542e-02, -2.18757093e-02, -2.31752632e-02, + -2.45122745e-02, -2.58847194e-02, -2.72926374e-02, -2.87339090e-02, + -3.02086274e-02, -3.17144037e-02, -3.32509886e-02, -3.48159779e-02, + -3.64089241e-02, -3.80274232e-02, -3.96706799e-02, -4.13357542e-02, + -4.30220337e-02, -4.47269805e-02, -4.64502229e-02, -4.81889149e-02, + -4.99422586e-02, -5.17069080e-02, -5.34816204e-02, -5.52633479e-02, + -5.70512315e-02, -5.88427175e-02, -6.06371724e-02, -6.24310403e-02, + -6.42230355e-02, -6.60096152e-02, -6.77896227e-02, -6.95599687e-02, + -7.13196627e-02, -7.30658127e-02, -7.47975891e-02, -7.65117823e-02, + -7.82071142e-02, -7.98801069e-02, -8.15296401e-02, -8.31523735e-02, + -8.47472895e-02, -8.63113754e-02, -8.78437445e-02, -8.93416436e-02, + -9.08041129e-02, -9.22279576e-02, -9.36123287e-02, -9.49537776e-02, + -9.62515531e-02, -9.75028462e-02, -9.87073651e-02, -9.98627129e-02, + -1.00968022e-01, -1.02020268e-01, -1.03018380e-01, -1.03959636e-01, + -1.04843883e-01, -1.05668684e-01, -1.06434282e-01, -1.07138231e-01, + -1.07779996e-01, -1.08357063e-01, -1.08869014e-01, -1.09313559e-01, + -1.09690356e-01, -1.09996966e-01, -1.10233226e-01, -1.10397281e-01, + -1.10489847e-01, -1.10508642e-01, -1.10453743e-01, -1.10322584e-01, + -1.10114583e-01, -1.09827693e-01, -1.09462175e-01, -1.09016396e-01, + -1.08490885e-01, -1.07883429e-01, -1.07193718e-01, -1.06419636e-01, + -1.05561251e-01, -1.04616281e-01, -1.03584904e-01, -1.02465016e-01, + -1.01256900e-01, -9.99586457e-02, -9.85701457e-02, -9.70891114e-02, + -9.55154582e-02, -9.38468492e-02, -9.20830006e-02, -9.02217102e-02, + -8.82630999e-02, -8.62049382e-02, -8.40474215e-02, -8.17879272e-02, + -7.94262503e-02, -7.69598078e-02, -7.43878560e-02, -7.17079700e-02, + -6.89199478e-02, -6.60218980e-02, -6.30134942e-02, -5.98919191e-02, + -5.66565564e-02, -5.33040616e-02, -4.98342724e-02, -4.62445689e-02, + -4.25345569e-02, -3.87019577e-02, -3.47458578e-02, -3.06634152e-02, + -2.64542508e-02, -2.21158161e-02, -1.76474054e-02, -1.30458136e-02, + -8.31042570e-03, -3.43826866e-03, 1.57031548e-03, 6.71769764e-03, + 1.20047702e-02, 1.74339832e-02, 2.30064206e-02, 2.87248142e-02, + 3.45889635e-02, 4.06010646e-02, 4.67610292e-02, 5.30713391e-02, + 5.95323909e-02, 6.61464781e-02, 7.29129318e-02, 7.98335419e-02, + 8.69080741e-02, 9.41381377e-02, 1.01523314e-01, 1.09065152e-01, + 1.16762655e-01, 1.24617139e-01, 1.32627295e-01, 1.40793819e-01, + 1.49115252e-01, 1.57592141e-01, 1.66222480e-01, 1.75006740e-01, + 1.83943194e-01, 1.93031818e-01, 2.02269985e-01, 2.11656743e-01, + 2.21188852e-01, 2.30865538e-01, 2.40683799e-01, 2.50642064e-01, + 2.60736512e-01, 2.70965907e-01, 2.81325902e-01, 2.91814469e-01, + 3.02427028e-01, 3.13160350e-01, 3.24009570e-01, 3.34971959e-01, + 3.46042294e-01, 3.57217518e-01, 3.68491565e-01, 3.79859512e-01, + 3.91314689e-01, 4.02853287e-01, 4.14468833e-01, 4.26157164e-01, + 4.37911390e-01, 4.49725632e-01, 4.61592545e-01, 4.73506703e-01, + 4.85460018e-01, 4.97447159e-01, 5.09459723e-01, 5.21490984e-01, + 5.33532682e-01, 5.45578981e-01, 5.57621716e-01, 5.69654673e-01, + 5.81668558e-01, 5.93656062e-01, 6.05608382e-01, 6.17519206e-01, + 6.29379661e-01, 6.41183084e-01, 6.52920354e-01, 6.64584079e-01, + 6.76165350e-01, 6.87657395e-01, 6.99051154e-01, 7.10340055e-01, + 7.21514933e-01, 7.32569177e-01, 7.43494372e-01, 7.54284633e-01, + 7.64931365e-01, 7.75428189e-01, 7.85767017e-01, 7.95941465e-01, + 8.05943723e-01, 8.15768707e-01, 8.25408622e-01, 8.34858937e-01, + 8.44112583e-01, 8.53165119e-01, 8.62010834e-01, 8.70645634e-01, + 8.79063156e-01, 8.87259971e-01, 8.95231329e-01, 9.02975168e-01, + 9.10486312e-01, 9.17762555e-01, 9.24799743e-01, 9.31596250e-01, + 9.38149486e-01, 9.44458839e-01, 9.50522086e-01, 9.56340292e-01, + 9.61911452e-01, 9.67236671e-01, 9.72315664e-01, 9.77150119e-01, + 9.81739750e-01, 9.86086587e-01, 9.90190638e-01, 9.94055718e-01, + 9.97684240e-01, 1.00108096e+00, 1.00424751e+00, 1.00718858e+00, + 1.00990665e+00, 1.01240743e+00, 1.01469470e+00, 1.01677466e+00, + 1.01865099e+00, 1.02033046e+00, 1.02181733e+00, 1.02311884e+00, + 1.02424026e+00, 1.02518972e+00, 1.02597245e+00, 1.02659694e+00, + 1.02706918e+00, 1.02739752e+00, 1.02758790e+00, 1.02764895e+00, + 1.02758583e+00, 1.02740852e+00, 1.02712299e+00, 1.02673867e+00, + 1.02626166e+00, 1.02570100e+00, 1.02506178e+00, 1.02435398e+00, + 1.02358239e+00, 1.02275651e+00, 1.02188060e+00, 1.02096387e+00, + 1.02000914e+00, 1.01902729e+00, 1.01801944e+00, 1.01699650e+00, + 1.01595743e+00, 1.01492344e+00, 1.01391595e+00, 1.01304757e+00, + 1.01221613e+00, 1.01104487e+00, 1.00991459e+00, 1.00882489e+00, + 1.00777386e+00, 1.00676170e+00, 1.00578665e+00, 1.00484875e+00, + 1.00394608e+00, 1.00307885e+00, 1.00224501e+00, 1.00144473e+00, + 1.00067619e+00, 9.99939317e-01, 9.99232085e-01, 9.98554813e-01, + 9.97905542e-01, 9.97284268e-01, 9.96689095e-01, 9.96120338e-01, + 9.95576126e-01, 9.95056572e-01, 9.94559753e-01, 9.94086038e-01, + 9.93633779e-01, 9.93203161e-01, 9.92792187e-01, 9.92401518e-01, + 9.92029727e-01, 9.91676778e-01, 9.91340877e-01, 9.91023065e-01, + 9.90721643e-01, 9.90436680e-01, 9.90166895e-01, 9.89913101e-01, + 9.89673564e-01, 9.89448837e-01, 9.89237484e-01, 9.89040193e-01, + 9.88855636e-01, 9.88684347e-01, 9.88524761e-01, 9.88377852e-01, + 9.88242327e-01, 9.88118564e-01, 9.88005163e-01, 9.87903202e-01, + 9.87811174e-01, 9.87729546e-01, 9.87657198e-01, 9.87594984e-01, + 9.87541274e-01, 9.87496906e-01, 9.87460625e-01, 9.87432981e-01, + 9.87412641e-01, 9.87400475e-01, 9.87394992e-01, 9.87396916e-01, + 9.87404906e-01, 9.87419705e-01, 9.87439972e-01, 9.87466328e-01, + 9.87497321e-01, 9.87533893e-01, 9.87574654e-01, 9.87620124e-01, + 9.87668980e-01, 9.87722156e-01, 9.87778192e-01, 9.87837649e-01, + 9.87899199e-01, 9.87963798e-01, 9.88030030e-01, 9.88098468e-01, + 9.88167801e-01, 9.88239030e-01, 9.88310769e-01, 9.88383520e-01, + 9.88456016e-01, 9.88529420e-01, 9.88602222e-01, 9.88674940e-01, + 9.88746626e-01, 9.88818277e-01, 9.88888248e-01, 9.88957438e-01, + 9.89024798e-01, 9.89091125e-01, 9.89155170e-01, 9.89217866e-01, + 9.89277956e-01, 9.89336519e-01, 9.89392368e-01, 9.89446283e-01, + 9.89497212e-01, 9.89546334e-01, 9.89592362e-01, 9.89636265e-01, + 9.89677201e-01, 9.89716220e-01, 9.89752029e-01, 9.89785920e-01, + 9.89817027e-01, 9.89846207e-01, 9.89872536e-01, 9.89897514e-01, + 9.89920005e-01, 9.89941079e-01, 9.89960061e-01, 9.89978226e-01, + 9.89994556e-01, 9.90010350e-01, 9.90024832e-01, 9.90039402e-01, + 9.90053211e-01, 9.90067475e-01, 9.90081472e-01, 9.90096693e-01, + 9.90112245e-01, 9.90129379e-01, 9.90147465e-01, 9.90168060e-01, + 9.90190227e-01, 9.90215190e-01, 9.90242442e-01, 9.90273445e-01, + 9.90307127e-01, 9.90344891e-01, 9.90386228e-01, 9.90432448e-01, + 9.90482565e-01, 9.90537983e-01, 9.90598060e-01, 9.90664037e-01, + 9.90734883e-01, 9.90812038e-01, 9.90894786e-01, 9.90984259e-01, + 9.91079525e-01, 9.91181924e-01, 9.91290512e-01, 9.91406471e-01, + 9.91528801e-01, 9.91658694e-01, 9.91795272e-01, 9.91939622e-01, + 9.92090615e-01, 9.92249503e-01, 9.92415240e-01, 9.92588721e-01, + 9.92768871e-01, 9.92956911e-01, 9.93151653e-01, 9.93353924e-01, + 9.93562689e-01, 9.93779087e-01, 9.94001643e-01, 9.94231202e-01, + 9.94466818e-01, 9.94709344e-01, 9.94957285e-01, 9.95211663e-01, + 9.95471264e-01, 9.95736795e-01, 9.96006862e-01, 9.96282303e-01, + 9.96561799e-01, 9.96846133e-01, 9.97133827e-01, 9.97425669e-01, + 9.97720337e-01, 9.98018509e-01, 9.98318587e-01, 9.98621352e-01, + 9.98925543e-01, 9.99231731e-01, 9.99538258e-01, 9.99846116e-01, + 1.00015391e+00, 1.00046196e+00, 1.00076886e+00, 1.00107561e+00, + 1.00138055e+00, 1.00168424e+00, 1.00198543e+00, 1.00228487e+00, + 1.00258098e+00, 1.00287441e+00, 1.00316385e+00, 1.00345006e+00, + 1.00373157e+00, 1.00400915e+00, 1.00428146e+00, 1.00454934e+00, + 1.00481138e+00, 1.00506827e+00, 1.00531880e+00, 1.00556397e+00, + 1.00580227e+00, 1.00603455e+00, 1.00625986e+00, 1.00647902e+00, + 1.00669054e+00, 1.00689557e+00, 1.00709305e+00, 1.00728380e+00, + 1.00746662e+00, 1.00764273e+00, 1.00781104e+00, 1.00797244e+00, + 1.00812588e+00, 1.00827260e+00, 1.00841147e+00, 1.00854357e+00, + 1.00866802e+00, 1.00878601e+00, 1.00889653e+00, 1.00900077e+00, + 1.00909776e+00, 1.00918888e+00, 1.00927316e+00, 1.00935176e+00, + 1.00942394e+00, 1.00949118e+00, 1.00955240e+00, 1.00960889e+00, + 1.00965997e+00, 1.00970709e+00, 1.00974924e+00, 1.00978774e+00, + 1.00982209e+00, 1.00985371e+00, 1.00988150e+00, 1.00990696e+00, + 1.00992957e+00, 1.00995057e+00, 1.00996902e+00, 1.00998650e+00, + 1.01000236e+00, 1.01001789e+00, 1.01003217e+00, 1.01004672e+00, + 1.01006081e+00, 1.01007567e+00, 1.01009045e+00, 1.01010656e+00, + 1.01012323e+00, 1.01014176e+00, 1.01016113e+00, 1.01018264e+00, + 1.01020559e+00, 1.01023108e+00, 1.01025795e+00, 1.01028773e+00, + 1.01031948e+00, 1.01035408e+00, 1.01039064e+00, 1.01043047e+00, + 1.01047227e+00, 1.01051710e+00, 1.01056410e+00, 1.01061427e+00, + 1.01066629e+00, 1.01072136e+00, 1.01077842e+00, 1.01083825e+00, + 1.01089966e+00, 1.01096373e+00, 1.01102919e+00, 1.01109699e+00, + 1.01116586e+00, 1.01123661e+00, 1.01130817e+00, 1.01138145e+00, + 1.01145479e+00, 1.01152919e+00, 1.01160368e+00, 1.01167880e+00, + 1.01175301e+00, 1.01182748e+00, 1.01190094e+00, 1.01197388e+00, + 1.01204489e+00, 1.01211499e+00, 1.01218284e+00, 1.01224902e+00, + 1.01231210e+00, 1.01237303e+00, 1.01243046e+00, 1.01248497e+00, + 1.01253506e+00, 1.01258168e+00, 1.01262347e+00, 1.01266098e+00, + 1.01269276e+00, 1.01271979e+00, 1.01274058e+00, 1.01275575e+00, + 1.01276395e+00, 1.01276592e+00, 1.01276030e+00, 1.01274782e+00, + 1.01272696e+00, 1.01269861e+00, 1.01266140e+00, 1.01261590e+00, + 1.01256083e+00, 1.01249705e+00, 1.01242289e+00, 1.01233923e+00, + 1.01224492e+00, 1.01214046e+00, 1.01202430e+00, 1.01189756e+00, + 1.01175881e+00, 1.01160845e+00, 1.01144516e+00, 1.01126996e+00, + 1.01108126e+00, 1.01087961e+00, 1.01066368e+00, 1.01043418e+00, + 1.01018968e+00, 1.00993075e+00, 1.00965566e+00, 1.00936525e+00, + 1.00905825e+00, 1.00873476e+00, 1.00839308e+00, 1.00803431e+00, + 1.00765666e+00, 1.00726014e+00, 1.00684335e+00, 1.00640701e+00, + 1.00594915e+00, 1.00547001e+00, 1.00496799e+00, 1.00444353e+00, + 1.00389477e+00, 1.00332190e+00, 1.00272313e+00, 1.00209885e+00, + 1.00144728e+00, 1.00076851e+00, 1.00006069e+00, 9.99324268e-01, + 9.98557350e-01, 9.97760020e-01, 9.96930604e-01, 9.96069427e-01, + 9.95174643e-01, 9.94246644e-01, 9.93283713e-01, 9.92286108e-01, + 9.91252309e-01, 9.90182742e-01, 9.89075787e-01, 9.87931302e-01, + 9.86355322e-01, 9.84736245e-01, 9.83175095e-01, 9.81558334e-01, + 9.79861353e-01, 9.78061749e-01, 9.76157432e-01, 9.74137862e-01, + 9.71999011e-01, 9.69732741e-01, 9.67333198e-01, 9.64791512e-01, + 9.62101150e-01, 9.59253976e-01, 9.56242718e-01, 9.53060091e-01, + 9.49698408e-01, 9.46149812e-01, 9.42407161e-01, 9.38463416e-01, + 9.34311297e-01, 9.29944987e-01, 9.25356797e-01, 9.20540463e-01, + 9.15489628e-01, 9.10198679e-01, 9.04662060e-01, 8.98875519e-01, + 8.92833832e-01, 8.86533719e-01, 8.79971272e-01, 8.73143784e-01, + 8.66047653e-01, 8.58681252e-01, 8.51042044e-01, 8.43129723e-01, + 8.34943514e-01, 8.26483991e-01, 8.17750537e-01, 8.08744982e-01, + 7.99468149e-01, 7.89923516e-01, 7.80113773e-01, 7.70043128e-01, + 7.59714574e-01, 7.49133097e-01, 7.38302860e-01, 7.27229876e-01, + 7.15920192e-01, 7.04381434e-01, 6.92619693e-01, 6.80643883e-01, + 6.68461648e-01, 6.56083014e-01, 6.43517927e-01, 6.30775533e-01, + 6.17864165e-01, 6.04795463e-01, 5.91579959e-01, 5.78228937e-01, + 5.64753589e-01, 5.51170316e-01, 5.37490509e-01, 5.23726350e-01, + 5.09891542e-01, 4.96000807e-01, 4.82066294e-01, 4.68101711e-01, + 4.54121700e-01, 4.40142182e-01, 4.26177297e-01, 4.12241789e-01, + 3.98349961e-01, 3.84517234e-01, 3.70758372e-01, 3.57088679e-01, + 3.43522867e-01, 3.30076376e-01, 3.16764033e-01, 3.03600465e-01, + 2.90599616e-01, 2.77775850e-01, 2.65143468e-01, 2.52716188e-01, + 2.40506985e-01, 2.28528397e-01, 2.16793343e-01, 2.05313990e-01, + 1.94102191e-01, 1.83168087e-01, 1.72522195e-01, 1.62173542e-01, + 1.52132068e-01, 1.42405280e-01, 1.33001524e-01, 1.23926066e-01, + 1.15185830e-01, 1.06784043e-01, 9.87263751e-02, 9.10137900e-02, + 8.36505724e-02, 7.66350831e-02, 6.99703341e-02, 6.36518811e-02, + 5.76817602e-02, 5.20524422e-02, 4.67653841e-02, 4.18095054e-02, + 3.71864025e-02, 3.28807275e-02, 2.88954850e-02, 2.52098057e-02, + 2.18305756e-02, 1.87289619e-02, 1.59212782e-02, 1.33638143e-02, + 1.10855888e-02, 8.94347419e-03, 6.75812489e-03, 3.50443813e-03, +}; + +static const float mdct_win_7m5_60[60+46] = { + 2.95060859e-03, 7.17541132e-03, 1.37695374e-02, 2.30953556e-02, + 3.54036230e-02, 5.08289304e-02, 6.94696293e-02, 9.13884278e-02, + 1.16604575e-01, 1.45073546e-01, 1.76711174e-01, 2.11342953e-01, + 2.48768614e-01, 2.88701102e-01, 3.30823871e-01, 3.74814544e-01, + 4.20308013e-01, 4.66904918e-01, 5.14185341e-01, 5.61710041e-01, + 6.09026346e-01, 6.55671016e-01, 7.01218384e-01, 7.45240679e-01, + 7.87369206e-01, 8.27223833e-01, 8.64513675e-01, 8.98977415e-01, + 9.30407518e-01, 9.58599937e-01, 9.83447719e-01, 1.00488283e+00, + 1.02285381e+00, 1.03740495e+00, 1.04859791e+00, 1.05656184e+00, + 1.06149371e+00, 1.06362578e+00, 1.06325973e+00, 1.06074505e+00, + 1.05643590e+00, 1.05069500e+00, 1.04392435e+00, 1.03647725e+00, + 1.02872867e+00, 1.02106486e+00, 1.01400658e+00, 1.00727455e+00, + 1.00172250e+00, 9.97309592e-01, 9.93985158e-01, 9.91683335e-01, + 9.90325325e-01, 9.89822613e-01, 9.90074734e-01, 9.90975314e-01, + 9.92412851e-01, 9.94273149e-01, 9.96439157e-01, 9.98791616e-01, + 1.00120985e+00, 1.00357357e+00, 1.00575984e+00, 1.00764515e+00, + 1.00910687e+00, 1.01002476e+00, 1.01028203e+00, 1.00976919e+00, + 1.00838641e+00, 1.00605124e+00, 1.00269767e+00, 9.98280464e-01, + 9.92777987e-01, 9.86186892e-01, 9.77634164e-01, 9.67447270e-01, + 9.55129725e-01, 9.40389877e-01, 9.22959280e-01, 9.02607350e-01, + 8.79202689e-01, 8.52641750e-01, 8.22881272e-01, 7.89971715e-01, + 7.54030328e-01, 7.15255742e-01, 6.73936911e-01, 6.30414716e-01, + 5.85078858e-01, 5.38398518e-01, 4.90833753e-01, 4.42885823e-01, + 3.95091024e-01, 3.48004343e-01, 3.02196710e-01, 2.58227431e-01, + 2.16641416e-01, 1.77922122e-01, 1.42480547e-01, 1.10652194e-01, + 8.26995967e-02, 5.88334516e-02, 3.92030848e-02, 2.38629107e-02, + 1.26976223e-02, 5.35665361e-03, +}; + +static const float mdct_win_7m5_120[120+92] = { + 2.20824874e-03, 3.81014420e-03, 5.91552473e-03, 8.58361457e-03, + 1.18759723e-02, 1.58335301e-02, 2.04918652e-02, 2.58883593e-02, + 3.20415894e-02, 3.89616721e-02, 4.66742169e-02, 5.51849337e-02, + 6.45038384e-02, 7.46411071e-02, 8.56000162e-02, 9.73846703e-02, + 1.09993603e-01, 1.23419277e-01, 1.37655457e-01, 1.52690437e-01, + 1.68513363e-01, 1.85093105e-01, 2.02410419e-01, 2.20450365e-01, + 2.39167941e-01, 2.58526168e-01, 2.78498539e-01, 2.99038432e-01, + 3.20104862e-01, 3.41658622e-01, 3.63660034e-01, 3.86062695e-01, + 4.08815272e-01, 4.31871046e-01, 4.55176988e-01, 4.78676593e-01, + 5.02324813e-01, 5.26060916e-01, 5.49831283e-01, 5.73576883e-01, + 5.97241338e-01, 6.20770242e-01, 6.44099662e-01, 6.67176382e-01, + 6.89958854e-01, 7.12379980e-01, 7.34396372e-01, 7.55966688e-01, + 7.77036981e-01, 7.97558114e-01, 8.17490856e-01, 8.36796950e-01, + 8.55447310e-01, 8.73400798e-01, 8.90635719e-01, 9.07128770e-01, + 9.22848784e-01, 9.37763323e-01, 9.51860206e-01, 9.65130600e-01, + 9.77556541e-01, 9.89126209e-01, 9.99846919e-01, 1.00970073e+00, + 1.01868229e+00, 1.02681455e+00, 1.03408981e+00, 1.04051196e+00, + 1.04610837e+00, 1.05088565e+00, 1.05486289e+00, 1.05807221e+00, + 1.06053414e+00, 1.06227662e+00, 1.06333815e+00, 1.06375557e+00, + 1.06356632e+00, 1.06282156e+00, 1.06155996e+00, 1.05981709e+00, + 1.05765876e+00, 1.05512006e+00, 1.05223985e+00, 1.04908779e+00, + 1.04569860e+00, 1.04210831e+00, 1.03838099e+00, 1.03455276e+00, + 1.03067200e+00, 1.02679167e+00, 1.02295558e+00, 1.01920733e+00, + 1.01587289e+00, 1.01221017e+00, 1.00884559e+00, 1.00577851e+00, + 1.00300262e+00, 1.00051460e+00, 9.98309229e-01, 9.96378601e-01, + 9.94718132e-01, 9.93316216e-01, 9.92166957e-01, 9.91258603e-01, + 9.90581104e-01, 9.90123118e-01, 9.89873712e-01, 9.89818707e-01, + 9.89946800e-01, 9.90243175e-01, 9.90695564e-01, 9.91288540e-01, + 9.92009469e-01, 9.92842693e-01, 9.93775067e-01, 9.94790398e-01, + 9.95875534e-01, 9.97014367e-01, 9.98192871e-01, 9.99394506e-01, + 1.00060586e+00, 1.00181040e+00, 1.00299457e+00, 1.00414155e+00, + 1.00523688e+00, 1.00626393e+00, 1.00720890e+00, 1.00805489e+00, + 1.00878802e+00, 1.00939182e+00, 1.00985296e+00, 1.01015529e+00, + 1.01028602e+00, 1.01022988e+00, 1.00997541e+00, 1.00950846e+00, + 1.00881848e+00, 1.00789488e+00, 1.00672876e+00, 1.00530991e+00, + 1.00363456e+00, 1.00169363e+00, 9.99485663e-01, 9.97006370e-01, + 9.94254687e-01, 9.91231967e-01, 9.87937115e-01, 9.84375125e-01, + 9.79890963e-01, 9.75269879e-01, 9.70180498e-01, 9.64580027e-01, + 9.58425534e-01, 9.51684014e-01, 9.44320232e-01, 9.36290624e-01, + 9.27580507e-01, 9.18153414e-01, 9.07976524e-01, 8.97050058e-01, + 8.85351360e-01, 8.72857927e-01, 8.59579819e-01, 8.45502615e-01, + 8.30619943e-01, 8.14946648e-01, 7.98489378e-01, 7.81262450e-01, + 7.63291769e-01, 7.44590843e-01, 7.25199287e-01, 7.05153668e-01, + 6.84490545e-01, 6.63245210e-01, 6.41477162e-01, 6.19235334e-01, + 5.96559133e-01, 5.73519989e-01, 5.50173851e-01, 5.26568538e-01, + 5.02781159e-01, 4.78860889e-01, 4.54877894e-01, 4.30898123e-01, + 4.06993964e-01, 3.83234031e-01, 3.59680098e-01, 3.36408100e-01, + 3.13496418e-01, 2.91010565e-01, 2.69019585e-01, 2.47584348e-01, + 2.26788433e-01, 2.06677771e-01, 1.87310343e-01, 1.68739644e-01, + 1.51012382e-01, 1.34171842e-01, 1.18254662e-01, 1.03290734e-01, + 8.93117360e-02, 7.63429787e-02, 6.44077291e-02, 5.35243715e-02, + 4.37084453e-02, 3.49667099e-02, 2.72984629e-02, 2.06895808e-02, + 1.51125125e-02, 1.05228754e-02, 6.85547314e-03, 4.02351119e-03, +}; + +static const float mdct_win_7m5_180[180+138] = { + 1.97084908e-03, 2.95060859e-03, 4.12447721e-03, 5.52688664e-03, + 7.17541132e-03, 9.08757730e-03, 1.12819105e-02, 1.37695374e-02, + 1.65600266e-02, 1.96650895e-02, 2.30953556e-02, 2.68612894e-02, + 3.09632560e-02, 3.54036230e-02, 4.01915610e-02, 4.53331403e-02, + 5.08289304e-02, 5.66815448e-02, 6.28935304e-02, 6.94696293e-02, + 7.64106314e-02, 8.37160016e-02, 9.13884278e-02, 9.94294008e-02, + 1.07834725e-01, 1.16604575e-01, 1.25736503e-01, 1.35226811e-01, + 1.45073546e-01, 1.55273819e-01, 1.65822194e-01, 1.76711174e-01, + 1.87928776e-01, 1.99473180e-01, 2.11342953e-01, 2.23524554e-01, + 2.36003100e-01, 2.48768614e-01, 2.61813811e-01, 2.75129161e-01, + 2.88701102e-01, 3.02514034e-01, 3.16558805e-01, 3.30823871e-01, + 3.45295567e-01, 3.59963992e-01, 3.74814544e-01, 3.89831817e-01, + 4.05001010e-01, 4.20308013e-01, 4.35739515e-01, 4.51277817e-01, + 4.66904918e-01, 4.82609041e-01, 4.98375466e-01, 5.14185341e-01, + 5.30021478e-01, 5.45869352e-01, 5.61710041e-01, 5.77528151e-01, + 5.93304696e-01, 6.09026346e-01, 6.24674189e-01, 6.40227555e-01, + 6.55671016e-01, 6.70995935e-01, 6.86184559e-01, 7.01218384e-01, + 7.16078449e-01, 7.30756084e-01, 7.45240679e-01, 7.59515122e-01, + 7.73561955e-01, 7.87369206e-01, 8.00923138e-01, 8.14211386e-01, + 8.27223833e-01, 8.39952374e-01, 8.52386102e-01, 8.64513675e-01, + 8.76324079e-01, 8.87814288e-01, 8.98977415e-01, 9.09803319e-01, + 9.20284312e-01, 9.30407518e-01, 9.40169652e-01, 9.49567795e-01, + 9.58599937e-01, 9.67260260e-01, 9.75545166e-01, 9.83447719e-01, + 9.90971957e-01, 9.98119269e-01, 1.00488283e+00, 1.01125773e+00, + 1.01724436e+00, 1.02285381e+00, 1.02808734e+00, 1.03293706e+00, + 1.03740495e+00, 1.04150164e+00, 1.04523236e+00, 1.04859791e+00, + 1.05160340e+00, 1.05425505e+00, 1.05656184e+00, 1.05853400e+00, + 1.06017414e+00, 1.06149371e+00, 1.06249943e+00, 1.06320577e+00, + 1.06362578e+00, 1.06376487e+00, 1.06363778e+00, 1.06325973e+00, + 1.06264695e+00, 1.06180496e+00, 1.06074505e+00, 1.05948492e+00, + 1.05804533e+00, 1.05643590e+00, 1.05466218e+00, 1.05274047e+00, + 1.05069500e+00, 1.04853894e+00, 1.04627898e+00, 1.04392435e+00, + 1.04149540e+00, 1.03901003e+00, 1.03647725e+00, 1.03390793e+00, + 1.03131989e+00, 1.02872867e+00, 1.02614832e+00, 1.02358988e+00, + 1.02106486e+00, 1.01856262e+00, 1.01655770e+00, 1.01400658e+00, + 1.01162953e+00, 1.00938590e+00, 1.00727455e+00, 1.00529616e+00, + 1.00344526e+00, 1.00172250e+00, 1.00012792e+00, 9.98657533e-01, + 9.97309592e-01, 9.96083571e-01, 9.94976569e-01, 9.93985158e-01, + 9.93107530e-01, 9.92341305e-01, 9.91683335e-01, 9.91130070e-01, + 9.90678325e-01, 9.90325325e-01, 9.90067562e-01, 9.89901282e-01, + 9.89822613e-01, 9.89827845e-01, 9.89913241e-01, 9.90074734e-01, + 9.90308256e-01, 9.90609852e-01, 9.90975314e-01, 9.91400330e-01, + 9.91880966e-01, 9.92412851e-01, 9.92991779e-01, 9.93613381e-01, + 9.94273149e-01, 9.94966958e-01, 9.95690370e-01, 9.96439157e-01, + 9.97208572e-01, 9.97994275e-01, 9.98791616e-01, 9.99596062e-01, + 1.00040410e+00, 1.00120985e+00, 1.00200976e+00, 1.00279924e+00, + 1.00357357e+00, 1.00432828e+00, 1.00505850e+00, 1.00575984e+00, + 1.00642767e+00, 1.00705768e+00, 1.00764515e+00, 1.00818549e+00, + 1.00867427e+00, 1.00910687e+00, 1.00947916e+00, 1.00978659e+00, + 1.01002476e+00, 1.01018954e+00, 1.01027669e+00, 1.01028203e+00, + 1.01020174e+00, 1.01003208e+00, 1.00976919e+00, 1.00940939e+00, + 1.00894931e+00, 1.00838641e+00, 1.00771780e+00, 1.00694031e+00, + 1.00605124e+00, 1.00504879e+00, 1.00393183e+00, 1.00269767e+00, + 1.00134427e+00, 9.99872092e-01, 9.98280464e-01, 9.96566569e-01, + 9.94731737e-01, 9.92777987e-01, 9.90701374e-01, 9.88504165e-01, + 9.86186892e-01, 9.83711989e-01, 9.80584643e-01, 9.77634164e-01, + 9.74455033e-01, 9.71062916e-01, 9.67447270e-01, 9.63593926e-01, + 9.59491398e-01, 9.55129725e-01, 9.50501326e-01, 9.45592810e-01, + 9.40389877e-01, 9.34886760e-01, 9.29080559e-01, 9.22959280e-01, + 9.16509579e-01, 9.09724456e-01, 9.02607350e-01, 8.95155084e-01, + 8.87356154e-01, 8.79202689e-01, 8.70699698e-01, 8.61847424e-01, + 8.52641750e-01, 8.43077833e-01, 8.33154905e-01, 8.22881272e-01, + 8.12257597e-01, 8.01285439e-01, 7.89971715e-01, 7.78318177e-01, + 7.66337710e-01, 7.54030328e-01, 7.41407991e-01, 7.28477501e-01, + 7.15255742e-01, 7.01751739e-01, 6.87975632e-01, 6.73936911e-01, + 6.59652573e-01, 6.45139489e-01, 6.30414716e-01, 6.15483622e-01, + 6.00365852e-01, 5.85078858e-01, 5.69649536e-01, 5.54084810e-01, + 5.38398518e-01, 5.22614738e-01, 5.06756805e-01, 4.90833753e-01, + 4.74866033e-01, 4.58876566e-01, 4.42885823e-01, 4.26906539e-01, + 4.10970973e-01, 3.95091024e-01, 3.79291327e-01, 3.63587417e-01, + 3.48004343e-01, 3.32563201e-01, 3.17287485e-01, 3.02196710e-01, + 2.87309403e-01, 2.72643992e-01, 2.58227431e-01, 2.44072856e-01, + 2.30208977e-01, 2.16641416e-01, 2.03398481e-01, 1.90486162e-01, + 1.77922122e-01, 1.65726674e-01, 1.53906397e-01, 1.42480547e-01, + 1.31453980e-01, 1.20841778e-01, 1.10652194e-01, 1.00891734e-01, + 9.15718851e-02, 8.26995967e-02, 7.42815529e-02, 6.63242382e-02, + 5.88334516e-02, 5.18140676e-02, 4.52698346e-02, 3.92030848e-02, + 3.36144159e-02, 2.85023308e-02, 2.38629107e-02, 1.96894227e-02, + 1.59720527e-02, 1.26976223e-02, 9.84937739e-03, 7.40724463e-03, + 5.35665361e-03, 3.83226552e-03, +}; + +static const float mdct_win_7m5_240[240+184] = { + 1.84833037e-03, 2.56481839e-03, 3.36762118e-03, 4.28736617e-03, + 5.33830143e-03, 6.52679223e-03, 7.86112587e-03, 9.34628179e-03, + 1.09916868e-02, 1.28011172e-02, 1.47805911e-02, 1.69307043e-02, + 1.92592307e-02, 2.17696937e-02, 2.44685983e-02, 2.73556543e-02, + 3.04319230e-02, 3.36980464e-02, 3.71583577e-02, 4.08148180e-02, + 4.46708068e-02, 4.87262995e-02, 5.29820633e-02, 5.74382470e-02, + 6.20968580e-02, 6.69609767e-02, 7.20298364e-02, 7.73039146e-02, + 8.27825574e-02, 8.84682102e-02, 9.43607566e-02, 1.00460272e-01, + 1.06763824e-01, 1.13273679e-01, 1.19986420e-01, 1.26903521e-01, + 1.34020853e-01, 1.41339557e-01, 1.48857211e-01, 1.56573685e-01, + 1.64484622e-01, 1.72589077e-01, 1.80879090e-01, 1.89354320e-01, + 1.98012244e-01, 2.06854141e-01, 2.15875319e-01, 2.25068672e-01, + 2.34427407e-01, 2.43948314e-01, 2.53627993e-01, 2.63464061e-01, + 2.73450494e-01, 2.83582189e-01, 2.93853469e-01, 3.04257373e-01, + 3.14790914e-01, 3.25449123e-01, 3.36227410e-01, 3.47118760e-01, + 3.58120177e-01, 3.69224663e-01, 3.80427793e-01, 3.91720023e-01, + 4.03097022e-01, 4.14551955e-01, 4.26081719e-01, 4.37676318e-01, + 4.49330196e-01, 4.61034855e-01, 4.72786043e-01, 4.84576777e-01, + 4.96401707e-01, 5.08252458e-01, 5.20122078e-01, 5.32002077e-01, + 5.43888090e-01, 5.55771601e-01, 5.67645739e-01, 5.79502786e-01, + 5.91335035e-01, 6.03138367e-01, 6.14904172e-01, 6.26623941e-01, + 6.38288834e-01, 6.49893375e-01, 6.61432360e-01, 6.72902514e-01, + 6.84293750e-01, 6.95600460e-01, 7.06811784e-01, 7.17923425e-01, + 7.28931386e-01, 7.39832773e-01, 7.50618982e-01, 7.61284053e-01, + 7.71818919e-01, 7.82220992e-01, 7.92481330e-01, 8.02599448e-01, + 8.12565230e-01, 8.22377129e-01, 8.32030518e-01, 8.41523208e-01, + 8.50848313e-01, 8.60002412e-01, 8.68979881e-01, 8.77778347e-01, + 8.86395904e-01, 8.94829421e-01, 9.03077626e-01, 9.11132652e-01, + 9.18993585e-01, 9.26652937e-01, 9.34111420e-01, 9.41364344e-01, + 9.48412967e-01, 9.55255630e-01, 9.61892013e-01, 9.68316363e-01, + 9.74530156e-01, 9.80528338e-01, 9.86313928e-01, 9.91886049e-01, + 9.97246345e-01, 1.00239190e+00, 1.00731946e+00, 1.01202707e+00, + 1.01651654e+00, 1.02079430e+00, 1.02486082e+00, 1.02871471e+00, + 1.03235170e+00, 1.03577375e+00, 1.03898432e+00, 1.04198786e+00, + 1.04478564e+00, 1.04737818e+00, 1.04976743e+00, 1.05195405e+00, + 1.05394290e+00, 1.05573463e+00, 1.05734177e+00, 1.05875726e+00, + 1.05998674e+00, 1.06103672e+00, 1.06190651e+00, 1.06260369e+00, + 1.06313289e+00, 1.06350237e+00, 1.06370981e+00, 1.06376322e+00, + 1.06366765e+00, 1.06343012e+00, 1.06305656e+00, 1.06255421e+00, + 1.06192235e+00, 1.06116702e+00, 1.06029469e+00, 1.05931469e+00, + 1.05823465e+00, 1.05705891e+00, 1.05578948e+00, 1.05442979e+00, + 1.05298793e+00, 1.05147505e+00, 1.04989930e+00, 1.04826213e+00, + 1.04656691e+00, 1.04481699e+00, 1.04302125e+00, 1.04118768e+00, + 1.03932339e+00, 1.03743168e+00, 1.03551757e+00, 1.03358511e+00, + 1.03164371e+00, 1.02969955e+00, 1.02775944e+00, 1.02582719e+00, + 1.02390791e+00, 1.02200805e+00, 1.02013910e+00, 1.01826310e+00, + 1.01687901e+00, 1.01492195e+00, 1.01309662e+00, 1.01134205e+00, + 1.00965912e+00, 1.00805036e+00, 1.00651754e+00, 1.00505799e+00, + 1.00366956e+00, 1.00235327e+00, 1.00110981e+00, 9.99937523e-01, + 9.98834524e-01, 9.97800606e-01, 9.96835756e-01, 9.95938881e-01, + 9.95108459e-01, 9.94343411e-01, 9.93642921e-01, 9.93005832e-01, + 9.92430984e-01, 9.91917493e-01, 9.91463898e-01, 9.91068214e-01, + 9.90729218e-01, 9.90446225e-01, 9.90217819e-01, 9.90041963e-01, + 9.89917085e-01, 9.89841975e-01, 9.89815048e-01, 9.89834329e-01, + 9.89898211e-01, 9.90005403e-01, 9.90154189e-01, 9.90342427e-01, + 9.90568459e-01, 9.90830953e-01, 9.91128038e-01, 9.91457566e-01, + 9.91817881e-01, 9.92207559e-01, 9.92624757e-01, 9.93067358e-01, + 9.93533398e-01, 9.94021410e-01, 9.94529685e-01, 9.95055964e-01, + 9.95598351e-01, 9.96155580e-01, 9.96725627e-01, 9.97306092e-01, + 9.97895214e-01, 9.98491441e-01, 9.99092890e-01, 9.99697063e-01, + 1.00030303e+00, 1.00090793e+00, 1.00151084e+00, 1.00210923e+00, + 1.00270118e+00, 1.00328513e+00, 1.00385926e+00, 1.00442111e+00, + 1.00496860e+00, 1.00550040e+00, 1.00601455e+00, 1.00650869e+00, + 1.00698104e+00, 1.00743004e+00, 1.00785364e+00, 1.00824962e+00, + 1.00861604e+00, 1.00895138e+00, 1.00925390e+00, 1.00952134e+00, + 1.00975175e+00, 1.00994371e+00, 1.01009550e+00, 1.01020488e+00, + 1.01027007e+00, 1.01028975e+00, 1.01026227e+00, 1.01018562e+00, + 1.01005820e+00, 1.00987882e+00, 1.00964593e+00, 1.00935753e+00, + 1.00901228e+00, 1.00860959e+00, 1.00814837e+00, 1.00762674e+00, + 1.00704343e+00, 1.00639775e+00, 1.00568877e+00, 1.00491559e+00, + 1.00407768e+00, 1.00317429e+00, 1.00220424e+00, 1.00116684e+00, + 1.00006248e+00, 9.98891422e-01, 9.97652252e-01, 9.96343856e-01, + 9.94967462e-01, 9.93524663e-01, 9.92013927e-01, 9.90433283e-01, + 9.88785147e-01, 9.87072681e-01, 9.85297443e-01, 9.83401161e-01, + 9.80949418e-01, 9.78782729e-01, 9.76468238e-01, 9.74042850e-01, + 9.71498848e-01, 9.68829968e-01, 9.66030974e-01, 9.63095104e-01, + 9.60018198e-01, 9.56795738e-01, 9.53426267e-01, 9.49903482e-01, + 9.46222115e-01, 9.42375820e-01, 9.38361702e-01, 9.34177798e-01, + 9.29823124e-01, 9.25292320e-01, 9.20580120e-01, 9.15679793e-01, + 9.10590604e-01, 9.05315030e-01, 8.99852756e-01, 8.94199497e-01, + 8.88350152e-01, 8.82301631e-01, 8.76054874e-01, 8.69612385e-01, + 8.62972799e-01, 8.56135198e-01, 8.49098179e-01, 8.41857024e-01, + 8.34414055e-01, 8.26774617e-01, 8.18939244e-01, 8.10904891e-01, + 8.02675318e-01, 7.94253751e-01, 7.85641662e-01, 7.76838609e-01, + 7.67853193e-01, 7.58685181e-01, 7.49330658e-01, 7.39809171e-01, + 7.30109944e-01, 7.20247781e-01, 7.10224161e-01, 7.00044326e-01, + 6.89711890e-01, 6.79231154e-01, 6.68608179e-01, 6.57850997e-01, + 6.46965718e-01, 6.35959617e-01, 6.24840336e-01, 6.13603503e-01, + 6.02265091e-01, 5.90829083e-01, 5.79309408e-01, 5.67711124e-01, + 5.56037416e-01, 5.44293664e-01, 5.32489768e-01, 5.20636084e-01, + 5.08743273e-01, 4.96811166e-01, 4.84849881e-01, 4.72868107e-01, + 4.60875918e-01, 4.48881081e-01, 4.36891039e-01, 4.24912022e-01, + 4.12960603e-01, 4.01035896e-01, 3.89157867e-01, 3.77322199e-01, + 3.65543767e-01, 3.53832356e-01, 3.42196115e-01, 3.30644820e-01, + 3.19187559e-01, 3.07833309e-01, 2.96588182e-01, 2.85463717e-01, + 2.74462409e-01, 2.63609584e-01, 2.52883101e-01, 2.42323489e-01, + 2.31925746e-01, 2.21690837e-01, 2.11638058e-01, 2.01766920e-01, + 1.92082236e-01, 1.82589160e-01, 1.73305997e-01, 1.64229200e-01, + 1.55362654e-01, 1.46717079e-01, 1.38299391e-01, 1.30105078e-01, + 1.22145310e-01, 1.14423458e-01, 1.06941076e-01, 9.97025893e-02, + 9.27124283e-02, 8.59737427e-02, 7.94893311e-02, 7.32616579e-02, + 6.72934102e-02, 6.15874081e-02, 5.61458003e-02, 5.09700747e-02, + 4.60617047e-02, 4.14220117e-02, 3.70514189e-02, 3.29494666e-02, + 2.91153327e-02, 2.55476401e-02, 2.22437711e-02, 1.92000659e-02, + 1.64122205e-02, 1.38747611e-02, 1.15806353e-02, 9.52213664e-03, + 7.69137380e-03, 6.07207833e-03, 4.62581217e-03, 3.60685164e-03, +}; + +static const float mdct_win_7m5_360[360+276] = { + 1.72152668e-03, 2.20824874e-03, 2.68901752e-03, 3.22613342e-03, + 3.81014420e-03, 4.45371932e-03, 5.15369240e-03, 5.91552473e-03, + 6.73869158e-03, 7.62861841e-03, 8.58361457e-03, 9.60938437e-03, + 1.07060753e-02, 1.18759723e-02, 1.31190130e-02, 1.44390108e-02, + 1.58335301e-02, 1.73063081e-02, 1.88584711e-02, 2.04918652e-02, + 2.22061476e-02, 2.40057166e-02, 2.58883593e-02, 2.78552326e-02, + 2.99059145e-02, 3.20415894e-02, 3.42610013e-02, 3.65680973e-02, + 3.89616721e-02, 4.14435824e-02, 4.40140796e-02, 4.66742169e-02, + 4.94214625e-02, 5.22588489e-02, 5.51849337e-02, 5.82005143e-02, + 6.13059845e-02, 6.45038384e-02, 6.77913923e-02, 7.11707833e-02, + 7.46411071e-02, 7.82028053e-02, 8.18549521e-02, 8.56000162e-02, + 8.94357617e-02, 9.33642589e-02, 9.73846703e-02, 1.01496718e-01, + 1.05698760e-01, 1.09993603e-01, 1.14378287e-01, 1.18853508e-01, + 1.23419277e-01, 1.28075997e-01, 1.32820581e-01, 1.37655457e-01, + 1.42578648e-01, 1.47590522e-01, 1.52690437e-01, 1.57878853e-01, + 1.63152529e-01, 1.68513363e-01, 1.73957969e-01, 1.79484737e-01, + 1.85093105e-01, 1.90784835e-01, 1.96556497e-01, 2.02410419e-01, + 2.08345433e-01, 2.14359825e-01, 2.20450365e-01, 2.26617296e-01, + 2.32856279e-01, 2.39167941e-01, 2.45550642e-01, 2.52003951e-01, + 2.58526168e-01, 2.65118408e-01, 2.71775911e-01, 2.78498539e-01, + 2.85284606e-01, 2.92132459e-01, 2.99038432e-01, 3.06004256e-01, + 3.13026529e-01, 3.20104862e-01, 3.27237324e-01, 3.34423210e-01, + 3.41658622e-01, 3.48944976e-01, 3.56279252e-01, 3.63660034e-01, + 3.71085146e-01, 3.78554327e-01, 3.86062695e-01, 3.93610554e-01, + 4.01195225e-01, 4.08815272e-01, 4.16468460e-01, 4.24155411e-01, + 4.31871046e-01, 4.39614744e-01, 4.47384019e-01, 4.55176988e-01, + 4.62990138e-01, 4.70824619e-01, 4.78676593e-01, 4.86545433e-01, + 4.94428714e-01, 5.02324813e-01, 5.10229471e-01, 5.18142927e-01, + 5.26060916e-01, 5.33982818e-01, 5.41906817e-01, 5.49831283e-01, + 5.57751234e-01, 5.65667636e-01, 5.73576883e-01, 5.81476666e-01, + 5.89364661e-01, 5.97241338e-01, 6.05102013e-01, 6.12946170e-01, + 6.20770242e-01, 6.28572094e-01, 6.36348526e-01, 6.44099662e-01, + 6.51820973e-01, 6.59513822e-01, 6.67176382e-01, 6.74806795e-01, + 6.82400711e-01, 6.89958854e-01, 6.97475722e-01, 7.04950145e-01, + 7.12379980e-01, 7.19765434e-01, 7.27103833e-01, 7.34396372e-01, + 7.41638561e-01, 7.48829639e-01, 7.55966688e-01, 7.63049259e-01, + 7.70072273e-01, 7.77036981e-01, 7.83941108e-01, 7.90781257e-01, + 7.97558114e-01, 8.04271381e-01, 8.10914901e-01, 8.17490856e-01, + 8.23997094e-01, 8.30432785e-01, 8.36796950e-01, 8.43089298e-01, + 8.49305847e-01, 8.55447310e-01, 8.61511037e-01, 8.67496281e-01, + 8.73400798e-01, 8.79227518e-01, 8.84972438e-01, 8.90635719e-01, + 8.96217173e-01, 9.01716414e-01, 9.07128770e-01, 9.12456578e-01, + 9.17697261e-01, 9.22848784e-01, 9.27909917e-01, 9.32882596e-01, + 9.37763323e-01, 9.42553356e-01, 9.47252428e-01, 9.51860206e-01, + 9.56376060e-01, 9.60800602e-01, 9.65130600e-01, 9.69366689e-01, + 9.73508812e-01, 9.77556541e-01, 9.81507226e-01, 9.85364580e-01, + 9.89126209e-01, 9.92794201e-01, 9.96367545e-01, 9.99846919e-01, + 1.00322812e+00, 1.00651341e+00, 1.00970073e+00, 1.01279029e+00, + 1.01578293e+00, 1.01868229e+00, 1.02148657e+00, 1.02419772e+00, + 1.02681455e+00, 1.02933598e+00, 1.03176043e+00, 1.03408981e+00, + 1.03632326e+00, 1.03846361e+00, 1.04051196e+00, 1.04246831e+00, + 1.04433331e+00, 1.04610837e+00, 1.04779018e+00, 1.04938334e+00, + 1.05088565e+00, 1.05229923e+00, 1.05362522e+00, 1.05486289e+00, + 1.05601521e+00, 1.05708746e+00, 1.05807221e+00, 1.05897524e+00, + 1.05979447e+00, 1.06053414e+00, 1.06119412e+00, 1.06177366e+00, + 1.06227662e+00, 1.06270324e+00, 1.06305569e+00, 1.06333815e+00, + 1.06354800e+00, 1.06368607e+00, 1.06375557e+00, 1.06375743e+00, + 1.06369358e+00, 1.06356632e+00, 1.06337707e+00, 1.06312782e+00, + 1.06282156e+00, 1.06245782e+00, 1.06203634e+00, 1.06155996e+00, + 1.06102951e+00, 1.06044797e+00, 1.05981709e+00, 1.05914163e+00, + 1.05842136e+00, 1.05765876e+00, 1.05685377e+00, 1.05600761e+00, + 1.05512006e+00, 1.05419505e+00, 1.05323346e+00, 1.05223985e+00, + 1.05121668e+00, 1.05016637e+00, 1.04908779e+00, 1.04798366e+00, + 1.04685334e+00, 1.04569860e+00, 1.04452056e+00, 1.04332348e+00, + 1.04210831e+00, 1.04087907e+00, 1.03963603e+00, 1.03838099e+00, + 1.03711403e+00, 1.03583813e+00, 1.03455276e+00, 1.03326200e+00, + 1.03196750e+00, 1.03067200e+00, 1.02937564e+00, 1.02808244e+00, + 1.02679167e+00, 1.02550635e+00, 1.02422655e+00, 1.02295558e+00, + 1.02169299e+00, 1.02044475e+00, 1.01920733e+00, 1.01799992e+00, + 1.01716022e+00, 1.01587289e+00, 1.01461783e+00, 1.01339738e+00, + 1.01221017e+00, 1.01105652e+00, 1.00993444e+00, 1.00884559e+00, + 1.00778956e+00, 1.00676790e+00, 1.00577851e+00, 1.00482173e+00, + 1.00389592e+00, 1.00300262e+00, 1.00214091e+00, 1.00131213e+00, + 1.00051460e+00, 9.99748988e-01, 9.99013486e-01, 9.98309229e-01, + 9.97634934e-01, 9.96991885e-01, 9.96378601e-01, 9.95795982e-01, + 9.95242217e-01, 9.94718132e-01, 9.94222122e-01, 9.93755313e-01, + 9.93316216e-01, 9.92905809e-01, 9.92522422e-01, 9.92166957e-01, + 9.91837704e-01, 9.91535508e-01, 9.91258603e-01, 9.91007878e-01, + 9.90781723e-01, 9.90581104e-01, 9.90404336e-01, 9.90252267e-01, + 9.90123118e-01, 9.90017726e-01, 9.89934325e-01, 9.89873712e-01, + 9.89834110e-01, 9.89816359e-01, 9.89818707e-01, 9.89841998e-01, + 9.89884438e-01, 9.89946800e-01, 9.90027287e-01, 9.90126680e-01, + 9.90243175e-01, 9.90377594e-01, 9.90528134e-01, 9.90695564e-01, + 9.90878043e-01, 9.91076302e-01, 9.91288540e-01, 9.91515602e-01, + 9.91755666e-01, 9.92009469e-01, 9.92275155e-01, 9.92553486e-01, + 9.92842693e-01, 9.93143533e-01, 9.93454080e-01, 9.93775067e-01, + 9.94104689e-01, 9.94443742e-01, 9.94790398e-01, 9.95145361e-01, + 9.95506800e-01, 9.95875534e-01, 9.96249681e-01, 9.96629919e-01, + 9.97014367e-01, 9.97403799e-01, 9.97796404e-01, 9.98192871e-01, + 9.98591286e-01, 9.98992436e-01, 9.99394506e-01, 9.99798247e-01, + 1.00020179e+00, 1.00060586e+00, 1.00100858e+00, 1.00141070e+00, + 1.00181040e+00, 1.00220846e+00, 1.00260296e+00, 1.00299457e+00, + 1.00338148e+00, 1.00376444e+00, 1.00414155e+00, 1.00451348e+00, + 1.00487832e+00, 1.00523688e+00, 1.00558730e+00, 1.00593027e+00, + 1.00626393e+00, 1.00658905e+00, 1.00690380e+00, 1.00720890e+00, + 1.00750238e+00, 1.00778498e+00, 1.00805489e+00, 1.00831287e+00, + 1.00855700e+00, 1.00878802e+00, 1.00900405e+00, 1.00920593e+00, + 1.00939182e+00, 1.00956244e+00, 1.00971590e+00, 1.00985296e+00, + 1.00997177e+00, 1.01007317e+00, 1.01015529e+00, 1.01021893e+00, + 1.01026225e+00, 1.01028602e+00, 1.01028842e+00, 1.01027030e+00, + 1.01022988e+00, 1.01016802e+00, 1.01008292e+00, 1.00997541e+00, + 1.00984369e+00, 1.00968863e+00, 1.00950846e+00, 1.00930404e+00, + 1.00907371e+00, 1.00881848e+00, 1.00853675e+00, 1.00822947e+00, + 1.00789488e+00, 1.00753391e+00, 1.00714488e+00, 1.00672876e+00, + 1.00628393e+00, 1.00581146e+00, 1.00530991e+00, 1.00478053e+00, + 1.00422177e+00, 1.00363456e+00, 1.00301719e+00, 1.00237067e+00, + 1.00169363e+00, 1.00098749e+00, 1.00025108e+00, 9.99485663e-01, + 9.98689592e-01, 9.97863666e-01, 9.97006370e-01, 9.96119199e-01, + 9.95201404e-01, 9.94254687e-01, 9.93277595e-01, 9.92270651e-01, + 9.91231967e-01, 9.90163286e-01, 9.89064394e-01, 9.87937115e-01, + 9.86779736e-01, 9.85592773e-01, 9.84375125e-01, 9.83129288e-01, + 9.81348463e-01, 9.79890963e-01, 9.78400459e-01, 9.76860435e-01, + 9.75269879e-01, 9.73627353e-01, 9.71931341e-01, 9.70180498e-01, + 9.68372652e-01, 9.66506952e-01, 9.64580027e-01, 9.62592318e-01, + 9.60540986e-01, 9.58425534e-01, 9.56244393e-01, 9.53998416e-01, + 9.51684014e-01, 9.49301185e-01, 9.46846884e-01, 9.44320232e-01, + 9.41718404e-01, 9.39042580e-01, 9.36290624e-01, 9.33464050e-01, + 9.30560854e-01, 9.27580507e-01, 9.24519592e-01, 9.21378471e-01, + 9.18153414e-01, 9.14844696e-01, 9.11451652e-01, 9.07976524e-01, + 9.04417545e-01, 9.00776308e-01, 8.97050058e-01, 8.93238398e-01, + 8.89338681e-01, 8.85351360e-01, 8.81274023e-01, 8.77109638e-01, + 8.72857927e-01, 8.68519505e-01, 8.64092796e-01, 8.59579819e-01, + 8.54976007e-01, 8.50285220e-01, 8.45502615e-01, 8.40630470e-01, + 8.35667925e-01, 8.30619943e-01, 8.25482007e-01, 8.20258909e-01, + 8.14946648e-01, 8.09546696e-01, 8.04059978e-01, 7.98489378e-01, + 7.92831417e-01, 7.87090668e-01, 7.81262450e-01, 7.75353947e-01, + 7.69363613e-01, 7.63291769e-01, 7.57139016e-01, 7.50901711e-01, + 7.44590843e-01, 7.38205136e-01, 7.31738075e-01, 7.25199287e-01, + 7.18588225e-01, 7.11905687e-01, 7.05153668e-01, 6.98332634e-01, + 6.91444101e-01, 6.84490545e-01, 6.77470119e-01, 6.70388375e-01, + 6.63245210e-01, 6.56045780e-01, 6.48788627e-01, 6.41477162e-01, + 6.34114323e-01, 6.26702000e-01, 6.19235334e-01, 6.11720596e-01, + 6.04161612e-01, 5.96559133e-01, 5.88914401e-01, 5.81234783e-01, + 5.73519989e-01, 5.65770616e-01, 5.57988067e-01, 5.50173851e-01, + 5.42330194e-01, 5.34460798e-01, 5.26568538e-01, 5.18656324e-01, + 5.10728813e-01, 5.02781159e-01, 4.94819491e-01, 4.86845139e-01, + 4.78860889e-01, 4.70869928e-01, 4.62875144e-01, 4.54877894e-01, + 4.46882512e-01, 4.38889325e-01, 4.30898123e-01, 4.22918322e-01, + 4.14950878e-01, 4.06993964e-01, 3.99052648e-01, 3.91134614e-01, + 3.83234031e-01, 3.75354653e-01, 3.67502060e-01, 3.59680098e-01, + 3.51887312e-01, 3.44130166e-01, 3.36408100e-01, 3.28728966e-01, + 3.21090505e-01, 3.13496418e-01, 3.05951565e-01, 2.98454319e-01, + 2.91010565e-01, 2.83621109e-01, 2.76285415e-01, 2.69019585e-01, + 2.61812445e-01, 2.54659232e-01, 2.47584348e-01, 2.40578694e-01, + 2.33647009e-01, 2.26788433e-01, 2.20001992e-01, 2.13301325e-01, + 2.06677771e-01, 2.00140409e-01, 1.93683630e-01, 1.87310343e-01, + 1.81027384e-01, 1.74839476e-01, 1.68739644e-01, 1.62737273e-01, + 1.56825277e-01, 1.51012382e-01, 1.45298230e-01, 1.39687469e-01, + 1.34171842e-01, 1.28762544e-01, 1.23455562e-01, 1.18254662e-01, + 1.13159677e-01, 1.08171439e-01, 1.03290734e-01, 9.85202978e-02, + 9.38600023e-02, 8.93117360e-02, 8.48752103e-02, 8.05523737e-02, + 7.63429787e-02, 7.22489246e-02, 6.82699120e-02, 6.44077291e-02, + 6.06620003e-02, 5.70343711e-02, 5.35243715e-02, 5.01334690e-02, + 4.68610790e-02, 4.37084453e-02, 4.06748365e-02, 3.77612269e-02, + 3.49667099e-02, 3.22919275e-02, 2.97357669e-02, 2.72984629e-02, + 2.49787186e-02, 2.27762542e-02, 2.06895808e-02, 1.87178169e-02, + 1.68593418e-02, 1.51125125e-02, 1.34757094e-02, 1.19462709e-02, + 1.05228754e-02, 9.20130941e-03, 7.98124316e-03, 6.85547314e-03, + 5.82657334e-03, 4.87838525e-03, 4.02351119e-03, 3.15418663e-03, +}; + +const float *lc3_mdct_win[LC3_NUM_DT][LC3_NUM_SRATE] = { + + [LC3_DT_7M5] = { + [LC3_SRATE_8K ] = mdct_win_7m5_60, + [LC3_SRATE_16K] = mdct_win_7m5_120, + [LC3_SRATE_24K] = mdct_win_7m5_180, + [LC3_SRATE_32K] = mdct_win_7m5_240, + [LC3_SRATE_48K] = mdct_win_7m5_360, + }, + + [LC3_DT_10M] = { + [LC3_SRATE_8K ] = mdct_win_10m_80, + [LC3_SRATE_16K] = mdct_win_10m_160, + [LC3_SRATE_24K] = mdct_win_10m_240, + [LC3_SRATE_32K] = mdct_win_10m_320, + [LC3_SRATE_48K] = mdct_win_10m_480, + }, +}; + + +/** + * Bands limits (cf. 3.7.1-2) + */ + +const int lc3_band_lim[LC3_NUM_DT][LC3_NUM_SRATE][LC3_NUM_BANDS+1] = { + + [LC3_DT_7M5] = { + + [LC3_SRATE_8K ] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 60, 60, 60, 60 }, + + [LC3_SRATE_16K] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 36, 38, 40, 42, 44, + 46, 48, 50, 52, 54, 56, 58, 60, 62, 65, + 68, 71, 74, 77, 80, 83, 86, 90, 94, 98, + 102, 106, 110, 115, 120 }, + + [LC3_SRATE_24K] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 29, 31, + 33, 35, 37, 39, 41, 43, 45, 47, 49, 52, + 55, 58, 61, 64, 67, 70, 74, 78, 82, 86, + 90, 95, 100, 105, 110, 115, 121, 127, 134, 141, + 148, 155, 163, 171, 180 }, + + [LC3_SRATE_32K] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 26, 28, 30, 32, 34, + 36, 38, 40, 42, 45, 48, 51, 54, 57, 60, + 63, 67, 71, 75, 79, 84, 89, 94, 99, 105, + 111, 117, 124, 131, 138, 146, 154, 163, 172, 182, + 192, 203, 215, 227, 240 }, + + [LC3_SRATE_48K] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 24, 26, 28, 30, 32, 34, 36, + 38, 40, 43, 46, 49, 52, 55, 59, 63, 67, + 71, 75, 80, 85, 90, 96, 102, 108, 115, 122, + 129, 137, 146, 155, 165, 175, 186, 197, 209, 222, + 236, 251, 266, 283, 300 }, + }, + + [LC3_DT_10M] = { + + [LC3_SRATE_8K ] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, + 71, 73, 75, 77, 80 }, + + [LC3_SRATE_16K] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 30, + 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, + 52, 55, 58, 61, 64, 67, 70, 73, 76, 80, + 84, 88, 92, 96, 101, 106, 111, 116, 121, 127, + 133, 139, 146, 153, 160 }, + + [LC3_SRATE_24K] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 25, 27, 29, 31, 33, 35, + 37, 39, 41, 43, 46, 49, 52, 55, 58, 61, + 64, 68, 72, 76, 80, 85, 90, 95, 100, 106, + 112, 118, 125, 132, 139, 147, 155, 164, 173, 183, + 193, 204, 215, 227, 240 }, + + [LC3_SRATE_32K] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, + 41, 44, 47, 50, 53, 56, 60, 64, 68, 72, + 76, 81, 86, 91, 97, 103, 109, 116, 123, 131, + 139, 148, 157, 166, 176, 187, 199, 211, 224, 238, + 252, 268, 284, 302, 320 }, + + [LC3_SRATE_48K] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, + 22, 24, 26, 28, 30, 32, 34, 36, 39, 42, + 45, 48, 51, 55, 59, 63, 67, 71, 76, 81, + 86, 92, 98, 105, 112, 119, 127, 135, 144, 154, + 164, 175, 186, 198, 211, 225, 240, 256, 273, 291, + 310, 330, 352, 375, 400 }, + } +}; + + +/** + * SNS Quantization (cf. 3.7.4) + */ + +const float lc3_sns_lfcb[32][8] = { + + { 2.26283366e+00, 8.13311269e-01, -5.30193495e-01, -1.35664836e+00, + -1.59952177e+00, -1.44098768e+00, -1.14381648e+00, -7.55203768e-01 }, + + { 2.94516479e+00, 2.41143318e+00, 9.60455106e-01, -4.43226488e-01, + -1.22913612e+00, -1.55590039e+00, -1.49688656e+00, -1.11689987e+00 }, + + { -2.18610707e+00, -1.97152136e+00, -1.78718620e+00, -1.91865896e+00, + -1.79399122e+00, -1.35738404e+00, -7.05444279e-01, -4.78172945e-02 }, + + { 6.93688237e-01, 9.55609857e-01, 5.75230787e-01, -1.14603419e-01, + -6.46050637e-01, -9.52351370e-01, -1.07405247e+00, -7.58087707e-01 }, + + { -1.29752132e+00, -7.40369057e-01, -3.45372484e-01, -3.13285696e-01, + -4.02977243e-01, -3.72020853e-01, -7.83414177e-02, 9.70441304e-02 }, + + { 9.14652038e-01, 1.74293043e+00, 1.90906627e+00, 1.54408484e+00, + 1.09344961e+00, 6.47479550e-01, 3.61790752e-02, -2.97092807e-01 }, + + { -2.51428813e+00, -2.89175271e+00, -2.00450667e+00, -7.50912274e-01, + 4.41202105e-01, 1.20190988e+00, 1.32742857e+00, 1.22049081e+00 }, + + { -9.22188405e-01, 6.32495141e-01, 1.08736431e+00, 6.08628625e-01, + 1.31174568e-01, -2.96149158e-01, -2.07013517e-01, 1.34924917e-01 }, + + { 7.90322288e-01, 6.28401262e-01, 3.93117924e-01, 4.80007711e-01, + 4.47815138e-01, 2.09734215e-01, 6.56691996e-03, -8.61242342e-02 }, + + { 1.44775580e+00, 2.72399952e+00, 2.31083269e+00, 9.35051270e-01, + -2.74743911e-01, -9.02077697e-01, -9.40681512e-01, -6.33697039e-01 }, + + { 7.93354526e-01, 1.43931186e-02, -5.67834845e-01, -6.54760468e-01, + -4.79458998e-01, -1.73894662e-01, 6.80162706e-02, 2.95125948e-01 }, + + { 2.72425347e+00, 2.95947572e+00, 1.84953559e+00, 5.63284922e-01, + 1.39917088e-01, 3.59641093e-01, 6.89461355e-01, 6.39790177e-01 }, + + { -5.30830198e-01, -2.12690683e-01, 5.76613628e-03, 4.24871484e-01, + 4.73128952e-01, 8.58894199e-01, 1.19111161e+00, 9.96189670e-01 }, + + { 1.68728411e+00, 2.43614509e+00, 2.33019429e+00, 1.77983778e+00, + 1.44411295e+00, 1.51995177e+00, 1.47199394e+00, 9.77682474e-01 }, + + { -2.95183273e+00, -1.59393497e+00, -1.09918773e-01, 3.88609073e-01, + 5.12932650e-01, 6.28112597e-01, 8.22621796e-01, 8.75891425e-01 }, + + { 1.01878343e-01, 5.89857324e-01, 6.19047647e-01, 1.26731314e+00, + 2.41961048e+00, 2.25174253e+00, 5.26537031e-01, -3.96591513e-01 }, + + { 2.68254575e+00, 1.32738011e+00, 1.30185274e-01, -3.38533089e-01, + -3.68219236e-01, -1.91689947e-01, -1.54782377e-01, -2.34207178e-01 }, + + { 4.82697924e+00, 3.11947804e+00, 1.39513671e+00, 2.50295316e-01, + -3.93613839e-01, -6.43458173e-01, -6.42570737e-01, -7.23193223e-01 }, + + { 8.78419936e-02, -5.69586840e-01, -1.14506016e+00, -1.66968488e+00, + -1.84534418e+00, -1.56468027e+00, -1.11746759e+00, -5.33981663e-01 }, + + { 1.39102308e+00, 1.98146479e+00, 1.11265796e+00, -2.20107509e-01, + -7.74965612e-01, -5.94063874e-01, 1.36937681e-01, 8.18242891e-01 }, + + { 3.84585894e-01, -1.60588786e-01, -5.39366810e-01, -5.29309079e-01, + 1.90433547e-01, 2.56062918e+00, 2.81896398e+00, 6.56670876e-01 }, + + { 1.93227399e+00, 3.01030180e+00, 3.06543894e+00, 2.50110161e+00, + 1.93089593e+00, 5.72153811e-01, -8.11741794e-01, -1.17641811e+00 }, + + { 1.75080463e-01, -7.50522832e-01, -1.03943893e+00, -1.13577509e+00, + -1.04197904e+00, -1.52060099e-02, 2.07048392e+00, 3.42948918e+00 }, + + { -1.18817020e+00, 3.66792874e-01, 1.30957830e+00, 1.68330687e+00, + 1.25100924e+00, 9.42375752e-01, 8.26250483e-01, 4.39952741e-01 }, + + { 2.53322203e+00, 2.11274643e+00, 1.26288412e+00, 7.61513512e-01, + 5.22117938e-01, 1.18680070e-01, -4.52346828e-01, -7.00352426e-01 }, + + { 3.99889837e+00, 4.07901751e+00, 2.82285661e+00, 1.72607213e+00, + 6.47144377e-01, -3.31148521e-01, -8.84042571e-01, -1.12697341e+00 }, + + { 5.07902593e-01, 1.58838450e+00, 1.72899024e+00, 1.00692230e+00, + 3.77121232e-01, 4.76370767e-01, 1.08754740e+00, 1.08756266e+00 }, + + { 3.16856825e+00, 3.25853458e+00, 2.42230591e+00, 1.79446078e+00, + 1.52177911e+00, 1.17196707e+00, 4.89394597e-01, -6.22795716e-02 }, + + { 1.89414767e+00, 1.25108695e+00, 5.90451211e-01, 6.08358583e-01, + 8.78171010e-01, 1.11912511e+00, 1.01857662e+00, 6.20453891e-01 }, + + { 9.48880605e-01, 2.13239439e+00, 2.72345350e+00, 2.76986077e+00, + 2.54286973e+00, 2.02046264e+00, 8.30045859e-01, -2.75569174e-02 }, + + { -1.88026757e+00, -1.26431073e+00, 3.11424977e-01, 1.83670210e+00, + 2.25634192e+00, 2.04818998e+00, 2.19526837e+00, 2.02659614e+00 }, + + { 2.46375746e-01, 9.55621773e-01, 1.52046777e+00, 1.97647400e+00, + 1.94043867e+00, 2.23375847e+00, 1.98835978e+00, 1.27232673e+00 }, + +}; + +const float lc3_sns_hfcb[32][8] = { + + { 2.32028419e-01, -1.00890271e+00, -2.14223503e+00, -2.37533814e+00, + -2.23041933e+00, -2.17595881e+00, -2.29065914e+00, -2.53286398e+00 }, + + { -1.29503937e+00, -1.79929965e+00, -1.88703148e+00, -1.80991660e+00, + -1.76340038e+00, -1.83418428e+00, -1.80480981e+00, -1.73679545e+00 }, + + { 1.39285716e-01, -2.58185126e-01, -6.50804573e-01, -1.06815732e+00, + -1.61928742e+00, -2.18762566e+00, -2.63757587e+00, -2.97897750e+00 }, + + { -3.16513102e-01, -4.77747657e-01, -5.51162076e-01, -4.84788283e-01, + -2.38388394e-01, -1.43024507e-01, 6.83186674e-02, 8.83061717e-02 }, + + { 8.79518405e-01, 2.98340096e-01, -9.15386396e-01, -2.20645975e+00, + -2.74142181e+00, -2.86139074e+00, -2.88841597e+00, -2.95182608e+00 }, + + { -2.96701922e-01, -9.75004919e-01, -1.35857500e+00, -9.83721106e-01, + -6.52956939e-01, -9.89986993e-01, -1.61467225e+00, -2.40712302e+00 }, + + { 3.40981100e-01, 2.68899789e-01, 5.63335685e-02, 4.99114047e-02, + -9.54130727e-02, -7.60166146e-01, -2.32758120e+00, -3.77155485e+00 }, + + { -1.41229759e+00, -1.48522119e+00, -1.18603580e+00, -6.25001634e-01, + 1.53902497e-01, 5.76386498e-01, 7.95092604e-01, 5.96564632e-01 }, + + { -2.28839512e-01, -3.33719070e-01, -8.09321359e-01, -1.63587877e+00, + -1.88486397e+00, -1.64496691e+00, -1.40515778e+00, -1.46666471e+00 }, + + { -1.07148629e+00, -1.41767015e+00, -1.54891762e+00, -1.45296062e+00, + -1.03182970e+00, -6.90642640e-01, -4.28843805e-01, -4.94960215e-01 }, + + { -5.90988511e-01, -7.11737759e-02, 3.45719523e-01, 3.00549461e-01, + -1.11865218e+00, -2.44089151e+00, -2.22854732e+00, -1.89509228e+00 }, + + { -8.48434099e-01, -5.83226811e-01, 9.00423688e-02, 8.45025008e-01, + 1.06572385e+00, 7.37582999e-01, 2.56590452e-01, -4.91963360e-01 }, + + { 1.14069146e+00, 9.64016892e-01, 3.81461206e-01, -4.82849341e-01, + -1.81632721e+00, -2.80279513e+00, -3.23385725e+00, -3.45908714e+00 }, + + { -3.76283238e-01, 4.25675462e-02, 5.16547697e-01, 2.51716882e-01, + -2.16179968e-01, -5.34074091e-01, -6.40786096e-01, -8.69745032e-01 }, + + { 6.65004121e-01, 1.09790765e+00, 1.38342667e+00, 1.34327359e+00, + 8.22978837e-01, 2.15876799e-01, -4.04925753e-01, -1.07025606e+00 }, + + { -8.26265954e-01, -6.71181233e-01, -2.28495593e-01, 5.18980853e-01, + 1.36721896e+00, 2.18023038e+00, 2.53596093e+00, 2.20121099e+00 }, + + { 1.41008327e+00, 7.54441908e-01, -1.30550585e+00, -1.87133711e+00, + -1.24008685e+00, -1.26712925e+00, -2.03670813e+00, -2.89685162e+00 }, + + { 3.61386818e-01, -2.19991705e-02, -5.79368834e-01, -8.79427961e-01, + -8.50685023e-01, -7.79397050e-01, -7.32182927e-01, -8.88348515e-01 }, + + { 4.37469239e-01, 3.05440420e-01, -7.38786566e-03, -4.95649855e-01, + -8.06651271e-01, -1.22431892e+00, -1.70157770e+00, -2.24491914e+00 }, + + { 6.48100319e-01, 6.82299134e-01, 2.53247464e-01, 7.35842144e-02, + 3.14216709e-01, 2.34729881e-01, 1.44600134e-01, -6.82120179e-02 }, + + { 1.11919833e+00, 1.23465533e+00, 5.89170238e-01, -1.37192460e+00, + -2.37095707e+00, -2.00779783e+00, -1.66688540e+00, -1.92631846e+00 }, + + { 1.41847497e-01, -1.10660071e-01, -2.82824593e-01, -6.59813475e-03, + 2.85929280e-01, 4.60445530e-02, -6.02596416e-01, -2.26568729e+00 }, + + { 5.04046955e-01, 8.26982163e-01, 1.11981236e+00, 1.17914044e+00, + 1.07987429e+00, 6.97536239e-01, -9.12548817e-01, -3.57684747e+00 }, + + { -5.01076050e-01, -3.25678006e-01, 2.80798195e-02, 2.62054555e-01, + 3.60590806e-01, 6.35623722e-01, 9.59012467e-01, 1.30745157e+00 }, + + { 3.74970983e+00, 1.52342612e+00, -4.57715662e-01, -7.98711008e-01, + -3.86819329e-01, -3.75901062e-01, -6.57836900e-01, -1.28163964e+00 }, + + { -1.15258991e+00, -1.10800886e+00, -5.62615117e-01, -2.20562124e-01, + -3.49842880e-01, -7.53432770e-01, -9.88596593e-01, -1.28790472e+00 }, + + { 1.02827246e+00, 1.09770519e+00, 7.68645546e-01, 2.06081978e-01, + -3.42805735e-01, -7.54939405e-01, -1.04196178e+00, -1.50335653e+00 }, + + { 1.28831972e-01, 6.89439395e-01, 1.12346905e+00, 1.30934523e+00, + 1.35511965e+00, 1.42311381e+00, 1.15706449e+00, 4.06319438e-01 }, + + { 1.34033030e+00, 1.38996825e+00, 1.04467922e+00, 6.35822746e-01, + -2.74733756e-01, -1.54923372e+00, -2.44239710e+00, -3.02457607e+00 }, + + { 2.13843105e+00, 4.24711267e+00, 2.89734110e+00, 9.32730658e-01, + -2.92822250e-01, -8.10404297e-01, -7.88868099e-01, -9.35353149e-01 }, + + { 5.64830487e-01, 1.59184978e+00, 2.39771699e+00, 3.03697344e+00, + 2.66424350e+00, 1.39304485e+00, 4.03834024e-01, -6.56270971e-01 }, + + { -4.22460548e-01, 3.26149625e-01, 1.39171313e+00, 2.23146615e+00, + 2.61179442e+00, 2.66540340e+00, 2.40103554e+00, 1.75920380e+00 }, + +}; + +const struct lc3_sns_vq_gains lc3_sns_vq_gains[4] = { + + { 2, (const float []){ + 8915.f / 4096, 12054.f / 4096 } }, + + { 4, (const float []){ + 6245.f / 4096, 15043.f / 4096, 17861.f / 4096, 21014.f / 4096 } }, + + { 4, (const float []){ + 7099.f / 4096, 9132.f / 4096, 11253.f / 4096, 14808.f / 4096 } }, + + { 8, (const float []){ + 4336.f / 4096, 5067.f / 4096, 5895.f / 4096, 8149.f / 4096, + 10235.f / 4096, 12825.f / 4096, 16868.f / 4096, 19882.f / 4096 } } +}; + +const int32_t lc3_sns_mpvq_offsets[][11] = { + { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19 }, + { 0, 1, 5, 13, 25, 41, 61, 85, 113, 145, 181 }, + { 0, 1, 7, 25, 63, 129, 231, 377, 575, 833, 1159 }, + { 0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649, 5641 }, + { 0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073 , 22363 }, + { 0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081, 75517 }, + { 0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545, 224143 }, + { 0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729, 598417 }, + { 0, 1, 19, 181, 1159, 5641, 22363, 75517, 224143, 598417, 1462563 }, + { 0, 1, 21, 221, 1561, 8361, 36365, 134245, 433905, 1256465, 3317445 }, + { 0, 1, 23, 265, 2047, 11969, 56695, 227305, 795455, 2485825, 7059735 }, + { 0, 1, 25, 313, 2625, 16641, 85305, 369305,1392065, 4673345,14218905 }, + { 0, 1, 27, 365, 3303, 22569, 124515, 579125,2340495, 8405905,27298155 }, + { 0, 1, 29, 421, 4089, 29961, 177045, 880685,3800305,14546705,50250765 }, + { 0, 1, 31, 481, 4991, 39041, 246047,1303777,5984767,24331777,89129247 }, +}; + + +/** + * TNS Arithmetic Coding (cf. 3.7.5) + * The number of bits are given at 2048th of bits + */ + +const struct lc3_ac_model lc3_tns_order_models[] = { + + { { { 0, 3 }, { 3, 9 }, { 12, 23 }, { 35, 54 }, + { 89, 111 }, { 200, 190 }, { 390, 268 }, { 658, 366 }, + { 1024, 0 }, { 1024, 0 }, { 1024, 0 }, { 1024, 0 }, + { 1024, 0 }, { 1024, 0 }, { 1024, 0 }, { 1024, 0 }, + { 1024, 0 } } }, + + { { { 0, 14 }, { 14, 42 }, { 56, 100 }, { 156, 157 }, + { 313, 181 }, { 494, 178 }, { 672, 167 }, { 839, 185 }, + { 1024, 0 }, { 1024, 0 }, { 1024, 0 }, { 1024, 0 }, + { 1024, 0 }, { 1024, 0 }, { 1024, 0 }, { 1024, 0 }, + { 1024, 0 } } }, +}; + +const uint16_t lc3_tns_order_bits[][8] = { + { 17234, 13988, 11216, 8694, 6566, 4977, 3961, 3040 }, + { 12683, 9437, 6874, 5541, 5121, 5170, 5359, 5056 } +}; + +const struct lc3_ac_model lc3_tns_coeffs_models[] = { + + { { { 0, 1 }, { 1, 5 }, { 6, 15 }, { 21, 31 }, + { 52, 54 }, { 106, 86 }, { 192, 97 }, { 289, 120 }, + { 409, 159 }, { 568, 152 }, { 720, 111 }, { 831, 104 }, + { 935, 59 }, { 994, 22 }, { 1016, 6 }, { 1022, 1 }, + { 1023, 1 } } }, + + { { { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, + { 4, 13 }, { 17, 43 }, { 60, 94 }, { 154, 139 }, + { 293, 173 }, { 466, 160 }, { 626, 154 }, { 780, 131 }, + { 911, 78 }, { 989, 27 }, { 1016, 6 }, { 1022, 1 }, + { 1023, 1 } } }, + + { { { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, + { 4, 9 }, { 13, 43 }, { 56, 106 }, { 162, 199 }, + { 361, 217 }, { 578, 210 }, { 788, 141 }, { 929, 74 }, + { 1003, 17 }, { 1020, 1 }, { 1021, 1 }, { 1022, 1 }, + { 1023, 1 } } }, + + { { { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, + { 4, 2 }, { 6, 11 }, { 17, 49 }, { 66, 204 }, + { 270, 285 }, { 555, 297 }, { 852, 120 }, { 972, 39 }, + { 1011, 9 }, { 1020, 1 }, { 1021, 1 }, { 1022, 1 }, + { 1023, 1 } } }, + + { { { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, + { 4, 1 }, { 5, 7 }, { 12, 42 }, { 54, 241 }, + { 295, 341 }, { 636, 314 }, { 950, 58 }, { 1008, 9 }, + { 1017, 3 }, { 1020, 1 }, { 1021, 1 }, { 1022, 1 }, + { 1023, 1 } } }, + + { { { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, + { 4, 1 }, { 5, 1 }, { 6, 13 }, { 19, 205 }, + { 224, 366 }, { 590, 377 }, { 967, 47 }, { 1014, 5 }, + { 1019, 1 }, { 1020, 1 }, { 1021, 1 }, { 1022, 1 }, + { 1023, 1 } } }, + + { { { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, + { 4, 1 }, { 5, 1 }, { 6, 13 }, { 19, 281 }, + { 300, 330 }, { 630, 371 }, { 1001, 17 }, { 1018, 1 }, + { 1019, 1 }, { 1020, 1 }, { 1021, 1 }, { 1022, 1 }, + { 1023, 1 } } }, + + { { { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }, + { 4, 1 }, { 5, 1 }, { 6, 5 }, { 11, 297 }, + { 308, 1 }, { 309, 682 }, { 991, 26 }, { 1017, 2 }, + { 1019, 1 }, { 1020, 1 }, { 1021, 1 }, { 1022, 1 }, + { 1023, 1 } } }, + +}; + +const uint16_t lc3_tns_coeffs_bits[][17] = { + + { 20480, 15725, 12479, 10334, 8694, 7320, 6964, 6335, + 5504, 5637, 6566, 6758, 8433, 11348, 15186, 20480, 20480 }, + + { 20480, 20480, 20480, 20480, 12902, 9368, 7057, 5901, + 5254, 5485, 5598, 6076, 7608, 10742, 15186, 20480, 20480 }, + + { 20480, 20480, 20480, 20480, 13988, 9368, 6702, 4841, + 4585, 4682, 5859, 7764, 12109, 20480, 20480, 20480, 20480 }, + + { 20480, 20480, 20480, 20480, 18432, 13396, 8982, 4767, + 3779, 3658, 6335, 9656, 13988, 20480, 20480, 20480, 20480 }, + + { 20480, 20480, 20480, 20480, 20480, 14731, 9437, 4275, + 3249, 3493, 8483, 13988, 17234, 20480, 20480, 20480, 20480 }, + + { 20480, 20480, 20480, 20480, 20480, 20480, 12902, 4753, + 3040, 2953, 9105, 15725, 20480, 20480, 20480, 20480, 20480 }, + + { 20480, 20480, 20480, 20480, 20480, 20480, 12902, 3821, + 3346, 3000, 12109, 20480, 20480, 20480, 20480, 20480, 20480 }, + + { 20480, 20480, 20480, 20480, 20480, 20480, 15725, 3658, + 20480, 1201, 10854, 18432, 20480, 20480, 20480, 20480, 20480 } + +}; + + +/** + * Long Term Postfilter Analysis (cf. 3.7.6) + * with the addition of `h[239] = 0` + */ + +const float lc3_ltpf_h12k8[240] = { + -2.04305583e-05, -4.46345894e-05, -7.16366399e-05, -1.00101113e-04, + -1.28372848e-04, -1.54543830e-04, -1.76544567e-04, -1.92256960e-04, + -1.99643819e-04, -1.96888686e-04, -1.82538332e-04, -1.55639427e-04, + -1.15860365e-04, -6.35893034e-05, 2.81006480e-19, 7.29218021e-05, + 1.52397076e-04, 2.34920777e-04, 3.16378650e-04, 3.92211738e-04, + 4.57623849e-04, 5.07824294e-04, 5.38295523e-04, 5.45072918e-04, + 5.25022155e-04, 4.76098424e-04, 3.97571380e-04, 2.90200217e-04, + 1.56344667e-04, -5.81880142e-19, -1.73252713e-04, -3.56385965e-04, + -5.41155231e-04, -7.18414023e-04, -8.78505232e-04, -1.01171451e-03, + -1.10876706e-03, -1.16134522e-03, -1.16260169e-03, -1.10764097e-03, + -9.93941563e-04, -8.21692190e-04, -5.94017766e-04, -3.17074654e-04, + 9.74695082e-19, 3.45293760e-04, 7.04480871e-04, 1.06133447e-03, + 1.39837473e-03, 1.69763080e-03, 1.94148675e-03, 2.11357591e-03, + 2.19968245e-03, 2.18860625e-03, 2.07294546e-03, 1.84975249e-03, + 1.52102188e-03, 1.09397426e-03, 5.81108062e-04, -1.42248266e-18, + -6.27153730e-04, -1.27425140e-03, -1.91223839e-03, -2.51026925e-03, + -3.03703830e-03, -3.46222687e-03, -3.75800672e-03, -3.90053247e-03, + -3.87135231e-03, -3.65866558e-03, -3.25835851e-03, -2.67475555e-03, + -1.92103305e-03, -1.01925433e-03, 1.86962369e-18, 1.09841545e-03, + 2.23113197e-03, 3.34830927e-03, 4.39702277e-03, 5.32342672e-03, + 6.07510531e-03, 6.60352025e-03, 6.86645399e-03, 6.83034270e-03, + 6.47239234e-03, 5.78237521e-03, 4.76401273e-03, 3.43586351e-03, + 1.83165284e-03, -2.25189837e-18, -1.99647619e-03, -4.08266886e-03, + -6.17308037e-03, -8.17444895e-03, -9.98882386e-03, -1.15169871e-02, + -1.26621006e-02, -1.33334458e-02, -1.34501120e-02, -1.29444881e-02, + -1.17654154e-02, -9.88086732e-03, -7.28003640e-03, -3.97473021e-03, + 2.50961778e-18, 4.58604422e-03, 9.70324900e-03, 1.52512477e-02, + 2.11120585e-02, 2.71533724e-02, 3.32324245e-02, 3.92003203e-02, + 4.49066644e-02, 5.02043309e-02, 5.49542017e-02, 5.90297032e-02, + 6.23209727e-02, 6.47385023e-02, 6.62161245e-02, 6.67132287e-02, + 6.62161245e-02, 6.47385023e-02, 6.23209727e-02, 5.90297032e-02, + 5.49542017e-02, 5.02043309e-02, 4.49066644e-02, 3.92003203e-02, + 3.32324245e-02, 2.71533724e-02, 2.11120585e-02, 1.52512477e-02, + 9.70324900e-03, 4.58604422e-03, 2.50961778e-18, -3.97473021e-03, + -7.28003640e-03, -9.88086732e-03, -1.17654154e-02, -1.29444881e-02, + -1.34501120e-02, -1.33334458e-02, -1.26621006e-02, -1.15169871e-02, + -9.98882386e-03, -8.17444895e-03, -6.17308037e-03, -4.08266886e-03, + -1.99647619e-03, -2.25189837e-18, 1.83165284e-03, 3.43586351e-03, + 4.76401273e-03, 5.78237521e-03, 6.47239234e-03, 6.83034270e-03, + 6.86645399e-03, 6.60352025e-03, 6.07510531e-03, 5.32342672e-03, + 4.39702277e-03, 3.34830927e-03, 2.23113197e-03, 1.09841545e-03, + 1.86962369e-18, -1.01925433e-03, -1.92103305e-03, -2.67475555e-03, + -3.25835851e-03, -3.65866558e-03, -3.87135231e-03, -3.90053247e-03, + -3.75800672e-03, -3.46222687e-03, -3.03703830e-03, -2.51026925e-03, + -1.91223839e-03, -1.27425140e-03, -6.27153730e-04, -1.42248266e-18, + 5.81108062e-04, 1.09397426e-03, 1.52102188e-03, 1.84975249e-03, + 2.07294546e-03, 2.18860625e-03, 2.19968245e-03, 2.11357591e-03, + 1.94148675e-03, 1.69763080e-03, 1.39837473e-03, 1.06133447e-03, + 7.04480871e-04, 3.45293760e-04, 9.74695082e-19, -3.17074654e-04, + -5.94017766e-04, -8.21692190e-04, -9.93941563e-04, -1.10764097e-03, + -1.16260169e-03, -1.16134522e-03, -1.10876706e-03, -1.01171451e-03, + -8.78505232e-04, -7.18414023e-04, -5.41155231e-04, -3.56385965e-04, + -1.73252713e-04, -5.81880142e-19, 1.56344667e-04, 2.90200217e-04, + 3.97571380e-04, 4.76098424e-04, 5.25022155e-04, 5.45072918e-04, + 5.38295523e-04, 5.07824294e-04, 4.57623849e-04, 3.92211738e-04, + 3.16378650e-04, 2.34920777e-04, 1.52397076e-04, 7.29218021e-05, + 2.81006480e-19, -6.35893034e-05, -1.15860365e-04, -1.55639427e-04, + -1.82538332e-04, -1.96888686e-04, -1.99643819e-04, -1.92256960e-04, + -1.76544567e-04, -1.54543830e-04, -1.28372848e-04, -1.00101113e-04, + -7.16366399e-05, -4.46345894e-05, -2.04305583e-05, 0.0 , +}; + + +/** + * Long Term Postfilter Synthesis (cf. 3.7.6) + * with - addition of a 0 for num coefficients + * - remove of first 0 den coefficients + */ + +const float *lc3_ltpf_cnum[LC3_NUM_SRATE][4] = { + + [LC3_SRATE_8K] = { + (const float []){ + 6.02361821e-01, 4.19760926e-01, -1.88342453e-02, 0. }, + (const float []){ + 5.99476858e-01, 4.19760926e-01, -1.59492828e-02, 0. }, + (const float []){ + 5.96776466e-01, 4.19760926e-01, -1.32488910e-02, 0. }, + (const float []){ + 5.94241012e-01, 4.19760926e-01, -1.07134366e-02, 0. }, + }, + + [LC3_SRATE_16K] = { + (const float []){ + 6.02361821e-01, 4.19760926e-01, -1.88342453e-02, 0. }, + (const float []){ + 5.99476858e-01, 4.19760926e-01, -1.59492828e-02, 0. }, + (const float []){ + 5.96776466e-01, 4.19760926e-01, -1.32488910e-02, 0. }, + (const float []){ + 5.94241012e-01, 4.19760926e-01, -1.07134366e-02, 0. }, + }, + + [LC3_SRATE_24K] = { + (const float []){ + 3.98969559e-01, 5.14250861e-01, 1.00438297e-01, -1.27889396e-02, + -1.57228008e-03, 0. }, + (const float []){ + 3.94863491e-01, 5.12381921e-01, 1.04319493e-01, -1.09199996e-02, + -1.34740833e-03, 0. }, + (const float []){ + 3.90984448e-01, 5.10605352e-01, 1.07983252e-01, -9.14343107e-03, + -1.13212462e-03, 0. }, + (const float []){ + 3.87309389e-01, 5.08912208e-01, 1.11451738e-01, -7.45028713e-03, + -9.25551405e-04, 0. }, + }, + + [LC3_SRATE_32K] = { + (const float []){ + 2.98237945e-01, 4.65280920e-01, 2.10599743e-01, 3.76678038e-02, + -1.01569616e-02, -2.53588100e-03, -3.18294617e-04, 0. }, + (const float []){ + 2.94383415e-01, 4.61929400e-01, 2.12946577e-01, 4.06617500e-02, + -8.69327230e-03, -2.17830711e-03, -2.74288806e-04, 0. }, + (const float []){ + 2.90743921e-01, 4.58746191e-01, 2.15145697e-01, 4.35010477e-02, + -7.29549535e-03, -1.83439564e-03, -2.31692019e-04, 0. }, + (const float []){ + 2.87297585e-01, 4.55714889e-01, 2.17212695e-01, 4.62008888e-02, + -5.95746380e-03, -1.50293428e-03, -1.90385191e-04, 0. }, + }, + + [LC3_SRATE_48K] = { + (const float []){ + 1.98136374e-01, 3.52449490e-01, 2.51369527e-01, 1.42414624e-01, + 5.70473102e-02, 9.29336624e-03, -7.22602537e-03, -3.17267989e-03, + -1.12183596e-03, -2.90295724e-04, -4.27081559e-05, 0. }, + (const float []){ + 1.95070943e-01, 3.48466041e-01, 2.50998846e-01, 1.44116741e-01, + 5.92894732e-02, 1.10892383e-02, -6.19290811e-03, -2.72670551e-03, + -9.66712583e-04, -2.50810092e-04, -3.69993877e-05, 0. }, + (const float []){ + 1.92181006e-01, 3.44694556e-01, 2.50622009e-01, 1.45710245e-01, + 6.14113213e-02, 1.27994140e-02, -5.20372109e-03, -2.29732451e-03, + -8.16560813e-04, -2.12385575e-04, -3.14127133e-05, 0. }, + (const float []){ + 1.89448531e-01, 3.41113925e-01, 2.50240688e-01, 1.47206563e-01, + 6.34247723e-02, 1.44320343e-02, -4.25444914e-03, -1.88308147e-03, + -6.70961906e-04, -1.74936334e-04, -2.59386474e-05, 0. }, + } +}; + +const float *lc3_ltpf_cden[LC3_NUM_SRATE][4] = { + + [LC3_SRATE_8K] = { + (const float []){ + 2.09880463e-01, 5.83527575e-01, 2.09880463e-01, 0.00000000e+00 }, + (const float []){ + 1.06999186e-01, 5.50075002e-01, 3.35690625e-01, 6.69885837e-03 }, + (const float []){ + 3.96711478e-02, 4.59220930e-01, 4.59220930e-01, 3.96711478e-02 }, + (const float []){ + 6.69885837e-03, 3.35690625e-01, 5.50075002e-01, 1.06999186e-01 }, + }, + + [LC3_SRATE_16K] = { + (const float []){ + 2.09880463e-01, 5.83527575e-01, 2.09880463e-01, 0.00000000e+00 }, + (const float []){ + 1.06999186e-01, 5.50075002e-01, 3.35690625e-01, 6.69885837e-03 }, + (const float []){ + 3.96711478e-02, 4.59220930e-01, 4.59220930e-01, 3.96711478e-02 }, + (const float []){ + 6.69885837e-03, 3.35690625e-01, 5.50075002e-01, 1.06999186e-01 }, + }, + + [LC3_SRATE_24K] = { + (const float []){ + 6.32223163e-02, 2.50730961e-01, 3.71390943e-01, 2.50730961e-01, + 6.32223163e-02, 0.00000000e+00 }, + (const float []){ + 3.45927217e-02, 1.98651560e-01, 3.62641173e-01, 2.98675055e-01, + 1.01309287e-01, 4.26354371e-03 }, + (const float []){ + 1.53574678e-02, 1.47434488e-01, 3.37425955e-01, 3.37425955e-01, + 1.47434488e-01, 1.53574678e-02 }, + (const float []){ + 4.26354371e-03, 1.01309287e-01, 2.98675055e-01, 3.62641173e-01, + 1.98651560e-01, 3.45927217e-02 }, + }, + + [LC3_SRATE_32K] = { + (const float []){ + 2.90040188e-02, 1.12985742e-01, 2.21202403e-01, 2.72390947e-01, + 2.21202403e-01, 1.12985742e-01, 2.90040188e-02, 0.00000000e+00 }, + (const float []){ + 1.70315342e-02, 8.72250379e-02, 1.96140776e-01, 2.68923798e-01, + 2.42499910e-01, 1.40577336e-01, 4.47487717e-02, 3.12703024e-03 }, + (const float []){ + 8.56367375e-03, 6.42622294e-02, 1.68767671e-01, 2.58744594e-01, + 2.58744594e-01, 1.68767671e-01, 6.42622294e-02, 8.56367375e-03 }, + (const float []){ + 3.12703024e-03, 4.47487717e-02, 1.40577336e-01, 2.42499910e-01, + 2.68923798e-01, 1.96140776e-01, 8.72250379e-02, 1.70315342e-02 }, + }, + + [LC3_SRATE_48K] = { + (const float []){ + 1.08235939e-02, 3.60896922e-02, 7.67640147e-02, 1.24153058e-01, + 1.62759644e-01, 1.77677142e-01, 1.62759644e-01, 1.24153058e-01, + 7.67640147e-02, 3.60896922e-02, 1.08235939e-02, 0.00000000e+00 }, + (const float []){ + 7.04140493e-03, 2.81970232e-02, 6.54704494e-02, 1.12464799e-01, + 1.54841896e-01, 1.76712238e-01, 1.69150721e-01, 1.35290158e-01, + 8.85142501e-02, 4.49935385e-02, 1.55761371e-02, 2.03972196e-03 }, + (const float []){ + 4.14699847e-03, 2.13575731e-02, 5.48273558e-02, 1.00497144e-01, + 1.45606034e-01, 1.73843984e-01, 1.73843984e-01, 1.45606034e-01, + 1.00497144e-01, 5.48273558e-02, 2.13575731e-02, 4.14699847e-03 }, + (const float []){ + 2.03972196e-03, 1.55761371e-02, 4.49935385e-02, 8.85142501e-02, + 1.35290158e-01, 1.69150721e-01, 1.76712238e-01, 1.54841896e-01, + 1.12464799e-01, 6.54704494e-02, 2.81970232e-02, 7.04140493e-03 }, + } +}; + + +/** + * Spectral Data Arithmetic Coding (cf. 3.7.7) + * The number of bits are given at 2048th of bits + * + * The dimensions of the lookup table are set as following : + * 1: Rate selection + * 2: Half spectrum selection (1st half / 2nd half) + * 3: State of the arithmetic coder + * 4: Number of msb bits (significant - 2), limited to 3 + * + * table[r][h][s][k] = table(normative)[s + h*256 + r*512 + k*1024] + */ + +const uint8_t lc3_spectrum_lookup[2][2][256][4] = { + + { { { 1,13, 0, 0 }, { 39,13, 0, 0 }, { 7,13, 0, 0 }, { 25,13, 0, 0 }, + { 22,13, 0, 0 }, { 22,13, 0, 0 }, { 28,13, 0, 0 }, { 22,13, 0, 0 }, + { 22,60, 0, 0 }, { 22,60, 0, 0 }, { 22,60, 0, 0 }, { 28,60, 0, 0 }, + { 28,60, 0, 0 }, { 28,60,13, 0 }, { 34,60,13, 0 }, { 31,16,13, 0 }, + { 31,16,13, 0 }, { 40, 0, 0, 0 }, { 43, 0, 0, 0 }, { 46, 0, 0, 0 }, + { 49, 0, 0, 0 }, { 52, 0, 0, 0 }, { 14, 0, 0, 0 }, { 17, 0, 0, 0 }, + { 36, 0, 0, 0 }, { 36, 0, 0, 0 }, { 36, 0, 0, 0 }, { 38, 0, 0, 0 }, + { 0, 0, 0, 0 }, { 57, 0, 0, 0 }, { 38,13, 0, 0 }, { 22,60, 0, 0 }, + { 0, 0, 0, 0 }, { 8, 0, 0, 0 }, { 9, 0, 0, 0 }, { 11, 0, 0, 0 }, + { 47, 0, 0, 0 }, { 14, 0, 0, 0 }, { 14, 0, 0, 0 }, { 17, 0, 0, 0 }, + { 36, 0, 0, 0 }, { 36, 0, 0, 0 }, { 36, 0, 0, 0 }, { 38, 0, 0, 0 }, + { 59, 0, 0, 0 }, { 59, 0, 0, 0 }, { 38,13, 0, 0 }, { 22,60, 0, 0 }, + { 22,60, 0, 0 }, { 26, 0, 0, 0 }, { 46, 0, 0, 0 }, { 29, 0, 0, 0 }, + { 30, 0, 0, 0 }, { 32, 0, 0, 0 }, { 33, 0, 0, 0 }, { 35, 0, 0, 0 }, + { 36, 0, 0, 0 }, { 36, 0, 0, 0 }, { 36, 0, 0, 0 }, { 38, 0, 0, 0 }, + { 0,13, 0, 0 }, { 59,13, 0, 0 }, { 23,13, 0, 0 }, { 22,60, 0, 0 }, + { 46,60, 0, 0 }, { 46, 0, 0, 0 }, { 45, 0, 0, 0 }, { 47, 0, 0, 0 }, + { 48, 0, 0, 0 }, { 50, 0, 0, 0 }, { 50, 0, 0, 0 }, { 18, 0, 0, 0 }, + { 54, 0, 0, 0 }, { 54, 0, 0, 0 }, { 54, 0, 0, 0 }, { 38, 0, 0, 0 }, + { 59,13, 0, 0 }, { 59,13, 0, 0 }, { 59,13, 0, 0 }, { 22,60, 0, 0 }, + { 0,60, 0, 0 }, { 62, 0, 0, 0 }, { 63, 0, 0, 0 }, { 3, 0, 0, 0 }, + { 33, 0, 0, 0 }, { 2, 0, 0, 0 }, { 2, 0, 0, 0 }, { 61, 0, 0, 0 }, + { 20, 0, 0, 0 }, { 20, 0, 0, 0 }, { 20,13, 0, 0 }, { 21,13, 0, 0 }, + { 59,13, 0, 0 }, { 59,13, 0, 0 }, { 39,13, 0, 0 }, { 28,60, 0, 0 }, + { 28,60, 0, 0 }, { 63, 0, 0, 0 }, { 63, 0, 0, 0 }, { 3, 0, 0, 0 }, + { 33, 0, 0, 0 }, { 2, 0, 0, 0 }, { 2, 0, 0, 0 }, { 61, 0, 0, 0 }, + { 38, 0, 0, 0 }, { 38, 0, 0, 0 }, { 38,13, 0, 0 }, { 21,13, 0, 0 }, + { 59,13, 0, 0 }, { 59,13, 0, 0 }, { 39,13, 0, 0 }, { 28,60, 0, 0 }, + { 28,60, 0, 0 }, { 6, 0, 0, 0 }, { 6, 0, 0, 0 }, { 6, 0, 0, 0 }, + { 2, 0, 0, 0 }, { 18, 0, 0, 0 }, { 61, 0, 0, 0 }, { 20, 0, 0, 0 }, + { 21, 0, 0, 0 }, { 21, 0, 0, 0 }, { 21,13, 0, 0 }, { 59,13, 0, 0 }, + { 39,13, 0, 0 }, { 39,13, 0, 0 }, { 7,13, 0, 0 }, { 34,60,13, 0 }, + { 34,60,13, 0 }, { 34,60,13, 0 }, { 34,60,13, 0 }, { 34,60,13, 0 }, + { 34,60,13, 0 }, { 34,60,13, 0 }, { 34,60,13, 0 }, { 34,60,13, 0 }, + { 34,60,13, 0 }, { 34,60,13, 0 }, { 34,60,13, 0 }, { 34,60,13, 0 }, + { 34,60,13, 0 }, { 34,60,13, 0 }, { 34,60,13, 0 }, { 34,60,13, 0 }, + { 34,60,13, 0 }, { 51, 0, 0, 0 }, { 51, 0, 0, 0 }, { 51, 0, 0, 0 }, + { 53, 0, 0, 0 }, { 54, 0, 0, 0 }, { 20, 0, 0, 0 }, { 38, 0, 0, 0 }, + { 38, 0, 0, 0 }, { 57, 0, 0, 0 }, { 39,13, 0, 0 }, { 39,13, 0, 0 }, + { 39,13, 0, 0 }, { 7,13, 0, 0 }, { 24,13, 0, 0 }, { 34,60,13, 0 }, + { 4,60, 0, 0 }, { 4,60, 0, 0 }, { 4,60, 0, 0 }, { 4,60, 0, 0 }, + { 4,60, 0, 0 }, { 4,60, 0, 0 }, { 4,60, 0, 0 }, { 4,60, 0, 0 }, + { 4,60, 0, 0 }, { 4,60, 0, 0 }, { 4,60, 0, 0 }, { 4,60, 0, 0 }, + { 4,60, 0, 0 }, { 4,60, 0, 0 }, { 4,60, 0, 0 }, { 4,60, 0, 0 }, + { 4,60, 0, 0 }, { 4, 0, 0, 0 }, { 4, 0, 0, 0 }, { 4, 0, 0, 0 }, + { 4, 0, 0, 0 }, { 56, 0, 0, 0 }, { 38, 0, 0, 0 }, { 57, 0, 0, 0 }, + { 57,13, 0, 0 }, { 59,13, 0, 0 }, { 7,13, 0, 0 }, { 7,13, 0, 0 }, + { 7,13, 0, 0 }, { 42,13, 0, 0 }, { 42,13, 0, 0 }, { 34,60,13, 0 }, + { 0,60,13, 0 }, { 0,60,13, 0 }, { 0,60,13, 0 }, { 0,60,13, 0 }, + { 0,60,13, 0 }, { 0,60,13, 0 }, { 0,60,13, 0 }, { 0,60,13, 0 }, + { 0,60,13, 0 }, { 0,60,13, 0 }, { 0,60,13, 0 }, { 0,60,13, 0 }, + { 0,60,13, 0 }, { 0,60,13, 0 }, { 0,60,13, 0 }, { 0,60,13, 0 }, + { 0,60,13, 0 }, { 5, 0, 0, 0 }, { 4, 0, 0, 0 }, { 4, 0, 0, 0 }, + { 5, 0, 0, 0 }, { 21, 0, 0, 0 }, { 21, 0, 0, 0 }, { 59,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 7,13, 0, 0 }, + { 25,13, 0, 0 }, { 25,13, 0, 0 }, { 25,13, 0, 0 }, { 34,60,13, 0 }, + { 4,13, 0, 0 }, { 4,13, 0, 0 }, { 4,13, 0, 0 }, { 4,13, 0, 0 }, + { 5,13, 0, 0 }, { 23,13, 0, 0 }, { 23,13, 0, 0 }, { 39,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 42,13, 0, 0 }, + { 25,13, 0, 0 }, { 25,13, 0, 0 }, { 22,13, 0, 0 }, { 31,60,13, 0 }, + { 31,60,13, 0 }, { 39,60, 0, 0 }, { 39,60, 0, 0 }, { 39,60, 0, 0 }, + { 39,60, 0, 0 }, { 7,60, 0, 0 }, { 7,60, 0, 0 }, { 42,60, 0, 0 }, + { 0,60, 0, 0 }, { 25,60, 0, 0 }, { 22,60, 0, 0 }, { 22,60, 0, 0 }, + { 22,60, 0, 0 }, { 28,60, 0, 0 }, { 34,60, 0, 0 }, { 31,16,13, 0 } }, + + { { 55, 0,13, 0 }, { 55, 0,13, 0 }, { 55, 0,13, 0 }, { 55, 0,13, 0 }, + { 55, 0,13, 0 }, { 55, 0,13, 0 }, { 55, 0,13, 0 }, { 55, 0,13, 0 }, + { 55, 0,13, 0 }, { 55, 0,13, 0 }, { 55, 0,13, 0 }, { 55, 0,13, 0 }, + { 55, 0,13, 0 }, { 55, 0,13, 0 }, { 55, 0,13, 0 }, { 55, 0,13, 0 }, + { 55, 0,13, 0 }, { 55, 0, 0, 0 }, { 40, 0, 0, 0 }, { 8, 0, 0, 0 }, + { 9, 0, 0, 0 }, { 49, 0, 0, 0 }, { 49, 0, 0, 0 }, { 52, 0, 0, 0 }, + { 17, 0, 0, 0 }, { 17, 0, 0, 0 }, { 17, 0, 0, 0 }, { 4,13, 0, 0 }, + { 0,13, 0, 0 }, { 20,13, 0, 0 }, { 17, 0, 0, 0 }, { 60,13,60,13 }, + { 40, 0, 0,13 }, { 40, 0, 0, 0 }, { 8, 0, 0, 0 }, { 43, 0, 0, 0 }, + { 27, 0, 0, 0 }, { 49, 0, 0, 0 }, { 49, 0, 0, 0 }, { 14, 0, 0, 0 }, + { 17, 0, 0, 0 }, { 17, 0, 0, 0 }, { 17, 0, 0, 0 }, { 36, 0, 0, 0 }, + { 42,13, 0, 0 }, { 42,13, 0, 0 }, { 17, 0, 0, 0 }, { 57,60,13, 0 }, + { 57, 0,13, 0 }, { 40, 0, 0, 0 }, { 8, 0, 0, 0 }, { 26, 0, 0, 0 }, + { 27, 0, 0, 0 }, { 49, 0, 0, 0 }, { 12, 0, 0, 0 }, { 14, 0, 0, 0 }, + { 17, 0, 0, 0 }, { 17, 0, 0, 0 }, { 17, 0, 0, 0 }, { 36, 0, 0, 0 }, + { 0, 0,13, 0 }, { 38, 0,13, 0 }, { 36,13, 0, 0 }, { 1,60, 0, 0 }, + { 8,60, 0, 0 }, { 8, 0, 0, 0 }, { 43, 0, 0, 0 }, { 9, 0, 0, 0 }, + { 11, 0, 0, 0 }, { 49, 0, 0, 0 }, { 12, 0, 0, 0 }, { 14, 0, 0, 0 }, + { 14, 0,13, 0 }, { 33, 0,13, 0 }, { 50, 0,13, 0 }, { 50, 0, 0, 0 }, + { 50, 0,13, 0 }, { 61, 0,13, 0 }, { 36,13, 0, 0 }, { 39,60, 0, 0 }, + { 8,60, 0, 0 }, { 8, 0, 0, 0 }, { 43, 0, 0, 0 }, { 46, 0, 0, 0 }, + { 49, 0, 0, 0 }, { 52, 0, 0, 0 }, { 30, 0, 0, 0 }, { 14, 0, 0, 0 }, + { 14, 0,13, 0 }, { 33, 0,13, 0 }, { 50, 0,13, 0 }, { 50, 0,13, 0 }, + { 50,13,13, 0 }, { 50,13, 0, 0 }, { 18,13,13, 0 }, { 25,60,13, 0 }, + { 8,60,13,13 }, { 8, 0, 0,13 }, { 43, 0, 0,13 }, { 46, 0, 0,13 }, + { 49, 0, 0,13 }, { 52, 0, 0, 0 }, { 30, 0, 0, 0 }, { 14, 0, 0, 0 }, + { 14, 0, 0, 0 }, { 18, 0,60, 0 }, { 5, 0, 0,13 }, { 5, 0, 0,13 }, + { 5, 0, 0,13 }, { 61,13, 0,13 }, { 18,13,13, 0 }, { 23,13,60, 0 }, + { 43,13, 0,13 }, { 43, 0, 0,13 }, { 43, 0, 0,13 }, { 9, 0, 0,13 }, + { 49, 0, 0,13 }, { 52, 0, 0, 0 }, { 3, 0, 0, 0 }, { 14, 0, 0, 0 }, + { 14, 0, 0, 0 }, { 50, 0, 0, 0 }, { 50,13,13, 0 }, { 50,13,13, 0 }, + { 50,13,13, 0 }, { 61, 0, 0, 0 }, { 17,13,13, 0 }, { 24,60,13, 0 }, + { 43,60,13, 0 }, { 43,60,13, 0 }, { 43,60,13, 0 }, { 43,60,13, 0 }, + { 43,60,13, 0 }, { 43,60,13, 0 }, { 43,60,13, 0 }, { 43,60,13, 0 }, + { 43,60,13, 0 }, { 43,60,13, 0 }, { 43,60,13, 0 }, { 43,60,13, 0 }, + { 43,60,13, 0 }, { 43,60,13, 0 }, { 43,60,13, 0 }, { 43,60,13, 0 }, + { 43,60,13, 0 }, { 43, 0, 0, 0 }, { 43, 0,19, 0 }, { 9, 0, 0, 0 }, + { 11, 0, 0, 0 }, { 52, 0, 0, 0 }, { 52, 0, 0, 0 }, { 14, 0, 0, 0 }, + { 14, 0, 0, 0 }, { 17, 0, 0, 0 }, { 61,13, 0, 0 }, { 61,13, 0, 0 }, + { 61,13, 0, 0 }, { 54, 0, 0, 0 }, { 17, 0,13,13 }, { 39,13,13, 0 }, + { 45,13,13, 0 }, { 45,13,13, 0 }, { 45,13,13, 0 }, { 45,13,13, 0 }, + { 45,13,13, 0 }, { 45,13,13, 0 }, { 45,13,13, 0 }, { 45,13,13, 0 }, + { 45,13,13, 0 }, { 45,13,13, 0 }, { 45,13,13, 0 }, { 45,13,13, 0 }, + { 45,13,13, 0 }, { 45,13,13, 0 }, { 45,13,13, 0 }, { 45,13,13, 0 }, + { 45,13,13, 0 }, { 45, 0,13, 0 }, { 44, 0,13, 0 }, { 27, 0, 0, 0 }, + { 29, 0, 0, 0 }, { 52, 0, 0, 0 }, { 48, 0, 0, 0 }, { 52, 0, 0, 0 }, + { 52, 0, 0, 0 }, { 17, 0, 0, 0 }, { 17, 0, 0, 0 }, { 17, 0,19, 0 }, + { 17, 0,13, 0 }, { 2, 0,13, 0 }, { 17, 0,13, 0 }, { 7,13, 0, 0 }, + { 27, 0, 0,13 }, { 27, 0, 0,13 }, { 27, 0, 0,13 }, { 27, 0, 0,13 }, + { 27, 0, 0,13 }, { 27, 0, 0,13 }, { 27, 0, 0,13 }, { 27, 0, 0,13 }, + { 27, 0, 0,13 }, { 27, 0, 0,13 }, { 27, 0, 0,13 }, { 27, 0, 0,13 }, + { 27, 0, 0,13 }, { 27, 0, 0,13 }, { 27, 0, 0,13 }, { 27, 0, 0,13 }, + { 27, 0, 0,13 }, { 27, 0, 0,13 }, { 9, 0, 0,13 }, { 27, 0, 0,13 }, + { 27, 0, 0,13 }, { 12, 0, 0,13 }, { 52, 0, 0,13 }, { 14, 0, 0,13 }, + { 14, 0, 0,13 }, { 58, 0, 0,13 }, { 41, 0, 0,13 }, { 41, 0, 0,13 }, + { 41, 0, 0,13 }, { 6, 0, 0,13 }, { 17,60, 0,13 }, { 37, 0,19,13 }, + { 9, 0, 0,13 }, { 9,16, 0,13 }, { 9, 0, 0,13 }, { 27, 0, 0,13 }, + { 11, 0, 0,13 }, { 49, 0, 0, 0 }, { 12, 0, 0, 0 }, { 52, 0, 0, 0 }, + { 14, 0, 0, 0 }, { 14, 0, 0, 0 }, { 14, 0, 0, 0 }, { 50, 0, 0, 0 }, + { 0, 0, 0,13 }, { 53, 0, 0,13 }, { 17, 0, 0,13 }, { 28, 0,13, 0 }, + { 52, 0,13, 0 }, { 52, 0,13, 0 }, { 49, 0,13, 0 }, { 52, 0, 0, 0 }, + { 12, 0, 0, 0 }, { 52, 0, 0, 0 }, { 30, 0, 0, 0 }, { 14, 0, 0, 0 }, + { 14, 0, 0, 0 }, { 17, 0, 0, 0 }, { 2, 0, 0, 0 }, { 2, 0, 0, 0 }, + { 2, 0, 0, 0 }, { 38, 0, 0, 0 }, { 38, 0, 0, 0 }, { 34, 0, 0, 0 } } }, + + { { { 31,16,60,13 }, { 34,16,13, 0 }, { 34,16,13, 0 }, { 31,16,13, 0 }, + { 31,16,13, 0 }, { 31,16,13, 0 }, { 31,16,13, 0 }, { 19,16,60, 0 }, + { 19,16,60, 0 }, { 19,16,60, 0 }, { 19,16,60, 0 }, { 19,16,60, 0 }, + { 19,16,60, 0 }, { 19,16,60, 0 }, { 31,16,60,13 }, { 19,37,16,60 }, + { 44, 0, 0,60 }, { 44, 0, 0, 0 }, { 62, 0, 0, 0 }, { 30, 0, 0, 0 }, + { 32, 0, 0, 0 }, { 58, 0, 0, 0 }, { 35, 0, 0, 0 }, { 36, 0, 0, 0 }, + { 36, 0, 0, 0 }, { 38,13, 0, 0 }, { 0,13, 0, 0 }, { 59,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 39,13, 0, 0 }, { 34,60,13, 0 }, + { 34, 0,13, 0 }, { 45, 0, 0, 0 }, { 47, 0, 0, 0 }, { 48, 0, 0, 0 }, + { 33, 0, 0, 0 }, { 35, 0, 0, 0 }, { 35, 0, 0, 0 }, { 36, 0, 0, 0 }, + { 38,13, 0, 0 }, { 38,13, 0, 0 }, { 38,13, 0, 0 }, { 59,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 39,13, 0, 0 }, { 34,60,13, 0 }, + { 34, 0,13, 0 }, { 62, 0, 0, 0 }, { 30, 0, 0, 0 }, { 15, 0, 0, 0 }, + { 50, 0, 0, 0 }, { 53, 0, 0, 0 }, { 53, 0, 0, 0 }, { 54,13, 0, 0 }, + { 21,13, 0, 0 }, { 21,13, 0, 0 }, { 21,13, 0, 0 }, { 59,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 34,60,13, 0 }, + { 30, 0,13, 0 }, { 30, 0, 0, 0 }, { 48, 0, 0, 0 }, { 33, 0, 0, 0 }, + { 58, 0, 0, 0 }, { 18, 0, 0, 0 }, { 18, 0, 0, 0 }, { 56,13, 0, 0 }, + { 23,13, 0, 0 }, { 23,13, 0, 0 }, { 23,13, 0, 0 }, { 59,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 24,13, 0, 0 }, { 34,60,13, 0 }, + { 34, 0,13, 0 }, { 6, 0, 0, 0 }, { 6, 0, 0, 0 }, { 58, 0, 0, 0 }, + { 53, 0, 0, 0 }, { 54, 0, 0, 0 }, { 54, 0, 0, 0 }, { 21,13, 0, 0 }, + { 59,13, 0, 0 }, { 59,13, 0, 0 }, { 59,13, 0, 0 }, { 39,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 42,60, 0, 0 }, { 34,16,13, 0 }, + { 6, 0,13, 0 }, { 6, 0, 0, 0 }, { 33, 0, 0, 0 }, { 58, 0, 0, 0 }, + { 53, 0, 0, 0 }, { 54, 0, 0, 0 }, { 61, 0, 0, 0 }, { 21,13, 0, 0 }, + { 59,13, 0, 0 }, { 59,13, 0, 0 }, { 59,13, 0, 0 }, { 39,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 42,60, 0, 0 }, { 34,16,13, 0 }, + { 34, 0,13, 0 }, { 51, 0, 0, 0 }, { 51, 0, 0, 0 }, { 53, 0, 0, 0 }, + { 54, 0, 0, 0 }, { 56,13, 0, 0 }, { 56,13, 0, 0 }, { 57,13, 0, 0 }, + { 39,13, 0, 0 }, { 39,13, 0, 0 }, { 39,13, 0, 0 }, { 7,13, 0, 0 }, + { 42,13, 0, 0 }, { 42,13, 0, 0 }, { 25,60, 0, 0 }, { 31,16,13, 0 }, + { 31, 0,13, 0 }, { 31, 0,13, 0 }, { 31, 0,13, 0 }, { 31, 0,13, 0 }, + { 31, 0,13, 0 }, { 31, 0,13, 0 }, { 31, 0,13, 0 }, { 31, 0,13, 0 }, + { 31, 0,13, 0 }, { 31, 0,13, 0 }, { 31, 0,13, 0 }, { 31, 0,13, 0 }, + { 31, 0,13, 0 }, { 31, 0,13, 0 }, { 31, 0,13, 0 }, { 31, 0,13, 0 }, + { 31, 0,13, 0 }, { 4, 0, 0, 0 }, { 4, 0, 0, 0 }, { 4, 0, 0, 0 }, + { 5,13, 0, 0 }, { 23,13, 0, 0 }, { 23,13, 0, 0 }, { 39,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 42,13, 0, 0 }, + { 25,13, 0, 0 }, { 25,13, 0, 0 }, { 22,60, 0, 0 }, { 31,16,60, 0 }, + { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, + { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, + { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, + { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, + { 31,13, 0, 0 }, { 5,13, 0, 0 }, { 5,13, 0, 0 }, { 5,13, 0, 0 }, + { 5,13, 0, 0 }, { 57,13, 0, 0 }, { 57,13, 0, 0 }, { 39,13, 0, 0 }, + { 24,13, 0, 0 }, { 24,13, 0, 0 }, { 24,13, 0, 0 }, { 42,13, 0, 0 }, + { 22,13, 0, 0 }, { 22,60, 0, 0 }, { 28,60,13, 0 }, { 31,16,60, 0 }, + { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, + { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, + { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, + { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, { 31,13, 0, 0 }, + { 31,13, 0, 0 }, { 41,13, 0, 0 }, { 41,13, 0, 0 }, { 41,13, 0, 0 }, + { 41,13, 0, 0 }, { 39,13, 0, 0 }, { 39,13, 0, 0 }, { 7,13, 0, 0 }, + { 42,13, 0, 0 }, { 42,13, 0, 0 }, { 42,13, 0, 0 }, { 25,13, 0, 0 }, + { 28,13, 0, 0 }, { 28,60, 0, 0 }, { 28,60,13, 0 }, { 31,16,60,13 }, + { 31,13, 0, 0 }, { 41,13, 0, 0 }, { 41,13, 0, 0 }, { 41,13, 0, 0 }, + { 41,13, 0, 0 }, { 39,13, 0, 0 }, { 39,13, 0, 0 }, { 24,13, 0, 0 }, + { 25,60, 0, 0 }, { 25,60, 0, 0 }, { 25,60, 0, 0 }, { 22,60, 0, 0 }, + { 28,60, 0, 0 }, { 28,60, 0, 0 }, { 34,60,13, 0 }, { 31,16,60,13 }, + { 31,60,13,13 }, { 10,60,13, 0 }, { 10,60,13, 0 }, { 10,60,13, 0 }, + { 10,60,13, 0 }, { 10,60,13, 0 }, { 10,60,13, 0 }, { 28,60,13, 0 }, + { 34,60,13, 0 }, { 34,60,13, 0 }, { 34,16,13, 0 }, { 34,16,13, 0 }, + { 34,16,60, 0 }, { 34,16,60, 0 }, { 31,16,60, 0 }, { 19,37,16,13 } }, + + { { 8, 0,16, 0 }, { 8, 0,16, 0 }, { 8, 0,16, 0 }, { 8, 0,16, 0 }, + { 8, 0,16, 0 }, { 8, 0,16, 0 }, { 8, 0,16, 0 }, { 8, 0,16, 0 }, + { 8, 0,16, 0 }, { 8, 0,16, 0 }, { 8, 0,16, 0 }, { 8, 0,16, 0 }, + { 8, 0,16, 0 }, { 8, 0,16, 0 }, { 8, 0,16, 0 }, { 8, 0,16, 0 }, + { 8, 0,16, 0 }, { 8, 0, 0, 0 }, { 9, 0, 0, 0 }, { 11, 0, 0, 0 }, + { 47, 0, 0, 0 }, { 32, 0, 0, 0 }, { 50, 0, 0, 0 }, { 18, 0, 0, 0 }, + { 18, 0, 0, 0 }, { 20, 0, 0, 0 }, { 21, 0, 0, 0 }, { 21, 0, 0, 0 }, + { 21,13, 0, 0 }, { 39,13, 0, 0 }, { 59,13, 0, 0 }, { 34,16,60, 0 }, + { 26, 0, 0, 0 }, { 26, 0, 0, 0 }, { 27, 0, 0, 0 }, { 29, 0, 0, 0 }, + { 30, 0, 0, 0 }, { 33, 0, 0, 0 }, { 50, 0, 0, 0 }, { 18, 0, 0, 0 }, + { 18, 0, 0, 0 }, { 20, 0, 0, 0 }, { 57, 0, 0, 0 }, { 57,13, 0, 0 }, + { 57,13, 0, 0 }, { 59,13, 0, 0 }, { 59,13, 0, 0 }, { 34,16,60, 0 }, + { 27, 0, 0, 0 }, { 27, 0, 0, 0 }, { 11, 0, 0, 0 }, { 12, 0, 0, 0 }, + { 48, 0, 0, 0 }, { 50, 0, 0, 0 }, { 58, 0, 0, 0 }, { 61, 0, 0, 0 }, + { 61, 0, 0, 0 }, { 56, 0, 0, 0 }, { 57,13, 0, 0 }, { 57,13, 0, 0 }, + { 57,13, 0, 0 }, { 59,13, 0, 0 }, { 39,13, 0, 0 }, { 34,16,60, 0 }, + { 45, 0, 0, 0 }, { 45, 0, 0, 0 }, { 12, 0, 0, 0 }, { 30, 0, 0, 0 }, + { 32, 0, 0, 0 }, { 2, 0, 0, 0 }, { 2, 0, 0, 0 }, { 61, 0, 0, 0 }, + { 38, 0, 0, 0 }, { 38, 0, 0, 0 }, { 38,13, 0, 0 }, { 57,13, 0, 0 }, + { 0,13, 0, 0 }, { 59,13, 0, 0 }, { 39,13, 0, 0 }, { 34,16,60, 0 }, + { 63, 0, 0, 0 }, { 63, 0, 0, 0 }, { 3, 0, 0, 0 }, { 32, 0, 0, 0 }, + { 58, 0, 0, 0 }, { 18, 0, 0, 0 }, { 18, 0, 0, 0 }, { 20, 0, 0, 0 }, + { 21, 0, 0, 0 }, { 21, 0, 0, 0 }, { 21,13, 0, 0 }, { 59,13, 0, 0 }, + { 39,13, 0, 0 }, { 39,13, 0, 0 }, { 7,13,13, 0 }, { 31,16,60, 0 }, + { 31, 0, 0, 0 }, { 3, 0, 0, 0 }, { 3, 0, 0, 0 }, { 33, 0, 0, 0 }, + { 58, 0, 0, 0 }, { 18, 0, 0, 0 }, { 18, 0, 0, 0 }, { 20, 0, 0, 0 }, + { 21, 0, 0, 0 }, { 21, 0, 0, 0 }, { 21,13, 0, 0 }, { 59,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 7,13,13, 0 }, { 31,16,60, 0 }, + { 6, 0, 0, 0 }, { 6, 0, 0, 0 }, { 51, 0, 0, 0 }, { 51, 0, 0, 0 }, + { 53, 0, 0, 0 }, { 54, 0, 0, 0 }, { 54, 0, 0, 0 }, { 38, 0, 0, 0 }, + { 57,13, 0, 0 }, { 57,13, 0, 0 }, { 57,13, 0, 0 }, { 39,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 42,60,13, 0 }, { 31,16,60, 0 }, + { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, + { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, + { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, + { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, + { 31, 0, 0, 0 }, { 51, 0, 0, 0 }, { 53, 0, 0, 0 }, { 53, 0, 0, 0 }, + { 54, 0, 0, 0 }, { 56, 0, 0, 0 }, { 56, 0, 0, 0 }, { 57,13, 0, 0 }, + { 59,13, 0, 0 }, { 59,13, 0, 0 }, { 59,13, 0, 0 }, { 7,13, 0, 0 }, + { 24,13, 0, 0 }, { 24,13, 0, 0 }, { 25,60,13, 0 }, { 31,16,60, 0 }, + { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, + { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, + { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, + { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, { 31, 0, 0, 0 }, + { 31, 0, 0, 0 }, { 4, 0, 0, 0 }, { 4, 0, 0, 0 }, { 4, 0, 0, 0 }, + { 54, 0, 0, 0 }, { 21,13, 0, 0 }, { 21, 0, 0, 0 }, { 57,13, 0, 0 }, + { 39,13, 0, 0 }, { 39,13, 0, 0 }, { 39,13, 0, 0 }, { 7,13, 0, 0 }, + { 42,13,13, 0 }, { 42,13,13, 0 }, { 22,60,13, 0 }, { 31,16,60, 0 }, + { 31,16, 0, 0 }, { 31,16, 0, 0 }, { 31,16, 0, 0 }, { 31,16, 0, 0 }, + { 31,16, 0, 0 }, { 31,16, 0, 0 }, { 31,16, 0, 0 }, { 31,16, 0, 0 }, + { 31,16, 0, 0 }, { 31,16, 0, 0 }, { 31,16, 0, 0 }, { 31,16, 0, 0 }, + { 31,16, 0, 0 }, { 31,16, 0, 0 }, { 31,16, 0, 0 }, { 31,16, 0, 0 }, + { 31,16, 0, 0 }, { 5, 0, 0, 0 }, { 5, 0, 0, 0 }, { 5, 0, 0, 0 }, + { 5,13, 0, 0 }, { 23,13, 0, 0 }, { 23,13, 0, 0 }, { 59,13, 0, 0 }, + { 7,13, 0, 0 }, { 7,13, 0, 0 }, { 7,13,13, 0 }, { 42,13,13, 0 }, + { 22,60,13, 0 }, { 22,60,13, 0 }, { 28,60,13, 0 }, { 31,16,60, 0 }, + { 31,13, 0, 0 }, { 4,13, 0, 0 }, { 4,13, 0, 0 }, { 4,13, 0, 0 }, + { 5,13, 0, 0 }, { 23,13, 0, 0 }, { 23,13, 0, 0 }, { 39,13,13, 0 }, + { 24,60,13, 0 }, { 24,60,13, 0 }, { 24,60,13, 0 }, { 25,60,13, 0 }, + { 28,60,13, 0 }, { 28,60,13, 0 }, { 34,16,13, 0 }, { 31,16,60, 0 }, + { 31,16,13, 0 }, { 10,16,13, 0 }, { 10,16,13, 0 }, { 10,16,13, 0 }, + { 10,16,13, 0 }, { 10,16,60, 0 }, { 10,16,60, 0 }, { 28,16,60, 0 }, + { 34,16,60, 0 }, { 34,16,60, 0 }, { 34,16,60, 0 }, { 31,16,60, 0 }, + { 31,16,60, 0 }, { 31,16,60, 0 }, { 31,16,60, 0 }, { 19,37,60, 0 } } } +}; + +const struct lc3_ac_model lc3_spectrum_models[] = { + + { { { 0, 1 }, { 1, 1 }, { 2, 175 }, { 177, 48 }, + { 225, 1 }, { 226, 1 }, { 227, 109 }, { 336, 36 }, + { 372, 171 }, { 543, 109 }, { 652, 47 }, { 699, 20 }, + { 719, 49 }, { 768, 36 }, { 804, 20 }, { 824, 10 }, + { 834, 190 } } }, + + { { { 0, 18 }, { 18, 26 }, { 44, 17 }, { 61, 10 }, + { 71, 27 }, { 98, 37 }, { 135, 24 }, { 159, 16 }, + { 175, 22 }, { 197, 32 }, { 229, 22 }, { 251, 14 }, + { 265, 17 }, { 282, 26 }, { 308, 20 }, { 328, 13 }, + { 341, 683 } } }, + + { { { 0, 71 }, { 71, 92 }, { 163, 49 }, { 212, 25 }, + { 237, 81 }, { 318, 102 }, { 420, 61 }, { 481, 33 }, + { 514, 42 }, { 556, 57 }, { 613, 39 }, { 652, 23 }, + { 675, 22 }, { 697, 30 }, { 727, 22 }, { 749, 15 }, + { 764, 260 } } }, + + { { { 0, 160 }, { 160, 130 }, { 290, 46 }, { 336, 18 }, + { 354, 121 }, { 475, 123 }, { 598, 55 }, { 653, 24 }, + { 677, 45 }, { 722, 55 }, { 777, 31 }, { 808, 15 }, + { 823, 19 }, { 842, 24 }, { 866, 15 }, { 881, 9 }, + { 890, 134 } } }, + + { { { 0, 71 }, { 71, 73 }, { 144, 33 }, { 177, 18 }, + { 195, 71 }, { 266, 76 }, { 342, 43 }, { 385, 26 }, + { 411, 34 }, { 445, 44 }, { 489, 30 }, { 519, 20 }, + { 539, 20 }, { 559, 27 }, { 586, 21 }, { 607, 15 }, + { 622, 402 } } }, + + { { { 0, 48 }, { 48, 60 }, { 108, 32 }, { 140, 19 }, + { 159, 58 }, { 217, 68 }, { 285, 42 }, { 327, 27 }, + { 354, 31 }, { 385, 42 }, { 427, 30 }, { 457, 21 }, + { 478, 19 }, { 497, 27 }, { 524, 21 }, { 545, 16 }, + { 561, 463 } } }, + + { { { 0, 138 }, { 138, 109 }, { 247, 43 }, { 290, 18 }, + { 308, 111 }, { 419, 112 }, { 531, 53 }, { 584, 25 }, + { 609, 46 }, { 655, 55 }, { 710, 32 }, { 742, 17 }, + { 759, 21 }, { 780, 27 }, { 807, 18 }, { 825, 11 }, + { 836, 188 } } }, + + { { { 0, 16 }, { 16, 24 }, { 40, 22 }, { 62, 17 }, + { 79, 24 }, { 103, 36 }, { 139, 31 }, { 170, 25 }, + { 195, 20 }, { 215, 30 }, { 245, 25 }, { 270, 20 }, + { 290, 15 }, { 305, 22 }, { 327, 19 }, { 346, 16 }, + { 362, 662 } } }, + + { { { 0, 579 }, { 579, 150 }, { 729, 12 }, { 741, 2 }, + { 743, 154 }, { 897, 73 }, { 970, 10 }, { 980, 2 }, + { 982, 14 }, { 996, 11 }, { 1007, 3 }, { 1010, 1 }, + { 1011, 3 }, { 1014, 3 }, { 1017, 1 }, { 1018, 1 }, + { 1019, 5 } } }, + + { { { 0, 398 }, { 398, 184 }, { 582, 25 }, { 607, 5 }, + { 612, 176 }, { 788, 114 }, { 902, 23 }, { 925, 6 }, + { 931, 25 }, { 956, 23 }, { 979, 8 }, { 987, 3 }, + { 990, 6 }, { 996, 6 }, { 1002, 3 }, { 1005, 2 }, + { 1007, 17 } } }, + + { { { 0, 13 }, { 13, 21 }, { 34, 18 }, { 52, 11 }, + { 63, 20 }, { 83, 29 }, { 112, 22 }, { 134, 15 }, + { 149, 14 }, { 163, 20 }, { 183, 16 }, { 199, 12 }, + { 211, 10 }, { 221, 14 }, { 235, 12 }, { 247, 10 }, + { 257, 767 } } }, + + { { { 0, 281 }, { 281, 183 }, { 464, 37 }, { 501, 9 }, + { 510, 171 }, { 681, 139 }, { 820, 37 }, { 857, 10 }, + { 867, 35 }, { 902, 36 }, { 938, 15 }, { 953, 6 }, + { 959, 9 }, { 968, 10 }, { 978, 6 }, { 984, 3 }, + { 987, 37 } } }, + + { { { 0, 198 }, { 198, 164 }, { 362, 46 }, { 408, 13 }, + { 421, 154 }, { 575, 147 }, { 722, 51 }, { 773, 16 }, + { 789, 43 }, { 832, 49 }, { 881, 24 }, { 905, 10 }, + { 915, 13 }, { 928, 16 }, { 944, 10 }, { 954, 5 }, + { 959, 65 } } }, + + { { { 0, 1 }, { 1, 1 }, { 2, 93 }, { 95, 44 }, + { 139, 1 }, { 140, 1 }, { 141, 72 }, { 213, 38 }, + { 251, 86 }, { 337, 70 }, { 407, 43 }, { 450, 25 }, + { 475, 40 }, { 515, 36 }, { 551, 25 }, { 576, 16 }, + { 592, 432 } } }, + + { { { 0, 133 }, { 133, 141 }, { 274, 64 }, { 338, 28 }, + { 366, 117 }, { 483, 122 }, { 605, 59 }, { 664, 27 }, + { 691, 39 }, { 730, 48 }, { 778, 29 }, { 807, 15 }, + { 822, 15 }, { 837, 20 }, { 857, 13 }, { 870, 8 }, + { 878, 146 } } }, + + { { { 0, 128 }, { 128, 125 }, { 253, 49 }, { 302, 18 }, + { 320, 123 }, { 443, 134 }, { 577, 59 }, { 636, 23 }, + { 659, 49 }, { 708, 59 }, { 767, 32 }, { 799, 15 }, + { 814, 19 }, { 833, 24 }, { 857, 15 }, { 872, 9 }, + { 881, 143 } } }, + + { { { 0, 1 }, { 1, 1 }, { 2, 23 }, { 25, 17 }, + { 42, 1 }, { 43, 1 }, { 44, 23 }, { 67, 18 }, + { 85, 20 }, { 105, 21 }, { 126, 18 }, { 144, 15 }, + { 159, 15 }, { 174, 17 }, { 191, 14 }, { 205, 12 }, + { 217, 807 } } }, + + { { { 0, 70 }, { 70, 96 }, { 166, 63 }, { 229, 38 }, + { 267, 89 }, { 356, 112 }, { 468, 65 }, { 533, 36 }, + { 569, 37 }, { 606, 47 }, { 653, 32 }, { 685, 20 }, + { 705, 17 }, { 722, 23 }, { 745, 17 }, { 762, 12 }, + { 774, 250 } } }, + + { { { 0, 55 }, { 55, 75 }, { 130, 45 }, { 175, 25 }, + { 200, 68 }, { 268, 90 }, { 358, 58 }, { 416, 33 }, + { 449, 39 }, { 488, 54 }, { 542, 39 }, { 581, 25 }, + { 606, 22 }, { 628, 31 }, { 659, 24 }, { 683, 16 }, + { 699, 325 } } }, + + { { { 0, 1 }, { 1, 2 }, { 3, 2 }, { 5, 2 }, + { 7, 2 }, { 9, 2 }, { 11, 2 }, { 13, 2 }, + { 15, 2 }, { 17, 2 }, { 19, 2 }, { 21, 2 }, + { 23, 2 }, { 25, 2 }, { 27, 2 }, { 29, 2 }, + { 31, 993 } } }, + + { { { 0, 34 }, { 34, 51 }, { 85, 38 }, { 123, 24 }, + { 147, 49 }, { 196, 69 }, { 265, 52 }, { 317, 35 }, + { 352, 34 }, { 386, 47 }, { 433, 37 }, { 470, 27 }, + { 497, 21 }, { 518, 31 }, { 549, 25 }, { 574, 19 }, + { 593, 431 } } }, + + { { { 0, 30 }, { 30, 43 }, { 73, 32 }, { 105, 22 }, + { 127, 43 }, { 170, 59 }, { 229, 45 }, { 274, 31 }, + { 305, 30 }, { 335, 42 }, { 377, 34 }, { 411, 25 }, + { 436, 19 }, { 455, 28 }, { 483, 23 }, { 506, 18 }, + { 524, 500 } } }, + + { { { 0, 9 }, { 9, 15 }, { 24, 14 }, { 38, 13 }, + { 51, 14 }, { 65, 22 }, { 87, 21 }, { 108, 18 }, + { 126, 13 }, { 139, 20 }, { 159, 18 }, { 177, 16 }, + { 193, 11 }, { 204, 17 }, { 221, 15 }, { 236, 14 }, + { 250, 774 } } }, + + { { { 0, 30 }, { 30, 44 }, { 74, 31 }, { 105, 20 }, + { 125, 41 }, { 166, 58 }, { 224, 42 }, { 266, 28 }, + { 294, 28 }, { 322, 39 }, { 361, 30 }, { 391, 22 }, + { 413, 18 }, { 431, 26 }, { 457, 21 }, { 478, 16 }, + { 494, 530 } } }, + + { { { 0, 15 }, { 15, 23 }, { 38, 20 }, { 58, 15 }, + { 73, 22 }, { 95, 33 }, { 128, 28 }, { 156, 22 }, + { 178, 18 }, { 196, 26 }, { 222, 23 }, { 245, 18 }, + { 263, 13 }, { 276, 20 }, { 296, 18 }, { 314, 15 }, + { 329, 695 } } }, + + { { { 0, 11 }, { 11, 17 }, { 28, 16 }, { 44, 13 }, + { 57, 17 }, { 74, 26 }, { 100, 23 }, { 123, 19 }, + { 142, 15 }, { 157, 22 }, { 179, 20 }, { 199, 17 }, + { 216, 12 }, { 228, 18 }, { 246, 16 }, { 262, 14 }, + { 276, 748 } } }, + + { { { 0, 448 }, { 448, 171 }, { 619, 20 }, { 639, 4 }, + { 643, 178 }, { 821, 105 }, { 926, 18 }, { 944, 4 }, + { 948, 23 }, { 971, 20 }, { 991, 7 }, { 998, 2 }, + { 1000, 5 }, { 1005, 5 }, { 1010, 2 }, { 1012, 1 }, + { 1013, 11 } } }, + + { { { 0, 332 }, { 332, 188 }, { 520, 29 }, { 549, 6 }, + { 555, 186 }, { 741, 133 }, { 874, 29 }, { 903, 7 }, + { 910, 30 }, { 940, 30 }, { 970, 11 }, { 981, 4 }, + { 985, 6 }, { 991, 7 }, { 998, 4 }, { 1002, 2 }, + { 1004, 20 } } }, + + { { { 0, 8 }, { 8, 13 }, { 21, 13 }, { 34, 11 }, + { 45, 13 }, { 58, 20 }, { 78, 18 }, { 96, 16 }, + { 112, 12 }, { 124, 17 }, { 141, 16 }, { 157, 13 }, + { 170, 10 }, { 180, 14 }, { 194, 13 }, { 207, 12 }, + { 219, 805 } } }, + + { { { 0, 239 }, { 239, 176 }, { 415, 42 }, { 457, 11 }, + { 468, 163 }, { 631, 145 }, { 776, 44 }, { 820, 13 }, + { 833, 39 }, { 872, 42 }, { 914, 19 }, { 933, 7 }, + { 940, 11 }, { 951, 13 }, { 964, 7 }, { 971, 4 }, + { 975, 49 } } }, + + { { { 0, 165 }, { 165, 145 }, { 310, 49 }, { 359, 16 }, + { 375, 138 }, { 513, 139 }, { 652, 55 }, { 707, 20 }, + { 727, 47 }, { 774, 54 }, { 828, 28 }, { 856, 12 }, + { 868, 16 }, { 884, 20 }, { 904, 12 }, { 916, 7 }, + { 923, 101 } } }, + + { { { 0, 3 }, { 3, 5 }, { 8, 5 }, { 13, 5 }, + { 18, 5 }, { 23, 7 }, { 30, 7 }, { 37, 7 }, + { 44, 4 }, { 48, 7 }, { 55, 7 }, { 62, 6 }, + { 68, 4 }, { 72, 6 }, { 78, 6 }, { 84, 6 }, + { 90, 934 } } }, + + { { { 0, 115 }, { 115, 122 }, { 237, 52 }, { 289, 22 }, + { 311, 111 }, { 422, 125 }, { 547, 61 }, { 608, 27 }, + { 635, 45 }, { 680, 57 }, { 737, 34 }, { 771, 17 }, + { 788, 19 }, { 807, 25 }, { 832, 17 }, { 849, 10 }, + { 859, 165 } } }, + + { { { 0, 107 }, { 107, 114 }, { 221, 51 }, { 272, 21 }, + { 293, 106 }, { 399, 122 }, { 521, 61 }, { 582, 28 }, + { 610, 46 }, { 656, 58 }, { 714, 35 }, { 749, 18 }, + { 767, 20 }, { 787, 26 }, { 813, 18 }, { 831, 11 }, + { 842, 182 } } }, + + { { { 0, 6 }, { 6, 10 }, { 16, 10 }, { 26, 9 }, + { 35, 10 }, { 45, 15 }, { 60, 15 }, { 75, 14 }, + { 89, 9 }, { 98, 14 }, { 112, 13 }, { 125, 12 }, + { 137, 8 }, { 145, 12 }, { 157, 11 }, { 168, 10 }, + { 178, 846 } } }, + + { { { 0, 72 }, { 72, 88 }, { 160, 50 }, { 210, 26 }, + { 236, 84 }, { 320, 102 }, { 422, 60 }, { 482, 32 }, + { 514, 41 }, { 555, 53 }, { 608, 36 }, { 644, 21 }, + { 665, 20 }, { 685, 27 }, { 712, 20 }, { 732, 13 }, + { 745, 279 } } }, + + { { { 0, 45 }, { 45, 63 }, { 108, 45 }, { 153, 30 }, + { 183, 61 }, { 244, 83 }, { 327, 58 }, { 385, 36 }, + { 421, 34 }, { 455, 47 }, { 502, 34 }, { 536, 23 }, + { 559, 19 }, { 578, 27 }, { 605, 21 }, { 626, 15 }, + { 641, 383 } } }, + + { { { 0, 1 }, { 1, 1 }, { 2, 7 }, { 9, 7 }, + { 16, 1 }, { 17, 1 }, { 18, 8 }, { 26, 8 }, + { 34, 6 }, { 40, 8 }, { 48, 7 }, { 55, 7 }, + { 62, 6 }, { 68, 7 }, { 75, 7 }, { 82, 6 }, + { 88, 936 } } }, + + { { { 0, 29 }, { 29, 44 }, { 73, 35 }, { 108, 24 }, + { 132, 42 }, { 174, 62 }, { 236, 48 }, { 284, 34 }, + { 318, 30 }, { 348, 43 }, { 391, 35 }, { 426, 26 }, + { 452, 19 }, { 471, 29 }, { 500, 24 }, { 524, 19 }, + { 543, 481 } } }, + + { { { 0, 20 }, { 20, 31 }, { 51, 25 }, { 76, 17 }, + { 93, 30 }, { 123, 43 }, { 166, 34 }, { 200, 25 }, + { 225, 22 }, { 247, 32 }, { 279, 26 }, { 305, 21 }, + { 326, 16 }, { 342, 23 }, { 365, 20 }, { 385, 16 }, + { 401, 623 } } }, + + { { { 0, 742 }, { 742, 103 }, { 845, 5 }, { 850, 1 }, + { 851, 108 }, { 959, 38 }, { 997, 4 }, { 1001, 1 }, + { 1002, 7 }, { 1009, 5 }, { 1014, 2 }, { 1016, 1 }, + { 1017, 2 }, { 1019, 1 }, { 1020, 1 }, { 1021, 1 }, + { 1022, 2 } } }, + + { { { 0, 42 }, { 42, 52 }, { 94, 27 }, { 121, 16 }, + { 137, 49 }, { 186, 58 }, { 244, 36 }, { 280, 23 }, + { 303, 27 }, { 330, 36 }, { 366, 26 }, { 392, 18 }, + { 410, 17 }, { 427, 24 }, { 451, 19 }, { 470, 14 }, + { 484, 540 } } }, + + { { { 0, 13 }, { 13, 20 }, { 33, 18 }, { 51, 15 }, + { 66, 19 }, { 85, 29 }, { 114, 26 }, { 140, 21 }, + { 161, 17 }, { 178, 25 }, { 203, 22 }, { 225, 18 }, + { 243, 13 }, { 256, 19 }, { 275, 17 }, { 292, 15 }, + { 307, 717 } } }, + + { { { 0, 501 }, { 501, 169 }, { 670, 19 }, { 689, 4 }, + { 693, 155 }, { 848, 88 }, { 936, 16 }, { 952, 4 }, + { 956, 19 }, { 975, 16 }, { 991, 6 }, { 997, 2 }, + { 999, 5 }, { 1004, 4 }, { 1008, 2 }, { 1010, 1 }, + { 1011, 13 } } }, + + { { { 0, 445 }, { 445, 136 }, { 581, 22 }, { 603, 6 }, + { 609, 158 }, { 767, 98 }, { 865, 23 }, { 888, 7 }, + { 895, 31 }, { 926, 28 }, { 954, 10 }, { 964, 4 }, + { 968, 9 }, { 977, 9 }, { 986, 5 }, { 991, 2 }, + { 993, 31 } } }, + + { { { 0, 285 }, { 285, 157 }, { 442, 37 }, { 479, 10 }, + { 489, 161 }, { 650, 129 }, { 779, 39 }, { 818, 12 }, + { 830, 40 }, { 870, 42 }, { 912, 18 }, { 930, 7 }, + { 937, 12 }, { 949, 14 }, { 963, 8 }, { 971, 4 }, + { 975, 49 } } }, + + { { { 0, 349 }, { 349, 179 }, { 528, 33 }, { 561, 8 }, + { 569, 162 }, { 731, 121 }, { 852, 31 }, { 883, 9 }, + { 892, 31 }, { 923, 30 }, { 953, 12 }, { 965, 5 }, + { 970, 8 }, { 978, 9 }, { 987, 5 }, { 992, 2 }, + { 994, 30 } } }, + + { { { 0, 199 }, { 199, 156 }, { 355, 47 }, { 402, 15 }, + { 417, 146 }, { 563, 137 }, { 700, 50 }, { 750, 17 }, + { 767, 44 }, { 811, 49 }, { 860, 24 }, { 884, 10 }, + { 894, 15 }, { 909, 17 }, { 926, 10 }, { 936, 6 }, + { 942, 82 } } }, + + { { { 0, 141 }, { 141, 134 }, { 275, 50 }, { 325, 18 }, + { 343, 128 }, { 471, 135 }, { 606, 58 }, { 664, 22 }, + { 686, 48 }, { 734, 57 }, { 791, 31 }, { 822, 14 }, + { 836, 18 }, { 854, 23 }, { 877, 14 }, { 891, 8 }, + { 899, 125 } } }, + + { { { 0, 243 }, { 243, 194 }, { 437, 56 }, { 493, 17 }, + { 510, 139 }, { 649, 126 }, { 775, 45 }, { 820, 16 }, + { 836, 33 }, { 869, 36 }, { 905, 18 }, { 923, 8 }, + { 931, 10 }, { 941, 12 }, { 953, 7 }, { 960, 4 }, + { 964, 60 } } }, + + { { { 0, 91 }, { 91, 106 }, { 197, 51 }, { 248, 23 }, + { 271, 99 }, { 370, 117 }, { 487, 63 }, { 550, 30 }, + { 580, 45 }, { 625, 59 }, { 684, 37 }, { 721, 20 }, + { 741, 20 }, { 761, 27 }, { 788, 19 }, { 807, 12 }, + { 819, 205 } } }, + + { { { 0, 107 }, { 107, 94 }, { 201, 41 }, { 242, 20 }, + { 262, 92 }, { 354, 97 }, { 451, 52 }, { 503, 28 }, + { 531, 42 }, { 573, 53 }, { 626, 34 }, { 660, 20 }, + { 680, 21 }, { 701, 29 }, { 730, 21 }, { 751, 14 }, + { 765, 259 } } }, + + { { { 0, 168 }, { 168, 171 }, { 339, 68 }, { 407, 25 }, + { 432, 121 }, { 553, 123 }, { 676, 55 }, { 731, 24 }, + { 755, 34 }, { 789, 41 }, { 830, 24 }, { 854, 12 }, + { 866, 13 }, { 879, 16 }, { 895, 11 }, { 906, 6 }, + { 912, 112 } } }, + + { { { 0, 67 }, { 67, 80 }, { 147, 44 }, { 191, 23 }, + { 214, 76 }, { 290, 94 }, { 384, 57 }, { 441, 31 }, + { 472, 41 }, { 513, 54 }, { 567, 37 }, { 604, 23 }, + { 627, 21 }, { 648, 30 }, { 678, 22 }, { 700, 15 }, + { 715, 309 } } }, + + { { { 0, 46 }, { 46, 63 }, { 109, 39 }, { 148, 23 }, + { 171, 58 }, { 229, 78 }, { 307, 52 }, { 359, 32 }, + { 391, 36 }, { 427, 49 }, { 476, 37 }, { 513, 24 }, + { 537, 21 }, { 558, 30 }, { 588, 24 }, { 612, 17 }, + { 629, 395 } } }, + + { { { 0, 848 }, { 848, 70 }, { 918, 2 }, { 920, 1 }, + { 921, 75 }, { 996, 16 }, { 1012, 1 }, { 1013, 1 }, + { 1014, 2 }, { 1016, 1 }, { 1017, 1 }, { 1018, 1 }, + { 1019, 1 }, { 1020, 1 }, { 1021, 1 }, { 1022, 1 }, + { 1023, 1 } } }, + + { { { 0, 36 }, { 36, 52 }, { 88, 35 }, { 123, 22 }, + { 145, 48 }, { 193, 67 }, { 260, 48 }, { 308, 32 }, + { 340, 32 }, { 372, 45 }, { 417, 35 }, { 452, 24 }, + { 476, 20 }, { 496, 29 }, { 525, 23 }, { 548, 17 }, + { 565, 459 } } }, + + { { { 0, 24 }, { 24, 37 }, { 61, 29 }, { 90, 20 }, + { 110, 35 }, { 145, 51 }, { 196, 41 }, { 237, 29 }, + { 266, 26 }, { 292, 38 }, { 330, 31 }, { 361, 24 }, + { 385, 18 }, { 403, 27 }, { 430, 23 }, { 453, 18 }, + { 471, 553 } } }, + + { { { 0, 85 }, { 85, 97 }, { 182, 48 }, { 230, 23 }, + { 253, 91 }, { 344, 110 }, { 454, 61 }, { 515, 30 }, + { 545, 45 }, { 590, 58 }, { 648, 37 }, { 685, 21 }, + { 706, 21 }, { 727, 29 }, { 756, 20 }, { 776, 13 }, + { 789, 235 } } }, + + { { { 0, 22 }, { 22, 33 }, { 55, 27 }, { 82, 20 }, + { 102, 33 }, { 135, 48 }, { 183, 39 }, { 222, 30 }, + { 252, 26 }, { 278, 37 }, { 315, 30 }, { 345, 23 }, + { 368, 17 }, { 385, 25 }, { 410, 21 }, { 431, 17 }, + { 448, 576 } } }, + + { { { 0, 1 }, { 1, 1 }, { 2, 54 }, { 56, 33 }, + { 89, 1 }, { 90, 1 }, { 91, 49 }, { 140, 32 }, + { 172, 49 }, { 221, 47 }, { 268, 35 }, { 303, 25 }, + { 328, 30 }, { 358, 30 }, { 388, 24 }, { 412, 18 }, + { 430, 594 } } }, + + { { { 0, 45 }, { 45, 64 }, { 109, 43 }, { 152, 25 }, + { 177, 62 }, { 239, 81 }, { 320, 56 }, { 376, 35 }, + { 411, 37 }, { 448, 51 }, { 499, 38 }, { 537, 26 }, + { 563, 22 }, { 585, 31 }, { 616, 24 }, { 640, 18 }, + { 658, 366 } } }, + + { { { 0, 247 }, { 247, 148 }, { 395, 38 }, { 433, 12 }, + { 445, 154 }, { 599, 130 }, { 729, 42 }, { 771, 14 }, + { 785, 44 }, { 829, 46 }, { 875, 21 }, { 896, 9 }, + { 905, 15 }, { 920, 17 }, { 937, 9 }, { 946, 5 }, + { 951, 73 } } }, + + { { { 0, 231 }, { 231, 136 }, { 367, 41 }, { 408, 15 }, + { 423, 134 }, { 557, 119 }, { 676, 47 }, { 723, 19 }, + { 742, 44 }, { 786, 49 }, { 835, 25 }, { 860, 12 }, + { 872, 17 }, { 889, 20 }, { 909, 12 }, { 921, 7 }, + { 928, 96 } } } + +}; + +const uint16_t lc3_spectrum_bits[][17] = { + + { 20480, 20480, 5220, 9042, 20480, 20480, 6619, 9892, + 5289, 6619, 9105, 11629, 8982, 9892, 11629, 13677, 4977 }, + + { 11940, 10854, 12109, 13677, 10742, 9812, 11090, 12288, + 11348, 10240, 11348, 12683, 12109, 10854, 11629, 12902, 1197 }, + + { 7886, 7120, 8982, 10970, 7496, 6815, 8334, 10150, + 9437, 8535, 9656, 11216, 11348, 10431, 11348, 12479, 4051 }, + + { 5485, 6099, 9168, 11940, 6311, 6262, 8640, 11090, + 9233, 8640, 10334, 12479, 11781, 11090, 12479, 13988, 6009 }, + + { 7886, 7804, 10150, 11940, 7886, 7685, 9368, 10854, + 10061, 9300, 10431, 11629, 11629, 10742, 11485, 12479, 2763 }, + + { 9042, 8383, 10240, 11781, 8483, 8013, 9437, 10742, + 10334, 9437, 10431, 11485, 11781, 10742, 11485, 12288, 2346 }, + + { 5922, 6619, 9368, 11940, 6566, 6539, 8750, 10970, + 9168, 8640, 10240, 12109, 11485, 10742, 11940, 13396, 5009 }, + + { 12288, 11090, 11348, 12109, 11090, 9892, 10334, 10970, + 11629, 10431, 10970, 11629, 12479, 11348, 11781, 12288, 1289 }, + + { 1685, 5676, 13138, 18432, 5598, 7804, 13677, 18432, + 12683, 13396, 17234, 20480, 17234, 17234, 20480, 20480, 15725 }, + + { 2793, 5072, 10970, 15725, 5204, 6487, 11216, 15186, + 10970, 11216, 14336, 17234, 15186, 15186, 17234, 18432, 12109 }, + + { 12902, 11485, 11940, 13396, 11629, 10531, 11348, 12479, + 12683, 11629, 12288, 13138, 13677, 12683, 13138, 13677, 854 }, + + { 3821, 5088, 9812, 13988, 5289, 5901, 9812, 13677, + 9976, 9892, 12479, 15186, 13988, 13677, 15186, 17234, 9812 }, + + { 4856, 5412, 9168, 12902, 5598, 5736, 8863, 12288, + 9368, 8982, 11090, 13677, 12902, 12288, 13677, 15725, 8147 }, + + { 20480, 20480, 7088, 9300, 20480, 20480, 7844, 9733, + 7320, 7928, 9368, 10970, 9581, 9892, 10970, 12288, 2550 }, + + { 6031, 5859, 8192, 10635, 6410, 6286, 8433, 10742, + 9656, 9042, 10531, 12479, 12479, 11629, 12902, 14336, 5756 }, + + { 6144, 6215, 8982, 11940, 6262, 6009, 8433, 11216, + 8982, 8433, 10240, 12479, 11781, 11090, 12479, 13988, 5817 }, + + { 20480, 20480, 11216, 12109, 20480, 20480, 11216, 11940, + 11629, 11485, 11940, 12479, 12479, 12109, 12683, 13138, 704 }, + + { 7928, 6994, 8239, 9733, 7218, 6539, 8147, 9892, + 9812, 9105, 10240, 11629, 12109, 11216, 12109, 13138, 4167 }, + + { 8640, 7724, 9233, 10970, 8013, 7185, 8483, 10150, + 9656, 8694, 9656, 10970, 11348, 10334, 11090, 12288, 3391 }, + + { 20480, 18432, 18432, 18432, 18432, 18432, 18432, 18432, + 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 91 }, + + { 10061, 8863, 9733, 11090, 8982, 7970, 8806, 9976, + 10061, 9105, 9812, 10742, 11485, 10334, 10970, 11781, 2557 }, + + { 10431, 9368, 10240, 11348, 9368, 8433, 9233, 10334, + 10431, 9437, 10061, 10970, 11781, 10635, 11216, 11940, 2119 }, + + { 13988, 12479, 12683, 12902, 12683, 11348, 11485, 11940, + 12902, 11629, 11940, 12288, 13396, 12109, 12479, 12683, 828 }, + + { 10431, 9300, 10334, 11629, 9508, 8483, 9437, 10635, + 10635, 9656, 10431, 11348, 11940, 10854, 11485, 12288, 1946 }, + + { 12479, 11216, 11629, 12479, 11348, 10150, 10635, 11348, + 11940, 10854, 11216, 11940, 12902, 11629, 11940, 12479, 1146 }, + + { 13396, 12109, 12288, 12902, 12109, 10854, 11216, 11781, + 12479, 11348, 11629, 12109, 13138, 11940, 12288, 12683, 928 }, + + { 2443, 5289, 11629, 16384, 5170, 6730, 11940, 16384, + 11216, 11629, 14731, 18432, 15725, 15725, 18432, 20480, 13396 }, + + { 3328, 5009, 10531, 15186, 5040, 6031, 10531, 14731, + 10431, 10431, 13396, 16384, 15186, 14731, 16384, 18432, 11629 }, + + { 14336, 12902, 12902, 13396, 12902, 11629, 11940, 12288, + 13138, 12109, 12288, 12902, 13677, 12683, 12902, 13138, 711 }, + + { 4300, 5204, 9437, 13396, 5430, 5776, 9300, 12902, + 9656, 9437, 11781, 14731, 13396, 12902, 14731, 16384, 8982 }, + + { 5394, 5776, 8982, 12288, 5922, 5901, 8640, 11629, + 9105, 8694, 10635, 13138, 12288, 11629, 13138, 14731, 6844 }, + + { 17234, 15725, 15725, 15725, 15725, 14731, 14731, 14731, + 16384, 14731, 14731, 15186, 16384, 15186, 15186, 15186, 272 }, + + { 6461, 6286, 8806, 11348, 6566, 6215, 8334, 10742, + 9233, 8535, 10061, 12109, 11781, 10970, 12109, 13677, 5394 }, + + { 6674, 6487, 8863, 11485, 6702, 6286, 8334, 10635, + 9168, 8483, 9976, 11940, 11629, 10854, 11940, 13396, 5105 }, + + { 15186, 13677, 13677, 13988, 13677, 12479, 12479, 12683, + 13988, 12683, 12902, 13138, 14336, 13138, 13396, 13677, 565 }, + + { 7844, 7252, 8922, 10854, 7389, 6815, 8383, 10240, + 9508, 8750, 9892, 11485, 11629, 10742, 11629, 12902, 3842 }, + + { 9233, 8239, 9233, 10431, 8334, 7424, 8483, 9892, + 10061, 9105, 10061, 11216, 11781, 10742, 11485, 12479, 2906 }, + + { 20480, 20480, 14731, 14731, 20480, 20480, 14336, 14336, + 15186, 14336, 14731, 14731, 15186, 14731, 14731, 15186, 266 }, + + { 10531, 9300, 9976, 11090, 9437, 8286, 9042, 10061, + 10431, 9368, 9976, 10854, 11781, 10531, 11090, 11781, 2233 }, + + { 11629, 10334, 10970, 12109, 10431, 9368, 10061, 10970, + 11348, 10240, 10854, 11485, 12288, 11216, 11629, 12288, 1469 }, + + { 952, 6787, 15725, 20480, 6646, 9733, 16384, 20480, + 14731, 15725, 18432, 20480, 18432, 20480, 20480, 20480, 18432 }, + + { 9437, 8806, 10742, 12288, 8982, 8483, 9892, 11216, + 10742, 9892, 10854, 11940, 12109, 11090, 11781, 12683, 1891 }, + + { 12902, 11629, 11940, 12479, 11781, 10531, 10854, 11485, + 12109, 10970, 11348, 11940, 12902, 11781, 12109, 12479, 1054 }, + + { 2113, 5323, 11781, 16384, 5579, 7252, 12288, 16384, + 11781, 12288, 15186, 18432, 15725, 16384, 18432, 20480, 12902 }, + + { 2463, 5965, 11348, 15186, 5522, 6934, 11216, 14731, + 10334, 10635, 13677, 16384, 13988, 13988, 15725, 18432, 10334 }, + + { 3779, 5541, 9812, 13677, 5467, 6122, 9656, 13138, + 9581, 9437, 11940, 14731, 13138, 12683, 14336, 16384, 8982 }, + + { 3181, 5154, 10150, 14336, 5448, 6311, 10334, 13988, + 10334, 10431, 13138, 15725, 14336, 13988, 15725, 18432, 10431 }, + + { 4841, 5560, 9105, 12479, 5756, 5944, 8922, 12109, + 9300, 8982, 11090, 13677, 12479, 12109, 13677, 15186, 7460 }, + + { 5859, 6009, 8922, 11940, 6144, 5987, 8483, 11348, + 9042, 8535, 10334, 12683, 11940, 11216, 12683, 14336, 6215 }, + + { 4250, 4916, 8587, 12109, 5901, 6191, 9233, 12288, + 10150, 9892, 11940, 14336, 13677, 13138, 14731, 16384, 8383 }, + + { 7153, 6702, 8863, 11216, 6904, 6410, 8239, 10431, + 9233, 8433, 9812, 11629, 11629, 10742, 11781, 13138, 4753 }, + + { 6674, 7057, 9508, 11629, 7120, 6964, 8806, 10635, + 9437, 8750, 10061, 11629, 11485, 10531, 11485, 12683, 4062 }, + + { 5341, 5289, 8013, 10970, 6311, 6262, 8640, 11090, + 10061, 9508, 11090, 13138, 12902, 12288, 13396, 15186, 6539 }, + + { 8057, 7533, 9300, 11216, 7685, 7057, 8535, 10334, + 9508, 8694, 9812, 11216, 11485, 10431, 11348, 12479, 3541 }, + + { 9168, 8239, 9656, 11216, 8483, 7608, 8806, 10240, + 9892, 8982, 9812, 11090, 11485, 10431, 11090, 12109, 2815 }, + + { 558, 7928, 18432, 20480, 7724, 12288, 20480, 20480, + 18432, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480 }, + + { 9892, 8806, 9976, 11348, 9042, 8057, 9042, 10240, + 10240, 9233, 9976, 11090, 11629, 10531, 11216, 12109, 2371 }, + + { 11090, 9812, 10531, 11629, 9976, 8863, 9508, 10531, + 10854, 9733, 10334, 11090, 11940, 10742, 11216, 11940, 1821 }, + + { 7354, 6964, 9042, 11216, 7153, 6592, 8334, 10431, + 9233, 8483, 9812, 11485, 11485, 10531, 11629, 12902, 4349 }, + + { 11348, 10150, 10742, 11629, 10150, 9042, 9656, 10431, + 10854, 9812, 10431, 11216, 12109, 10970, 11485, 12109, 1700 }, + + { 20480, 20480, 8694, 10150, 20480, 20480, 8982, 10240, + 8982, 9105, 9976, 10970, 10431, 10431, 11090, 11940, 1610 }, + + { 9233, 8192, 9368, 10970, 8286, 7496, 8587, 9976, + 9812, 8863, 9733, 10854, 11348, 10334, 11090, 11940, 3040 }, + + { 4202, 5716, 9733, 13138, 5598, 6099, 9437, 12683, + 9300, 9168, 11485, 13988, 12479, 12109, 13988, 15725, 7804 }, + + { 4400, 5965, 9508, 12479, 6009, 6360, 9105, 11781, + 9300, 8982, 10970, 13138, 12109, 11629, 13138, 14731, 6994 } + +}; diff --git a/3rd-party/lc3-google/src/tables.h b/3rd-party/lc3-google/src/tables.h new file mode 100644 index 000000000..c974235e9 --- /dev/null +++ b/3rd-party/lc3-google/src/tables.h @@ -0,0 +1,96 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#ifndef __LC3_TABLES_H +#define __LC3_TABLES_H + +#include "common.h" +#include "bits.h" + + +/** + * MDCT Twiddles and window coefficients + */ + +struct lc3_fft_bf3_twiddles { int n3; const struct lc3_complex (*t)[2]; }; +struct lc3_fft_bf2_twiddles { int n2; const struct lc3_complex *t; }; +struct lc3_mdct_rot_def { int n4; const struct lc3_complex *w; }; + +extern const struct lc3_fft_bf3_twiddles *lc3_fft_twiddles_bf3[]; +extern const struct lc3_fft_bf2_twiddles *lc3_fft_twiddles_bf2[][3]; +extern const struct lc3_mdct_rot_def *lc3_mdct_rot[LC3_NUM_DT][LC3_NUM_SRATE]; + +extern const float *lc3_mdct_win[LC3_NUM_DT][LC3_NUM_SRATE]; + + +/** + * Limits of bands + */ + +#define LC3_NUM_BANDS 64 + +extern const int lc3_band_lim[LC3_NUM_DT][LC3_NUM_SRATE][LC3_NUM_BANDS+1]; + + +/** + * SNS Quantization + */ + +extern const float lc3_sns_lfcb[32][8]; +extern const float lc3_sns_hfcb[32][8]; + +struct lc3_sns_vq_gains { + int count; const float *v; +}; + +extern const struct lc3_sns_vq_gains lc3_sns_vq_gains[4]; + +extern const int32_t lc3_sns_mpvq_offsets[][11]; + + +/** + * TNS Arithmetic Coding + */ + +extern const struct lc3_ac_model lc3_tns_order_models[]; +extern const uint16_t lc3_tns_order_bits[][8]; + +extern const struct lc3_ac_model lc3_tns_coeffs_models[]; +extern const uint16_t lc3_tns_coeffs_bits[][17]; + + +/** + * Long Term Postfilter + */ + +extern const float lc3_ltpf_h12k8[240]; + +extern const float *lc3_ltpf_cnum[LC3_NUM_SRATE][4]; +extern const float *lc3_ltpf_cden[LC3_NUM_SRATE][4]; + + +/** + * Spectral Data Arithmetic Coding + */ + +extern const uint8_t lc3_spectrum_lookup[2][2][256][4]; +extern const struct lc3_ac_model lc3_spectrum_models[]; +extern const uint16_t lc3_spectrum_bits[][17]; + + +#endif /* __LC3_TABLES_H */ diff --git a/3rd-party/lc3-google/src/tns.c b/3rd-party/lc3-google/src/tns.c new file mode 100644 index 000000000..7c6d1e81e --- /dev/null +++ b/3rd-party/lc3-google/src/tns.c @@ -0,0 +1,454 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +#include "tns.h" +#include "tables.h" + + +/* ---------------------------------------------------------------------------- + * Filter Coefficients + * -------------------------------------------------------------------------- */ + +/** + * Resolve LPC Weighting indication according bitrate + * dt, nbytes Duration and size of the frame + * return True when LPC Weighting enabled + */ +static bool resolve_lpc_weighting(enum lc3_dt dt, int nbytes) +{ + return nbytes < (dt == LC3_DT_7M5 ? 360/8 : 480/8); +} + +/** + * Return dot product of 2 vectors + * a, b, n The 2 vectors of size `n` + * return sum( a[i] * b[i] ), i = [0..n-1] + */ +static inline float dot(const float *a, const float *b, int n) +{ + float v = 0; + + while (n--) + v += *(a++) * *(b++); + + return v; +} + +/** + * LPC Coefficients + * dt, bw Duration and bandwidth of the frame + * x Spectral coefficients + * gain, a Output the prediction gains and LPC coefficients + */ +static void compute_lpc_coeffs(enum lc3_dt dt, enum lc3_bandwidth bw, + const float *x, float *gain, float (*a)[9]) +{ + static const int sub_7m5_nb[] = { 9, 26, 43, 60 }; + static const int sub_7m5_wb[] = { 9, 46, 83, 120 }; + static const int sub_7m5_sswb[] = { 9, 66, 123, 180 }; + static const int sub_7m5_swb[] = { 9, 46, 82, 120, 159, 200, 240 }; + static const int sub_7m5_fb[] = { 9, 56, 103, 150, 200, 250, 300 }; + + static const int sub_10m_nb[] = { 12, 34, 57, 80 }; + static const int sub_10m_wb[] = { 12, 61, 110, 160 }; + static const int sub_10m_sswb[] = { 12, 88, 164, 240 }; + static const int sub_10m_swb[] = { 12, 61, 110, 160, 213, 266, 320 }; + static const int sub_10m_fb[] = { 12, 74, 137, 200, 266, 333, 400 }; + + /* --- Normalized autocorrelation --- */ + + static const float lag_window[] = { + 1.00000000e+00, 9.98028026e-01, 9.92135406e-01, 9.82391584e-01, + 9.68910791e-01, 9.51849807e-01, 9.31404933e-01, 9.07808230e-01, + 8.81323137e-01 + }; + + const int *sub = (const int * const [LC3_NUM_DT][LC3_NUM_SRATE]){ + { sub_7m5_nb, sub_7m5_wb, sub_7m5_sswb, sub_7m5_swb, sub_7m5_fb }, + { sub_10m_nb, sub_10m_wb, sub_10m_sswb, sub_10m_swb, sub_10m_fb }, + }[dt][bw]; + + int nfilters = 1 + (bw >= LC3_BANDWIDTH_SWB); + + const float *xs, *xe = x + *sub; + float r[2][9]; + + for (int f = 0; f < nfilters; f++) { + float c[9][3]; + + for (int s = 0; s < 3; s++) { + xs = xe, xe = x + *(++sub); + + for (int k = 0; k < 9; k++) + c[k][s] = dot(xs, xs + k, (xe - xs) - k); + } + + float e0 = c[0][0], e1 = c[0][1], e2 = c[0][2]; + + r[f][0] = 3; + for (int k = 1; k < 9; k++) + r[f][k] = e0 == 0 || e1 == 0 || e2 == 0 ? 0 : + (c[k][0]/e0 + c[k][1]/e1 + c[k][2]/e2) * lag_window[k]; + } + + /* --- Levinson-Durbin recursion --- */ + + for (int f = 0; f < nfilters; f++) { + float *a0 = a[f], a1[9]; + float err = r[f][0], rc; + + gain[f] = err; + + a0[0] = 1; + for (int k = 1; k < 9; ) { + + rc = -r[f][k]; + for (int i = 1; i < k; i++) + rc -= a0[i] * r[f][k-i]; + + rc /= err; + err *= 1 - rc * rc; + + for (int i = 1; i < k; i++) + a1[i] = a0[i] + rc * a0[k-i]; + a1[k++] = rc; + + rc = -r[f][k]; + for (int i = 1; i < k; i++) + rc -= a1[i] * r[f][k-i]; + + rc /= err; + err *= 1 - rc * rc; + + for (int i = 1; i < k; i++) + a0[i] = a1[i] + rc * a1[k-i]; + a0[k++] = rc; + } + + gain[f] /= err; + } +} + +/** + * LPC Weighting + * gain, a Prediction gain and LPC coefficients, weighted as output + */ +static void lpc_weighting(float pred_gain, float *a) +{ + float gamma = 1. - (1. - 0.85) * (2. - pred_gain) / (2. - 1.5), g = 1; + for (int i = 1; i < 9; i++) + a[i] *= (g *= gamma); +} + +/** + * LPC reflection + * a LPC coefficients + * rc Output refelection coefficients + */ +static void lpc_reflection(const float *a, float *rc) +{ + float e, b[2][7], *b0, *b1; + + rc[7] = a[1+7]; + e = 1 - rc[7] * rc[7]; + + b1 = b[1]; + for (int i = 0; i < 7; i++) + b1[i] = (a[1+i] - rc[7] * a[7-i]) / e; + + for (int k = 6; k > 0; k--) { + b0 = b1, b1 = b[k & 1]; + + rc[k] = b0[k]; + e = 1 - rc[k] * rc[k]; + + for (int i = 0; i < k; i++) + b1[i] = (b0[i] - rc[k] * b0[k-1-i]) / e; + } + + rc[0] = b1[0]; +} + +/** + * Quantization of RC coefficients + * rc Refelection coefficients + * rc_order Return order of coefficients + * rc_i Return quantized coefficients + */ +static void quantize_rc(const float *rc, int *rc_order, int *rc_q) +{ + /* Quantization table, sin(delta * (i + 0.5)), delta = Pi / 17 */ + + static float q_thr[] = { + 9.22683595e-02, 2.73662990e-01, 4.45738356e-01, 6.02634636e-01, + 7.39008917e-01, 8.50217136e-01, 9.32472229e-01, 9.82973100e-01 + }; + + *rc_order = 8; + + for (int i = 0; i < 8; i++) { + float rc_m = fabsf(rc[i]); + + rc_q[i] = 4 * (rc_m >= q_thr[4]); + for (int j = 0; j < 4 && rc_m >= q_thr[rc_q[i]]; j++, rc_q[i]++); + + if (rc[i] < 0) + rc_q[i] = -rc_q[i]; + + *rc_order = rc_q[i] != 0 ? 8 : *rc_order - 1; + } +} + +/** + * Unquantization of RC coefficients + * rc_q Quantized coefficients + * rc_order Order of coefficients + * rc Return refelection coefficients + */ +static void unquantize_rc(const int *rc_q, int rc_order, float rc[8]) +{ + /* Quantization table, sin(delta * i), delta = Pi / 17 */ + + static float q_inv[] = { + 0.00000000e+00, 1.83749517e-01, 3.61241664e-01, 5.26432173e-01, + 6.73695641e-01, 7.98017215e-01, 8.95163302e-01, 9.61825645e-01, + 9.95734176e-01 + }; + + int i; + + for (i = 0; i < rc_order; i++) { + float rc_m = q_inv[LC3_ABS(rc_q[i])]; + rc[i] = rc_q[i] < 0 ? -rc_m : rc_m; + } +} + + +/* ---------------------------------------------------------------------------- + * Filtering + * -------------------------------------------------------------------------- */ + +/** + * Forward filtering + * dt, bw Duration and bandwidth of the frame + * rc_order, rc Order of coefficients, and coefficients + * x Spectral coefficients, filtered as output + */ +static void forward_filtering( + enum lc3_dt dt, enum lc3_bandwidth bw, + const int rc_order[2], const float rc[2][8], float *x) +{ + int nfilters = 1 + (bw >= LC3_BANDWIDTH_SWB); + int nf = LC3_NE(dt, bw) >> (nfilters - 1); + int i0, ie = 3*(3 + dt); + + float s[8] = { 0 }; + + for (int f = 0; f < nfilters; f++) { + + i0 = ie; + ie = nf * (1 + f); + + if (!rc_order[f]) + continue; + + for (int i = i0; i < ie; i++) { + float xi = x[i]; + float s0, s1 = xi; + + for (int k = 0; k < rc_order[f]; k++) { + s0 = s[k]; + s[k] = s1; + + s1 = rc[f][k] * xi + s0; + xi += rc[f][k] * s0; + } + + x[i] = xi; + } + } +} + +/** + * Inverse filtering + * dt, bw Duration and bandwidth of the frame + * rc_order, rc Order of coefficients, and unquantized coefficients + * x Spectral coefficients, filtered as output + */ +static void inverse_filtering( + enum lc3_dt dt, enum lc3_bandwidth bw, + const int rc_order[2], const float rc[2][8], float *x) +{ + int nfilters = 1 + (bw >= LC3_BANDWIDTH_SWB); + int nf = LC3_NE(dt, bw) >> (nfilters - 1); + int i0, ie = 3*(3 + dt); + + float s[8] = { 0 }; + + for (int f = 0; f < nfilters; f++) { + + i0 = ie; + ie = nf * (1 + f); + + if (!rc_order[f]) + continue; + + for (int i = i0; i < ie; i++) { + float xi = x[i]; + + xi -= s[7] * rc[f][7]; + for (int k = 6; k >= 0; k--) { + xi -= s[k] * rc[f][k]; + s[k+1] = s[k] + rc[f][k] * xi; + } + s[0] = xi; + x[i] = xi; + } + + for (int k = 7; k >= rc_order[f]; k--) + s[k] = 0; + } +} + + +/* ---------------------------------------------------------------------------- + * Interface + * -------------------------------------------------------------------------- */ + +/** + * TNS analysis + */ +void lc3_tns_analyze(enum lc3_dt dt, enum lc3_bandwidth bw, + bool nn_flag, int nbytes, struct lc3_tns_data *data, float *x) +{ + /* Processing steps : + * - Determine the LPC (Linear Predictive Coding) Coefficients + * - Check is the filtering is disabled + * - The coefficients are weighted on low bitrates and predicition gain + * - Convert to reflection coefficients and quantize + * - Finally filter the spectral coefficients */ + + float pred_gain[2], a[2][9]; + float rc[2][8]; + + data->nfilters = 1 + (bw >= LC3_BANDWIDTH_SWB); + data->lpc_weighting = resolve_lpc_weighting(dt, nbytes); + + compute_lpc_coeffs(dt, bw, x, pred_gain, a); + + for (int f = 0; f < data->nfilters; f++) { + + data->rc_order[f] = 0; + if (nn_flag || pred_gain[f] <= 1.5) + continue; + + if (data->lpc_weighting && pred_gain[f] < 2) + lpc_weighting(pred_gain[f], a[f]); + + lpc_reflection(a[f], rc[f]); + + quantize_rc(rc[f], &data->rc_order[f], data->rc[f]); + unquantize_rc(data->rc[f], data->rc_order[f], rc[f]); + } + + forward_filtering(dt, bw, data->rc_order, rc, x); +} + +/** + * TNS synthesis + */ +void lc3_tns_synthesize(enum lc3_dt dt, enum lc3_bandwidth bw, + const struct lc3_tns_data *data, float *x) +{ + float rc[2][8] = { }; + + for (int f = 0; f < data->nfilters; f++) + if (data->rc_order[f]) + unquantize_rc(data->rc[f], data->rc_order[f], rc[f]); + + inverse_filtering(dt, bw, data->rc_order, rc, x); +} + +/** + * Bit consumption of bitstream data + */ +int lc3_tns_get_nbits(const struct lc3_tns_data *data) +{ + int nbits = 0; + + for (int f = 0; f < data->nfilters; f++) { + + int nbits_2048 = 2048; + int rc_order = data->rc_order[f]; + + nbits_2048 += rc_order > 0 ? lc3_tns_order_bits + [data->lpc_weighting][rc_order-1] : 0; + + for (int i = 0; i < rc_order; i++) + nbits_2048 += lc3_tns_coeffs_bits[i][8 + data->rc[f][i]]; + + nbits += (nbits_2048 + (1 << 11) - 1) >> 11; + } + + return nbits; +} + +/** + * Put bitstream data + */ +void lc3_tns_put_data(lc3_bits_t *bits, const struct lc3_tns_data *data) +{ + for (int f = 0; f < data->nfilters; f++) { + int rc_order = data->rc_order[f]; + + lc3_put_bits(bits, rc_order > 0, 1); + if (rc_order <= 0) + continue; + + lc3_put_symbol(bits, + lc3_tns_order_models + data->lpc_weighting, rc_order-1); + + for (int i = 0; i < rc_order; i++) + lc3_put_symbol(bits, + lc3_tns_coeffs_models + i, 8 + data->rc[f][i]); + } +} + +/** + * Get bitstream data + */ +void lc3_tns_get_data(lc3_bits_t *bits, + enum lc3_dt dt, enum lc3_bandwidth bw, int nbytes, lc3_tns_data_t *data) +{ + data->nfilters = 1 + (bw >= LC3_BANDWIDTH_SWB); + data->lpc_weighting = resolve_lpc_weighting(dt, nbytes); + + for (int f = 0; f < data->nfilters; f++) { + + data->rc_order[f] = lc3_get_bit(bits); + if (!data->rc_order[f]) + continue; + + data->rc_order[f] += lc3_get_symbol(bits, + lc3_tns_order_models + data->lpc_weighting); + + for (int i = 0; i < data->rc_order[f]; i++) + data->rc[f][i] = (int)lc3_get_symbol(bits, + lc3_tns_coeffs_models + i) - 8; + } +} diff --git a/3rd-party/lc3-google/src/tns.h b/3rd-party/lc3-google/src/tns.h new file mode 100644 index 000000000..95e172d65 --- /dev/null +++ b/3rd-party/lc3-google/src/tns.h @@ -0,0 +1,99 @@ +/****************************************************************************** + * + * Copyright 2021 Google, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * LC3 - Temporal Noise Shaping + * + * Reference : Low Complexity Communication Codec (LC3) + * Bluetooth Specification v1.0 + */ + +#ifndef __LC3_TNS_H +#define __LC3_TNS_H + +#include "common.h" +#include "bits.h" + + +/** + * Bitstream data + */ + +typedef struct lc3_tns_data { + int nfilters; + bool lpc_weighting; + int rc_order[2]; + int rc[2][8]; +} lc3_tns_data_t; + + +/* ---------------------------------------------------------------------------- + * Encoding + * -------------------------------------------------------------------------- */ + +/** + * TNS analysis + * dt, bw Duration and bandwidth of the frame + * nn_flag True when high energy detected near Nyquist frequency + * nbytes Size in bytes of the frame + * data Return bitstream data + * x Spectral coefficients, filtered as output + */ +void lc3_tns_analyze(enum lc3_dt dt, enum lc3_bandwidth bw, + bool nn_flag, int nbytes, lc3_tns_data_t *data, float *x); + +/** + * Return number of bits coding the data + * data Bitstream data + * return Bit consumption + */ +int lc3_tns_get_nbits(const lc3_tns_data_t *data); + +/** + * Put bitstream data + * bits Bitstream context + * data Bitstream data + */ +void lc3_tns_put_data(lc3_bits_t *bits, const lc3_tns_data_t *data); + + +/* ---------------------------------------------------------------------------- + * Decoding + * -------------------------------------------------------------------------- */ + +/** + * Get bitstream data + * bits Bitstream context + * dt, bw Duration and bandwidth of the frame + * nbytes Size in bytes of the frame + * data Bitstream data + */ +void lc3_tns_get_data(lc3_bits_t *bits, + enum lc3_dt dt, enum lc3_bandwidth bw, int nbytes, lc3_tns_data_t *data); + +/** + * TNS synthesis + * dt, bw Duration and bandwidth of the frame + * data Bitstream data + * x Spectral coefficients, filtered as output + */ +void lc3_tns_synthesize(enum lc3_dt dt, enum lc3_bandwidth bw, + const lc3_tns_data_t *data, float *x); + + +#endif /* __LC3_TNS_H */ diff --git a/src/btstack_lc3_google.c b/src/btstack_lc3_google.c new file mode 100644 index 000000000..0de90553e --- /dev/null +++ b/src/btstack_lc3_google.c @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2022 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN + * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#define BTSTACK_FILE__ "btstack_lc3_google.c" + +/** + * @title LC3 Google Adapter + */ + +#include "btstack_config.h" +#include "bluetooth.h" + +#include "btstack_lc3_google.h" +#include "btstack_debug.h" +#include + +static uint16_t lc3_frame_duration_in_us(btstack_lc3_frame_duration_t frame_duration){ + switch (frame_duration) { + case BTSTACK_LC3_FRAME_DURATION_7500US: + return 7500; + case BTSTACK_LC3_FRAME_DURATION_10000US: + return 10000; + default: + return 0; + } +} + +/* Decoder implementation */ + +static uint8_t lc3_decoder_google_configure(void * context, uint32_t sample_rate, btstack_lc3_frame_duration_t frame_duration){ + btstack_lc3_decoder_google_t * instance = (btstack_lc3_decoder_google_t *) context; + + // map frame duration + uint16_t duration_us = lc3_frame_duration_in_us(frame_duration); + if (duration_us == 0){ + return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } + + // store config + instance->sample_rate = sample_rate; + instance->frame_duration = frame_duration; + + // config decoder + instance->decoder = lc3_setup_decoder(duration_us, sample_rate, 0, &instance->decoder_mem); + + if (instance->decoder == NULL) { + return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } + + return ERROR_CODE_SUCCESS; +} + +static uint16_t lc3_decoder_google_get_number_octets_for_bitrate(void * context, uint32_t bitrate){ + btstack_lc3_decoder_google_t * instance = (btstack_lc3_decoder_google_t *) context; + uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration); + if (duration_us == 0){ + return 0; + } + return lc3_frame_bytes(duration_us, bitrate); +} + +static uint16_t lc3_decoder_google_get_number_samples_per_frame(void * context){ + btstack_lc3_decoder_google_t * instance = (btstack_lc3_decoder_google_t *) context; + uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration); + if (duration_us == 0){ + return 0; + } + return lc3_frame_samples(duration_us, instance->sample_rate); +} + +static uint8_t lc3_decoder_google_decode(void * context, const uint8_t *bytes, uint16_t byte_count, uint8_t BFI, enum lc3_pcm_format fmt, void * pcm_out, uint16_t stride, uint8_t * BEC_detect){ + btstack_lc3_decoder_google_t * instance = (btstack_lc3_decoder_google_t *) context; + + if (BFI){ + // bit errors, trigger PLC by passing NULL as buffer + *BEC_detect = 1; + bytes = NULL; + } else { + // no bit errors, regular processing + *BEC_detect = 0; + } + + int result = lc3_decode(instance->decoder, (const void *) bytes, byte_count, fmt, pcm_out, stride); + switch (result){ + case 0: // success + return ERROR_CODE_SUCCESS; + case -1: // PLC engaged + *BEC_detect = 1; + return ERROR_CODE_SUCCESS; + default: + return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } +} + +static uint8_t lc3_decoder_google_decode_signed_16(void * context, const uint8_t *bytes, uint16_t byte_count, uint8_t BFI, int16_t* pcm_out, uint16_t stride, uint8_t * BEC_detect){ + return lc3_decoder_google_decode(context, bytes, byte_count, BFI, LC3_PCM_FORMAT_S16, (void *) pcm_out, stride, BEC_detect); +} + +static uint8_t lc3_decoder_google_decode_signed_24(void * context, const uint8_t *bytes, uint16_t byte_count, uint8_t BFI, int32_t* pcm_out, uint16_t stride, uint8_t * BEC_detect) { + return lc3_decoder_google_decode(context, bytes, byte_count, BFI, LC3_PCM_FORMAT_S24, (void *) pcm_out, stride, BEC_detect); +} + +static const btstack_lc3_decoder_t btstack_l3c_decoder_google_instance = { + lc3_decoder_google_configure, + lc3_decoder_google_get_number_octets_for_bitrate, + lc3_decoder_google_get_number_samples_per_frame, + lc3_decoder_google_decode_signed_16, + lc3_decoder_google_decode_signed_24 +}; + +const btstack_lc3_decoder_t * btstack_lc3_decoder_google_init_instance(btstack_lc3_decoder_google_t * context){ + memset(context, 0, sizeof(btstack_lc3_decoder_google_t)); + return &btstack_l3c_decoder_google_instance; +} + +/* Encoder implementation */ + +static uint8_t lc3_encoder_google_configure(void * context, uint32_t sample_rate, btstack_lc3_frame_duration_t frame_duration){ + btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context; + + // map frame duration + uint16_t duration_us = lc3_frame_duration_in_us(frame_duration); + if (duration_us == 0){ + return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } + + // store config + instance->sample_rate = sample_rate; + instance->frame_duration = frame_duration; + + // config encoder + instance->encoder = lc3_setup_encoder(duration_us, sample_rate, 0, &instance->encoder_mem); + + if (instance->encoder == NULL) { + return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } + + return ERROR_CODE_SUCCESS; +} + +static uint32_t lc3_encoder_google_get_bitrate_for_number_of_octets(void * context, uint16_t number_of_octets){ + btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context; + // map frame duration + uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration); + if (duration_us == 0){ + return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } + return lc3_resolve_bitrate(duration_us, number_of_octets); +} + +static uint16_t lc3_encoder_google_get_number_samples_per_frame(void * context){ + btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context; + // map frame duration + uint16_t duration_us = lc3_frame_duration_in_us(instance->frame_duration); + if (duration_us == 0){ + return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } + return lc3_frame_samples(duration_us, instance->sample_rate); +} +static uint8_t lc3_encoder_google_encode_signed(void * context, enum lc3_pcm_format fmt, const void *pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count) { + btstack_lc3_encoder_google_t * instance = (btstack_lc3_encoder_google_t *) context; + int result = lc3_encode(instance->encoder, fmt, pcm_in, stride, byte_count, (void*) bytes); + switch (result){ + case 0: + return ERROR_CODE_SUCCESS; + default: + return ERROR_CODE_INVALID_HCI_COMMAND_PARAMETERS; + } +} + +static uint8_t lc3_encoder_google_encode_signed_16(void * context, const int16_t* pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count){ + return lc3_encoder_google_encode_signed(context, LC3_PCM_FORMAT_S16, (const void *) pcm_in, stride, bytes, byte_count); +} + +static uint8_t lc3_encoder_google_encode_signed_24(void * context, const int32_t* pcm_in, uint16_t stride, uint8_t *bytes, uint16_t byte_count){ + return lc3_encoder_google_encode_signed(context, LC3_PCM_FORMAT_S24, (const void *) pcm_in, stride, bytes, byte_count); +} + +static const btstack_lc3_encoder_t btstack_l3c_encoder_google_instance = { + lc3_encoder_google_configure, + lc3_encoder_google_get_bitrate_for_number_of_octets, + lc3_encoder_google_get_number_samples_per_frame, + lc3_encoder_google_encode_signed_16, + lc3_encoder_google_encode_signed_24 +}; + +const btstack_lc3_encoder_t * btstack_lc3_encoder_google_init_instance(btstack_lc3_encoder_google_t * context){ + memset(context, 0, sizeof(btstack_lc3_encoder_google_t)); + return &btstack_l3c_encoder_google_instance; +} + diff --git a/src/btstack_lc3_google.h b/src/btstack_lc3_google.h new file mode 100644 index 000000000..764b611bb --- /dev/null +++ b/src/btstack_lc3_google.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2022 BlueKitchen GmbH + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the names of + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BLUEKITCHEN + * GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/** + * @title LC3 Google Adapter + */ + +#ifndef BTSTACK_LC3_GOOGLE_H +#define BTSTACK_LC3_GOOGLE_H + +#include +#include "lc3.h" +#include "btstack_lc3.h" + +#if defined __cplusplus +extern "C" { +#endif + +/* API_START */ + +typedef struct { + lc3_decoder_mem_48k_t decoder_mem; + lc3_decoder_t decoder; // pointer + uint32_t sample_rate; + btstack_lc3_frame_duration_t frame_duration; +} btstack_lc3_decoder_google_t; + +typedef struct { + lc3_encoder_mem_48k_t encoder_mem; + lc3_encoder_t encoder; // pointer + uint32_t sample_rate; + btstack_lc3_frame_duration_t frame_duration; +} btstack_lc3_encoder_google_t; + +/** + * Init LC3 Decoder Instance + * @param context for EHIMA LC3 decoder + */ +const btstack_lc3_decoder_t * btstack_lc3_decoder_google_init_instance(btstack_lc3_decoder_google_t * context); + +/** + * Init LC3 Decoder Instance + * @param context for EHIMA LC3 decoder + */ +const btstack_lc3_encoder_t * btstack_lc3_encoder_google_init_instance(btstack_lc3_encoder_google_t * context); + +/* API_END */ + +#if defined __cplusplus +} +#endif +#endif // BTSTACK_LC3_GOOGLE_H