/* * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ /****************************************************************** iLBC Speech Coder ANSI-C Source Code iLBCInterface.c ******************************************************************/ #include "modules/audio_coding/codecs/ilbc/ilbc.h" #include #include "modules/audio_coding/codecs/ilbc/decode.h" #include "modules/audio_coding/codecs/ilbc/defines.h" #include "modules/audio_coding/codecs/ilbc/encode.h" #include "modules/audio_coding/codecs/ilbc/init_decode.h" #include "modules/audio_coding/codecs/ilbc/init_encode.h" #include "rtc_base/checks.h" int16_t WebRtcIlbcfix_EncoderAssign(IlbcEncoderInstance** iLBC_encinst, int16_t* ILBCENC_inst_Addr, int16_t* size) { *iLBC_encinst=(IlbcEncoderInstance*)ILBCENC_inst_Addr; *size=sizeof(IlbcEncoder)/sizeof(int16_t); if (*iLBC_encinst!=NULL) { return(0); } else { return(-1); } } int16_t WebRtcIlbcfix_DecoderAssign(IlbcDecoderInstance** iLBC_decinst, int16_t* ILBCDEC_inst_Addr, int16_t* size) { *iLBC_decinst=(IlbcDecoderInstance*)ILBCDEC_inst_Addr; *size=sizeof(IlbcDecoder)/sizeof(int16_t); if (*iLBC_decinst!=NULL) { return(0); } else { return(-1); } } int16_t WebRtcIlbcfix_EncoderCreate(IlbcEncoderInstance **iLBC_encinst) { *iLBC_encinst=(IlbcEncoderInstance*)malloc(sizeof(IlbcEncoder)); if (*iLBC_encinst!=NULL) { return(0); } else { return(-1); } } int16_t WebRtcIlbcfix_DecoderCreate(IlbcDecoderInstance **iLBC_decinst) { *iLBC_decinst=(IlbcDecoderInstance*)malloc(sizeof(IlbcDecoder)); if (*iLBC_decinst!=NULL) { return(0); } else { return(-1); } } int16_t WebRtcIlbcfix_EncoderFree(IlbcEncoderInstance *iLBC_encinst) { free(iLBC_encinst); return(0); } int16_t WebRtcIlbcfix_DecoderFree(IlbcDecoderInstance *iLBC_decinst) { free(iLBC_decinst); return(0); } int16_t WebRtcIlbcfix_EncoderInit(IlbcEncoderInstance* iLBCenc_inst, int16_t mode) { if ((mode==20)||(mode==30)) { WebRtcIlbcfix_InitEncode((IlbcEncoder*) iLBCenc_inst, mode); return(0); } else { return(-1); } } int WebRtcIlbcfix_Encode(IlbcEncoderInstance* iLBCenc_inst, const int16_t* speechIn, size_t len, uint8_t* encoded) { size_t pos = 0; size_t encpos = 0; if ((len != ((IlbcEncoder*)iLBCenc_inst)->blockl) && #ifdef SPLIT_10MS (len != 80) && #endif (len != 2*((IlbcEncoder*)iLBCenc_inst)->blockl) && (len != 3*((IlbcEncoder*)iLBCenc_inst)->blockl)) { /* A maximum of 3 frames/packet is allowed */ return(-1); } else { /* call encoder */ while (possection == 0) #else pos += ((IlbcEncoder*)iLBCenc_inst)->blockl; #endif encpos += ((IlbcEncoder*)iLBCenc_inst)->no_of_words; } return (int)(encpos*2); } } int16_t WebRtcIlbcfix_DecoderInit(IlbcDecoderInstance* iLBCdec_inst, int16_t mode) { if ((mode==20)||(mode==30)) { WebRtcIlbcfix_InitDecode((IlbcDecoder*) iLBCdec_inst, mode, 1); return(0); } else { return(-1); } } void WebRtcIlbcfix_DecoderInit20Ms(IlbcDecoderInstance* iLBCdec_inst) { WebRtcIlbcfix_InitDecode((IlbcDecoder*) iLBCdec_inst, 20, 1); } void WebRtcIlbcfix_Decoderinit30Ms(IlbcDecoderInstance* iLBCdec_inst) { WebRtcIlbcfix_InitDecode((IlbcDecoder*) iLBCdec_inst, 30, 1); } int WebRtcIlbcfix_Decode(IlbcDecoderInstance* iLBCdec_inst, const uint8_t* encoded, size_t len, int16_t* decoded, int16_t* speechType) { size_t i=0; /* Allow for automatic switching between the frame sizes (although you do get some discontinuity) */ if ((len==((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)|| (len==2*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)|| (len==3*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)) { /* ok, do nothing */ } else { /* Test if the mode has changed */ if (((IlbcDecoder*)iLBCdec_inst)->mode==20) { if ((len==NO_OF_BYTES_30MS)|| (len==2*NO_OF_BYTES_30MS)|| (len==3*NO_OF_BYTES_30MS)) { WebRtcIlbcfix_InitDecode( ((IlbcDecoder*)iLBCdec_inst), 30, ((IlbcDecoder*)iLBCdec_inst)->use_enhancer); } else { /* Unsupported frame length */ return(-1); } } else { if ((len==NO_OF_BYTES_20MS)|| (len==2*NO_OF_BYTES_20MS)|| (len==3*NO_OF_BYTES_20MS)) { WebRtcIlbcfix_InitDecode( ((IlbcDecoder*)iLBCdec_inst), 20, ((IlbcDecoder*)iLBCdec_inst)->use_enhancer); } else { /* Unsupported frame length */ return(-1); } } } while ((i*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)blockl], (const uint16_t*)&encoded [2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words], (IlbcDecoder*)iLBCdec_inst, 1) == -1) return -1; i++; } /* iLBC does not support VAD/CNG yet */ *speechType=1; return (int)(i*((IlbcDecoder*)iLBCdec_inst)->blockl); } int WebRtcIlbcfix_Decode20Ms(IlbcDecoderInstance* iLBCdec_inst, const uint8_t* encoded, size_t len, int16_t* decoded, int16_t* speechType) { size_t i=0; if ((len==((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)|| (len==2*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)|| (len==3*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)) { /* ok, do nothing */ } else { return(-1); } while ((i*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)blockl], (const uint16_t*)&encoded [2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words], (IlbcDecoder*)iLBCdec_inst, 1)) return -1; i++; } /* iLBC does not support VAD/CNG yet */ *speechType=1; return (int)(i*((IlbcDecoder*)iLBCdec_inst)->blockl); } int WebRtcIlbcfix_Decode30Ms(IlbcDecoderInstance* iLBCdec_inst, const uint8_t* encoded, size_t len, int16_t* decoded, int16_t* speechType) { size_t i=0; if ((len==((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)|| (len==2*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)|| (len==3*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)) { /* ok, do nothing */ } else { return(-1); } while ((i*((IlbcDecoder*)iLBCdec_inst)->no_of_bytes)blockl], (const uint16_t*)&encoded [2 * i * ((IlbcDecoder*)iLBCdec_inst)->no_of_words], (IlbcDecoder*)iLBCdec_inst, 1)) return -1; i++; } /* iLBC does not support VAD/CNG yet */ *speechType=1; return (int)(i*((IlbcDecoder*)iLBCdec_inst)->blockl); } size_t WebRtcIlbcfix_DecodePlc(IlbcDecoderInstance* iLBCdec_inst, int16_t* decoded, size_t noOfLostFrames) { size_t i; uint16_t dummy; for (i=0;iblockl], &dummy, (IlbcDecoder*)iLBCdec_inst, 0); RTC_CHECK_EQ(result, 0); } return (noOfLostFrames*((IlbcDecoder*)iLBCdec_inst)->blockl); } size_t WebRtcIlbcfix_NetEqPlc(IlbcDecoderInstance* iLBCdec_inst, int16_t* decoded, size_t noOfLostFrames) { /* Two input parameters not used, but needed for function pointers in NetEQ */ (void)(decoded = NULL); (void)(noOfLostFrames = 0); WebRtcSpl_MemSetW16(((IlbcDecoder*)iLBCdec_inst)->enh_buf, 0, ENH_BUFL); ((IlbcDecoder*)iLBCdec_inst)->prev_enh_pl = 2; return (0); } void WebRtcIlbcfix_version(char *version) { strcpy((char*)version, "1.1.1"); }