blob: 21d159f587ba50d269c7226578bf9a59bc47c1e3 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
leozwang@webrtc.org91b359e2012-02-28 17:26:14 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11/******************************************************************
12
13 iLBC Speech Coder ANSI-C Source Code
14
15 iLBCInterface.c
16
17******************************************************************/
18
19#include "ilbc.h"
20#include "defines.h"
21#include "init_encode.h"
22#include "encode.h"
23#include "init_decode.h"
24#include "decode.h"
25#include <stdlib.h>
26
27
pbos@webrtc.org0946a562013-04-09 00:28:06 +000028int16_t WebRtcIlbcfix_EncoderAssign(iLBC_encinst_t **iLBC_encinst, int16_t *ILBCENC_inst_Addr, int16_t *size) {
niklase@google.com470e71d2011-07-07 08:21:25 +000029 *iLBC_encinst=(iLBC_encinst_t*)ILBCENC_inst_Addr;
pbos@webrtc.org0946a562013-04-09 00:28:06 +000030 *size=sizeof(iLBC_Enc_Inst_t)/sizeof(int16_t);
niklase@google.com470e71d2011-07-07 08:21:25 +000031 if (*iLBC_encinst!=NULL) {
32 return(0);
33 } else {
34 return(-1);
35 }
36}
37
pbos@webrtc.org0946a562013-04-09 00:28:06 +000038int16_t WebRtcIlbcfix_DecoderAssign(iLBC_decinst_t **iLBC_decinst, int16_t *ILBCDEC_inst_Addr, int16_t *size) {
niklase@google.com470e71d2011-07-07 08:21:25 +000039 *iLBC_decinst=(iLBC_decinst_t*)ILBCDEC_inst_Addr;
pbos@webrtc.org0946a562013-04-09 00:28:06 +000040 *size=sizeof(iLBC_Dec_Inst_t)/sizeof(int16_t);
niklase@google.com470e71d2011-07-07 08:21:25 +000041 if (*iLBC_decinst!=NULL) {
42 return(0);
43 } else {
44 return(-1);
45 }
46}
47
pbos@webrtc.org0946a562013-04-09 00:28:06 +000048int16_t WebRtcIlbcfix_EncoderCreate(iLBC_encinst_t **iLBC_encinst) {
niklase@google.com470e71d2011-07-07 08:21:25 +000049 *iLBC_encinst=(iLBC_encinst_t*)malloc(sizeof(iLBC_Enc_Inst_t));
50 if (*iLBC_encinst!=NULL) {
kma@webrtc.orgac4d70d2012-10-05 00:19:01 +000051 WebRtcSpl_Init();
niklase@google.com470e71d2011-07-07 08:21:25 +000052 return(0);
53 } else {
54 return(-1);
55 }
56}
57
pbos@webrtc.org0946a562013-04-09 00:28:06 +000058int16_t WebRtcIlbcfix_DecoderCreate(iLBC_decinst_t **iLBC_decinst) {
niklase@google.com470e71d2011-07-07 08:21:25 +000059 *iLBC_decinst=(iLBC_decinst_t*)malloc(sizeof(iLBC_Dec_Inst_t));
60 if (*iLBC_decinst!=NULL) {
kma@webrtc.orgac4d70d2012-10-05 00:19:01 +000061 WebRtcSpl_Init();
niklase@google.com470e71d2011-07-07 08:21:25 +000062 return(0);
63 } else {
64 return(-1);
65 }
66}
67
pbos@webrtc.org0946a562013-04-09 00:28:06 +000068int16_t WebRtcIlbcfix_EncoderFree(iLBC_encinst_t *iLBC_encinst) {
niklase@google.com470e71d2011-07-07 08:21:25 +000069 free(iLBC_encinst);
70 return(0);
71}
72
pbos@webrtc.org0946a562013-04-09 00:28:06 +000073int16_t WebRtcIlbcfix_DecoderFree(iLBC_decinst_t *iLBC_decinst) {
niklase@google.com470e71d2011-07-07 08:21:25 +000074 free(iLBC_decinst);
75 return(0);
76}
77
78
pbos@webrtc.org0946a562013-04-09 00:28:06 +000079int16_t WebRtcIlbcfix_EncoderInit(iLBC_encinst_t *iLBCenc_inst, int16_t mode)
niklase@google.com470e71d2011-07-07 08:21:25 +000080{
81 if ((mode==20)||(mode==30)) {
82 WebRtcIlbcfix_InitEncode((iLBC_Enc_Inst_t*) iLBCenc_inst, mode);
83 return(0);
84 } else {
85 return(-1);
86 }
87}
88
pbos@webrtc.org0946a562013-04-09 00:28:06 +000089int16_t WebRtcIlbcfix_Encode(iLBC_encinst_t *iLBCenc_inst, const int16_t *speechIn, int16_t len, int16_t *encoded) {
niklase@google.com470e71d2011-07-07 08:21:25 +000090
pbos@webrtc.org0946a562013-04-09 00:28:06 +000091 int16_t pos = 0;
92 int16_t encpos = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000093
94 if ((len != ((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl) &&
95#ifdef SPLIT_10MS
96 (len != 80) &&
97#endif
98 (len != 2*((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl) &&
99 (len != 3*((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl))
100 {
101 /* A maximum of 3 frames/packet is allowed */
102 return(-1);
103 } else {
104
105 /* call encoder */
106 while (pos<len) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000107 WebRtcIlbcfix_EncodeImpl((uint16_t*) &encoded[encpos], &speechIn[pos], (iLBC_Enc_Inst_t*) iLBCenc_inst);
niklase@google.com470e71d2011-07-07 08:21:25 +0000108#ifdef SPLIT_10MS
109 pos += 80;
110 if(((iLBC_Enc_Inst_t*)iLBCenc_inst)->section == 0)
111#else
112 pos += ((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl;
113#endif
114 encpos += ((iLBC_Enc_Inst_t*)iLBCenc_inst)->no_of_words;
115 }
116 return (encpos*2);
117 }
118}
119
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000120int16_t WebRtcIlbcfix_DecoderInit(iLBC_decinst_t *iLBCdec_inst, int16_t mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000121 if ((mode==20)||(mode==30)) {
122 WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, mode, 1);
123 return(0);
124 } else {
125 return(-1);
126 }
127}
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000128int16_t WebRtcIlbcfix_DecoderInit20Ms(iLBC_decinst_t *iLBCdec_inst) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000129 WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, 20, 1);
130 return(0);
131}
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000132int16_t WebRtcIlbcfix_Decoderinit30Ms(iLBC_decinst_t *iLBCdec_inst) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000133 WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, 30, 1);
134 return(0);
135}
136
137
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000138int16_t WebRtcIlbcfix_Decode(iLBC_decinst_t *iLBCdec_inst,
139 const int16_t *encoded,
140 int16_t len,
141 int16_t *decoded,
142 int16_t *speechType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000143{
144 int i=0;
145 /* Allow for automatic switching between the frame sizes
146 (although you do get some discontinuity) */
147 if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
148 (len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
149 (len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) {
150 /* ok, do nothing */
151 } else {
152 /* Test if the mode has changed */
153 if (((iLBC_Dec_Inst_t*)iLBCdec_inst)->mode==20) {
154 if ((len==NO_OF_BYTES_30MS)||
155 (len==2*NO_OF_BYTES_30MS)||
156 (len==3*NO_OF_BYTES_30MS)) {
157 WebRtcIlbcfix_InitDecode(((iLBC_Dec_Inst_t*)iLBCdec_inst), 30, ((iLBC_Dec_Inst_t*)iLBCdec_inst)->use_enhancer);
158 } else {
159 /* Unsupported frame length */
160 return(-1);
161 }
162 } else {
163 if ((len==NO_OF_BYTES_20MS)||
164 (len==2*NO_OF_BYTES_20MS)||
165 (len==3*NO_OF_BYTES_20MS)) {
166 WebRtcIlbcfix_InitDecode(((iLBC_Dec_Inst_t*)iLBCdec_inst), 20, ((iLBC_Dec_Inst_t*)iLBCdec_inst)->use_enhancer);
167 } else {
168 /* Unsupported frame length */
169 return(-1);
170 }
171 }
172 }
173
174 while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000175 WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (const uint16_t*) &encoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_words], (iLBC_Dec_Inst_t*) iLBCdec_inst, 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000176 i++;
177 }
178 /* iLBC does not support VAD/CNG yet */
179 *speechType=1;
180 return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
181}
182
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000183int16_t WebRtcIlbcfix_Decode20Ms(iLBC_decinst_t *iLBCdec_inst,
184 const int16_t *encoded,
185 int16_t len,
186 int16_t *decoded,
187 int16_t *speechType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000188{
189 int i=0;
190 if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
191 (len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
192 (len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) {
193 /* ok, do nothing */
194 } else {
195 return(-1);
196 }
197
198 while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000199 WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (const uint16_t*) &encoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_words], (iLBC_Dec_Inst_t*) iLBCdec_inst, 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000200 i++;
201 }
202 /* iLBC does not support VAD/CNG yet */
203 *speechType=1;
204 return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
205}
206
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000207int16_t WebRtcIlbcfix_Decode30Ms(iLBC_decinst_t *iLBCdec_inst,
208 const int16_t *encoded,
209 int16_t len,
210 int16_t *decoded,
211 int16_t *speechType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000212{
213 int i=0;
214 if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
215 (len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
216 (len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) {
217 /* ok, do nothing */
218 } else {
219 return(-1);
220 }
221
222 while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000223 WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (const uint16_t*) &encoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_words], (iLBC_Dec_Inst_t*) iLBCdec_inst, 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000224 i++;
225 }
226 /* iLBC does not support VAD/CNG yet */
227 *speechType=1;
228 return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
229}
230
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000231int16_t WebRtcIlbcfix_DecodePlc(iLBC_decinst_t *iLBCdec_inst, int16_t *decoded, int16_t noOfLostFrames) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000232 int i;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000233 uint16_t dummy;
niklase@google.com470e71d2011-07-07 08:21:25 +0000234
235 for (i=0;i<noOfLostFrames;i++) {
236 /* call decoder */
237 WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], &dummy, (iLBC_Dec_Inst_t*) iLBCdec_inst, 0);
238 }
239 return (noOfLostFrames*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
240}
241
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000242int16_t WebRtcIlbcfix_NetEqPlc(iLBC_decinst_t *iLBCdec_inst, int16_t *decoded, int16_t noOfLostFrames) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000243
244 /* Two input parameters not used, but needed for function pointers in NetEQ */
andrew@webrtc.org9562a362011-08-31 18:50:12 +0000245 (void)(decoded = NULL);
246 (void)(noOfLostFrames = 0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000247
248 WebRtcSpl_MemSetW16(((iLBC_Dec_Inst_t*)iLBCdec_inst)->enh_buf, 0, ENH_BUFL);
249 ((iLBC_Dec_Inst_t*)iLBCdec_inst)->prev_enh_pl = 2;
250
251 return (0);
252}
253
leozwang@webrtc.org91b359e2012-02-28 17:26:14 +0000254void WebRtcIlbcfix_version(char *version)
niklase@google.com470e71d2011-07-07 08:21:25 +0000255{
tina.legrand@webrtc.orga41b4ce2011-08-29 08:19:30 +0000256 strcpy((char*)version, "1.1.1");
niklase@google.com470e71d2011-07-07 08:21:25 +0000257}