📄 sp_enc.c
字号:
/*************************************************************************
Function: Speech_Encode_Frame
Purpose: speech frame encoding
Inputs: st : post filter states
sidst : sid frame encoding state
mode: speech coder required mode
new_speech : speech input
Outputs: st : post filter states
serial : serial bit stream
usedMode : used speech coder mode
tx_frame_type : frame type send by encoder
Return:
Modification:
**************************************************************************/
int Speech_Encode_Frame (void *amrcoder, Mode mode, Word16 *new_speech,
unsigned char* bitstr, Mode *usedMode, TXFrameType *tx_frame_type)
{
Word16 prm[MAX_PRM_SIZE]; /* Analysis parameters. */
Word16 syn[L_FRAME]; /* Buffer for synthesis speech */
Word16 i,reset_flag = 1;
AmrNBCoder *pamrcoder = (AmrNBCoder *)amrcoder;
Word16* pnew_speech = new_speech;
Speech_Encode_FrameState *pst = (Speech_Encode_FrameState *) pamrcoder->SpeechEncodeFrameState;
sid_syncState *psidst = (sid_syncState *)pamrcoder->SidsyncState;
//sid_syncState *psidst = (sid_syncState *)sidst;
Mode *pusedMode = usedMode;
TXFrameType *ptx_frame_type = tx_frame_type;
/* check for homing frame */
for (i = 0; i < L_FRAME; i++)
{
if ( pnew_speech[i] != EHF_MASK)
{
reset_flag = 0;
break;
}
}
/* initialize the serial output frame to zero */
/* have been initialized out of function */
#if !defined(NO13BIT)
/* Delete the 3 LSBs (13-bit input) */
for (i = 0; i < L_FRAME; i+=4 )
{
pnew_speech[i] = pnew_speech[i ] & 0xfff8;
pnew_speech[i+1] = pnew_speech[i+1] & 0xfff8;
pnew_speech[i+2] = pnew_speech[i+2] & 0xfff8;
pnew_speech[i+3] = pnew_speech[i+3] & 0xfff8;
}
#endif
/* filter + downscaling */
Pre_Process (pst->pre_state, pnew_speech, L_FRAME);
/* Call the speech encoder */
cod_amr(pst->cod_amr_state, mode, pnew_speech, prm, pusedMode, syn);
if (*pusedMode == MRDTX)
{
psidst->sid_update_counter--;
if (psidst->prev_ft == TX_SPEECH_GOOD)
{
*ptx_frame_type = TX_SID_FIRST;
psidst->sid_update_counter = 3;
}
else
{
/* TX_SID_UPDATE or TX_NO_DATA */
if( (psidst->sid_handover_debt > 0) && (psidst->sid_update_counter > 2) )
{
/* ensure extra updates are properly delayed after a possible SID_FIRST */
*ptx_frame_type = TX_SID_UPDATE;
psidst->sid_handover_debt--;
}
else
{
*ptx_frame_type = (psidst->sid_update_counter == 0) ? TX_SID_UPDATE : TX_NO_DATA;
psidst->sid_update_counter = (psidst->sid_update_counter == 0) ? psidst->sid_update_rate : psidst->sid_update_counter ;
}
}
}
else
{
psidst->sid_update_counter = psidst->sid_update_rate ;
*ptx_frame_type = TX_SPEECH_GOOD;
}
psidst->prev_ft = *ptx_frame_type;
/*when ehoming ,reset state */
if (reset_flag != 0)
{
Speech_Encode_Frame_reset(pst);
//sid_sync_reset(sidst);
psidst->sid_update_counter = 3;
psidst->sid_handover_debt = 0;
psidst->prev_ft = TX_SPEECH_GOOD;
}
/* Parameters to serial bits */
Prm2bits (*pusedMode, mode, *ptx_frame_type, prm, &bitstr[0]);
return 0;
}
#ifdef MMS_IO/*************************************************************************
Function: PackBits
Purpose: Sorts speech bits according decreasing subjective importance
and packs into octets according to AMR file storage format
as specified in RFC 3267 (Sections 5.1 and 5.3).
Description: Depending on the mode, different numbers of bits are
processed. Details can be found in specification mentioned
above and in file "bitno.tab".
Input :
used_mode : actual AMR mode
mode : requested AMR (speech) mode
fr_type : frame type
bits[]i : serial bits
Output:
packed_bits[]: sorted&packed bits
Return:
*************************************************************************/Word16 PackBits(Mode used_mode, Mode mode, TXFrameType fr_type, Word16 bits[], UWord8 packed_bits[] )
{ Word16 i; UWord8 temp; UWord8 *pack_ptr; temp = 0; pack_ptr = (UWord8*)packed_bits; /* file storage format can handle only speech frames, AMR SID frames and NO_DATA frames */ /* -> force NO_DATA frame */ if (used_mode < 0 || used_mode > 15 || (used_mode > 8 && used_mode < 15)) { used_mode = 15; } /* mark empty frames between SID updates as NO_DATA frames */ if (used_mode == MRDTX && fr_type == TX_NO_DATA) { used_mode = 15; } /* insert table of contents (ToC) byte at the beginning of the frame */ *pack_ptr = toc_byte[used_mode]; pack_ptr++; /* note that NO_DATA frames (used_mode==15) do not need further processing */ if (used_mode == 15) { return 1; } temp = 0; /* sort and pack speech bits */ for (i = 1; i < unpacked_size[used_mode] + 1; i++) { if (bits[sort_ptr[used_mode][i-1]] == BIT_1) { temp++; } if (i % 8) { temp <<= 1; } else { *pack_ptr = temp; pack_ptr++; temp = 0; } } /* insert SID type indication and speech mode in case of SID frame */ if (used_mode == MRDTX) { if (fr_type == TX_SID_UPDATE) { temp++; } temp <<= 3; temp += mode & 0x0007; temp <<= 1; } /* insert unused bits (zeros) at the tail of the last byte */ temp <<= (unused_size[used_mode] - 1); *pack_ptr = temp; return packed_size[used_mode];}#endif
/* filter coefficients (fc = 80 Hz, coeff. b[] is divided by 2) */
static const Word16 b[3] = {1899, -3798, 1899};static const Word16 a[3] = {4096, 7807, -3733};
/*************************************************************************
Function: Pre_Process()
Purpose: Preprocessing of input speech.
Description:
- 2nd order high pass filtering with cut off frequency at 80 Hz.
- Divide input by two.
Algorithm:
y[i] = b[0]*x[i]/2 + b[1]*x[i-1]/2 + b[2]*x[i-2]/2
+ a[1]*y[i-1] + a[2]*y[i-2];
Input is divided by two in the filtering process.
*************************************************************************/int Pre_Process (Pre_ProcessState *st ,Word16 signal[], Word16 lg)
{
Word16 i, x2, x1, x0, y1hi,y1lo, y2hi, y2lo; Word32 L_tmp, tmp1,tmp2; Word16* pSignal; pSignal = signal; x1 = st->x1; x0 = st->x0; y1hi = st->y1_hi; y1lo = st->y1_lo; y2hi = st->y2_hi; y2lo = st->y2_lo; for (i = 0; i < lg; i+=4 ) { x2 = x1; x1 = x0; x0 = pSignal[i]; tmp1 = ((y1hi*7807 + y2hi*(-3733) )<<1) + (((( y1lo*7807)>>15) + ((y2lo*(-3733))>>15 ))<<1); tmp2 = (x0 + x2 - x1*2)*3798; L_tmp = ( tmp1+ tmp2)<< 3; tmp1 = L_tmp + 0x00008000L; tmp1 = (L_tmp > 0)&(tmp1<0) ? MAX_32 : tmp1; pSignal[i] = (Word16)(tmp1>>16); y2hi = y1hi; y2lo = y1lo; y1hi = (Word16)(L_tmp >> 16); y1lo = (Word16)((L_tmp - (y1hi << 16)) >>1); x2 = x1; x1 = x0; x0 = pSignal[i+1]; tmp1 = ((y1hi*7807 + y2hi*(-3733) )<<1) + (((( y1lo*7807)>>15) + ((y2lo*(-3733))>>15 ))<<1); tmp2 = (x0 + x2 - x1*2)*3798; L_tmp = ( tmp1+ tmp2)<< 3; tmp1 = L_tmp + 0x00008000L; tmp1 = (L_tmp > 0)&(tmp1<0) ? MAX_32 : tmp1; pSignal[i+1] = (Word16)(tmp1>>16); y2hi = y1hi; y2lo = y1lo; y1hi = (Word16)(L_tmp >> 16); y1lo = (Word16)((L_tmp - (y1hi << 16)) >>1); x2 = x1; x1 = x0; x0 = pSignal[i+2]; tmp1 = ((y1hi*7807 + y2hi*(-3733) )<<1) + (((( y1lo*7807)>>15) + ((y2lo*(-3733))>>15 ))<<1); tmp2 = (x0 + x2 - x1*2)*3798; L_tmp = ( tmp1+ tmp2)<< 3; tmp1 = L_tmp + 0x00008000L; tmp1 = (L_tmp > 0)&(tmp1<0) ? MAX_32 : tmp1; pSignal[i+2] = (Word16)(tmp1>>16); y2hi = y1hi; y2lo = y1lo; y1hi = (Word16)(L_tmp >> 16); y1lo = (Word16)((L_tmp - (y1hi << 16)) >>1); x2 = x1; x1 = x0; x0 = pSignal[i+3]; tmp1 = ((y1hi*7807 + y2hi*(-3733) )<<1) + (((( y1lo*7807)>>15) + ((y2lo*(-3733))>>15 ))<<1); tmp2 = (x0 + x2 - x1*2)*3798; L_tmp = ( tmp1+ tmp2)<< 3; tmp1 = L_tmp + 0x00008000L; tmp1 = (L_tmp > 0)&(tmp1<0) ? MAX_32 : tmp1; pSignal[i+3] = (Word16)(tmp1>>16); y2hi = y1hi; y2lo = y1lo; y1hi = (Word16)(L_tmp >> 16); y1lo = (Word16)((L_tmp - (y1hi << 16)) >>1); } st->x1 = x1; st->x0 = x0; st->y1_hi = y1hi ; st->y1_lo = y1lo; st->y2_hi = y2hi; st->y2_lo = y2lo;
return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -