📄 gsm.c
字号:
move.w d3,-(a2)
//*srr++ = v[0] = sri
move.w d1,(a0)
move.w d1,(a4)+
subq.w #1,d0
bne @loop
movem.l (a7)+,d3-d7/a2-a4
frfree
rts
}
#else /* __MC68K__ */
static void Short_term_synthesis_filtering(
word *v,
word * rrp, /* [0..7] IN */
int k, /* k_end - k_start */
word * wt, /* [0..k-1] IN */
word * sr /* [0..k-1] OUT */
)
{
register int i;
register word sri;
while (k--) {
sri = *wt++;
for (i = 8; i--;) {
if (rrp[i] == MIN_WORD) {
sri = GSM_SUB( sri, (v[i]==MIN_WORD) ? MAX_WORD :
GSM_MULT_R( rrp[i], v[i] ));
v[i+1]=GSM_ADD( v[i], (sri == MIN_WORD) ? MAX_WORD :
GSM_MULT_R( rrp[i], sri ));
}
#ifdef BUG_FIX
else
{
#endif /* BUG_FIX */
sri = GSM_SUB( sri, GSM_MULT_R( rrp[i], v[i] ) );
v[i+1] = GSM_ADD( v[i], GSM_MULT_R( rrp[i], sri ) );
#ifdef BUG_FIX
}
#endif /* BUG_FIX */
}
*sr++ = v[0] = sri;
}
}
#endif /* __MC68K__ */
static void Gsm_Short_Term_Analysis_Filter(
struct gsm_state * S,
word * LARc, /* coded log area ratio [0..7] IN */
word * s /* signal [0..159] IN/OUT */
)
{
word * LARpp_j = S->LARpp[ S->j ];
word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ];
word LARp[8];
# define FILTER GSM_ST_ANAL_FILT
Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j );
Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
LARp_to_rp( LARp );
FILTER( S->u, LARp, 13, s);
Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
LARp_to_rp( LARp );
FILTER( S->u, LARp, 14, s + 13);
Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
LARp_to_rp( LARp );
FILTER( S->u, LARp, 13, s + 27);
Coefficients_40_159( LARpp_j, LARp);
LARp_to_rp( LARp );
FILTER( S->u, LARp, 120, s + 40);
}
static void Gsm_Short_Term_Synthesis_Filter(
struct gsm_state * S,
word * LARcr, /* received log area ratios [0..7] IN */
word * wt, /* received d [0..159] IN */
word * s /* signal s [0..159] OUT */
)
{
word * LARpp_j = S->LARpp[ S->j ];
word * LARpp_j_1 = S->LARpp[ S->j ^=1 ];
word LARp[8];
Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j );
Coefficients_0_12( LARpp_j_1, LARpp_j, LARp );
LARp_to_rp( LARp );
GSM_ST_SYNTH_FILT( S->v, LARp, 13, wt, s );
Coefficients_13_26( LARpp_j_1, LARpp_j, LARp);
LARp_to_rp( LARp );
GSM_ST_SYNTH_FILT( S->v, LARp, 14, wt + 13, s + 13 );
Coefficients_27_39( LARpp_j_1, LARpp_j, LARp);
LARp_to_rp( LARp );
GSM_ST_SYNTH_FILT( S->v, LARp, 13, wt + 27, s + 27 );
Coefficients_40_159( LARpp_j, LARp );
LARp_to_rp( LARp );
GSM_ST_SYNTH_FILT( S->v, LARp, 120, wt + 40, s + 40);
}
/*
* 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION
*/
/*
* This module computes the LTP gain (bc) and the LTP lag (Nc)
* for the long term analysis filter. This is done by calculating a
* maximum of the cross-correlation function between the current
* sub-segment short term residual signal d[0..39] (output of
* the short term analysis filter; for simplification the index
* of this array begins at 0 and ends at 39 for each sub-segment of the
* RPE-LTP analysis) and the previous reconstructed short term
* residual signal dp[ -120 .. -1 ]. A dynamic scaling must be
* performed to avoid overflow.
*/
/* The next procedure exists in six versions. First two integer
* version (if USE_FLOAT_MUL is not defined); then four floating
* point versions, twice with proper scaling (USE_FLOAT_MUL defined),
* once without (USE_FLOAT_MUL and FAST defined, and fast run-time
* option used). Every pair has first a Cut version (see the -C
* option to toast or the LTP_CUT option to gsm_option()), then the
* uncut one. (For a detailed explanation of why this is altogether
* a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered
* Harmful''.)
*/
#ifdef LTP_CUT
static void Cut_Calculation_of_the_LTP_parameters(
register word * d, /* [0..39] IN */
register word * dp, /* [-120..-1] IN */
word * bc_out, /* OUT */
word * Nc_out /* OUT */
)
{
register int k, lambda;
word Nc, bc;
longword L_result;
longword L_max, L_power;
word R, S, dmax, scal, best_k;
register word temp, wt_k;
/* Search of the optimum scaling of d[0..39].
*/
dmax = 0;
for (k = 0; k <= 39; k++) {
temp = d[k];
temp = GSM_ABS( temp );
if (temp > dmax) {
dmax = temp;
best_k = k;
}
}
temp = 0;
if (dmax == 0) scal = 0;
else {
pgpAssert(dmax > 0);
temp = gsm_norm( (longword)dmax << 16 );
}
if (temp > 6) scal = 0;
else scal = 6 - temp;
pgpAssert(scal >= 0);
/* Search for the maximum cross-correlation and coding of the LTP lag
*/
L_max = 0;
Nc = 40; /* index for the maximum cross-correlation */
wt_k = SASR(d[best_k], scal);
for (lambda = 40; lambda <= 120; lambda++) {
L_result = (longword)wt_k * dp[best_k - lambda];
if (L_result > L_max) {
Nc = lambda;
L_max = L_result;
}
}
*Nc_out = Nc;
L_max <<= 1;
/* Rescaling of L_max
*/
pgpAssert(scal <= 100 && scal >= -100);
L_max = L_max >> (6 - scal); /* sub(6, scal) */
pgpAssert( Nc <= 120 && Nc >= 40);
/* Compute the power of the reconstructed short term residual
* signal dp[..]
*/
L_power = 0;
for (k = 0; k <= 39; k++) {
register longword L_temp;
L_temp = SASR( dp[k - Nc], 3 );
L_power += L_temp * L_temp;
}
L_power <<= 1; /* from L_MULT */
/* Normalization of L_max and L_power
*/
if (L_max <= 0) {
*bc_out = 0;
return;
}
if (L_max >= L_power) {
*bc_out = 3;
return;
}
temp = gsm_norm( L_power );
R = SASR( L_max << temp, 16 );
S = SASR( L_power << temp, 16 );
/* Coding of the LTP gain
*/
/* Table 4.3a must be used to obtain the level DLB[i] for the
* quantization of the LTP gain b to get the coded version bc.
*/
for (bc = 0; bc <= 2; bc++) if (R <= GSM_MULT(S, gsm_DLB[bc])) break;
*bc_out = bc;
}
#endif /* LTP_CUT */
#ifdef __MC68K__
static asm longword LTP_loop_internal(word *wt,word *dp)
{
fralloc+
/*
* Registers used:
*
* a0: wt
* a1: dp
* d0: L_result
* d1: scratch register
*
*/
movea.l wt,a0
movea.l dp,a1
moveq.l #0,d0
// Unrolled loop: do it forty times!
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
move.w (a0)+,d1
muls.w (a1)+,d1
add.l d1,d0
frfree
rts
}
#else /* __MC68K__ */
static longword LTP_loop_internal(word *wt,word *dp) {
word i;
longword L_result = 0;
for (i=0; i<40; i++) {
L_result += (longword) *wt++ * *dp++;
}
return L_result;
}
#endif /* __MC68K__ */
static void Calculation_of_the_LTP_parameters(
register word * d, /* [0..39] IN */
register word * dp, /* [-120..-1] IN */
word * bc_out, /* OUT */
word * Nc_out /* OUT */
)
{
register int k, lambda;
word Nc, bc;
word wt[40];
longword L_max, L_power;
word R, S, dmax, scal;
register word temp;
/* Search of the optimum scaling of d[0..39].
*/
dmax = 0;
for (k = 0; k <= 39; k++) {
temp = d[k];
temp = GSM_ABS( temp );
if (temp > dmax) dmax = temp;
}
temp =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -