Wed Jan 8 2020 09:49:46

Asterisk developer's documentation


codec_ilbc.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * The iLBC code is from The IETF code base and is copyright The Internet Society (2004)
5  *
6  * Copyright (C) 1999 - 2005, Digium, Inc.
7  *
8  * Mark Spencer <markster@digium.com>
9  *
10  * See http://www.asterisk.org for more information about
11  * the Asterisk project. Please do not directly contact
12  * any of the maintainers of this project for assistance;
13  * the project provides a web site, mailing lists and IRC
14  * channels for your use.
15  *
16  * This program is free software, distributed under the terms of
17  * the GNU General Public License Version 2. See the LICENSE file
18  * at the top of the source tree.
19  */
20 
21 /*! \file
22  *
23  * \brief Translate between signed linear and Internet Low Bitrate Codec
24  *
25  * \ingroup codecs
26  */
27 
28 /*** MODULEINFO
29  <support_level>core</support_level>
30  ***/
31 
32 #include "asterisk.h"
33 
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 379718 $")
35 
36 #include "asterisk/translate.h"
37 #include "asterisk/module.h"
38 #include "asterisk/utils.h"
39 
40 #include "ilbc/iLBC_encode.h"
41 #include "ilbc/iLBC_decode.h"
42 
43 #define USE_ILBC_ENHANCER 0
44 #define ILBC_MS 30
45 /* #define ILBC_MS 20 */
46 
47 #define ILBC_FRAME_LEN 50 /* apparently... */
48 #define ILBC_SAMPLES 240 /* 30ms at 8000 hz */
49 #define BUFFER_SAMPLES 8000
50 
51 /* Sample frame data */
52 #include "asterisk/slin.h"
53 #include "ex_ilbc.h"
54 
56  iLBC_Enc_Inst_t enc;
57  iLBC_Dec_Inst_t dec;
58  /* Enough to store a full second */
59  int16_t buf[BUFFER_SAMPLES];
60 };
61 
62 static int lintoilbc_new(struct ast_trans_pvt *pvt)
63 {
64  struct ilbc_coder_pvt *tmp = pvt->pvt;
65 
66  initEncode(&tmp->enc, ILBC_MS);
67 
68  return 0;
69 }
70 
71 static int ilbctolin_new(struct ast_trans_pvt *pvt)
72 {
73  struct ilbc_coder_pvt *tmp = pvt->pvt;
74 
75  initDecode(&tmp->dec, ILBC_MS, USE_ILBC_ENHANCER);
76 
77  return 0;
78 }
79 
80 /*! \brief decode a frame and store in outbuf */
81 static int ilbctolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
82 {
83  struct ilbc_coder_pvt *tmp = pvt->pvt;
84  int plc_mode = 1; /* 1 = normal data, 0 = plc */
85  /* Assuming there's space left, decode into the current buffer at
86  the tail location. Read in as many frames as there are */
87  int x,i;
88  int datalen = f->datalen;
89  int16_t *dst = pvt->outbuf.i16;
90  float tmpf[ILBC_SAMPLES];
91 
92  if (!f->data.ptr && datalen) {
93  ast_log(LOG_DEBUG, "issue 16070, ILIB ERROR. data = NULL datalen = %d src = %s\n", datalen, f->src ? f->src : "no src set");
94  f->datalen = 0;
95  datalen = 0;
96  }
97 
98  if (datalen == 0) { /* native PLC, set fake datalen and clear plc_mode */
99  datalen = ILBC_FRAME_LEN;
100  f->samples = ILBC_SAMPLES;
101  plc_mode = 0; /* do native plc */
102  pvt->samples += ILBC_SAMPLES;
103  }
104 
105  if (datalen % ILBC_FRAME_LEN) {
106  ast_log(LOG_WARNING, "Huh? An ilbc frame that isn't a multiple of 50 bytes long from %s (%d)?\n", f->src, datalen);
107  return -1;
108  }
109 
110  for (x=0; x < datalen ; x += ILBC_FRAME_LEN) {
111  if (pvt->samples + ILBC_SAMPLES > BUFFER_SAMPLES) {
112  ast_log(LOG_WARNING, "Out of buffer space\n");
113  return -1;
114  }
115  iLBC_decode(tmpf, plc_mode ? f->data.ptr + x : NULL, &tmp->dec, plc_mode);
116  for ( i=0; i < ILBC_SAMPLES; i++)
117  dst[pvt->samples + i] = tmpf[i];
118  pvt->samples += ILBC_SAMPLES;
119  pvt->datalen += 2*ILBC_SAMPLES;
120  }
121  return 0;
122 }
123 
124 /*! \brief store a frame into a temporary buffer, for later decoding */
125 static int lintoilbc_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
126 {
127  struct ilbc_coder_pvt *tmp = pvt->pvt;
128 
129  /* Just add the frames to our stream */
130  /* XXX We should look at how old the rest of our stream is, and if it
131  is too old, then we should overwrite it entirely, otherwise we can
132  get artifacts of earlier talk that do not belong */
133  memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
134  pvt->samples += f->samples;
135  return 0;
136 }
137 
138 /*! \brief encode the temporary buffer and generate a frame */
139 static struct ast_frame *lintoilbc_frameout(struct ast_trans_pvt *pvt)
140 {
141  struct ilbc_coder_pvt *tmp = pvt->pvt;
142  int datalen = 0;
143  int samples = 0;
144 
145  /* We can't work on anything less than a frame in size */
146  if (pvt->samples < ILBC_SAMPLES)
147  return NULL;
148  while (pvt->samples >= ILBC_SAMPLES) {
149  float tmpf[ILBC_SAMPLES];
150  int i;
151 
152  /* Encode a frame of data */
153  for (i = 0 ; i < ILBC_SAMPLES ; i++)
154  tmpf[i] = tmp->buf[samples + i];
155  iLBC_encode( pvt->outbuf.uc + datalen, tmpf, &tmp->enc);
156 
157  datalen += ILBC_FRAME_LEN;
158  samples += ILBC_SAMPLES;
159  pvt->samples -= ILBC_SAMPLES;
160  }
161 
162  /* Move the data at the end of the buffer to the front */
163  if (pvt->samples)
164  memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
165 
166  return ast_trans_frameout(pvt, datalen, samples);
167 }
168 
169 static struct ast_translator ilbctolin = {
170  .name = "ilbctolin",
171  .srcfmt = AST_FORMAT_ILBC,
172  .dstfmt = AST_FORMAT_SLINEAR,
173  .newpvt = ilbctolin_new,
174  .framein = ilbctolin_framein,
175  .sample = ilbc_sample,
176  .desc_size = sizeof(struct ilbc_coder_pvt),
177  .buf_size = BUFFER_SAMPLES * 2,
178  .native_plc = 1,
179 };
180 
181 static struct ast_translator lintoilbc = {
182  .name = "lintoilbc",
183  .srcfmt = AST_FORMAT_SLINEAR,
184  .dstfmt = AST_FORMAT_ILBC,
185  .newpvt = lintoilbc_new,
186  .framein = lintoilbc_framein,
187  .frameout = lintoilbc_frameout,
188  .sample = slin8_sample,
189  .desc_size = sizeof(struct ilbc_coder_pvt),
190  .buf_size = (BUFFER_SAMPLES * ILBC_FRAME_LEN + ILBC_SAMPLES - 1) / ILBC_SAMPLES,
191 };
192 
193 static int unload_module(void)
194 {
195  int res;
196 
197  res = ast_unregister_translator(&lintoilbc);
198  res |= ast_unregister_translator(&ilbctolin);
199 
200  return res;
201 }
202 
203 static int load_module(void)
204 {
205  int res;
206 
207  res = ast_register_translator(&ilbctolin);
208  if (!res)
209  res=ast_register_translator(&lintoilbc);
210  else
211  ast_unregister_translator(&ilbctolin);
212  if (res)
215 }
216 
struct ast_frame * ast_trans_frameout(struct ast_trans_pvt *pvt, int datalen, int samples)
generic frameout function
Definition: translate.c:235
int datalen
actual space used in outbuf
Definition: translate.h:140
#define AST_MODULE_INFO_STANDARD(keystr, desc)
Definition: module.h:396
static int ilbctolin_new(struct ast_trans_pvt *pvt)
Definition: codec_ilbc.c:71
Asterisk main include file. File version handling, generic pbx functions.
union ast_trans_pvt::@213 outbuf
iLBC_Enc_Inst_t enc
Definition: codec_ilbc.c:56
Descriptor of a translator.
Definition: translate.h:71
void * ptr
Definition: frame.h:160
static struct ast_translator ilbctolin
Definition: codec_ilbc.c:169
#define LOG_WARNING
Definition: logger.h:144
static struct ast_translator lintoilbc
Definition: codec_ilbc.c:181
unsigned char * uc
Definition: translate.h:144
const char name[80]
Definition: translate.h:72
static struct ast_frame * slin8_sample(void)
Definition: slin.h:61
static int load_module(void)
Definition: codec_ilbc.c:203
void * pvt
Definition: translate.h:141
#define LOG_DEBUG
Definition: logger.h:122
int16_t * i16
Definition: translate.h:145
Utility functions.
static struct ast_frame * ilbc_sample(void)
Definition: ex_ilbc.h:18
const char * src
Definition: frame.h:158
#define ILBC_SAMPLES
Definition: codec_ilbc.c:48
int datalen
Definition: frame.h:148
#define ast_register_translator(t)
See __ast_register_translator()
Definition: translate.h:170
int ast_unregister_translator(struct ast_translator *t)
Unregister a translator Unregisters the given tranlator.
Definition: translate.c:942
static int ilbctolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
decode a frame and store in outbuf
Definition: codec_ilbc.c:81
int16_t buf[BUFFER_SAMPLES]
Definition: codec_ilbc.c:59
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:135
#define ILBC_MS
Definition: codec_ilbc.c:44
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define ILBC_FRAME_LEN
Definition: codec_ilbc.c:47
iLBC_Dec_Inst_t dec
Definition: codec_ilbc.c:57
static int unload_module(void)
Definition: codec_ilbc.c:193
static struct ast_format f[]
Definition: format_g726.c:181
#define BUFFER_SAMPLES
Definition: codec_ilbc.c:49
Raw 8-bit data.
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
static struct ast_frame * lintoilbc_frameout(struct ast_trans_pvt *pvt)
encode the temporary buffer and generate a frame
Definition: codec_ilbc.c:139
#define USE_ILBC_ENHANCER
Definition: codec_ilbc.c:43
Data structure associated with a single frame of data.
Definition: frame.h:142
static int lintoilbc_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
store a frame into a temporary buffer, for later decoding
Definition: codec_ilbc.c:125
static int lintoilbc_new(struct ast_trans_pvt *pvt)
Definition: codec_ilbc.c:62
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
union ast_frame::@172 data
#define AST_FORMAT_ILBC
Definition: frame.h:262
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
Definition: asterisk.h:180
int samples
Definition: frame.h:150