blob: 97b317460e6186987d58fb835d5d79b5c0f547f2 [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
kwiberg@webrtc.orgcb858ba2014-12-08 17:11:44 +000089int16_t WebRtcIlbcfix_Encode(iLBC_encinst_t* iLBCenc_inst,
90 const int16_t* speechIn,
91 int16_t len,
92 uint8_t* encoded) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +000093 int16_t pos = 0;
94 int16_t encpos = 0;
niklase@google.com470e71d2011-07-07 08:21:25 +000095
96 if ((len != ((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl) &&
97#ifdef SPLIT_10MS
98 (len != 80) &&
99#endif
100 (len != 2*((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl) &&
101 (len != 3*((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl))
102 {
103 /* A maximum of 3 frames/packet is allowed */
104 return(-1);
105 } else {
106
107 /* call encoder */
108 while (pos<len) {
kwiberg@webrtc.orgcb858ba2014-12-08 17:11:44 +0000109 WebRtcIlbcfix_EncodeImpl((uint16_t*)&encoded[2 * encpos], &speechIn[pos],
110 (iLBC_Enc_Inst_t*)iLBCenc_inst);
niklase@google.com470e71d2011-07-07 08:21:25 +0000111#ifdef SPLIT_10MS
112 pos += 80;
113 if(((iLBC_Enc_Inst_t*)iLBCenc_inst)->section == 0)
114#else
115 pos += ((iLBC_Enc_Inst_t*)iLBCenc_inst)->blockl;
116#endif
117 encpos += ((iLBC_Enc_Inst_t*)iLBCenc_inst)->no_of_words;
118 }
119 return (encpos*2);
120 }
121}
122
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000123int16_t WebRtcIlbcfix_DecoderInit(iLBC_decinst_t *iLBCdec_inst, int16_t mode) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000124 if ((mode==20)||(mode==30)) {
125 WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, mode, 1);
126 return(0);
127 } else {
128 return(-1);
129 }
130}
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000131int16_t WebRtcIlbcfix_DecoderInit20Ms(iLBC_decinst_t *iLBCdec_inst) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000132 WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, 20, 1);
133 return(0);
134}
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000135int16_t WebRtcIlbcfix_Decoderinit30Ms(iLBC_decinst_t *iLBCdec_inst) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000136 WebRtcIlbcfix_InitDecode((iLBC_Dec_Inst_t*) iLBCdec_inst, 30, 1);
137 return(0);
138}
139
140
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000141int16_t WebRtcIlbcfix_Decode(iLBC_decinst_t *iLBCdec_inst,
142 const int16_t *encoded,
143 int16_t len,
144 int16_t *decoded,
145 int16_t *speechType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000146{
147 int i=0;
148 /* Allow for automatic switching between the frame sizes
149 (although you do get some discontinuity) */
150 if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
151 (len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
152 (len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) {
153 /* ok, do nothing */
154 } else {
155 /* Test if the mode has changed */
156 if (((iLBC_Dec_Inst_t*)iLBCdec_inst)->mode==20) {
157 if ((len==NO_OF_BYTES_30MS)||
158 (len==2*NO_OF_BYTES_30MS)||
159 (len==3*NO_OF_BYTES_30MS)) {
160 WebRtcIlbcfix_InitDecode(((iLBC_Dec_Inst_t*)iLBCdec_inst), 30, ((iLBC_Dec_Inst_t*)iLBCdec_inst)->use_enhancer);
161 } else {
162 /* Unsupported frame length */
163 return(-1);
164 }
165 } else {
166 if ((len==NO_OF_BYTES_20MS)||
167 (len==2*NO_OF_BYTES_20MS)||
168 (len==3*NO_OF_BYTES_20MS)) {
169 WebRtcIlbcfix_InitDecode(((iLBC_Dec_Inst_t*)iLBCdec_inst), 20, ((iLBC_Dec_Inst_t*)iLBCdec_inst)->use_enhancer);
170 } else {
171 /* Unsupported frame length */
172 return(-1);
173 }
174 }
175 }
176
177 while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000178 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 +0000179 i++;
180 }
181 /* iLBC does not support VAD/CNG yet */
182 *speechType=1;
183 return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
184}
185
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000186int16_t WebRtcIlbcfix_Decode20Ms(iLBC_decinst_t *iLBCdec_inst,
187 const int16_t *encoded,
188 int16_t len,
189 int16_t *decoded,
190 int16_t *speechType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000191{
192 int i=0;
193 if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
194 (len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
195 (len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) {
196 /* ok, do nothing */
197 } else {
198 return(-1);
199 }
200
201 while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000202 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 +0000203 i++;
204 }
205 /* iLBC does not support VAD/CNG yet */
206 *speechType=1;
207 return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
208}
209
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000210int16_t WebRtcIlbcfix_Decode30Ms(iLBC_decinst_t *iLBCdec_inst,
211 const int16_t *encoded,
212 int16_t len,
213 int16_t *decoded,
214 int16_t *speechType)
niklase@google.com470e71d2011-07-07 08:21:25 +0000215{
216 int i=0;
217 if ((len==((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
218 (len==2*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)||
219 (len==3*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)) {
220 /* ok, do nothing */
221 } else {
222 return(-1);
223 }
224
225 while ((i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->no_of_bytes)<len) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000226 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 +0000227 i++;
228 }
229 /* iLBC does not support VAD/CNG yet */
230 *speechType=1;
231 return(i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
232}
233
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000234int16_t WebRtcIlbcfix_DecodePlc(iLBC_decinst_t *iLBCdec_inst, int16_t *decoded, int16_t noOfLostFrames) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000235 int i;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000236 uint16_t dummy;
niklase@google.com470e71d2011-07-07 08:21:25 +0000237
238 for (i=0;i<noOfLostFrames;i++) {
239 /* call decoder */
240 WebRtcIlbcfix_DecodeImpl(&decoded[i*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl], &dummy, (iLBC_Dec_Inst_t*) iLBCdec_inst, 0);
241 }
242 return (noOfLostFrames*((iLBC_Dec_Inst_t*)iLBCdec_inst)->blockl);
243}
244
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000245int16_t WebRtcIlbcfix_NetEqPlc(iLBC_decinst_t *iLBCdec_inst, int16_t *decoded, int16_t noOfLostFrames) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000246
247 /* Two input parameters not used, but needed for function pointers in NetEQ */
andrew@webrtc.org9562a362011-08-31 18:50:12 +0000248 (void)(decoded = NULL);
249 (void)(noOfLostFrames = 0);
niklase@google.com470e71d2011-07-07 08:21:25 +0000250
251 WebRtcSpl_MemSetW16(((iLBC_Dec_Inst_t*)iLBCdec_inst)->enh_buf, 0, ENH_BUFL);
252 ((iLBC_Dec_Inst_t*)iLBCdec_inst)->prev_enh_pl = 2;
253
254 return (0);
255}
256
leozwang@webrtc.org91b359e2012-02-28 17:26:14 +0000257void WebRtcIlbcfix_version(char *version)
niklase@google.com470e71d2011-07-07 08:21:25 +0000258{
tina.legrand@webrtc.orga41b4ce2011-08-29 08:19:30 +0000259 strcpy((char*)version, "1.1.1");
niklase@google.com470e71d2011-07-07 08:21:25 +0000260}