ref: d12f80faa4a0a08a38cb05de3960b2a6e01569df
parent: 60fa9e81165a47bf492e0835459e2dedf72df660
author: menno <menno>
date: Fri May 18 09:38:19 EDT 2001
Cleaned up backward prediction code
--- a/libfaac/backpred.c
+++ b/libfaac/backpred.c
@@ -16,396 +16,343 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: backpred.c,v 1.1 2001/05/02 05:40:15 menno Exp $
+ * $Id: backpred.c,v 1.2 2001/05/18 13:38:19 menno Exp $
*/
-/**********************************************************************
-
-INPUT:
-act_spec[]: the current frame's spectral components to be encoded.
-last_spec[]: the previous frame's quantized spectral error components
-btype: the current frame's window type
-nsfb: the number of scalefactor bands
-isfb_width[]: scalefactor bandwidth
-
-OUTPUT:
-act_spec[]: the current frame's spectral error components to be encoded
-pred_global_flag: global prediction enable/disable flag
-pred_sbf_glag[]: enable/disable flag for each scalefactor band
-reset_group: number for the reset group => if -1, then no reset
-***********************************************************************/
-
#include <math.h>
+#include "frame.h"
#include "coder.h"
#include "channels.h"
#include "backpred.h"
-/* Make these work for mulitchannels */ /* CL, 1/98 */
-/*static int psy_init = 0;
-static float dr[LPC][FLEN_LONG/2],e[LPC+1+1][FLEN_LONG/2];
-static float K[LPC+1][FLEN_LONG/2], R[LPC+1][FLEN_LONG/2];
-static float VAR[LPC+1][FLEN_LONG/2], KOR[LPC+1][FLEN_LONG/2];
-static float sb_samples_pred[FLEN_LONG/2];
-static int thisLineNeedsResetting[FLEN_LONG/2];
-static int reset_count = 0;*/
-
-static int psy_init_mc[MAX_CHANNELS];
-static float dr_mc[MAX_CHANNELS][LPC][FLEN_LONG/2],e_mc[MAX_CHANNELS][LPC+1+1][FLEN_LONG/2];
-static float K_mc[MAX_CHANNELS][LPC+1][FLEN_LONG/2], R_mc[MAX_CHANNELS][LPC+1][FLEN_LONG/2];
-static float VAR_mc[MAX_CHANNELS][LPC+1][FLEN_LONG/2], KOR_mc[MAX_CHANNELS][LPC+1][FLEN_LONG/2];
-static float sb_samples_pred_mc[MAX_CHANNELS][FLEN_LONG/2];
-static int thisLineNeedsResetting_mc[MAX_CHANNELS][FLEN_LONG/2];
-static int reset_count_mc[MAX_CHANNELS];
-
-/* Max prediction band as function of fs index */
-int MAX_PRED_SFB[][2] = {
- {96000,33},
- {88200,33},
- {64000,38},
- {48000,40},
- {44100,40},
- {32000,40},
- {24000,41},
- {22050,41},
- {16000,37},
- {12000,37},
- {11025,37},
- {8000,34},
- {-1,0}};
-
-int GetMaxPredSfb(int samplingRateIdx)
+void PredInit(faacEncHandle hEncoder)
{
- return MAX_PRED_SFB[samplingRateIdx][1];
-}
+ unsigned int channel;
+ for (channel = 0; channel < hEncoder->numChannels; channel++) {
+ BwpInfo *bwpInfo = &(hEncoder->coderInfo[channel].bwpInfo);
-
-void PredInit()
-{
- int i;
-
- for (i=0;i<MAX_CHANNELS;i++) {
- psy_init_mc[i] = 0;
- reset_count_mc[i] = 0;
+ bwpInfo->psy_init_mc = 0;
+ bwpInfo->reset_count_mc = 0;
}
}
-void PredCalcPrediction( double *act_spec, double *last_spec, int btype,
- int nsfb,
- int *isfb_width,
- CoderInfo *coderInfo,
- ChannelInfo *channelInfo, /* Pointer to Ch_Info */
- int chanNum)
+void PredCalcPrediction(double *act_spec, double *last_spec, int btype,
+ int nsfb,
+ int *isfb_width,
+ CoderInfo *coderInfo,
+ ChannelInfo *channelInfo,
+ int chanNum)
{
- int i, k, j, cb_long;
- int leftChanNum;
- int isRightWithCommonWindow;
- float small, small_p, num_bit, snr[SBMAX_L];
- float energy[FLEN_LONG/2], snr_p[FLEN_LONG/2], temp1, temp2;
- ChannelInfo *thisChannel;
+ int i, k, j, cb_long;
+ int leftChanNum;
+ int isRightWithCommonWindow;
+ double num_bit, snr[SBMAX_L];
+ double energy[BLOCK_LEN_LONG], snr_p[BLOCK_LEN_LONG], temp1, temp2;
+ ChannelInfo *thisChannel;
- /* Set pointers for specified channel number */
- /* int psy_init; */
- int *psy_init;
- float (*dr)[FLEN_LONG/2],(*e)[FLEN_LONG/2];
- float (*K)[FLEN_LONG/2], (*R)[FLEN_LONG/2];
- float (*VAR)[FLEN_LONG/2], (*KOR)[FLEN_LONG/2];
- float *sb_samples_pred;
- int *thisLineNeedsResetting;
- /* int reset_count; */
- int *reset_count;
- int *pred_global_flag;
- int *pred_sfb_flag;
- int *reset_group;
+ /* Set pointers for specified channel number */
+ /* int psy_init; */
+ int *psy_init;
+ double (*dr)[BLOCK_LEN_LONG],(*e)[BLOCK_LEN_LONG];
+ double (*K)[BLOCK_LEN_LONG], (*R)[BLOCK_LEN_LONG];
+ double (*VAR)[BLOCK_LEN_LONG], (*KOR)[BLOCK_LEN_LONG];
+ double *sb_samples_pred;
+ int *thisLineNeedsResetting;
+ /* int reset_count; */
+ int *reset_count;
+ int *pred_global_flag;
+ int *pred_sfb_flag;
+ int *reset_group;
- /* Set pointers for this chanNum */
- pred_global_flag = &(coderInfo[chanNum].pred_global_flag);
- pred_sfb_flag = coderInfo[chanNum].pred_sfb_flag;
- reset_group = &(coderInfo[chanNum].reset_group_number);
- /* psy_init = psy_init_mc[chanNum]; */
- psy_init = &psy_init_mc[chanNum];
- dr = &dr_mc[chanNum][0];
- e = &e_mc[chanNum][0];
- K = &K_mc[chanNum][0];
- R = &R_mc[chanNum][0];
- VAR = &VAR_mc[chanNum][0];
- KOR = &KOR_mc[chanNum][0];
- sb_samples_pred = &sb_samples_pred_mc[chanNum][0];
- thisLineNeedsResetting = &thisLineNeedsResetting_mc[chanNum][0];
- reset_count = &reset_count_mc[chanNum];
+ /* Set pointers for this chanNum */
+ pred_global_flag = &(coderInfo[chanNum].pred_global_flag);
+ pred_sfb_flag = coderInfo[chanNum].pred_sfb_flag;
+ reset_group = &(coderInfo[chanNum].reset_group_number);
+ psy_init = &coderInfo[chanNum].bwpInfo.psy_init_mc;
+ dr = &coderInfo[chanNum].bwpInfo.dr_mc[0];
+ e = &coderInfo[chanNum].bwpInfo.e_mc[0];
+ K = &coderInfo[chanNum].bwpInfo.K_mc[0];
+ R = &coderInfo[chanNum].bwpInfo.R_mc[0];
+ VAR = &coderInfo[chanNum].bwpInfo.VAR_mc[0];
+ KOR = &coderInfo[chanNum].bwpInfo.KOR_mc[0];
+ sb_samples_pred = &coderInfo[chanNum].bwpInfo.sb_samples_pred_mc[0];
+ thisLineNeedsResetting = &coderInfo[chanNum].bwpInfo.thisLineNeedsResetting_mc[0];
+ reset_count = &coderInfo[chanNum].bwpInfo.reset_count_mc;
- thisChannel = &(channelInfo[chanNum]);
- *psy_init = (*psy_init && (btype!=2));
+ thisChannel = &(channelInfo[chanNum]);
+ *psy_init = (*psy_init && (btype!=2));
- if((*psy_init) == 0) {
- for (j=0; j<FLEN_LONG/2; j++) {
- thisLineNeedsResetting[j]=1;
- }
- *psy_init = 1;
- }
+ if((*psy_init) == 0) {
+ for (j=0; j<BLOCK_LEN_LONG; j++) {
+ thisLineNeedsResetting[j]=1;
+ }
+ *psy_init = 1;
+ }
- if (btype==2) {
- pred_global_flag[0]=0;
- /* SHORT WINDOWS reset all the co-efficients */
- if (thisChannel->ch_is_left) {
- (*reset_count)++;
- if (*reset_count >= 31 * RESET_FRAME)
- *reset_count = RESET_FRAME;
- /* *reset_count = ((*reset_count) / RESET_FRAME) * RESET_FRAME;*/
- }
- return;
- }
+ if (btype==2) {
+ pred_global_flag[0]=0;
+ /* SHORT WINDOWS reset all the co-efficients */
+ if (thisChannel->ch_is_left) {
+ (*reset_count)++;
+ if (*reset_count >= 31 * RESET_FRAME)
+ *reset_count = RESET_FRAME;
+ }
+ return;
+ }
- /**************************************************/
- /* Compute state using last_spec */
- /**************************************************/
- for (i=0;i<FLEN_LONG/2;i++)
+ /**************************************************/
+ /* Compute state using last_spec */
+ /**************************************************/
+ for (i=0;i<BLOCK_LEN_LONG;i++)
{
- /* e[0][i]=last_spec[i]; */
- e[0][i]=last_spec[i]+sb_samples_pred[i];
-
- for(j=1;j<=LPC;j++)
- e[j][i] = e[j-1][i]-K[j][i]*R[j-1][i];
-
- for(j=1;j<LPC;j++)
- dr[j][i] = K[j][i]*e[j-1][i];
-
- for(j=1;j<=LPC;j++) {
- VAR[j][i] = ALPHA*VAR[j][i]+.5*(R[j-1][i]*R[j-1][i]+e[j-1][i]*e[j-1][i]);
- KOR[j][i] = ALPHA*KOR[j][i]+R[j-1][i]*e[j-1][i];
- }
+ /* e[0][i]=last_spec[i]; */
+ e[0][i]=last_spec[i]+sb_samples_pred[i];
+
+ for(j=1;j<=LPC;j++)
+ e[j][i] = e[j-1][i]-K[j][i]*R[j-1][i];
+
+ for(j=1;j<LPC;j++)
+ dr[j][i] = K[j][i]*e[j-1][i];
+
+ for(j=1;j<=LPC;j++) {
+ VAR[j][i] = ALPHA*VAR[j][i]+.5*(R[j-1][i]*R[j-1][i]+e[j-1][i]*e[j-1][i]);
+ KOR[j][i] = ALPHA*KOR[j][i]+R[j-1][i]*e[j-1][i];
+ }
- for(j=LPC-1;j>=1;j--)
- R[j][i] = A*(R[j-1][i]-dr[j][i]);
- R[0][i] = A*e[0][i];
+ for(j=LPC-1;j>=1;j--)
+ R[j][i] = A*(R[j-1][i]-dr[j][i]);
+ R[0][i] = A*e[0][i];
}
- /**************************************************/
- /* Reset state here if resets were sent */
- /**************************************************/
- for (i=0;i<FLEN_LONG/2;i++) {
- if (thisLineNeedsResetting[i]) {
- for (j = 0; j <= LPC; j++)
- {
- K[j][i] = 0.0;
- e[j][i] = 0.0;
- R[j][i] = 0.0;
- VAR[j][i] = 1.0;
- KOR[j][i] = 0.0;
- dr[j][i] = 0.0;
- }
- }
- }
+ /**************************************************/
+ /* Reset state here if resets were sent */
+ /**************************************************/
+ for (i=0;i<BLOCK_LEN_LONG;i++) {
+ if (thisLineNeedsResetting[i]) {
+ for (j = 0; j <= LPC; j++)
+ {
+ K[j][i] = 0.0;
+ e[j][i] = 0.0;
+ R[j][i] = 0.0;
+ VAR[j][i] = 1.0;
+ KOR[j][i] = 0.0;
+ dr[j][i] = 0.0;
+ }
+ }
+ }
- /**************************************************/
- /* Compute predictor coefficients, predicted data */
- /**************************************************/
- for (i=0;i<FLEN_LONG/2;i++)
+ /**************************************************/
+ /* Compute predictor coefficients, predicted data */
+ /**************************************************/
+ for (i=0;i<BLOCK_LEN_LONG;i++)
{
- for(j=1;j<=LPC;j++) {
- if(VAR[j][i]>MINVAR)
- K[j][i] = KOR[j][i]/VAR[j][i]*B;
- else
- K[j][i] = 0;
- }
+ for(j=1;j<=LPC;j++) {
+ if(VAR[j][i]>MINVAR)
+ K[j][i] = KOR[j][i]/VAR[j][i]*B;
+ else
+ K[j][i] = 0;
+ }
}
- for (k=0; k<FLEN_LONG/2; k++)
+ for (k=0; k<BLOCK_LEN_LONG; k++)
{
- sb_samples_pred[k]=0.0;
- for (i=1; i<=LPC; i++)
- sb_samples_pred[k]+=K[i][k]*R[i-1][k];
+ sb_samples_pred[k]=0.0;
+ for (i=1; i<=LPC; i++)
+ sb_samples_pred[k]+=K[i][k]*R[i-1][k];
}
- /***********************************************************/
- /* If this is the right channel of a channel_pair_element, */
- /* AND common_window is 1 in this channel_pair_element, */
- /* THEN copy predictor data to use from the left channel. */
- /* ELSE determine independent predictor data and resets. */
- /***********************************************************/
- /* BE CAREFUL HERE, this assumes that predictor data has */
- /* already been determined for the left channel!! */
- /***********************************************************/
- isRightWithCommonWindow = 0; /* Is this a right channel with common_window?*/
- if ((thisChannel->cpe)&&( !(thisChannel->ch_is_left))) {
- leftChanNum = thisChannel->paired_ch;
- if (channelInfo[leftChanNum].common_window) {
- isRightWithCommonWindow = 1;
- }
- }
+ /***********************************************************/
+ /* If this is the right channel of a channel_pair_element, */
+ /* AND common_window is 1 in this channel_pair_element, */
+ /* THEN copy predictor data to use from the left channel. */
+ /* ELSE determine independent predictor data and resets. */
+ /***********************************************************/
+ /* BE CAREFUL HERE, this assumes that predictor data has */
+ /* already been determined for the left channel!! */
+ /***********************************************************/
+ isRightWithCommonWindow = 0; /* Is this a right channel with common_window?*/
+ if ((thisChannel->cpe)&&( !(thisChannel->ch_is_left))) {
+ leftChanNum = thisChannel->paired_ch;
+ if (channelInfo[leftChanNum].common_window) {
+ isRightWithCommonWindow = 1;
+ }
+ }
- if (isRightWithCommonWindow) {
-
- /**************************************************/
- /* Use predictor data from the left channel. */
- /**************************************************/
- CopyPredInfo(&(coderInfo[chanNum]),&(coderInfo[leftChanNum]));
+ if (isRightWithCommonWindow) {
+
+ /**************************************************/
+ /* Use predictor data from the left channel. */
+ /**************************************************/
+ CopyPredInfo(&(coderInfo[chanNum]),&(coderInfo[leftChanNum]));
- /* Make sure to turn off bands with intensity stereo */
+ /* Make sure to turn off bands with intensity stereo */
#if 0
- if (thisChannel->is_info.is_present) {
- for (i=0; i<nsfb; i++) {
- if (thisChannel->is_info.is_used[i]) {
- pred_sfb_flag[i] = 0;
+ if (thisChannel->is_info.is_present) {
+ for (i=0; i<nsfb; i++) {
+ if (thisChannel->is_info.is_used[i]) {
+ pred_sfb_flag[i] = 0;
+ }
}
}
- }
#endif
-
- cb_long=0;
- for (i=0; i<nsfb; i++)
- {
- if (!pred_sfb_flag[i]) {
- for (j=cb_long; j<cb_long+isfb_width[i]; j++)
- sb_samples_pred[j]=0.0;
- }
- cb_long+=isfb_width[i];
- }
-
- /* Disable prediction for bands nsfb through SBMAX_L */
- for (i=j;i<FLEN_LONG/2;i++) {
- sb_samples_pred[i]=0.0;
- }
- for (i=nsfb;i<SBMAX_L;i++) {
- pred_sfb_flag[i]=0;
- }
-
- /* Is global enable set, if not enabled predicted samples are zeroed */
- if(!pred_global_flag[0]) {
- for (j=0; j<FLEN_LONG/2; j++)
- sb_samples_pred[j]=0.0;
- }
- for (j=0; j<FLEN_LONG/2; j++)
- act_spec[j]-=sb_samples_pred[j];
-
- } else {
+
+ cb_long=0;
+ for (i=0; i<nsfb; i++)
+ {
+ if (!pred_sfb_flag[i]) {
+ for (j=cb_long; j<cb_long+isfb_width[i]; j++)
+ sb_samples_pred[j]=0.0;
+ }
+ cb_long+=isfb_width[i];
+ }
+
+ /* Disable prediction for bands nsfb through SBMAX_L */
+ for (i=j;i<BLOCK_LEN_LONG;i++) {
+ sb_samples_pred[i]=0.0;
+ }
+ for (i=nsfb;i<SBMAX_L;i++) {
+ pred_sfb_flag[i]=0;
+ }
+
+ /* Is global enable set, if not enabled predicted samples are zeroed */
+ if(!pred_global_flag[0]) {
+ for (j=0; j<BLOCK_LEN_LONG; j++)
+ sb_samples_pred[j]=0.0;
+ }
+ for (j=0; j<BLOCK_LEN_LONG; j++)
+ act_spec[j]-=sb_samples_pred[j];
+
+ } else {
- /**************************************************/
- /* Determine whether to enable/disable prediction */
- /**************************************************/
-
- for (k=0; k<FLEN_LONG/2; k++)
- {energy[k]=act_spec[k]*act_spec[k];
- snr_p[k]=(act_spec[k]-sb_samples_pred[k])*(act_spec[k]-sb_samples_pred[k]);
- }
-
- cb_long=0;
- for (i=0; i<nsfb; i++)
- {
- pred_sfb_flag[i]=1;
- temp1=0.0;
- temp2=0.0;
- for (j=cb_long; j<cb_long+isfb_width[i]; j++)
- {temp1+=energy[j]; temp2+=snr_p[j];}
- if(temp2<1.e-20) temp2=1.e-20;
- if(temp1!=0.0) {snr[i]=-10.*log10((double ) temp2/temp1);}
- else snr[i]=0.0;
- if(snr[i]<=0.0) {pred_sfb_flag[i]=0;
- for (j=cb_long; j<cb_long+isfb_width[i]; j++)
- sb_samples_pred[j]=0.0; }
- cb_long+=isfb_width[i];
- }
-
- /* Disable prediction for bands nsfb through SBMAX_L */
- for (i=j;i<FLEN_LONG/2;i++) {
- sb_samples_pred[i]=0.0;
- }
- for (i=nsfb;i<SBMAX_L;i++) {
- pred_sfb_flag[i]=0;
- }
+ /**************************************************/
+ /* Determine whether to enable/disable prediction */
+ /**************************************************/
+
+ for (k=0; k<BLOCK_LEN_LONG; k++) {
+ energy[k]=act_spec[k]*act_spec[k];
+ snr_p[k]=(act_spec[k]-sb_samples_pred[k])*(act_spec[k]-sb_samples_pred[k]);
+ }
+
+ cb_long=0;
+ for (i=0; i<nsfb; i++) {
+ pred_sfb_flag[i]=1;
+ temp1=0.0;
+ temp2=0.0;
+ for (j=cb_long; j<cb_long+isfb_width[i]; j++) {
+ temp1+=energy[j];
+ temp2+=snr_p[j];
+ }
+ if(temp2<1.e-20)
+ temp2=1.e-20;
+ if(temp1!=0.0)
+ snr[i]=-10.*log10((double ) temp2/temp1);
+ else
+ snr[i]=0.0;
- num_bit=0.0;
- for (i=0; i<nsfb; i++)
- if(snr[i]>0.0) num_bit+=snr[i]/6.*isfb_width[i];
-
- /* Determine global enable, if not enabled predicted samples are zeroed */
- pred_global_flag[0]=1;
- if(num_bit<50) {
- pred_global_flag[0]=0; num_bit=0.0;
- for (j=0; j<FLEN_LONG/2; j++)
- sb_samples_pred[j]=0.0;
- }
- for (j=0; j<FLEN_LONG/2; j++)
- act_spec[j]-=sb_samples_pred[j];
-
- }
-
- /**********************************************************/
- /* If this is a left channel, determine pred resets. */
- /* If this is a right channel, using pred reset data from */
- /* left channel. Keep left and right resets in sync. */
- /**********************************************************/
- if ((thisChannel->cpe)&&( !(thisChannel->ch_is_left))) {
- /* if (!thisChannel->ch_is_left) {*/
- /**********************************************************/
- /* Using predictor reset data from the left channel. */
- /**********************************************************/
- reset_count = &reset_count_mc[leftChanNum];
- /* Reset the frame counter */
- for (i=0;i<FLEN_LONG/2;i++) {
- thisLineNeedsResetting[i]=0;
- }
- reset_group = &(coderInfo[chanNum].reset_group_number);
- if (*reset_count % RESET_FRAME == 0)
- { /* Send a reset in this frame */
- *reset_group = *reset_count / 8;
- for (i = *reset_group - 1; i < FLEN_LONG / 2; i += 30)
- {
- thisLineNeedsResetting[i]=1;
- }
- }
- else
- *reset_group = -1;
- } else {
- /* Code segment added by JB */
- /******************************************************************/
- /* Determine whether a prediction reset is required - if so, then */
- /* set reset flag for the appropriate group. */
- /******************************************************************/
-
- /* Increase counter on left channel, keep left and right resets in sync */
- (*reset_count)++;
+ if(snr[i]<=0.0) {
+ pred_sfb_flag[i]=0;
+ for (j=cb_long; j<cb_long+isfb_width[i]; j++)
+ sb_samples_pred[j]=0.0;
+ }
+ cb_long+=isfb_width[i];
+ }
- /* Reset the frame counter */
- for (i=0;i<FLEN_LONG/2;i++) {
- thisLineNeedsResetting[i]=0;
- }
- if (*reset_count >= 31 * RESET_FRAME)
- *reset_count = RESET_FRAME;
- if (*reset_count % RESET_FRAME == 0)
- { /* Send a reset in this frame */
- *reset_group = *reset_count / 8;
- for (i = *reset_group - 1; i < FLEN_LONG / 2; i += 30)
- {
- thisLineNeedsResetting[i]=1;
- }
- }
- else
- *reset_group = -1;
- /* End of code segment */
- }
+ /* Disable prediction for bands nsfb through SBMAX_L */
+ for (i=j;i<BLOCK_LEN_LONG;i++) {
+ sb_samples_pred[i]=0.0;
+ }
+ for (i=nsfb;i<SBMAX_L;i++) {
+ pred_sfb_flag[i]=0;
+ }
+ num_bit=0.0;
+ for (i=0; i<nsfb; i++)
+ if(snr[i]>0.0)
+ num_bit+=snr[i]/6.*isfb_width[i];
+
+ /* Determine global enable, if not enabled predicted samples are zeroed */
+ pred_global_flag[0]=1;
+ if(num_bit<50) {
+ pred_global_flag[0]=0; num_bit=0.0;
+ for (j=0; j<BLOCK_LEN_LONG; j++)
+ sb_samples_pred[j]=0.0;
+ }
+ for (j=0; j<BLOCK_LEN_LONG; j++)
+ act_spec[j]-=sb_samples_pred[j];
+
+ }
+
+ /**********************************************************/
+ /* If this is a left channel, determine pred resets. */
+ /* If this is a right channel, using pred reset data from */
+ /* left channel. Keep left and right resets in sync. */
+ /**********************************************************/
+ if ((thisChannel->cpe)&&( !(thisChannel->ch_is_left))) {
+ /* if (!thisChannel->ch_is_left) {*/
+ /**********************************************************/
+ /* Using predictor reset data from the left channel. */
+ /**********************************************************/
+ reset_count = &coderInfo[leftChanNum].bwpInfo.reset_count_mc;
+ /* Reset the frame counter */
+ for (i=0;i<BLOCK_LEN_LONG;i++) {
+ thisLineNeedsResetting[i]=0;
+ }
+ reset_group = &(coderInfo[chanNum].reset_group_number);
+ if (*reset_count % RESET_FRAME == 0)
+ { /* Send a reset in this frame */
+ *reset_group = *reset_count / 8;
+ for (i = *reset_group - 1; i < BLOCK_LEN_LONG; i += 30)
+ {
+ thisLineNeedsResetting[i]=1;
+ }
+ }
+ else
+ *reset_group = -1;
+ } else {
+ /******************************************************************/
+ /* Determine whether a prediction reset is required - if so, then */
+ /* set reset flag for the appropriate group. */
+ /******************************************************************/
+
+ /* Increase counter on left channel, keep left and right resets in sync */
+ (*reset_count)++;
- /* Code segment added by JB */
+ /* Reset the frame counter */
+ for (i=0;i<BLOCK_LEN_LONG;i++) {
+ thisLineNeedsResetting[i]=0;
+ }
+ if (*reset_count >= 31 * RESET_FRAME)
+ *reset_count = RESET_FRAME;
+ if (*reset_count % RESET_FRAME == 0)
+ { /* Send a reset in this frame */
+ *reset_group = *reset_count / 8;
+ for (i = *reset_group - 1; i < BLOCK_LEN_LONG; i += 30)
+ {
+ thisLineNeedsResetting[i]=1;
+ }
+ }
+ else
+ *reset_group = -1;
+ }
- /* Ensure that prediction data is sent when there is a prediction
- * reset.
- */
- if (*reset_group != -1 && pred_global_flag[0] == 0)
+
+ /* Ensure that prediction data is sent when there is a prediction
+ * reset.
+ */
+ if (*reset_group != -1 && pred_global_flag[0] == 0)
{
- pred_global_flag[0] = 1;
- for (i = 0; i < nsfb; i++)
- pred_sfb_flag[i] = 0;
+ pred_global_flag[0] = 1;
+ for (i = 0; i < nsfb; i++)
+ pred_sfb_flag[i] = 0;
}
- /* End of code segment */
-
}
--- a/libfaac/backpred.h
+++ b/libfaac/backpred.h
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: backpred.h,v 1.1 2001/05/02 05:40:16 menno Exp $
+ * $Id: backpred.h,v 1.2 2001/05/18 13:38:19 menno Exp $
*/
#ifndef _AAC_BACK_H_INCLUDED
@@ -26,27 +26,22 @@
#define PRED_A 0.953125
#define PRED_B 0.953125
-#define FLEN_LONG 2048
-#define SBMAX_L 49
-#define LPC 2
-#define ALPHA PRED_ALPHA
-#define A PRED_A
-#define B PRED_B
-#define MINVAR 1.e-10
+#define ALPHA PRED_ALPHA
+#define A PRED_A
+#define B PRED_B
+#define MINVAR 1.e-10
/* Reset every RESET_FRAME frames. */
-#define RESET_FRAME 8
+#define RESET_FRAME 8
-int GetMaxPredSfb(int samplingRateIdx);
-
-void PredCalcPrediction( double *act_spec,
- double *last_spec,
- int btype,
- int nsfb,
- int *isfb_width,
- CoderInfo *coderInfo,
- ChannelInfo *channelInfo,
- int chanNum);
+void PredCalcPrediction(double *act_spec,
+ double *last_spec,
+ int btype,
+ int nsfb,
+ int *isfb_width,
+ CoderInfo *coderInfo,
+ ChannelInfo *channelInfo,
+ int chanNum);
void PredInit();
--- a/libfaac/coder.h
+++ b/libfaac/coder.h
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: coder.h,v 1.6 2001/05/02 05:39:14 menno Exp $
+ * $Id: coder.h,v 1.7 2001/05/18 13:38:19 menno Exp $
*/
#ifndef CODER_H
@@ -67,6 +67,8 @@
#define CODESIZE 8
#define NOK_LT_BLEN (3 * BLOCK_LEN_LONG)
+#define SBMAX_L 49
+#define LPC 2
typedef struct {
int order; /* Filter order */
@@ -111,6 +113,18 @@
double *ltp_overlap_buffer;
} LtpInfo;
+typedef struct
+{
+ int psy_init_mc;
+ double dr_mc[LPC][BLOCK_LEN_LONG],e_mc[LPC+1+1][BLOCK_LEN_LONG];
+ double K_mc[LPC+1][BLOCK_LEN_LONG], R_mc[LPC+1][BLOCK_LEN_LONG];
+ double VAR_mc[LPC+1][BLOCK_LEN_LONG], KOR_mc[LPC+1][BLOCK_LEN_LONG];
+ double sb_samples_pred_mc[BLOCK_LEN_LONG];
+ int thisLineNeedsResetting_mc[BLOCK_LEN_LONG];
+ int reset_count_mc;
+} BwpInfo;
+
+
typedef struct {
int window_shape;
int prev_window_shape;
@@ -145,6 +159,7 @@
TnsInfo tnsInfo;
LtpInfo ltpInfo;
+ BwpInfo bwpInfo;
int max_pred_sfb;
int pred_global_flag;
--- a/libfaac/util.c
+++ b/libfaac/util.c
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: util.c,v 1.6 2001/02/28 18:39:34 menno Exp $
+ * $Id: util.c,v 1.7 2001/05/18 13:38:19 menno Exp $
*/
#include <math.h>
@@ -55,6 +55,17 @@
{
return 8000;
}
+
+
+/* Max prediction band for backward predictionas function of fs index */
+const int MaxPredSfb[] = { 33, 33, 38, 40, 40, 40, 41, 41, 37, 37, 37, 34, 0 };
+
+int GetMaxPredSfb(int samplingRateIdx)
+{
+ return MaxPredSfb[samplingRateIdx];
+}
+
+
/* Calculate bit_allocation based on PE */
unsigned int BitAllocation(double pe, int short_block)
--- a/libfaac/util.h
+++ b/libfaac/util.h
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * $Id: util.h,v 1.5 2001/03/12 16:58:37 menno Exp $
+ * $Id: util.h,v 1.6 2001/05/18 13:38:19 menno Exp $
*/
#ifndef UTIL_H
@@ -46,6 +46,7 @@
#define SetMemory(block, value, size) memset(block, value, size)
int GetSRIndex(unsigned int sampleRate);
+int GetMaxPredSfb(int samplingRateIdx);
unsigned int MaxBitrate(unsigned long sampleRate);
unsigned int MinBitrate();
unsigned int MaxBitresSize(unsigned long bitRate, unsigned long sampleRate);
--- a/todo.txt
+++ b/todo.txt
@@ -10,6 +10,7 @@
- DONE: Add backward prediction (MPEG2-AAC)????
- DONE: Test (and maybe fix) sample rates other than 44100 Hz
- DONE: Test (and maybe fix) multichannel and mono support
+- DONE: Figure out how to read and write ".mp4" format
- Add PNS
- Add IS
- Add bit reservoir control
@@ -23,4 +24,3 @@
- Improve command line tool (wildcards)
- Write documentation for library interface
- Speedup?? (no priority)
-- Figure out how to read and write ".mp4" format
\ No newline at end of file