📄 agc.cpp
字号:
s = L_shl (s, 7); // s = gain_out / gain_in s = L_shr (s, exp); // add exponent s = Inv_sqrt (s); // function result i = pv_round (L_shl (s, 9)); // g0 = i * (1-agc_fac) g0 = mult (i, sub (32767, agc_fac)); } // compute gain[n] = agc_fac * gain[n-1] + (1-agc_fac) * sqrt(gain_in/gain_out) // sig_out[n] = gain[n] * sig_out[n] gain = st->past_gain; for (i = 0; i < l_trm; i++) { gain = mult (gain, agc_fac); gain = add (gain, g0); sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], gain), 3)); } st->past_gain = gain; return 0;}------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name]------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function]------------------------------------------------------------------------------*/void agc( agcState *st, /* i/o : agc state */ Word16 *sig_in, /* i : postfilter input signal (l_trm) */ Word16 *sig_out, /* i/o : postfilter output signal (l_trm) */ Word16 agc_fac, /* i : AGC factor */ Word16 l_trm, /* i : subframe size */ Flag *pOverflow /* i : overflow Flag */){ Word16 i; Word16 exp; Word16 gain_in; Word16 gain_out; Word16 g0; Word16 gain; Word32 s; Word32 L_temp; Word16 temp; Word16 *p_sig_out; /* calculate gain_out with exponent */ s = energy_new(sig_out, l_trm, pOverflow); /* function result */ if (s == 0) { st->past_gain = 0; return; } exp = norm_l(s) - 1; L_temp = L_shl(s, exp, pOverflow); gain_out = pv_round(L_temp, pOverflow); /* calculate gain_in with exponent */ s = energy_new(sig_in, l_trm, pOverflow); /* function result */ if (s == 0) { g0 = 0; } else { i = norm_l(s); /* L_temp = L_shl(s, i, pOverflow); */ L_temp = s << i; gain_in = pv_round(L_temp, pOverflow); exp -= i; /*---------------------------------------------------* * g0 = (1-agc_fac) * sqrt(gain_in/gain_out); * *---------------------------------------------------*/ /* s = gain_out / gain_in */ temp = div_s(gain_out, gain_in); /* s = L_deposit_l (temp); */ s = (Word32) temp; s = s << 7; s = L_shr(s, exp, pOverflow); /* add exponent */ s = Inv_sqrt(s, pOverflow); /* function result */ L_temp = s << 9; i = (Word16)((L_temp + (Word32) 0x00008000L) >> 16); /* g0 = i * (1-agc_fac) */ temp = 32767 - agc_fac; g0 = (Word16)(((Word32) i * temp) >> 15); } /* compute gain[n] = agc_fac * gain[n-1] + (1-agc_fac) * sqrt(gain_in/gain_out) */ /* sig_out[n] = gain[n] * sig_out[n] */ gain = st->past_gain; p_sig_out = sig_out; for (i = 0; i < l_trm; i++) { /* gain = mult (gain, agc_fac, pOverflow); */ gain = (Word16)(((Word32) gain * agc_fac) >> 15); /* gain = add (gain, g0, pOverflow); */ gain += g0; /* L_temp = L_mult (sig_out[i], gain, pOverflow); */ L_temp = ((Word32)(*(p_sig_out)) * gain) << 1; *(p_sig_out++) = (Word16)(L_temp >> 13); } st->past_gain = gain; return;}/*--------------------------------------------------------------------------*//*------------------------------------------------------------------------------ FUNCTION NAME: agc2------------------------------------------------------------------------------ INPUT AND OUTPUT DEFINITIONS Inputs: sig_in = pointer to a buffer containing the postfilter input signal sig_out = pointer to a buffer containing the postfilter output signal l_trm = subframe size pOverflow = pointer to overflow flag Outputs: sig_out points to a buffer containing the new scaled output signal. pOverflow -> 1 if the agc computation saturates Returns: None. Global Variables Used: None. Local Variables Needed: None.------------------------------------------------------------------------------ FUNCTION DESCRIPTION Scales the excitation on a subframe basis.------------------------------------------------------------------------------ REQUIREMENTS None.------------------------------------------------------------------------------ REFERENCES agc.c, UMTS GSM AMR speech codec, R99 - Version 3.2.0, March 2, 2001------------------------------------------------------------------------------ PSEUDO-CODEvoid agc2 ( Word16 *sig_in, // i : postfilter input signal Word16 *sig_out, // i/o : postfilter output signal Word16 l_trm // i : subframe size){ Word16 i, exp; Word16 gain_in, gain_out, g0; Word32 s; // calculate gain_out with exponent s = energy_new(sig_out, l_trm); // function result if (s == 0) { return; } exp = sub (norm_l (s), 1); gain_out = pv_round (L_shl (s, exp)); // calculate gain_in with exponent s = energy_new(sig_in, l_trm); // function result if (s == 0) { g0 = 0; } else { i = norm_l (s); gain_in = pv_round (L_shl (s, i)); exp = sub (exp, i); *---------------------------------------------------* * g0 = sqrt(gain_in/gain_out); * *---------------------------------------------------* s = L_deposit_l (div_s (gain_out, gain_in)); s = L_shl (s, 7); // s = gain_out / gain_in s = L_shr (s, exp); // add exponent s = Inv_sqrt (s); // function result g0 = pv_round (L_shl (s, 9)); } // sig_out(n) = gain(n) sig_out(n) for (i = 0; i < l_trm; i++) { sig_out[i] = extract_h (L_shl (L_mult (sig_out[i], g0), 3)); } return;}------------------------------------------------------------------------------ RESOURCES USED [optional] When the code is written for a specific target processor the the resources used should be documented below. HEAP MEMORY USED: x bytes STACK MEMORY USED: x bytes CLOCK CYCLES: (cycle count equation for this function) + (variable used to represent cycle count for each subroutine called) where: (cycle count variable) = cycle count for [subroutine name]------------------------------------------------------------------------------ CAUTION [optional] [State any special notes, constraints or cautions for users of this function]------------------------------------------------------------------------------*/void agc2( Word16 *sig_in, /* i : postfilter input signal */ Word16 *sig_out, /* i/o : postfilter output signal */ Word16 l_trm, /* i : subframe size */ Flag *pOverflow /* i : overflow flag */){ Word16 i; Word16 exp; Word16 gain_in; Word16 gain_out; Word16 g0; Word32 s; Word32 L_temp; Word16 temp; /* calculate gain_out with exponent */ s = energy_new(sig_out, l_trm, pOverflow); /* function result */ if (s == 0) { return; } exp = norm_l(s) - 1; L_temp = L_shl(s, exp, pOverflow); gain_out = pv_round(L_temp, pOverflow); /* calculate gain_in with exponent */ s = energy_new(sig_in, l_trm, pOverflow); /* function result */ if (s == 0) { g0 = 0; } else { i = norm_l(s); L_temp = L_shl(s, i, pOverflow); gain_in = pv_round(L_temp, pOverflow); exp -= i; /*---------------------------------------------------* * g0 = sqrt(gain_in/gain_out); * *---------------------------------------------------*/ /* s = gain_out / gain_in */ temp = div_s(gain_out, gain_in); /* s = L_deposit_l (temp); */ s = (Word32)temp; if (s > (Word32) 0x00FFFFFFL) { s = MAX_32; } else if (s < (Word32) 0xFF000000L) { s = MIN_32; } else { s = s << 7; } s = L_shr(s, exp, pOverflow); /* add exponent */ s = Inv_sqrt(s, pOverflow); /* function result */ if (s > (Word32) 0x003FFFFFL) { L_temp = MAX_32; } else if (s < (Word32) 0xFFC00000L) { L_temp = MIN_32; } else { L_temp = s << 9; } g0 = pv_round(L_temp, pOverflow); } /* sig_out(n) = gain(n) sig_out(n) */ for (i = l_trm - 1; i >= 0; i--) { L_temp = L_mult(sig_out[i], g0, pOverflow); if (L_temp > (Word32) 0x0FFFFFFFL) { sig_out[i] = MAX_16; } else if (L_temp < (Word32) 0xF0000000L) { sig_out[i] = MIN_16; } else { sig_out[i] = (Word16)(L_temp >> 13); } } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -