| /* | |
| * Copyright (c) 2011 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 | |
| WebRtcIlbcfix_CbConstruct.c | |
| ******************************************************************/ | |
| #include "modules/audio_coding/codecs/ilbc/cb_construct.h" | |
| #include "modules/audio_coding/codecs/ilbc/defines.h" | |
| #include "modules/audio_coding/codecs/ilbc/gain_dequant.h" | |
| #include "modules/audio_coding/codecs/ilbc/get_cd_vec.h" | |
| #include "rtc_base/sanitizer.h" | |
| // An arithmetic operation that is allowed to overflow. (It's still undefined | |
| // behavior, so not a good idea; this just makes UBSan ignore the violation, so | |
| // that our old code can continue to do what it's always been doing.) | |
| static inline int32_t RTC_NO_SANITIZE("signed-integer-overflow") | |
| OverflowingAddS32S32ToS32(int32_t a, int32_t b) { | |
| return a + b; | |
| } | |
| /*----------------------------------------------------------------* | |
| * Construct decoded vector from codebook and gains. | |
| *---------------------------------------------------------------*/ | |
| bool WebRtcIlbcfix_CbConstruct( | |
| int16_t* decvector, /* (o) Decoded vector */ | |
| const int16_t* index, /* (i) Codebook indices */ | |
| const int16_t* gain_index, /* (i) Gain quantization indices */ | |
| int16_t* mem, /* (i) Buffer for codevector construction */ | |
| size_t lMem, /* (i) Length of buffer */ | |
| size_t veclen) { /* (i) Length of vector */ | |
| size_t j; | |
| int16_t gain[CB_NSTAGES]; | |
| /* Stack based */ | |
| int16_t cbvec0[SUBL]; | |
| int16_t cbvec1[SUBL]; | |
| int16_t cbvec2[SUBL]; | |
| int32_t a32; | |
| int16_t *gainPtr; | |
| /* gain de-quantization */ | |
| gain[0] = WebRtcIlbcfix_GainDequant(gain_index[0], 16384, 0); | |
| gain[1] = WebRtcIlbcfix_GainDequant(gain_index[1], gain[0], 1); | |
| gain[2] = WebRtcIlbcfix_GainDequant(gain_index[2], gain[1], 2); | |
| /* codebook vector construction and construction of total vector */ | |
| /* Stack based */ | |
| if (!WebRtcIlbcfix_GetCbVec(cbvec0, mem, (size_t)index[0], lMem, veclen)) | |
| return false; // Failure. | |
| if (!WebRtcIlbcfix_GetCbVec(cbvec1, mem, (size_t)index[1], lMem, veclen)) | |
| return false; // Failure. | |
| if (!WebRtcIlbcfix_GetCbVec(cbvec2, mem, (size_t)index[2], lMem, veclen)) | |
| return false; // Failure. | |
| gainPtr = &gain[0]; | |
| for (j=0;j<veclen;j++) { | |
| a32 = (*gainPtr++) * cbvec0[j]; | |
| a32 += (*gainPtr++) * cbvec1[j]; | |
| a32 = OverflowingAddS32S32ToS32(a32, (*gainPtr) * cbvec2[j]); | |
| gainPtr -= 2; | |
| decvector[j] = (int16_t)((a32 + 8192) >> 14); | |
| } | |
| return true; // Success. | |
| } |