summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/amrwbenc/src/dtx.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/amrwbenc/src/dtx.c')
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/dtx.c964
1 files changed, 482 insertions, 482 deletions
diff --git a/media/libstagefright/codecs/amrwbenc/src/dtx.c b/media/libstagefright/codecs/amrwbenc/src/dtx.c
index 2cfaced..6be8683 100644
--- a/media/libstagefright/codecs/amrwbenc/src/dtx.c
+++ b/media/libstagefright/codecs/amrwbenc/src/dtx.c
@@ -17,7 +17,7 @@
/***********************************************************************
* File: dtx.c *
* *
-* Description:DTX functions *
+* Description:DTX functions *
* *
************************************************************************/
@@ -35,33 +35,33 @@
#include "mem_align.h"
static void aver_isf_history(
- Word16 isf_old[],
- Word16 indices[],
- Word32 isf_aver[]
- );
+ Word16 isf_old[],
+ Word16 indices[],
+ Word32 isf_aver[]
+ );
static void find_frame_indices(
- Word16 isf_old_tx[],
- Word16 indices[],
- dtx_encState * st
- );
+ Word16 isf_old_tx[],
+ Word16 indices[],
+ dtx_encState * st
+ );
static Word16 dithering_control(
- dtx_encState * st
- );
+ dtx_encState * st
+ );
/* excitation energy adjustment depending on speech coder mode used, Q7 */
static Word16 en_adjust[9] =
{
- 230, /* mode0 = 7k : -5.4dB */
- 179, /* mode1 = 9k : -4.2dB */
- 141, /* mode2 = 12k : -3.3dB */
- 128, /* mode3 = 14k : -3.0dB */
- 122, /* mode4 = 16k : -2.85dB */
- 115, /* mode5 = 18k : -2.7dB */
- 115, /* mode6 = 20k : -2.7dB */
- 115, /* mode7 = 23k : -2.7dB */
- 115 /* mode8 = 24k : -2.7dB */
+ 230, /* mode0 = 7k : -5.4dB */
+ 179, /* mode1 = 9k : -4.2dB */
+ 141, /* mode2 = 12k : -3.3dB */
+ 128, /* mode3 = 14k : -3.0dB */
+ 122, /* mode4 = 16k : -2.85dB */
+ 115, /* mode5 = 18k : -2.7dB */
+ 115, /* mode6 = 20k : -2.7dB */
+ 115, /* mode7 = 23k : -2.7dB */
+ 115 /* mode8 = 24k : -2.7dB */
};
/**************************************************************************
@@ -71,24 +71,24 @@ static Word16 en_adjust[9] =
**************************************************************************/
Word16 dtx_enc_init(dtx_encState ** st, Word16 isf_init[], VO_MEM_OPERATOR *pMemOP)
{
- dtx_encState *s;
-
- if (st == (dtx_encState **) NULL)
- {
- fprintf(stderr, "dtx_enc_init: invalid parameter\n");
- return -1;
- }
- *st = NULL;
-
- /* allocate memory */
- if ((s = (dtx_encState *)mem_malloc(pMemOP, sizeof(dtx_encState), 32, VO_INDEX_ENC_AMRWB)) == NULL)
- {
- fprintf(stderr, "dtx_enc_init: can not malloc state structure\n");
- return -1;
- }
- dtx_enc_reset(s, isf_init);
- *st = s;
- return 0;
+ dtx_encState *s;
+
+ if (st == (dtx_encState **) NULL)
+ {
+ fprintf(stderr, "dtx_enc_init: invalid parameter\n");
+ return -1;
+ }
+ *st = NULL;
+
+ /* allocate memory */
+ if ((s = (dtx_encState *)mem_malloc(pMemOP, sizeof(dtx_encState), 32, VO_INDEX_ENC_AMRWB)) == NULL)
+ {
+ fprintf(stderr, "dtx_enc_init: can not malloc state structure\n");
+ return -1;
+ }
+ dtx_enc_reset(s, isf_init);
+ *st = s;
+ return 0;
}
/**************************************************************************
@@ -98,40 +98,40 @@ Word16 dtx_enc_init(dtx_encState ** st, Word16 isf_init[], VO_MEM_OPERATOR *pMem
**************************************************************************/
Word16 dtx_enc_reset(dtx_encState * st, Word16 isf_init[])
{
- Word32 i;
-
- if (st == (dtx_encState *) NULL)
- {
- fprintf(stderr, "dtx_enc_reset: invalid parameter\n");
- return -1;
- }
- st->hist_ptr = 0;
- st->log_en_index = 0;
-
- /* Init isf_hist[] */
- for (i = 0; i < DTX_HIST_SIZE; i++)
- {
- Copy(isf_init, &st->isf_hist[i * M], M);
- }
- st->cng_seed = RANDOM_INITSEED;
-
- /* Reset energy history */
- Set_zero(st->log_en_hist, DTX_HIST_SIZE);
-
- st->dtxHangoverCount = DTX_HANG_CONST;
- st->decAnaElapsedCount = 32767;
-
- for (i = 0; i < 28; i++)
- {
- st->D[i] = 0;
- }
-
- for (i = 0; i < DTX_HIST_SIZE - 1; i++)
- {
- st->sumD[i] = 0;
- }
-
- return 1;
+ Word32 i;
+
+ if (st == (dtx_encState *) NULL)
+ {
+ fprintf(stderr, "dtx_enc_reset: invalid parameter\n");
+ return -1;
+ }
+ st->hist_ptr = 0;
+ st->log_en_index = 0;
+
+ /* Init isf_hist[] */
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ Copy(isf_init, &st->isf_hist[i * M], M);
+ }
+ st->cng_seed = RANDOM_INITSEED;
+
+ /* Reset energy history */
+ Set_zero(st->log_en_hist, DTX_HIST_SIZE);
+
+ st->dtxHangoverCount = DTX_HANG_CONST;
+ st->decAnaElapsedCount = 32767;
+
+ for (i = 0; i < 28; i++)
+ {
+ st->D[i] = 0;
+ }
+
+ for (i = 0; i < DTX_HIST_SIZE - 1; i++)
+ {
+ st->sumD[i] = 0;
+ }
+
+ return 1;
}
/**************************************************************************
@@ -141,12 +141,12 @@ Word16 dtx_enc_reset(dtx_encState * st, Word16 isf_init[])
**************************************************************************/
void dtx_enc_exit(dtx_encState ** st, VO_MEM_OPERATOR *pMemOP)
{
- if (st == NULL || *st == NULL)
- return;
- /* deallocate memory */
- mem_free(pMemOP, *st, VO_INDEX_ENC_AMRWB);
- *st = NULL;
- return;
+ if (st == NULL || *st == NULL)
+ return;
+ /* deallocate memory */
+ mem_free(pMemOP, *st, VO_INDEX_ENC_AMRWB);
+ *st = NULL;
+ return;
}
@@ -156,133 +156,133 @@ void dtx_enc_exit(dtx_encState ** st, VO_MEM_OPERATOR *pMemOP)
*
**************************************************************************/
Word16 dtx_enc(
- dtx_encState * st, /* i/o : State struct */
- Word16 isf[M], /* o : CN ISF vector */
- Word16 * exc2, /* o : CN excitation */
- Word16 ** prms
- )
+ dtx_encState * st, /* i/o : State struct */
+ Word16 isf[M], /* o : CN ISF vector */
+ Word16 * exc2, /* o : CN excitation */
+ Word16 ** prms
+ )
{
- Word32 i, j;
- Word16 indice[7];
- Word16 log_en, gain, level, exp, exp0, tmp;
- Word16 log_en_int_e, log_en_int_m;
- Word32 L_isf[M], ener32, level32;
- Word16 isf_order[3];
- Word16 CN_dith;
-
- /* VOX mode computation of SID parameters */
- log_en = 0;
- for (i = 0; i < M; i++)
- {
- L_isf[i] = 0;
- }
- /* average energy and isf */
- for (i = 0; i < DTX_HIST_SIZE; i++)
- {
- /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer. log_en is in Q10 */
- log_en = add(log_en, st->log_en_hist[i]);
-
- }
- find_frame_indices(st->isf_hist, isf_order, st);
- aver_isf_history(st->isf_hist, isf_order, L_isf);
-
- for (j = 0; j < M; j++)
- {
- isf[j] = (Word16)(L_isf[j] >> 3); /* divide by 8 */
- }
-
- /* quantize logarithmic energy to 6 bits (-6 : 66 dB) which corresponds to -2:22 in log2(E). */
- /* st->log_en_index = (short)( (log_en + 2.0) * 2.625 ); */
-
- /* increase dynamics to 7 bits (Q8) */
- log_en = (log_en >> 2);
-
- /* Add 2 in Q8 = 512 to get log2(E) between 0:24 */
- log_en = add(log_en, 512);
-
- /* Multiply by 2.625 to get full 6 bit range. 2.625 = 21504 in Q13. The result is in Q6 */
- log_en = mult(log_en, 21504);
-
- /* Quantize Energy */
- st->log_en_index = shr(log_en, 6);
-
- if(st->log_en_index > 63)
- {
- st->log_en_index = 63;
- }
- if (st->log_en_index < 0)
- {
- st->log_en_index = 0;
- }
- /* Quantize ISFs */
- Qisf_ns(isf, isf, indice);
-
-
- Parm_serial(indice[0], 6, prms);
- Parm_serial(indice[1], 6, prms);
- Parm_serial(indice[2], 6, prms);
- Parm_serial(indice[3], 5, prms);
- Parm_serial(indice[4], 5, prms);
-
- Parm_serial((st->log_en_index), 6, prms);
-
- CN_dith = dithering_control(st);
- Parm_serial(CN_dith, 1, prms);
-
- /* level = (float)( pow( 2.0f, (float)st->log_en_index / 2.625 - 2.0 ) ); */
- /* log2(E) in Q9 (log2(E) lies in between -2:22) */
- log_en = shl(st->log_en_index, 15 - 6);
-
- /* Divide by 2.625; log_en will be between 0:24 */
- log_en = mult(log_en, 12483);
- /* the result corresponds to log2(gain) in Q10 */
-
- /* Find integer part */
- log_en_int_e = (log_en >> 10);
-
- /* Find fractional part */
- log_en_int_m = (Word16) (log_en & 0x3ff);
- log_en_int_m = shl(log_en_int_m, 5);
-
- /* Subtract 2 from log_en in Q9, i.e divide the gain by 2 (energy by 4) */
- /* Add 16 in order to have the result of pow2 in Q16 */
- log_en_int_e = add(log_en_int_e, 16 - 1);
-
- level32 = Pow2(log_en_int_e, log_en_int_m); /* Q16 */
- exp0 = norm_l(level32);
- level32 = (level32 << exp0); /* level in Q31 */
- exp0 = (15 - exp0);
- level = extract_h(level32); /* level in Q15 */
-
- /* generate white noise vector */
- for (i = 0; i < L_FRAME; i++)
- {
- exc2[i] = (Random(&(st->cng_seed)) >> 4);
- }
-
- /* gain = level / sqrt(ener) * sqrt(L_FRAME) */
-
- /* energy of generated excitation */
- ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp);
+ Word32 i, j;
+ Word16 indice[7];
+ Word16 log_en, gain, level, exp, exp0, tmp;
+ Word16 log_en_int_e, log_en_int_m;
+ Word32 L_isf[M], ener32, level32;
+ Word16 isf_order[3];
+ Word16 CN_dith;
+
+ /* VOX mode computation of SID parameters */
+ log_en = 0;
+ for (i = 0; i < M; i++)
+ {
+ L_isf[i] = 0;
+ }
+ /* average energy and isf */
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ /* Division by DTX_HIST_SIZE = 8 has been done in dtx_buffer. log_en is in Q10 */
+ log_en = add(log_en, st->log_en_hist[i]);
+
+ }
+ find_frame_indices(st->isf_hist, isf_order, st);
+ aver_isf_history(st->isf_hist, isf_order, L_isf);
+
+ for (j = 0; j < M; j++)
+ {
+ isf[j] = (Word16)(L_isf[j] >> 3); /* divide by 8 */
+ }
+
+ /* quantize logarithmic energy to 6 bits (-6 : 66 dB) which corresponds to -2:22 in log2(E). */
+ /* st->log_en_index = (short)( (log_en + 2.0) * 2.625 ); */
+
+ /* increase dynamics to 7 bits (Q8) */
+ log_en = (log_en >> 2);
+
+ /* Add 2 in Q8 = 512 to get log2(E) between 0:24 */
+ log_en = add(log_en, 512);
+
+ /* Multiply by 2.625 to get full 6 bit range. 2.625 = 21504 in Q13. The result is in Q6 */
+ log_en = mult(log_en, 21504);
+
+ /* Quantize Energy */
+ st->log_en_index = shr(log_en, 6);
+
+ if(st->log_en_index > 63)
+ {
+ st->log_en_index = 63;
+ }
+ if (st->log_en_index < 0)
+ {
+ st->log_en_index = 0;
+ }
+ /* Quantize ISFs */
+ Qisf_ns(isf, isf, indice);
+
+
+ Parm_serial(indice[0], 6, prms);
+ Parm_serial(indice[1], 6, prms);
+ Parm_serial(indice[2], 6, prms);
+ Parm_serial(indice[3], 5, prms);
+ Parm_serial(indice[4], 5, prms);
+
+ Parm_serial((st->log_en_index), 6, prms);
+
+ CN_dith = dithering_control(st);
+ Parm_serial(CN_dith, 1, prms);
+
+ /* level = (float)( pow( 2.0f, (float)st->log_en_index / 2.625 - 2.0 ) ); */
+ /* log2(E) in Q9 (log2(E) lies in between -2:22) */
+ log_en = shl(st->log_en_index, 15 - 6);
+
+ /* Divide by 2.625; log_en will be between 0:24 */
+ log_en = mult(log_en, 12483);
+ /* the result corresponds to log2(gain) in Q10 */
+
+ /* Find integer part */
+ log_en_int_e = (log_en >> 10);
+
+ /* Find fractional part */
+ log_en_int_m = (Word16) (log_en & 0x3ff);
+ log_en_int_m = shl(log_en_int_m, 5);
+
+ /* Subtract 2 from log_en in Q9, i.e divide the gain by 2 (energy by 4) */
+ /* Add 16 in order to have the result of pow2 in Q16 */
+ log_en_int_e = add(log_en_int_e, 16 - 1);
+
+ level32 = Pow2(log_en_int_e, log_en_int_m); /* Q16 */
+ exp0 = norm_l(level32);
+ level32 = (level32 << exp0); /* level in Q31 */
+ exp0 = (15 - exp0);
+ level = extract_h(level32); /* level in Q15 */
+
+ /* generate white noise vector */
+ for (i = 0; i < L_FRAME; i++)
+ {
+ exc2[i] = (Random(&(st->cng_seed)) >> 4);
+ }
+
+ /* gain = level / sqrt(ener) * sqrt(L_FRAME) */
+
+ /* energy of generated excitation */
+ ener32 = Dot_product12(exc2, exc2, L_FRAME, &exp);
- Isqrt_n(&ener32, &exp);
+ Isqrt_n(&ener32, &exp);
- gain = extract_h(ener32);
+ gain = extract_h(ener32);
- gain = mult(level, gain); /* gain in Q15 */
+ gain = mult(level, gain); /* gain in Q15 */
- exp = add(exp0, exp);
+ exp = add(exp0, exp);
- /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */
- exp += 4;
+ /* Multiply by sqrt(L_FRAME)=16, i.e. shift left by 4 */
+ exp += 4;
- for (i = 0; i < L_FRAME; i++)
- {
- tmp = mult(exc2[i], gain); /* Q0 * Q15 */
- exc2[i] = shl(tmp, exp);
- }
+ for (i = 0; i < L_FRAME; i++)
+ {
+ tmp = mult(exc2[i], gain); /* Q0 * Q15 */
+ exc2[i] = shl(tmp, exp);
+ }
- return 0;
+ return 0;
}
/**************************************************************************
@@ -291,45 +291,45 @@ Word16 dtx_enc(
*
**************************************************************************/
Word16 dtx_buffer(
- dtx_encState * st, /* i/o : State struct */
- Word16 isf_new[], /* i : isf vector */
- Word32 enr, /* i : residual energy (in L_FRAME) */
- Word16 codec_mode
- )
+ dtx_encState * st, /* i/o : State struct */
+ Word16 isf_new[], /* i : isf vector */
+ Word32 enr, /* i : residual energy (in L_FRAME) */
+ Word16 codec_mode
+ )
{
- Word16 log_en;
-
- Word16 log_en_e;
- Word16 log_en_m;
- st->hist_ptr = add(st->hist_ptr, 1);
- if(st->hist_ptr == DTX_HIST_SIZE)
- {
- st->hist_ptr = 0;
- }
- /* copy lsp vector into buffer */
- Copy(isf_new, &st->isf_hist[st->hist_ptr * M], M);
-
- /* log_en = (float)log10(enr*0.0059322)/(float)log10(2.0f); */
- Log2(enr, &log_en_e, &log_en_m);
-
- /* convert exponent and mantissa to Word16 Q7. Q7 is used to simplify averaging in dtx_enc */
- log_en = shl(log_en_e, 7); /* Q7 */
- log_en = add(log_en, shr(log_en_m, 15 - 7));
-
- /* Find energy per sample by multiplying with 0.0059322, i.e subtract log2(1/0.0059322) = 7.39722 The
- * constant 0.0059322 takes into account windowings and analysis length from autocorrelation
- * computations; 7.39722 in Q7 = 947 */
- /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */
- /* log_en = sub( log_en, 947 + en_adjust[codec_mode] ); */
-
- /* Find energy per sample (divide by L_FRAME=256), i.e subtract log2(256) = 8.0 (1024 in Q7) */
- /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */
-
- log_en = sub(log_en, add(1024, en_adjust[codec_mode]));
-
- /* Insert into the buffer */
- st->log_en_hist[st->hist_ptr] = log_en;
- return 0;
+ Word16 log_en;
+
+ Word16 log_en_e;
+ Word16 log_en_m;
+ st->hist_ptr = add(st->hist_ptr, 1);
+ if(st->hist_ptr == DTX_HIST_SIZE)
+ {
+ st->hist_ptr = 0;
+ }
+ /* copy lsp vector into buffer */
+ Copy(isf_new, &st->isf_hist[st->hist_ptr * M], M);
+
+ /* log_en = (float)log10(enr*0.0059322)/(float)log10(2.0f); */
+ Log2(enr, &log_en_e, &log_en_m);
+
+ /* convert exponent and mantissa to Word16 Q7. Q7 is used to simplify averaging in dtx_enc */
+ log_en = shl(log_en_e, 7); /* Q7 */
+ log_en = add(log_en, shr(log_en_m, 15 - 7));
+
+ /* Find energy per sample by multiplying with 0.0059322, i.e subtract log2(1/0.0059322) = 7.39722 The
+ * constant 0.0059322 takes into account windowings and analysis length from autocorrelation
+ * computations; 7.39722 in Q7 = 947 */
+ /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */
+ /* log_en = sub( log_en, 947 + en_adjust[codec_mode] ); */
+
+ /* Find energy per sample (divide by L_FRAME=256), i.e subtract log2(256) = 8.0 (1024 in Q7) */
+ /* Subtract 3 dB = 0.99658 in log2(E) = 127 in Q7. */
+
+ log_en = sub(log_en, add(1024, en_adjust[codec_mode]));
+
+ /* Insert into the buffer */
+ st->log_en_hist[st->hist_ptr] = log_en;
+ return 0;
}
/**************************************************************************
@@ -339,267 +339,267 @@ Word16 dtx_buffer(
* the decoding side.
**************************************************************************/
void tx_dtx_handler(dtx_encState * st, /* i/o : State struct */
- Word16 vad_flag, /* i : vad decision */
- Word16 * usedMode /* i/o : mode changed or not */
- )
+ Word16 vad_flag, /* i : vad decision */
+ Word16 * usedMode /* i/o : mode changed or not */
+ )
{
- /* this state machine is in synch with the GSMEFR txDtx machine */
- st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
-
- if (vad_flag != 0)
- {
- st->dtxHangoverCount = DTX_HANG_CONST;
- } else
- { /* non-speech */
- if (st->dtxHangoverCount == 0)
- { /* out of decoder analysis hangover */
- st->decAnaElapsedCount = 0;
- *usedMode = MRDTX;
- } else
- { /* in possible analysis hangover */
- st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);
-
- /* decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH */
- if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount),
- DTX_ELAPSED_FRAMES_THRESH) < 0)
- {
- *usedMode = MRDTX;
- /* if short time since decoder update, do not add extra HO */
- }
- /* else override VAD and stay in speech mode *usedMode and add extra hangover */
- }
- }
-
- return;
+ /* this state machine is in synch with the GSMEFR txDtx machine */
+ st->decAnaElapsedCount = add(st->decAnaElapsedCount, 1);
+
+ if (vad_flag != 0)
+ {
+ st->dtxHangoverCount = DTX_HANG_CONST;
+ } else
+ { /* non-speech */
+ if (st->dtxHangoverCount == 0)
+ { /* out of decoder analysis hangover */
+ st->decAnaElapsedCount = 0;
+ *usedMode = MRDTX;
+ } else
+ { /* in possible analysis hangover */
+ st->dtxHangoverCount = sub(st->dtxHangoverCount, 1);
+
+ /* decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH */
+ if (sub(add(st->decAnaElapsedCount, st->dtxHangoverCount),
+ DTX_ELAPSED_FRAMES_THRESH) < 0)
+ {
+ *usedMode = MRDTX;
+ /* if short time since decoder update, do not add extra HO */
+ }
+ /* else override VAD and stay in speech mode *usedMode and add extra hangover */
+ }
+ }
+
+ return;
}
static void aver_isf_history(
- Word16 isf_old[],
- Word16 indices[],
- Word32 isf_aver[]
- )
+ Word16 isf_old[],
+ Word16 indices[],
+ Word32 isf_aver[]
+ )
{
- Word32 i, j, k;
- Word16 isf_tmp[2 * M];
- Word32 L_tmp;
-
- /* Memorize in isf_tmp[][] the ISF vectors to be replaced by */
- /* the median ISF vector prior to the averaging */
- for (k = 0; k < 2; k++)
- {
- if ((indices[k] + 1) != 0)
- {
- for (i = 0; i < M; i++)
- {
- isf_tmp[k * M + i] = isf_old[indices[k] * M + i];
- isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i];
- }
- }
- }
-
- /* Perform the ISF averaging */
- for (j = 0; j < M; j++)
- {
- L_tmp = 0;
-
- for (i = 0; i < DTX_HIST_SIZE; i++)
- {
- L_tmp = L_add(L_tmp, L_deposit_l(isf_old[i * M + j]));
- }
- isf_aver[j] = L_tmp;
- }
-
- /* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */
- for (k = 0; k < 2; k++)
- {
- if ((indices[k] + 1) != 0)
- {
- for (i = 0; i < M; i++)
- {
- isf_old[indices[k] * M + i] = isf_tmp[k * M + i];
- }
- }
- }
-
- return;
+ Word32 i, j, k;
+ Word16 isf_tmp[2 * M];
+ Word32 L_tmp;
+
+ /* Memorize in isf_tmp[][] the ISF vectors to be replaced by */
+ /* the median ISF vector prior to the averaging */
+ for (k = 0; k < 2; k++)
+ {
+ if ((indices[k] + 1) != 0)
+ {
+ for (i = 0; i < M; i++)
+ {
+ isf_tmp[k * M + i] = isf_old[indices[k] * M + i];
+ isf_old[indices[k] * M + i] = isf_old[indices[2] * M + i];
+ }
+ }
+ }
+
+ /* Perform the ISF averaging */
+ for (j = 0; j < M; j++)
+ {
+ L_tmp = 0;
+
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ L_tmp = L_add(L_tmp, L_deposit_l(isf_old[i * M + j]));
+ }
+ isf_aver[j] = L_tmp;
+ }
+
+ /* Retrieve from isf_tmp[][] the ISF vectors saved prior to averaging */
+ for (k = 0; k < 2; k++)
+ {
+ if ((indices[k] + 1) != 0)
+ {
+ for (i = 0; i < M; i++)
+ {
+ isf_old[indices[k] * M + i] = isf_tmp[k * M + i];
+ }
+ }
+ }
+
+ return;
}
static void find_frame_indices(
- Word16 isf_old_tx[],
- Word16 indices[],
- dtx_encState * st
- )
+ Word16 isf_old_tx[],
+ Word16 indices[],
+ dtx_encState * st
+ )
{
- Word32 L_tmp, summin, summax, summax2nd;
- Word16 i, j, tmp;
- Word16 ptr;
-
- /* Remove the effect of the oldest frame from the column */
- /* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is */
- /* not updated since it will be removed later. */
-
- tmp = DTX_HIST_SIZE_MIN_ONE;
- j = -1;
- for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++)
- {
- j = add(j, tmp);
- st->sumD[i] = L_sub(st->sumD[i], st->D[j]);
- tmp = sub(tmp, 1);
- }
-
- /* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1] */
- /* corresponding to the oldest frame is removed. The sum of */
- /* the distances between the latest isf and other isfs, */
- /* i.e. the element sumD[0], will be computed during this call. */
- /* Hence this element is initialized to zero. */
-
- for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--)
- {
- st->sumD[i] = st->sumD[i - 1];
- }
- st->sumD[0] = 0;
-
- /* Remove the oldest frame from the distance matrix. */
- /* Note that the distance matrix is replaced by a one- */
- /* dimensional array to save static memory. */
-
- tmp = 0;
- for (i = 27; i >= 12; i = (Word16) (i - tmp))
- {
- tmp = add(tmp, 1);
- for (j = tmp; j > 0; j--)
- {
- st->D[i - j + 1] = st->D[i - j - tmp];
- }
- }
-
- /* Compute the first column of the distance matrix D */
- /* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */
-
- ptr = st->hist_ptr;
- for (i = 1; i < DTX_HIST_SIZE; i++)
- {
- /* Compute the distance between the latest isf and the other isfs. */
- ptr = sub(ptr, 1);
- if (ptr < 0)
- {
- ptr = DTX_HIST_SIZE_MIN_ONE;
- }
- L_tmp = 0;
- for (j = 0; j < M; j++)
- {
- tmp = sub(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]);
- L_tmp = L_mac(L_tmp, tmp, tmp);
- }
- st->D[i - 1] = L_tmp;
-
- /* Update also the column sums. */
- st->sumD[0] = L_add(st->sumD[0], st->D[i - 1]);
- st->sumD[i] = L_add(st->sumD[i], st->D[i - 1]);
- }
-
- /* Find the minimum and maximum distances */
- summax = st->sumD[0];
- summin = st->sumD[0];
- indices[0] = 0;
- indices[2] = 0;
- for (i = 1; i < DTX_HIST_SIZE; i++)
- {
- if (L_sub(st->sumD[i], summax) > 0)
- {
- indices[0] = i;
- summax = st->sumD[i];
- }
- if (L_sub(st->sumD[i], summin) < 0)
- {
- indices[2] = i;
- summin = st->sumD[i];
- }
- }
-
- /* Find the second largest distance */
- summax2nd = -2147483647L;
- indices[1] = -1;
- for (i = 0; i < DTX_HIST_SIZE; i++)
- {
- if ((L_sub(st->sumD[i], summax2nd) > 0) && (sub(i, indices[0]) != 0))
- {
- indices[1] = i;
- summax2nd = st->sumD[i];
- }
- }
-
- for (i = 0; i < 3; i++)
- {
- indices[i] = sub(st->hist_ptr, indices[i]);
- if (indices[i] < 0)
- {
- indices[i] = add(indices[i], DTX_HIST_SIZE);
- }
- }
-
- /* If maximum distance/MED_THRESH is smaller than minimum distance */
- /* then the median ISF vector replacement is not performed */
- tmp = norm_l(summax);
- summax = (summax << tmp);
- summin = (summin << tmp);
- L_tmp = L_mult(voround(summax), INV_MED_THRESH);
- if(L_tmp <= summin)
- {
- indices[0] = -1;
- }
- /* If second largest distance/MED_THRESH is smaller than */
- /* minimum distance then the median ISF vector replacement is */
- /* not performed */
- summax2nd = L_shl(summax2nd, tmp);
- L_tmp = L_mult(voround(summax2nd), INV_MED_THRESH);
- if(L_tmp <= summin)
- {
- indices[1] = -1;
- }
- return;
+ Word32 L_tmp, summin, summax, summax2nd;
+ Word16 i, j, tmp;
+ Word16 ptr;
+
+ /* Remove the effect of the oldest frame from the column */
+ /* sum sumD[0..DTX_HIST_SIZE-1]. sumD[DTX_HIST_SIZE] is */
+ /* not updated since it will be removed later. */
+
+ tmp = DTX_HIST_SIZE_MIN_ONE;
+ j = -1;
+ for (i = 0; i < DTX_HIST_SIZE_MIN_ONE; i++)
+ {
+ j = add(j, tmp);
+ st->sumD[i] = L_sub(st->sumD[i], st->D[j]);
+ tmp = sub(tmp, 1);
+ }
+
+ /* Shift the column sum sumD. The element sumD[DTX_HIST_SIZE-1] */
+ /* corresponding to the oldest frame is removed. The sum of */
+ /* the distances between the latest isf and other isfs, */
+ /* i.e. the element sumD[0], will be computed during this call. */
+ /* Hence this element is initialized to zero. */
+
+ for (i = DTX_HIST_SIZE_MIN_ONE; i > 0; i--)
+ {
+ st->sumD[i] = st->sumD[i - 1];
+ }
+ st->sumD[0] = 0;
+
+ /* Remove the oldest frame from the distance matrix. */
+ /* Note that the distance matrix is replaced by a one- */
+ /* dimensional array to save static memory. */
+
+ tmp = 0;
+ for (i = 27; i >= 12; i = (Word16) (i - tmp))
+ {
+ tmp = add(tmp, 1);
+ for (j = tmp; j > 0; j--)
+ {
+ st->D[i - j + 1] = st->D[i - j - tmp];
+ }
+ }
+
+ /* Compute the first column of the distance matrix D */
+ /* (squared Euclidean distances from isf1[] to isf_old_tx[][]). */
+
+ ptr = st->hist_ptr;
+ for (i = 1; i < DTX_HIST_SIZE; i++)
+ {
+ /* Compute the distance between the latest isf and the other isfs. */
+ ptr = sub(ptr, 1);
+ if (ptr < 0)
+ {
+ ptr = DTX_HIST_SIZE_MIN_ONE;
+ }
+ L_tmp = 0;
+ for (j = 0; j < M; j++)
+ {
+ tmp = sub(isf_old_tx[st->hist_ptr * M + j], isf_old_tx[ptr * M + j]);
+ L_tmp = L_mac(L_tmp, tmp, tmp);
+ }
+ st->D[i - 1] = L_tmp;
+
+ /* Update also the column sums. */
+ st->sumD[0] = L_add(st->sumD[0], st->D[i - 1]);
+ st->sumD[i] = L_add(st->sumD[i], st->D[i - 1]);
+ }
+
+ /* Find the minimum and maximum distances */
+ summax = st->sumD[0];
+ summin = st->sumD[0];
+ indices[0] = 0;
+ indices[2] = 0;
+ for (i = 1; i < DTX_HIST_SIZE; i++)
+ {
+ if (L_sub(st->sumD[i], summax) > 0)
+ {
+ indices[0] = i;
+ summax = st->sumD[i];
+ }
+ if (L_sub(st->sumD[i], summin) < 0)
+ {
+ indices[2] = i;
+ summin = st->sumD[i];
+ }
+ }
+
+ /* Find the second largest distance */
+ summax2nd = -2147483647L;
+ indices[1] = -1;
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ if ((L_sub(st->sumD[i], summax2nd) > 0) && (sub(i, indices[0]) != 0))
+ {
+ indices[1] = i;
+ summax2nd = st->sumD[i];
+ }
+ }
+
+ for (i = 0; i < 3; i++)
+ {
+ indices[i] = sub(st->hist_ptr, indices[i]);
+ if (indices[i] < 0)
+ {
+ indices[i] = add(indices[i], DTX_HIST_SIZE);
+ }
+ }
+
+ /* If maximum distance/MED_THRESH is smaller than minimum distance */
+ /* then the median ISF vector replacement is not performed */
+ tmp = norm_l(summax);
+ summax = (summax << tmp);
+ summin = (summin << tmp);
+ L_tmp = L_mult(voround(summax), INV_MED_THRESH);
+ if(L_tmp <= summin)
+ {
+ indices[0] = -1;
+ }
+ /* If second largest distance/MED_THRESH is smaller than */
+ /* minimum distance then the median ISF vector replacement is */
+ /* not performed */
+ summax2nd = L_shl(summax2nd, tmp);
+ L_tmp = L_mult(voround(summax2nd), INV_MED_THRESH);
+ if(L_tmp <= summin)
+ {
+ indices[1] = -1;
+ }
+ return;
}
static Word16 dithering_control(
- dtx_encState * st
- )
+ dtx_encState * st
+ )
{
- Word16 tmp, mean, CN_dith, gain_diff;
- Word32 i, ISF_diff;
-
- /* determine how stationary the spectrum of background noise is */
- ISF_diff = 0;
- for (i = 0; i < 8; i++)
- {
- ISF_diff = L_add(ISF_diff, st->sumD[i]);
- }
- if ((ISF_diff >> 26) > 0)
- {
- CN_dith = 1;
- } else
- {
- CN_dith = 0;
- }
-
- /* determine how stationary the energy of background noise is */
- mean = 0;
- for (i = 0; i < DTX_HIST_SIZE; i++)
- {
- mean = add(mean, st->log_en_hist[i]);
- }
- mean = (mean >> 3);
- gain_diff = 0;
- for (i = 0; i < DTX_HIST_SIZE; i++)
- {
- tmp = abs_s(sub(st->log_en_hist[i], mean));
- gain_diff = add(gain_diff, tmp);
- }
- if (gain_diff > GAIN_THR)
- {
- CN_dith = 1;
- }
- return CN_dith;
+ Word16 tmp, mean, CN_dith, gain_diff;
+ Word32 i, ISF_diff;
+
+ /* determine how stationary the spectrum of background noise is */
+ ISF_diff = 0;
+ for (i = 0; i < 8; i++)
+ {
+ ISF_diff = L_add(ISF_diff, st->sumD[i]);
+ }
+ if ((ISF_diff >> 26) > 0)
+ {
+ CN_dith = 1;
+ } else
+ {
+ CN_dith = 0;
+ }
+
+ /* determine how stationary the energy of background noise is */
+ mean = 0;
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ mean = add(mean, st->log_en_hist[i]);
+ }
+ mean = (mean >> 3);
+ gain_diff = 0;
+ for (i = 0; i < DTX_HIST_SIZE; i++)
+ {
+ tmp = abs_s(sub(st->log_en_hist[i], mean));
+ gain_diff = add(gain_diff, tmp);
+ }
+ if (gain_diff > GAIN_THR)
+ {
+ CN_dith = 1;
+ }
+ return CN_dith;
}