Initial import of NFC GNSS SDK project
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
/* L3SubBand */
|
||||
|
||||
#include "l3subband.h"
|
||||
#include "tables.h"
|
||||
#include "types.h"
|
||||
|
||||
/*
|
||||
* shine_subband_initialise:
|
||||
* ----------------------
|
||||
* Calculates the analysis filterbank coefficients and rounds to the
|
||||
* 9th decimal place accuracy of the filterbank tables in the ISO
|
||||
* document. The coefficients are stored in #filter#
|
||||
*/
|
||||
void shine_subband_initialise(shine_global_config *config) {
|
||||
int i, j;
|
||||
double filter;
|
||||
|
||||
for (i = MAX_CHANNELS; i--;) {
|
||||
config->subband.off[i] = 0;
|
||||
memset(config->subband.x[i], 0, sizeof(config->subband.x[i]));
|
||||
}
|
||||
|
||||
for (i = SBLIMIT; i--;)
|
||||
for (j = 64; j--;) {
|
||||
if ((filter = 1e9 * cos((double)((2 * i + 1) * (16 - j) * PI64))) >= 0)
|
||||
modf(filter + 0.5, &filter);
|
||||
else
|
||||
modf(filter - 0.5, &filter);
|
||||
/* scale and convert to fixed point before storing */
|
||||
config->subband.fl[i][j] = (int32_t)(filter * (0x7fffffff * 1e-9));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* shine_window_filter_subband:
|
||||
* -------------------------
|
||||
* Overlapping window on PCM samples
|
||||
* 32 16-bit pcm samples are scaled to fractional 2's complement and
|
||||
* concatenated to the end of the window buffer #x#. The updated window
|
||||
* buffer #x# is then windowed by the analysis window #shine_enwindow# to
|
||||
* produce the windowed sample #z# Calculates the analysis filter bank
|
||||
* coefficients The windowed samples #z# is filtered by the digital filter
|
||||
* matrix #filter# to produce the subband samples #s#. This done by first
|
||||
* selectively picking out values from the windowed samples, and then
|
||||
* multiplying them by the filter matrix, producing 32 subband samples.
|
||||
*/
|
||||
void shine_window_filter_subband(int16_t **buffer, int32_t s[SBLIMIT], int ch,
|
||||
shine_global_config *config, int stride) {
|
||||
int32_t y[64];
|
||||
int i, j;
|
||||
int16_t *ptr = *buffer;
|
||||
|
||||
/* replace 32 oldest samples with 32 new samples */
|
||||
for (i = 32; i--;) {
|
||||
config->subband.x[ch][i + config->subband.off[ch]] = ((int32_t)*ptr) << 16;
|
||||
ptr += stride;
|
||||
}
|
||||
*buffer = ptr;
|
||||
|
||||
for (i = 64; i--;) {
|
||||
int32_t s_value;
|
||||
#ifdef __BORLANDC__
|
||||
uint32_t s_value_lo;
|
||||
#else
|
||||
uint32_t s_value_lo __attribute__((unused));
|
||||
#endif
|
||||
|
||||
mul0(s_value, s_value_lo,
|
||||
config->subband
|
||||
.x[ch][(config->subband.off[ch] + i + (0 << 6)) & (HAN_SIZE - 1)],
|
||||
shine_enwindow[i + (0 << 6)]);
|
||||
muladd(s_value, s_value_lo,
|
||||
config->subband.x[ch][(config->subband.off[ch] + i + (1 << 6)) &
|
||||
(HAN_SIZE - 1)],
|
||||
shine_enwindow[i + (1 << 6)]);
|
||||
muladd(s_value, s_value_lo,
|
||||
config->subband.x[ch][(config->subband.off[ch] + i + (2 << 6)) &
|
||||
(HAN_SIZE - 1)],
|
||||
shine_enwindow[i + (2 << 6)]);
|
||||
muladd(s_value, s_value_lo,
|
||||
config->subband.x[ch][(config->subband.off[ch] + i + (3 << 6)) &
|
||||
(HAN_SIZE - 1)],
|
||||
shine_enwindow[i + (3 << 6)]);
|
||||
muladd(s_value, s_value_lo,
|
||||
config->subband.x[ch][(config->subband.off[ch] + i + (4 << 6)) &
|
||||
(HAN_SIZE - 1)],
|
||||
shine_enwindow[i + (4 << 6)]);
|
||||
muladd(s_value, s_value_lo,
|
||||
config->subband.x[ch][(config->subband.off[ch] + i + (5 << 6)) &
|
||||
(HAN_SIZE - 1)],
|
||||
shine_enwindow[i + (5 << 6)]);
|
||||
muladd(s_value, s_value_lo,
|
||||
config->subband.x[ch][(config->subband.off[ch] + i + (6 << 6)) &
|
||||
(HAN_SIZE - 1)],
|
||||
shine_enwindow[i + (6 << 6)]);
|
||||
muladd(s_value, s_value_lo,
|
||||
config->subband.x[ch][(config->subband.off[ch] + i + (7 << 6)) &
|
||||
(HAN_SIZE - 1)],
|
||||
shine_enwindow[i + (7 << 6)]);
|
||||
mulz(s_value, s_value_lo);
|
||||
y[i] = s_value;
|
||||
}
|
||||
|
||||
config->subband.off[ch] = (config->subband.off[ch] + 480) &
|
||||
(HAN_SIZE - 1); /* offset is modulo (HAN_SIZE)*/
|
||||
|
||||
for (i = SBLIMIT; i--;) {
|
||||
int32_t s_value;
|
||||
#ifdef __BORLANDC__
|
||||
uint32_t s_value_lo;
|
||||
#else
|
||||
uint32_t s_value_lo __attribute__((unused));
|
||||
#endif
|
||||
|
||||
mul0(s_value, s_value_lo, config->subband.fl[i][63], y[63]);
|
||||
for (j = 63; j; j -= 7) {
|
||||
muladd(s_value, s_value_lo, config->subband.fl[i][j - 1], y[j - 1]);
|
||||
muladd(s_value, s_value_lo, config->subband.fl[i][j - 2], y[j - 2]);
|
||||
muladd(s_value, s_value_lo, config->subband.fl[i][j - 3], y[j - 3]);
|
||||
muladd(s_value, s_value_lo, config->subband.fl[i][j - 4], y[j - 4]);
|
||||
muladd(s_value, s_value_lo, config->subband.fl[i][j - 5], y[j - 5]);
|
||||
muladd(s_value, s_value_lo, config->subband.fl[i][j - 6], y[j - 6]);
|
||||
muladd(s_value, s_value_lo, config->subband.fl[i][j - 7], y[j - 7]);
|
||||
}
|
||||
mulz(s_value, s_value_lo);
|
||||
s[i] = s_value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user