123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- /*
- ********************************************************************************
- *
- * GSM AMR-NB speech codec R98 Version 7.6.0 December 12, 2001
- * R99 Version 3.3.0
- * REL-4 Version 4.1.0
- *
- ********************************************************************************
- *
- * File : dtx_enc.c
- * Purpose : DTX mode computation of SID parameters
- *
- ********************************************************************************
- */
- /*
- ********************************************************************************
- * MODULE INCLUDE FILE AND VERSION ID
- ********************************************************************************
- */
- #include "dtx_enc.h"
- const char dtx_enc_id[] = "@(#)$Id $" dtx_enc_h;
-
- /*
- ********************************************************************************
- * INCLUDE FILES
- ********************************************************************************
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include "q_plsf.h"
- #include "typedef.h"
- #include "basic_op.h"
- #include "oper_32b.h"
- #include "copy.h"
- #include "set_zero.h"
- #include "mode.h"
- #include "log2.h"
- #include "lsp_lsf.h"
- #include "reorder.h"
- #include "count.h"
- /*
- ********************************************************************************
- * LOCAL VARIABLES AND TABLES
- ********************************************************************************
- */
- #include "lsp.tab"
- /*
- ********************************************************************************
- * PUBLIC PROGRAM CODE
- ********************************************************************************
- */
- /*
- **************************************************************************
- *
- * Function : dtx_enc_init
- *
- **************************************************************************
- */
- int dtx_enc_init (dtx_encState **st)
- {
- dtx_encState* s;
-
- if (st == (dtx_encState **) NULL){
- wfprintf(stderr, "dtx_enc_init: invalid parameter\n");
- return -1;
- }
-
- *st = NULL;
-
- /* allocate memory */
- if ((s= (dtx_encState *) wmalloc(sizeof(dtx_encState))) == NULL){
- wfprintf(stderr, "dtx_enc_init: can not malloc state structure\n");
- return -1;
- }
-
- dtx_enc_reset(s);
- *st = s;
-
- return 0;
- }
-
- /*
- **************************************************************************
- *
- * Function : dtx_enc_reset
- *
- **************************************************************************
- */
- int dtx_enc_reset (dtx_encState *st)
- {
- Word16 i;
- if (st == (dtx_encState *) NULL){
- wfprintf(stderr, "dtx_enc_reset: invalid parameter\n");
- return -1;
- }
- st->hist_ptr = 0;
- st->log_en_index = 0;
- st->init_lsf_vq_index = 0;
- st->lsp_index[0] = 0;
- st->lsp_index[1] = 0;
- st->lsp_index[2] = 0;
-
- /* Init lsp_hist[] */
- for(i = 0; i < DTX_HIST_SIZE; i++)
- {
- Copy(lsp_init_data, &st->lsp_hist[i * M], M);
- }
- /* Reset energy history */
- Set_zero(st->log_en_hist, M);
- st->dtxHangoverCount = DTX_HANG_CONST;
- st->decAnaElapsedCount = 32767;
- return 1;
- }
-
- /*
- **************************************************************************
- *
- * Function : dtx_enc_exit
- *
- **************************************************************************
- */
- void dtx_enc_exit (dtx_encState **st)
- {
- if (st == NULL || *st == NULL)
- return;
-
- /* deallocate memory */
- wfree(*st);
- *st = NULL;
-
- return;
- }
-
- /*
- **************************************************************************
- *
- * Function : dtx_enc
- *
- **************************************************************************
- */
- int dtx_enc(dtx_encState *st, /* i/o : State struct */
- Word16 computeSidFlag, /* i : compute SID */
- Q_plsfState *qSt, /* i/o : Qunatizer state struct */
- gc_predState* predState, /* i/o : State struct */
- Word16 **anap /* o : analysis parameters */
- )
- {
- Word16 i,j;
- Word16 log_en;
- Word16 lsf[M];
- Word16 lsp[M];
- Word16 lsp_q[M];
- Word32 L_lsp[M];
- /* VOX mode computation of SID parameters */
- test (); test ();
- if ((computeSidFlag != 0))
- {
- /* compute new SID frame if safe i.e don't
- * compute immediately after a talk spurt */
- log_en = 0; move16 ();
- for (i = 0; i < M; i++)
- {
- L_lsp[i] = 0; move16 ();
- }
-
- /* average energy and lsp */
- for (i = 0; i < DTX_HIST_SIZE; i++)
- {
- log_en = add_ex(log_en,
- shr_ex(st->log_en_hist[i],2));
- for (j = 0; j < M; j++)
- {
- L_lsp[j] = L_add_ex(L_lsp[j],
- L_deposit_l_ex(st->lsp_hist[i * M + j]));
- }
- }
- log_en = shr_ex(log_en, 1);
- for (j = 0; j < M; j++)
- {
- lsp[j] = extract_l_ex(L_shr_ex(L_lsp[j], 3)); /* divide by 8 */
- }
- /* quantize logarithmic energy to 6 bits */
- st->log_en_index = add_ex(log_en, 2560); /* +2.5 in Q10 */
- st->log_en_index = add_ex(st->log_en_index, 128); /* add 0.5/4 in Q10 */
- st->log_en_index = shr_ex(st->log_en_index, 8);
- test ();
- if (sub_ex(st->log_en_index, 63) > 0)
- {
- st->log_en_index = 63; move16 ();
- }
- test ();
- if (st->log_en_index < 0)
- {
- st->log_en_index = 0; move16 ();
- }
-
- /* update gain predictor memory */
- log_en = shl_ex(st->log_en_index, -2+10); /* Q11 and divide by 4 */
- log_en = sub_ex(log_en, 2560); /* add 2.5 in Q11 */
-
- log_en = sub_ex(log_en, 9000);
- test ();
- if (log_en > 0)
- {
- log_en = 0; move16 ();
- }
- test ();
- if (sub_ex(log_en, -14436) < 0)
- {
- log_en = -14436; move16 ();
- }
-
- /* past_qua_en for other modes than MR122 */
- predState->past_qua_en[0] = log_en; move16 ();
- predState->past_qua_en[1] = log_en; move16 ();
- predState->past_qua_en[2] = log_en; move16 ();
- predState->past_qua_en[3] = log_en; move16 ();
- /* scale down by factor 20*log10(2) in Q15 */
- log_en = mult_ex(5443, log_en);
-
- /* past_qua_en for mode MR122 */
- predState->past_qua_en_MR122[0] = log_en; move16 ();
- predState->past_qua_en_MR122[1] = log_en; move16 ();
- predState->past_qua_en_MR122[2] = log_en; move16 ();
- predState->past_qua_en_MR122[3] = log_en; move16 ();
-
- /* make sure that LSP's are ordered */
- Lsp_lsf(lsp, lsf, M);
- Reorder_lsf(lsf, LSF_GAP, M);
- Lsf_lsp(lsf, lsp, M);
-
- /* Quantize lsp and put on parameter list */
- Q_plsf_3(qSt, MRDTX, lsp, lsp_q, st->lsp_index,
- &st->init_lsf_vq_index);
- }
-
- *(*anap)++ = st->init_lsf_vq_index; /* 3 bits */ move16 ();
-
- *(*anap)++ = st->lsp_index[0]; /* 8 bits */ move16 ();
- *(*anap)++ = st->lsp_index[1]; /* 9 bits */ move16 ();
- *(*anap)++ = st->lsp_index[2]; /* 9 bits */ move16 ();
-
-
- *(*anap)++ = st->log_en_index; /* 6 bits */ move16 ();
- /* = 35 bits */
-
- return 0;
- }
- /*
- **************************************************************************
- *
- * Function : dtx_buffer
- * Purpose : handles the DTX buffer
- *
- **************************************************************************
- */
- int dtx_buffer(dtx_encState *st, /* i/o : State struct */
- Word16 lsp_new[], /* i : LSP vector */
- Word16 speech[] /* i : speech samples */
- )
- {
- Word16 i;
- Word32 L_frame_en;
- Word16 log_en_e;
- Word16 log_en_m;
- Word16 log_en;
-
- /* update pointer to circular buffer */
- st->hist_ptr = add_ex(st->hist_ptr, 1);
- test ();
- if (sub_ex(st->hist_ptr, DTX_HIST_SIZE) == 0)
- {
- st->hist_ptr = 0; move16 ();
- }
-
- /* copy lsp vector into buffer */
- Copy(lsp_new, &st->lsp_hist[st->hist_ptr * M], M);
-
- /* compute log energy based on frame energy */
- L_frame_en = 0; /* Q0 */ move32 ();
- for (i=0; i < L_FRAME; i++)
- {
- L_frame_en = L_mac_ex(L_frame_en, speech[i], speech[i]);
- }
- Log2(L_frame_en, &log_en_e, &log_en_m);
-
- /* convert exponent and mantissa to Word16 Q10 */
- log_en = shl_ex(log_en_e, 10); /* Q10 */
- log_en = add_ex(log_en, shr_ex(log_en_m, 15-10));
-
- /* divide with L_FRAME i.e subtract with log2(L_FRAME) = 7.32193 */
- log_en = sub_ex(log_en, 8521);
-
- /* insert into log energy buffer with division by 2 */
- log_en = shr_ex(log_en, 1);
- st->log_en_hist[st->hist_ptr] = log_en; /* Q10 */ move16 ();
- return 0;
- }
- /*
- **************************************************************************
- *
- * Function : tx_dtx_handler
- * Purpose : adds extra speech hangover to analyze speech on the decoding side.
- *
- **************************************************************************
- */
- Word16 tx_dtx_handler(dtx_encState *st, /* i/o : State struct */
- Word16 vad_flag, /* i : vad decision */
- enum Mode *usedMode /* i/o : mode changed or not */
- )
- {
- Word16 compute_new_sid_possible;
-
- /* this state machine is in synch with the GSMEFR txDtx machine */
- st->decAnaElapsedCount = add_ex(st->decAnaElapsedCount, 1);
-
- compute_new_sid_possible = 0; move16();
- test();
- if (vad_flag != 0)
- {
- st->dtxHangoverCount = DTX_HANG_CONST; move16();
- }
- else
- { /* non-speech */
- test();
- if (st->dtxHangoverCount == 0)
- { /* out of decoder analysis hangover */
- st->decAnaElapsedCount = 0; move16();
- *usedMode = MRDTX; move16();
- compute_new_sid_possible = 1; move16();
- }
- else
- { /* in possible analysis hangover */
- st->dtxHangoverCount = sub_ex(st->dtxHangoverCount, 1);
-
- /* decAnaElapsedCount + dtxHangoverCount < DTX_ELAPSED_FRAMES_THRESH */
- test ();
- if (sub_ex(add_ex(st->decAnaElapsedCount, st->dtxHangoverCount),
- DTX_ELAPSED_FRAMES_THRESH) < 0)
- {
- *usedMode = MRDTX; move16();
- /* 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 compute_new_sid_possible;
- }
|