blob: 9a93d61f25cdbbec06719b4a9d38d2bb5f7c2ff8 [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
28WebRtc_Word16 WebRtcIlbcfix_EncoderAssign(iLBC_encinst_t **iLBC_encinst, WebRtc_Word16 *ILBCENC_inst_Addr, WebRtc_Word16 *size) {
29 *iLBC_encinst=(iLBC_encinst_t*)ILBCENC_inst_Addr;
30 *size=sizeof(iLBC_Enc_Inst_t)/sizeof(WebRtc_Word16);
31 if (*iLBC_encinst!=NULL) {
32 return(0);
33 } else {
34 return(-1);
35 }
36}
37
38WebRtc_Word16 WebRtcIlbcfix_DecoderAssign(iLBC_decinst_t **iLBC_decinst, WebRtc_Word16 *ILBCDEC_inst_Addr, WebRtc_Word16 *size) {
39 *iLBC_decinst=(iLBC_decinst_t*)ILBCDEC_inst_Addr;
40 *size=sizeof(iLBC_Dec_Inst_t)/sizeof(WebRtc_Word16);
41 if (*iLBC_decinst!=NULL) {
42 return(0);
43 } else {
44 return(-1);
45 }
46}
47
48WebRtc_Word16 WebRtcIlbcfix_EncoderCreate(iLBC_encinst_t **iLBC_encinst) {
49 *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
58WebRtc_Word16 WebRtcIlbcfix_DecoderCreate(iLBC_decinst_t **iLBC_decinst) {
59 *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
68WebRtc_Word16 WebRtcIlbcfix_EncoderFree(iLBC_encinst_t *iLBC_encinst) {
69 free(iLBC_encinst);
70 return(0);
71}
72
73WebRtc_Word16 WebRtcIlbcfix_DecoderFree(iLBC_decinst_t *iLBC_decinst) {
74 free(iLBC_decinst);
75 return(0);
76}
77
78
79WebRtc_Word16 WebRtcIlbcfix_EncoderInit(iLBC_encinst_t *iLBCenc_inst, WebRtc_Word16 mode)
80{
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
turaj@webrtc.org01ad7582012-07-03 21:35:46 +000089WebRtc_Word16 WebRtcIlbcfix_Encode(iLBC_encinst_t *iLBCenc_inst, const WebRtc_Word16 *speechIn, WebRtc_Word16 len, WebRtc_Word16 *encoded) {
niklase@google.com470e71d2011-07-07 08:21:25 +000090
91 WebRtc_Word16 pos = 0;
92 WebRtc_Word16 encpos = 0;
93
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) {
107 WebRtcIlbcfix_EncodeImpl((WebRtc_UWord16*) &encoded[encpos], &speechIn[pos], (iLBC_Enc_Inst_t*) iLBCenc_inst);
108#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
120WebRtc_Word16 WebRtcIlbcfix_DecoderInit(iLBC_decinst_t *iLBCdec_inst, WebRtc_Word16 mode) {
121 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}
128WebRtc_Word16 WebRtcIlbcfix_DecoderInit20Ms(iLBC_decinst_t *iLBCdec_inst) {
129 WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, 20, 1);
130 return(0);
131}
132WebRtc_Word16 WebRtcIlbcfix_Decoderinit30Ms(iLBC_decinst_t *iLBCdec_inst) {
133 WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, 30, 1);
134 return(0);
135}
136
137
138WebRtc_Word16 WebRtcIlbcfix_Decode(iLBC_decinst_t *iLBCdec_inst,
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +0000139 const WebRtc_Word16 *encoded,
niklase@google.com470e71d2011-07-07 08:21:25 +0000140 WebRtc_Word16 len,
141 WebRtc_Word16 *decoded,
142 WebRtc_Word16 *speechType)
143{
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) {
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +0000175 WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (const WebRtc_UWord16*) &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
183WebRtc_Word16 WebRtcIlbcfix_Decode20Ms(iLBC_decinst_t *iLBCdec_inst,
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +0000184 const WebRtc_Word16 *encoded,
niklase@google.com470e71d2011-07-07 08:21:25 +0000185 WebRtc_Word16 len,
186 WebRtc_Word16 *decoded,
187 WebRtc_Word16 *speechType)
188{
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) {
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +0000199 WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (const WebRtc_UWord16*) &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
207WebRtc_Word16 WebRtcIlbcfix_Decode30Ms(iLBC_decinst_t *iLBCdec_inst,
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +0000208 const WebRtc_Word16 *encoded,
niklase@google.com470e71d2011-07-07 08:21:25 +0000209 WebRtc_Word16 len,
210 WebRtc_Word16 *decoded,
211 WebRtc_Word16 *speechType)
212{
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) {
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +0000223 WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], (const WebRtc_UWord16*) &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
231WebRtc_Word16 WebRtcIlbcfix_DecodePlc(iLBC_decinst_t *iLBCdec_inst, WebRtc_Word16 *decoded, WebRtc_Word16 noOfLostFrames) {
232 int i;
233 WebRtc_UWord16 dummy;
234
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
242WebRtc_Word16 WebRtcIlbcfix_NetEqPlc(iLBC_decinst_t *iLBCdec_inst, WebRtc_Word16 *decoded, WebRtc_Word16 noOfLostFrames) {
243
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}