aboutsummaryrefslogtreecommitdiff
path: root/nok_lt_prediction.c
diff options
context:
space:
mode:
Diffstat (limited to 'nok_lt_prediction.c')
-rw-r--r--nok_lt_prediction.c178
1 files changed, 178 insertions, 0 deletions
diff --git a/nok_lt_prediction.c b/nok_lt_prediction.c
new file mode 100644
index 0000000..3b415e4
--- /dev/null
+++ b/nok_lt_prediction.c
@@ -0,0 +1,178 @@
+/**************************************************************************
+
+This software module was originally developed by
+Nokia in the course of development of the MPEG-2 AAC/MPEG-4
+Audio standard ISO/IEC13818-7, 14496-1, 2 and 3.
+This software module is an implementation of a part
+of one or more MPEG-2 AAC/MPEG-4 Audio tools as specified by the
+MPEG-2 aac/MPEG-4 Audio standard. ISO/IEC gives users of the
+MPEG-2aac/MPEG-4 Audio standards free license to this software module
+or modifications thereof for use in hardware or software products
+claiming conformance to the MPEG-2 aac/MPEG-4 Audio standards. Those
+intending to use this software module in hardware or software products
+are advised that this use may infringe existing patents. The original
+developer of this software module, the subsequent
+editors and their companies, and ISO/IEC have no liability for use of
+this software module or modifications thereof in an
+implementation. Copyright is not released for non MPEG-2 aac/MPEG-4
+Audio conforming products. The original developer retains full right to
+use the code for the developer's own purpose, assign or donate the code to a
+third party and to inhibit third party from using the code for non
+MPEG-2 aac/MPEG-4 Audio conforming products. This copyright notice
+must be included in all copies or derivative works.
+Copyright (c)1997.
+
+***************************************************************************/
+/*
+ * $Id: nok_lt_prediction.c,v 1.9 2003/02/18 18:51:31 wmaycisco Exp $
+ */
+
+#include "all.h"
+#include "tns.h"
+#include "block.h"
+#include "nok_ltp_common.h"
+#include "nok_lt_prediction.h"
+#include "nok_ltp_common_internal.h"
+#include "port.h"
+#include "bits.h"
+#include "util.h"
+
+/*
+ Initialize the history buffer for long term prediction
+ */
+
+void nok_init_lt_pred(NOK_LT_PRED_STATUS **lt_status, int channels)
+{
+ int ch;
+
+ for (ch = 0; ch < channels; ch++) {
+ lt_status[ch]->buffer = AllocMemory(NOK_LT_BLEN*sizeof(float));
+#ifndef _WIN32
+ SetMemory(lt_status[ch]->buffer, 0, NOK_LT_BLEN*sizeof(float));
+#endif
+ }
+}
+
+void nok_end_lt_pred(NOK_LT_PRED_STATUS **lt_status, int channels)
+{
+ int ch;
+
+ for (ch = 0; ch < channels; ch++) {
+ if (lt_status[ch]->buffer) FreeMemory(lt_status[ch]->buffer);
+ }
+}
+
+
+/**************************************************************************
+ nok_lt_prediction
+ *************************************************************************/
+
+void nok_lt_predict(faacDecHandle hDecoder, Info *info, WINDOW_TYPE win_type, Wnd_Shape *win_shape,
+ int *sbk_prediction_used, int *sfb_prediction_used,
+ NOK_LT_PRED_STATUS *lt_status, Float weight, int *delay,
+ Float *current_frame, int block_size_long, int block_size_medium,
+ int block_size_short, TNS_frame_info *tns_frame_info)
+{
+ int i, j, num_samples;
+ float_ext *mdct_predicted;
+ float_ext *predicted_samples;
+
+ mdct_predicted = AllocMemory(2*NOK_MAX_BLOCK_LEN_LONG*sizeof(float_ext));
+ predicted_samples = AllocMemory(2*NOK_MAX_BLOCK_LEN_LONG*sizeof(float_ext));
+
+
+ switch(win_type) {
+
+ case ONLY_LONG_WINDOW:
+ case LONG_START_WINDOW:
+ case LONG_STOP_WINDOW:
+ if (sbk_prediction_used[0])
+ {
+ /* Prediction for time domain signal */
+ num_samples = 2 * block_size_long;
+ j = NOK_LT_BLEN - 2 * block_size_long - (delay[0] - MAX_LTP_DELAY / 2);
+ if(NOK_LT_BLEN - j < 2 * block_size_long)
+ num_samples = NOK_LT_BLEN - j;
+
+ for(i = 0; i < num_samples; i++)
+ predicted_samples[i] = weight * lt_status->buffer[i + j];
+ for( ; i < 2 * block_size_long; i++)
+ predicted_samples[i] = 0.0f;
+
+ /* Transform prediction to frequency domain. */
+ time2freq_adapt(hDecoder, win_type, win_shape, predicted_samples, mdct_predicted);
+
+ /* Apply the TNS analysis filter to the predicted spectrum. */
+ if(tns_frame_info != NULL)
+ tns_filter_subblock(hDecoder, mdct_predicted, info->sfb_per_bk, info->sbk_sfb_top[0],
+ 1, &tns_frame_info->info[0]);
+
+ /* Clean those sfb's where prediction is not used. */
+ for (i = 0, j = 0; i < info->sfb_per_bk; i++) {
+ if (sfb_prediction_used[i + 1] == 0) {
+ for (; j < info->sbk_sfb_top[0][i]; j++)
+ mdct_predicted[j] = 0.0;
+ } else {
+ j = info->sbk_sfb_top[0][i];
+ }
+ }
+
+ /* Add the prediction to dequantized spectrum. */
+ for (i = 0; i < block_size_long; i++)
+ current_frame[i] = current_frame[i] + mdct_predicted[i];
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ FreeMemory(mdct_predicted);
+ FreeMemory(predicted_samples);
+}
+
+/**************************************************************************
+ nok_lt_update
+ *************************************************************************/
+
+void nok_lt_update(NOK_LT_PRED_STATUS *lt_status, Float *time_signal,
+ Float *overlap_signal, int block_size_long)
+{
+ int i;
+
+ for(i = 0; i < NOK_LT_BLEN - 2 * block_size_long; i++)
+ lt_status->buffer[i] = lt_status->buffer[i + block_size_long];
+
+ for(i = 0; i < block_size_long; i++)
+ {
+ lt_status->buffer[NOK_LT_BLEN - 2 * block_size_long + i] =
+ time_signal[i];
+
+ lt_status->buffer[NOK_LT_BLEN - block_size_long + i] =
+ overlap_signal[i];
+ }
+}
+
+/**************************************************************************
+ nok_lt_decode
+ *************************************************************************/
+void nok_lt_decode(faacDecHandle hDecoder, int max_sfb, int *sbk_prediction_used,
+ int *sfb_prediction_used, Float *weight, int *delay)
+{
+ int i, last_band;
+
+ if ((sbk_prediction_used[0] = faad_getbits(&hDecoder->ld, LEN_LTP_DATA_PRESENT)))
+ {
+ delay[0] = faad_getbits(&hDecoder->ld, 11);
+ *weight = codebook[faad_getbits(&hDecoder->ld, 3)];
+
+ last_band = (max_sfb < NOK_MAX_LT_PRED_LONG_SFB
+ ? max_sfb : NOK_MAX_LT_PRED_LONG_SFB) + 1;
+
+ sfb_prediction_used[0] = sbk_prediction_used[0];
+ for (i = 1; i < last_band; i++)
+ sfb_prediction_used[i] = faad_getbits(&hDecoder->ld, LEN_LTP_LONG_USED);
+ for (; i < max_sfb + 1; i++)
+ sfb_prediction_used[i] = 0;
+ }
+}