/* * =================================================================== * TS 26.104 * REL-5 V5.4.0 2004-03 * REL-6 V6.1.0 2004-03 * 3GPP AMR Floating-point Speech Codec * =================================================================== * */ /* * interf_enc.c * * * Project: * AMR Floating-Point Codec * * Contains: * This module contains all the functions needed encoding 160 * 16-bit speech samples to AMR encoder parameters. * */ /* * include files */ #include #include #include #include "sp_enc.h" #include "interf_rom.h" /* * Declare structure types */ /* Declaration transmitted frame types */ enum TXFrameType { TX_SPEECH_GOOD = 0, TX_SID_FIRST, TX_SID_UPDATE, TX_NO_DATA, TX_SPEECH_DEGRADED, TX_SPEECH_BAD, TX_SID_BAD, TX_ONSET, TX_N_FRAMETYPES /* number of frame types */ }; /* Declaration of interface structure */ typedef struct { Word16 sid_update_counter; /* Number of frames since last SID */ Word16 sid_handover_debt; /* Number of extra SID_UPD frames to schedule */ Word32 dtx; enum TXFrameType prev_ft; /* Type of the previous frame */ void *encoderState; /* Points encoder state structure */ } enc_interface_State; #ifdef ETSI /* * Prm2Bits * * * Parameters: * value I: value to be converted to binary * no_of_bits I: number of bits associated with value * bitstream O: address where bits are written * * Function: * Convert integer to binary and write the bits to the array. * The most significant bits are written first. * Returns: * void */ static void Int2Bin( Word16 value, Word16 no_of_bits, Word16 *bitstream ) { Word32 i, bit; Word16 *pt_bitstream; pt_bitstream = &bitstream[no_of_bits]; for ( i = 0; i < no_of_bits; i++ ) { bit = value & 0x0001; if ( bit == 0 ) { * --pt_bitstream = 0; } else { * --pt_bitstream = 1; } value = ( Word16 )( value >> 1 ); } } /* * Prm2Bits * * * Parameters: * mode I: AMR mode * prm I: analysis parameters * bits O: serial bits * * Function: * converts the encoder parameter vector into a vector of serial bits. * Returns: * void */ static void Prm2Bits( enum Mode mode, Word16 prm[], Word16 bits[] ) { Word32 i; switch ( mode ) { case MR122: for ( i = 0; i < PRMNO_MR122; i++ ) { Int2Bin( prm[i], bitno_MR122[i], bits ); bits += bitno_MR122[i]; } break; case MR102: for ( i = 0; i < PRMNO_MR102; i++ ) { Int2Bin( prm[i], bitno_MR102[i], bits ); bits += bitno_MR102[i]; } break; case MR795: for ( i = 0; i < PRMNO_MR795; i++ ) { Int2Bin( prm[i], bitno_MR795[i], bits ); bits += bitno_MR795[i]; } break; case MR74: for ( i = 0; i < PRMNO_MR74; i++ ) { Int2Bin( prm[i], bitno_MR74[i], bits ); bits += bitno_MR74[i]; } break; case MR67: for ( i = 0; i < PRMNO_MR67; i++ ) { Int2Bin( prm[i], bitno_MR67[i], bits ); bits += bitno_MR67[i]; } break; case MR59: for ( i = 0; i < PRMNO_MR59; i++ ) { Int2Bin( prm[i], bitno_MR59[i], bits ); bits += bitno_MR59[i]; } break; case MR515: for ( i = 0; i < PRMNO_MR515; i++ ) { Int2Bin( prm[i], bitno_MR515[i], bits ); bits += bitno_MR515[i]; } break; case MR475: for ( i = 0; i < PRMNO_MR475; i++ ) { Int2Bin( prm[i], bitno_MR475[i], bits ); bits += bitno_MR475[i]; } break; case MRDTX: for ( i = 0; i < PRMNO_MRDTX; i++ ) { Int2Bin( prm[i], bitno_MRDTX[i], bits ); bits += bitno_MRDTX[i]; } break; } return; } #else #ifndef IF2 /* * EncoderMMS * * * Parameters: * mode I: AMR mode * param I: Encoder output parameters * stream O: packed speech frame * frame_type I: frame type (DTX) * speech_mode I: speech mode (DTX) * * Function: * Pack encoder output parameters to octet structure according * importance table and AMR file storage format according to * RFC 3267. * Returns: * number of octets */ static int EncoderMMS( enum Mode mode, Word16 *param, UWord8 *stream, enum TXFrameType frame_type, enum Mode speech_mode ) { Word32 j = 0, k; Word16 *mask; memset(stream, 0, block_size[mode]); *stream = toc_byte[mode]; stream++; if ( mode == 15 ) { return 1; } else if ( mode == MRDTX ) { mask = order_MRDTX; for ( j = 1; j < 36; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x01; mask += 2; if ( j % 8 ) *stream <<= 1; else stream++; } /* add SID type information */ if ( frame_type == TX_SID_UPDATE ) *stream += 0x01; *stream <<= 3; /* speech mode indication */ *stream += ( unsigned char )(speech_mode & 0x0007); *stream <<= 1; /* don't shift at the end of the function */ return 6; } else if ( mode == MR475 ) { mask = order_MR475; for ( j = 1; j < 96; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x01; mask += 2; if ( j % 8 ) *stream <<= 1; else stream++; } } else if ( mode == MR515 ) { mask = order_MR515; for ( j = 1; j < 104; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x01; mask += 2; if ( j % 8 ) *stream <<= 1; else stream++; } } else if ( mode == MR59 ) { mask = order_MR59; for ( j = 1; j < 119; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x01; mask += 2; if ( j % 8 ) *stream <<= 1; else stream++; } } else if ( mode == MR67 ) { mask = order_MR67; for ( j = 1; j < 135; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x01; mask += 2; if ( j % 8 ) *stream <<= 1; else stream++; } } else if ( mode == MR74 ) { mask = order_MR74; for ( j = 1; j < 149; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x01; mask += 2; if ( j % 8 ) *stream <<= 1; else stream++; } } else if ( mode == MR795 ) { mask = order_MR795; for ( j = 1; j < 160; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x01; mask += 2; if ( j % 8 ) *stream <<= 1; else stream++; } } else if ( mode == MR102 ) { mask = order_MR102; for ( j = 1; j < 205; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x01; mask += 2; if ( j % 8 ) *stream <<= 1; else stream++; } } else if ( mode == MR122 ) { mask = order_MR122; for ( j = 1; j < 245; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x01; mask += 2; if ( j % 8 ) *stream <<= 1; else stream++; } } /* shift remaining bits */ if ( k = j % 8 ) *stream <<= ( 8 - k ); return( (int)block_size[mode] ); } #else /* * Encoder3GPP * * * Parameters: * mode I: AMR mode * param I: Encoder output parameters * stream O: packed speech frame * frame_type I: frame type (DTX) * speech_mode I: speech mode (DTX) * * Function: * Pack encoder output parameters to octet structure according * importance table. * Returns: * number of octets */ static int Encoder3GPP( enum Mode mode, Word16 *param, UWord8 *stream, enum TXFrameType frame_type, enum Mode speech_mode ) { Word32 j = 0; Word16 *mask; memset(stream, 0, block_size[mode]); if ( mode == 15 ) { *stream = 0xF; return 1; } else if ( mode == MRDTX ) { mask = order_MRDTX; *stream = 0x40; for ( j = 5; j < 40; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x80; mask += 2; if ( j % 8 ) *stream >>= 1; else stream++; } /* add SID type information */ if ( frame_type == TX_SID_UPDATE ) *stream += 0x80; stream++; /* speech mode indication */ *stream = ( unsigned char )speech_mode; /* don't shift at the end of the function */ return 6; } else if ( mode == MR475 ) { mask = order_MR475; *stream = 0; for ( j = 5; j < 100; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x80; mask += 2; if ( j % 8 ) *stream >>= 1; else stream++; } } else if ( mode == MR515 ) { mask = order_MR515; *stream = 0x8; for ( j = 5; j < 108; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x80; mask += 2; if ( j % 8 ) *stream >>= 1; else stream++; } } else if ( mode == MR59 ) { mask = order_MR59; *stream = 0x10; for ( j = 5; j < 123; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x80; mask += 2; if ( j % 8 ) *stream >>= 1; else stream++; } } else if ( mode == MR67 ) { mask = order_MR67; *stream = 0x18; for ( j = 5; j < 139; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x80; mask += 2; if ( j % 8 ) *stream >>= 1; else stream++; } } else if ( mode == MR74 ) { mask = order_MR74; *stream = 0x20; for ( j = 5; j < 153; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x80; mask += 2; if ( j % 8 ) *stream >>= 1; else stream++; } } else if ( mode == MR795 ) { mask = order_MR795; *stream = 0x28; for ( j = 5; j < 164; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x80; mask += 2; if ( j % 8 ) *stream >>= 1; else stream++; } } else if ( mode == MR102 ) { mask = order_MR102; *stream = 0x30; for ( j = 5; j < 209; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x80; mask += 2; if ( j % 8 ) *stream >>= 1; else stream++; } } else if ( mode == MR122 ) { mask = order_MR122; *stream = 0x38; for ( j = 5; j < 249; j++ ) { if ( param[ * mask] & *( mask + 1 ) ) *stream += 0x80; mask += 2; if ( j % 8 ) *stream >>= 1; else stream++; } } /* shift remaining bits */ *stream >>= ( 8 - j % 8 ); return( (int)block_size[mode] ); } #endif #endif /* * Sid_Sync_reset * * * Parameters: * st O: state structure * * Function: * Initializes state memory * * Returns: * void */ static void Sid_Sync_reset( enc_interface_State *st ) { st->sid_update_counter = 3; st->sid_handover_debt = 0; st->prev_ft = TX_SPEECH_GOOD; } /* * Encoder_Interface_Encode * * * Parameters: * st I: pointer to state structure * mode I: Speech Mode * speech I: Input speech * serial O: Output octet structure 3GPP or * ETSI serial stream * force_speech I: Force speech in DTX * * Function: * Encoding and packing one frame of speech * * Returns: * number of octets */ int Encoder_Interface_Encode( void *st, enum Mode mode, Word16 *speech, #ifndef ETSI UWord8 *serial, #else Word16 *serial, #endif int force_speech ) { Word16 prm[PRMNO_MR122]; /* speech parameters, max size */ const Word16 *homing; /* pointer to homing frame */ Word16 homing_size; /* frame size for homing frame */ enc_interface_State * s; enum TXFrameType txFrameType; /* frame type */ int i, noHoming = 0; /* * used encoder mode, * if used_mode == -1, force VAD on */ enum Mode used_mode = -force_speech; s = ( enc_interface_State * )st; /* * Checks if all samples of the input frame matches the encoder * homing frame pattern, which is 0x0008 for all samples. */ for ( i = 0; i < 160; i++ ) { noHoming = speech[i] ^ 0x0008; if ( noHoming ) break; } if (noHoming){ Speech_Encode_Frame( s->encoderState, mode, speech, prm, &used_mode ); } else { switch ( mode ) { case MR122: homing = dhf_MR122; homing_size = 18; break; case MR102: homing = dhf_MR102; homing_size = 12; break; case MR795: homing = dhf_MR795; homing_size = 8; break; case MR74: homing = dhf_MR74; homing_size = 7; break; case MR67: homing = dhf_MR67; homing_size = 7; break; case MR59: homing = dhf_MR59; homing_size = 7; break; case MR515: homing = dhf_MR515; homing_size = 7; break; case MR475: homing = dhf_MR475; homing_size = 7; break; default: homing = NULL; homing_size = 0; break; } for( i = 0; i < homing_size; i++){ prm[i] = homing[i]; } /* rest of the parameters are zero */ memset(&prm[homing_size], 0, (PRMNO_MR122 - homing_size) << 1); used_mode = mode; } if ( used_mode == MRDTX ) { s->sid_update_counter--; if ( s->prev_ft == TX_SPEECH_GOOD ) { txFrameType = TX_SID_FIRST; s->sid_update_counter = 3; } else { /* TX_SID_UPDATE or TX_NO_DATA */ if ( ( s->sid_handover_debt > 0 ) && ( s->sid_update_counter > 2 ) ) { /* * ensure extra updates are properly delayed after * a possible SID_FIRST */ txFrameType = TX_SID_UPDATE; s->sid_handover_debt--; } else { if ( s->sid_update_counter == 0 ) { txFrameType = TX_SID_UPDATE; s->sid_update_counter = 8; } else { txFrameType = TX_NO_DATA; used_mode = 15; } } } } else { s->sid_update_counter = 8; txFrameType = TX_SPEECH_GOOD; } s->prev_ft = txFrameType; if ( noHoming == 0 ) { Speech_Encode_Frame_reset( s->encoderState, s->dtx ); Sid_Sync_reset( s ); } #ifndef ETSI #ifdef IF2 return Encoder3GPP( used_mode, prm, serial, txFrameType, mode ); #else return EncoderMMS( used_mode, prm, serial, txFrameType, mode ); #endif #else Prm2Bits( used_mode, prm, &serial[1] ); serial[0] = ( Word16 )txFrameType; serial[245] = ( Word16 )mode; return 500; #endif } /* * Encoder_Interface_init * * * Parameters: * dtx I: DTX flag * * Function: * Allocates state memory and initializes state memory * * Returns: * pointer to encoder interface structure */ void * Encoder_Interface_init( int dtx ) { enc_interface_State * s; /* allocate memory */ if ( ( s = ( enc_interface_State * ) malloc( sizeof( enc_interface_State ) ) ) == NULL ) { fprintf( stderr, "Encoder_Interface_init: " "can not malloc state structure\n" ); return NULL; } s->encoderState = Speech_Encode_Frame_init( dtx ); Sid_Sync_reset( s ); s->dtx = dtx; return s; } /* * DecoderInterfaceExit * * * Parameters: * state I: state structure * * Function: * The memory used for state memory is freed * * Returns: * Void */ void Encoder_Interface_exit( void *state ) { enc_interface_State * s; s = ( enc_interface_State * )state; /* free memory */ Speech_Encode_Frame_exit( &s->encoderState ); free( s ); state = NULL; }