static USC_Status Decode(USC_Handle handle, USC_Bitstream *in, USC_PCMStream *out) { AMRWB_Handle_Header *amrwb_header; AMRWBDecoder_Obj *DecObj; int bitrate_idx; int mode; RXFrameType rx_type; short prm[56]; if(out==NULL) return USC_BadDataPointer; if(handle==NULL) return USC_InvalidHandler; amrwb_header = (AMRWB_Handle_Header*)handle; DecObj = (AMRWBDecoder_Obj *)((char*)handle + sizeof(AMRWB_Handle_Header)); if(in == NULL) { bitrate_idx = CheckRate_AMRWB(amrwb_header->bitrate_old); if(bitrate_idx < 0) return USC_UnsupportedBitRate; amrwb_header->bitrate = amrwb_header->bitrate_old; out->bitrate = amrwb_header->bitrate_old; rx_type = RX_SPEECH_LOST; if(apiAMRWBDecode(DecObj,(const unsigned char*)LostFrame, usc2amrwb[bitrate_idx],rx_type,(unsigned short*)out->pBuffer) != APIAMRWB_StsNoErr){ return USC_NoOperation; } if(amrwb_header->trunc) { ippsAndC_16u_I((Ipp16u)IO_MASK, (unsigned short*)out->pBuffer, AMRWB_Frame); // int i; // short *pPCM = (short *)out->pBuffer; // for (i = 0; i < AMRWB_Frame; i ++) pPCM[i] &= IO_MASK; } amrwb_header->reset_flag = 0; amrwb_header->reset_flag_old = 1; out->nbytes = AMRWB_Frame*sizeof(short); } else { if(in->nbytes<=0) return USC_NoOperation; bitrate_idx = CheckRate_AMRWB(in->bitrate); if(bitrate_idx < 0) return USC_UnsupportedBitRate; amrwb_header->bitrate = in->bitrate; out->bitrate = in->bitrate; rx_type = ownTX2RX((TXFrameType)in->frametype); if ((rx_type == RX_SID_BAD) || (rx_type == RX_SID_UPDATE) || (rx_type == RX_NO_DATA)) { mode = AMRWB_RATE_DTX; } else { mode = bitrate_idx; } if ((rx_type == RX_SPEECH_LOST)) { out->bitrate = amrwb_header->usedRate; amrwb_header->reset_flag = 0; } else { amrwb_header->usedRate = out->bitrate; /* if homed: check if this frame is another homing frame */ ownConvert15(mode,in->pBuffer, prm); amrwb_header->reset_flag = ownTestBitstreamFrameHoming(prm, mode); } /* produce encoder homing frame if homed & input=decoder homing frame */ if ((amrwb_header->reset_flag != 0) && (amrwb_header->reset_flag_old != 0)) { ippsSet_16s(EHF_MASK, (short*)out->pBuffer, AMRWB_Frame); } else { if(apiAMRWBDecode(DecObj,(const unsigned char*)in->pBuffer,usc2amrwb[bitrate_idx],rx_type,(unsigned short*)out->pBuffer) != APIAMRWB_StsNoErr){ return USC_NoOperation; } if (amrwb_header->trunc) { /* Truncate LSBs */ ippsAndC_16u_I((Ipp16u)IO_MASK, (unsigned short*)out->pBuffer, AMRWB_Frame); // int i; // short *pPCM = (short *)out->pBuffer; // for (i = 0; i < AMRWB_Frame; i ++) pPCM[i] &= IO_MASK; } } /* reset decoder if current frame is a homing frame */ if (amrwb_header->reset_flag != 0) { apiAMRWBDecoder_Init((AMRWBDecoder_Obj*)DecObj); amrwb_header->usedRate = 6600; } amrwb_header->reset_flag_old = amrwb_header->reset_flag; out->nbytes = AMRWB_Frame*sizeof(short); { int foo; in->nbytes = getBitstreamSize(bitrate_idx, in->frametype, &foo); } } return USC_NoError; }
inline void MemorySet(Ipp16u *dst, Ipp32s val, Ipp32s length) { ippsSet_16s((Ipp16s)val, (Ipp16s*)dst, length); }
void tree_build(Ipp32s sfb_bit_len[MAX_SFB][12], Ipp32s cb_trace[MAX_SFB][12], Ipp32s max_sfb, Ipp32s len_esc_value) { #if !defined(ANDROID) Ipp16s sect_len[12]; #else static Ipp16s sect_len[12]; #endif Ipp32u index, i; Ipp32s min_value; Ipp32s sect_esc_value; Ipp32s bits_for_changes, sfb, cb; #if 0 ippsSet_16s(1, (Ipp16s*)sect_len, 12); #else for (i=0; i<12; i++){ sect_len[i] = 1; } #endif bits_for_changes = 4 + len_esc_value; sect_esc_value = (1 << len_esc_value) - 2; for (sfb = 0; sfb < max_sfb - 1; sfb++) { #if 0 ippsMinIndx_32s(sfb_bit_len[sfb], 12, &min_value, &index); #else int i; min_value = sfb_bit_len[sfb][0]; index = 0; for ( i = 1; i < 12; i++ ) { if ( sfb_bit_len[sfb][i] < min_value ) { min_value = sfb_bit_len[sfb][i]; index = i; } } #endif min_value += bits_for_changes; for (cb = 0; cb < 12; cb++) { /* if it is very expensive to change a codebook */ if (sfb_bit_len[sfb][cb] <= min_value) { if (sect_len[cb] != sect_esc_value) { sfb_bit_len[sfb+1][cb] += sfb_bit_len[sfb][cb]; cb_trace[sfb][cb] = cb; sect_len[cb]++; } else { if (sfb_bit_len[sfb][cb] + len_esc_value <= min_value) { sfb_bit_len[sfb+1][cb] += sfb_bit_len[sfb][cb] + len_esc_value; cb_trace[sfb][cb] = cb; sect_len[cb] = 0; } else { sfb_bit_len[sfb+1][cb] += min_value; cb_trace[sfb][cb] = index; sect_len[cb] = 1; } } } else { /* if no */ sfb_bit_len[sfb+1][cb] += min_value; cb_trace[sfb][cb] = index; sect_len[cb] = 1; } } } }