diff options
Diffstat (limited to 'nok_lt_prediction.c')
-rw-r--r-- | nok_lt_prediction.c | 178 |
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; + } +} |