Wed Jan 8 2020 09:49:46

Asterisk developer's documentation


codec_lpc10.c
Go to the documentation of this file.
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2005, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
8  * The lpc10 code is from a library used by nautilus, modified to be a bit
9  * nicer to the compiler.
10  * See http://www.arl.wustl.edu/~jaf/
11  *
12  * See http://www.asterisk.org for more information about
13  * the Asterisk project. Please do not directly contact
14  * any of the maintainers of this project for assistance;
15  * the project provides a web site, mailing lists and IRC
16  * channels for your use.
17  *
18  * This program is free software, distributed under the terms of
19  * the GNU General Public License Version 2. See the LICENSE file
20  * at the top of the source tree.
21  */
22 
23 /*! \file
24  *
25  * \brief Translate between signed linear and LPC10 (Linear Predictor Code)
26  *
27  * \ingroup codecs
28  */
29 
30 /*** MODULEINFO
31  <support_level>core</support_level>
32  ***/
33 
34 #include "asterisk.h"
35 
36 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 328209 $")
37 
38 #include "asterisk/translate.h"
39 #include "asterisk/config.h"
40 #include "asterisk/module.h"
41 #include "asterisk/utils.h"
42 
43 #include "lpc10/lpc10.h"
44 
45 /* Sample frame data */
46 #include "asterisk/slin.h"
47 #include "ex_lpc10.h"
48 
49 /* We use a very strange format here... I have no idea why... The frames are 180
50  samples long, which isn't even an even number of milliseconds... Not only that
51  but we hvae to waste two bits of each frame to keep them ending on a byte boundary
52  because the frames are 54 bits long */
53 
54 #define LPC10_BYTES_IN_COMPRESSED_FRAME (LPC10_BITS_IN_COMPRESSED_FRAME + 7)/8
55 
56 #define BUFFER_SAMPLES 8000
57 
59  union {
60  struct lpc10_encoder_state *enc;
61  struct lpc10_decoder_state *dec;
62  } lpc10;
63  /* Enough to store a full second */
65  int longer;
66 };
67 
68 static int lpc10_enc_new(struct ast_trans_pvt *pvt)
69 {
70  struct lpc10_coder_pvt *tmp = pvt->pvt;
71 
72  return (tmp->lpc10.enc = create_lpc10_encoder_state()) ? 0 : -1;
73 }
74 
75 static int lpc10_dec_new(struct ast_trans_pvt *pvt)
76 {
77  struct lpc10_coder_pvt *tmp = pvt->pvt;
78 
79  return (tmp->lpc10.dec = create_lpc10_decoder_state()) ? 0 : -1;
80 }
81 
82 static void extract_bits(INT32 *bits, unsigned char *c)
83 {
84  int x;
85  for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
86  if (*c & (0x80 >> (x & 7)))
87  bits[x] = 1;
88  else
89  bits[x] = 0;
90  if ((x & 7) == 7)
91  c++;
92  }
93 }
94 
95 /* XXX note lpc10_encode() produces one bit per word in bits[] */
96 static void build_bits(unsigned char *c, INT32 *bits)
97 {
98  unsigned char mask=0x80;
99  int x;
100  *c = 0;
101  for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
102  if (bits[x])
103  *c |= mask;
104  mask = mask >> 1;
105  if ((x % 8)==7) {
106  c++;
107  *c = 0;
108  mask = 0x80;
109  }
110  }
111 }
112 
113 static int lpc10tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
114 {
115  struct lpc10_coder_pvt *tmp = pvt->pvt;
116  int16_t *dst = pvt->outbuf.i16;
117  int len = 0;
118 
119  while (len + LPC10_BYTES_IN_COMPRESSED_FRAME <= f->datalen) {
120  int x;
121  float tmpbuf[LPC10_SAMPLES_PER_FRAME];
122  INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; /* XXX see note */
123  if (pvt->samples + LPC10_SAMPLES_PER_FRAME > BUFFER_SAMPLES) {
124  ast_log(LOG_WARNING, "Out of buffer space\n");
125  return -1;
126  }
127  extract_bits(bits, f->data.ptr + len);
128  if (lpc10_decode(bits, tmpbuf, tmp->lpc10.dec)) {
129  ast_log(LOG_WARNING, "Invalid lpc10 data\n");
130  return -1;
131  }
132  for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
133  /* Convert to a short between -1.0 and 1.0 */
134  dst[pvt->samples + x] = (int16_t)(32768.0 * tmpbuf[x]);
135  }
136 
137  pvt->samples += LPC10_SAMPLES_PER_FRAME;
138  pvt->datalen += 2*LPC10_SAMPLES_PER_FRAME;
140  }
141  if (len != f->datalen)
142  printf("Decoded %d, expected %d\n", len, f->datalen);
143  return 0;
144 }
145 
146 static int lintolpc10_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
147 {
148  struct lpc10_coder_pvt *tmp = pvt->pvt;
149 
150  /* Just add the frames to our stream */
151  if (pvt->samples + f->samples > BUFFER_SAMPLES) {
152  ast_log(LOG_WARNING, "Out of buffer space\n");
153  return -1;
154  }
155  memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
156  pvt->samples += f->samples;
157  return 0;
158 }
159 
160 static struct ast_frame *lintolpc10_frameout(struct ast_trans_pvt *pvt)
161 {
162  struct lpc10_coder_pvt *tmp = pvt->pvt;
163  int x;
164  int datalen = 0; /* output frame */
165  int samples = 0; /* output samples */
166  float tmpbuf[LPC10_SAMPLES_PER_FRAME];
167  INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; /* XXX what ??? */
168  /* We can't work on anything less than a frame in size */
169  if (pvt->samples < LPC10_SAMPLES_PER_FRAME)
170  return NULL;
171  while (pvt->samples >= LPC10_SAMPLES_PER_FRAME) {
172  /* Encode a frame of data */
173  for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++)
174  tmpbuf[x] = (float)tmp->buf[x + samples] / 32768.0;
175  lpc10_encode(tmpbuf, bits, tmp->lpc10.enc);
176  build_bits(pvt->outbuf.uc + datalen, bits);
178  samples += LPC10_SAMPLES_PER_FRAME;
179  pvt->samples -= LPC10_SAMPLES_PER_FRAME;
180  /* Use one of the two left over bits to record if this is a 22 or 23 ms frame...
181  important for IAX use */
182  tmp->longer = 1 - tmp->longer;
183  }
184  /* Move the data at the end of the buffer to the front */
185  if (pvt->samples)
186  memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
187  return ast_trans_frameout(pvt, datalen, samples);
188 }
189 
190 
191 static void lpc10_destroy(struct ast_trans_pvt *arg)
192 {
193  struct lpc10_coder_pvt *pvt = arg->pvt;
194  /* Enc and DEC are both just allocated, so they can be freed */
195  ast_free(pvt->lpc10.enc);
196 }
197 
198 static struct ast_translator lpc10tolin = {
199  .name = "lpc10tolin",
200  .srcfmt = AST_FORMAT_LPC10,
201  .dstfmt = AST_FORMAT_SLINEAR,
202  .newpvt = lpc10_dec_new,
203  .framein = lpc10tolin_framein,
204  .destroy = lpc10_destroy,
205  .sample = lpc10_sample,
206  .desc_size = sizeof(struct lpc10_coder_pvt),
207  .buffer_samples = BUFFER_SAMPLES,
208  .buf_size = BUFFER_SAMPLES * 2,
209 };
210 
211 static struct ast_translator lintolpc10 = {
212  .name = "lintolpc10",
213  .srcfmt = AST_FORMAT_SLINEAR,
214  .dstfmt = AST_FORMAT_LPC10,
215  .newpvt = lpc10_enc_new,
216  .framein = lintolpc10_framein,
217  .frameout = lintolpc10_frameout,
218  .destroy = lpc10_destroy,
219  .sample = slin8_sample,
220  .desc_size = sizeof(struct lpc10_coder_pvt),
221  .buffer_samples = BUFFER_SAMPLES,
222  .buf_size = LPC10_BYTES_IN_COMPRESSED_FRAME * (1 + BUFFER_SAMPLES / LPC10_SAMPLES_PER_FRAME),
223 };
224 
225 static int reload(void)
226 {
228 }
229 
230 
231 static int unload_module(void)
232 {
233  int res;
234 
235  res = ast_unregister_translator(&lintolpc10);
236  res |= ast_unregister_translator(&lpc10tolin);
237 
238  return res;
239 }
240 
241 static int load_module(void)
242 {
243  int res;
244 
245  res = ast_register_translator(&lpc10tolin);
246  if (!res)
247  res = ast_register_translator(&lintolpc10);
248  else
249  ast_unregister_translator(&lpc10tolin);
250  if (res)
253 }
254 
255 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "LPC10 2.4kbps Coder/Decoder",
256  .load = load_module,
257  .unload = unload_module,
258  .reload = reload,
259  );
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 LPC10_BYTES_IN_COMPRESSED_FRAME
Definition: codec_lpc10.c:54
Asterisk main include file. File version handling, generic pbx functions.
static int lpc10tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
Definition: codec_lpc10.c:113
union ast_trans_pvt::@213 outbuf
Descriptor of a translator.
Definition: translate.h:71
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
static int lpc10_enc_new(struct ast_trans_pvt *pvt)
Definition: codec_lpc10.c:68
static struct ast_translator lpc10tolin
Definition: codec_lpc10.c:198
Configuration File Parser.
unsigned char * uc
Definition: translate.h:144
const char name[80]
Definition: translate.h:72
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:374
static struct ast_frame * slin8_sample(void)
Definition: slin.h:61
static int lintolpc10_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
Definition: codec_lpc10.c:146
void * pvt
Definition: translate.h:141
#define AST_FORMAT_LPC10
Definition: frame.h:256
int16_t * i16
Definition: translate.h:145
Utility functions.
short buf[BUFFER_SAMPLES]
Definition: codec_lpc10.c:64
static struct ast_translator lintolpc10
Definition: codec_lpc10.c:211
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
struct lpc10_encoder_state * enc
Definition: codec_lpc10.c:60
static struct ast_frame * lintolpc10_frameout(struct ast_trans_pvt *pvt)
Definition: codec_lpc10.c:160
static void lpc10_destroy(struct ast_trans_pvt *arg)
Definition: codec_lpc10.c:191
static void extract_bits(INT32 *bits, unsigned char *c)
Definition: codec_lpc10.c:82
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:135
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static struct ast_frame * lpc10_sample(void)
Definition: ex_lpc10.h:14
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
union lpc10_coder_pvt::@128 lpc10
#define ast_free(a)
Definition: astmm.h:97
static int lpc10_dec_new(struct ast_trans_pvt *pvt)
Definition: codec_lpc10.c:75
static struct ast_format f[]
Definition: format_g726.c:181
Copyright (C) 2008, Digium, Inc.
static int unload_module(void)
Definition: codec_lpc10.c:231
static void build_bits(unsigned char *c, INT32 *bits)
Definition: codec_lpc10.c:96
#define BUFFER_SAMPLES
Definition: codec_lpc10.c:56
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
Data structure associated with a single frame of data.
Definition: frame.h:142
struct lpc10_decoder_state * dec
Definition: codec_lpc10.c:61
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:38
Asterisk module definitions.
union ast_frame::@172 data
static int load_module(void)
Definition: codec_lpc10.c:241
#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
static int reload(void)
Definition: codec_lpc10.c:225