Asterisk - The Open Source Telephony Project GIT-master-a358458
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#include "asterisk/translate.h"
37#include "asterisk/config.h"
38#include "asterisk/module.h"
39#include "asterisk/utils.h"
41
42#include "lpc10/lpc10.h"
43
44/* Sample frame data */
45#include "asterisk/slin.h"
46#include "ex_lpc10.h"
47
48/* We use a very strange format here... I have no idea why... The frames are 180
49 samples long, which isn't even an even number of milliseconds... Not only that
50 but we hvae to waste two bits of each frame to keep them ending on a byte boundary
51 because the frames are 54 bits long */
52
53#define LPC10_BYTES_IN_COMPRESSED_FRAME (LPC10_BITS_IN_COMPRESSED_FRAME + 7)/8
54
55#define BUFFER_SAMPLES 8000
56
58 union {
62 /* Enough to store a full second */
64 int longer;
65};
66
67static int lpc10_enc_new(struct ast_trans_pvt *pvt)
68{
69 struct lpc10_coder_pvt *tmp = pvt->pvt;
70
71 return (tmp->lpc10.enc = create_lpc10_encoder_state()) ? 0 : -1;
72}
73
74static int lpc10_dec_new(struct ast_trans_pvt *pvt)
75{
76 struct lpc10_coder_pvt *tmp = pvt->pvt;
77
78 return (tmp->lpc10.dec = create_lpc10_decoder_state()) ? 0 : -1;
79}
80
81static void extract_bits(INT32 *bits, unsigned char *c)
82{
83 int x;
84 for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
85 if (*c & (0x80 >> (x & 7)))
86 bits[x] = 1;
87 else
88 bits[x] = 0;
89 if ((x & 7) == 7)
90 c++;
91 }
92}
93
94/* XXX note lpc10_encode() produces one bit per word in bits[] */
95static void build_bits(unsigned char *c, INT32 *bits)
96{
97 unsigned char mask=0x80;
98 int x;
99 *c = 0;
100 for (x=0;x<LPC10_BITS_IN_COMPRESSED_FRAME;x++) {
101 if (bits[x])
102 *c |= mask;
103 mask = mask >> 1;
104 if ((x % 8)==7) {
105 c++;
106 *c = 0;
107 mask = 0x80;
108 }
109 }
110}
111
112static int lpc10tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
113{
114 struct lpc10_coder_pvt *tmp = pvt->pvt;
115 int16_t *dst = pvt->outbuf.i16;
116 int len = 0;
117
118 while (len + LPC10_BYTES_IN_COMPRESSED_FRAME <= f->datalen) {
119 int x;
120 float tmpbuf[LPC10_SAMPLES_PER_FRAME];
121 INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; /* XXX see note */
123 ast_log(LOG_WARNING, "Out of buffer space\n");
124 return -1;
125 }
126 extract_bits(bits, f->data.ptr + len);
127 if (lpc10_decode(bits, tmpbuf, tmp->lpc10.dec)) {
128 ast_log(LOG_WARNING, "Invalid lpc10 data\n");
129 return -1;
130 }
131 for (x=0;x<LPC10_SAMPLES_PER_FRAME;x++) {
132 /* Convert to a short between -1.0 and 1.0 */
133 dst[pvt->samples + x] = (int16_t)(32768.0 * tmpbuf[x]);
134 }
135
139 }
140 if (len != f->datalen)
141 printf("Decoded %d, expected %d\n", len, f->datalen);
142 return 0;
143}
144
145static int lintolpc10_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
146{
147 struct lpc10_coder_pvt *tmp = pvt->pvt;
148
149 /* Just add the frames to our stream */
150 if (pvt->samples + f->samples > BUFFER_SAMPLES) {
151 ast_log(LOG_WARNING, "Out of buffer space\n");
152 return -1;
153 }
154 memcpy(tmp->buf + pvt->samples, f->data.ptr, f->datalen);
155 pvt->samples += f->samples;
156 return 0;
157}
158
159static struct ast_frame *lintolpc10_frameout(struct ast_trans_pvt *pvt)
160{
161 struct lpc10_coder_pvt *tmp = pvt->pvt;
162 struct ast_frame *result = NULL;
163 struct ast_frame *last = NULL;
164 int samples = 0; /* output samples */
165
166 while (pvt->samples >= LPC10_SAMPLES_PER_FRAME) {
167 struct ast_frame *current;
168 float tmpbuf[LPC10_SAMPLES_PER_FRAME];
169 INT32 bits[LPC10_BITS_IN_COMPRESSED_FRAME]; /* XXX what ??? */
170 int x;
171
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, bits);
177
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
185 if (!current) {
186 continue;
187 } else if (last) {
189 } else {
190 result = current;
191 }
192 last = current;
193 }
194
195 /* Move the data at the end of the buffer to the front */
196 if (samples) {
197 memmove(tmp->buf, tmp->buf + samples, pvt->samples * 2);
198 }
199
200 return result;
201}
202
203
204static void lpc10_destroy(struct ast_trans_pvt *arg)
205{
206 struct lpc10_coder_pvt *pvt = arg->pvt;
207 /* Enc and DEC are both just allocated, so they can be freed */
208 ast_free(pvt->lpc10.enc);
209}
210
211static struct ast_translator lpc10tolin = {
212 .name = "lpc10tolin",
213 .src_codec = {
214 .name = "lpc10",
215 .type = AST_MEDIA_TYPE_AUDIO,
216 .sample_rate = 8000,
217 },
218 .dst_codec = {
219 .name = "slin",
220 .type = AST_MEDIA_TYPE_AUDIO,
221 .sample_rate = 8000,
222 },
223 .format = "slin",
224 .newpvt = lpc10_dec_new,
225 .framein = lpc10tolin_framein,
226 .destroy = lpc10_destroy,
227 .sample = lpc10_sample,
228 .desc_size = sizeof(struct lpc10_coder_pvt),
229 .buffer_samples = BUFFER_SAMPLES,
230 .buf_size = BUFFER_SAMPLES * 2,
231};
232
233static struct ast_translator lintolpc10 = {
234 .name = "lintolpc10",
235 .src_codec = {
236 .name = "slin",
237 .type = AST_MEDIA_TYPE_AUDIO,
238 .sample_rate = 8000,
239 },
240 .dst_codec = {
241 .name = "lpc10",
242 .type = AST_MEDIA_TYPE_AUDIO,
243 .sample_rate = 8000,
244 },
245 .format = "lpc10",
246 .newpvt = lpc10_enc_new,
247 .framein = lintolpc10_framein,
248 .frameout = lintolpc10_frameout,
249 .destroy = lpc10_destroy,
250 .sample = slin8_sample,
251 .desc_size = sizeof(struct lpc10_coder_pvt),
252 .buffer_samples = BUFFER_SAMPLES,
254};
255
256static int unload_module(void)
257{
258 int res;
259
262
263 return res;
264}
265
266static int load_module(void)
267{
268 int res;
269
272
273 if (res) {
276 }
277
279}
280
281AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "LPC10 2.4kbps Coder/Decoder",
282 .support_level = AST_MODULE_SUPPORT_CORE,
283 .load = load_module,
284 .unload = unload_module,
struct sla_ringing_trunk * last
Definition: app_sla.c:332
Asterisk main include file. File version handling, generic pbx functions.
#define ast_free(a)
Definition: astmm.h:180
#define ast_log
Definition: astobj2.c:42
static int tmp()
Definition: bt_open.c:389
static PGresult * result
Definition: cel_pgsql.c:84
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
static struct ast_frame * lintolpc10_frameout(struct ast_trans_pvt *pvt)
Definition: codec_lpc10.c:159
#define BUFFER_SAMPLES
Definition: codec_lpc10.c:55
static int lpc10_dec_new(struct ast_trans_pvt *pvt)
Definition: codec_lpc10.c:74
static void lpc10_destroy(struct ast_trans_pvt *arg)
Definition: codec_lpc10.c:204
static void build_bits(unsigned char *c, INT32 *bits)
Definition: codec_lpc10.c:95
static int lintolpc10_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
Definition: codec_lpc10.c:145
static struct ast_translator lpc10tolin
Definition: codec_lpc10.c:211
static struct ast_translator lintolpc10
Definition: codec_lpc10.c:233
static int load_module(void)
Definition: codec_lpc10.c:266
static int lpc10tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
Definition: codec_lpc10.c:112
static int lpc10_enc_new(struct ast_trans_pvt *pvt)
Definition: codec_lpc10.c:67
static int unload_module(void)
Definition: codec_lpc10.c:256
static void extract_bits(INT32 *bits, unsigned char *c)
Definition: codec_lpc10.c:81
#define LPC10_BYTES_IN_COMPRESSED_FRAME
Definition: codec_lpc10.c:53
short int16_t
Definition: db.h:59
Copyright (C) 2008, Digium, Inc.
static struct ast_frame * lpc10_sample(void)
Definition: ex_lpc10.h:14
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Configuration File Parser.
#define LOG_WARNING
A set of macros to manage forward-linked lists.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
struct lpc10_decoder_state * create_lpc10_decoder_state(void)
Definition: lpcini.c:369
int lpc10_decode(INT32 *bits, real *speech, struct lpc10_decoder_state *st)
Definition: lpcdec.c:113
#define LPC10_SAMPLES_PER_FRAME
Definition: lpc10.h:36
struct lpc10_encoder_state * create_lpc10_encoder_state(void)
Definition: lpcini.c:258
#define LPC10_BITS_IN_COMPRESSED_FRAME
Definition: lpc10.h:37
int lpc10_encode(real *speech, INT32 *bits, struct lpc10_encoder_state *st)
Definition: lpcenc.c:108
size_t current
Definition: main/cli.c:113
Asterisk module definitions.
@ AST_MODFLAG_DEFAULT
Definition: module.h:315
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition: module.h:543
@ AST_MODULE_SUPPORT_CORE
Definition: module.h:121
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
@ AST_MODULE_LOAD_SUCCESS
Definition: module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
#define NULL
Definition: resample.c:96
static struct ast_frame * slin8_sample(void)
Definition: slin.h:64
Data structure associated with a single frame of data.
union ast_frame::@226 data
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition: translate.h:213
void * pvt
Definition: translate.h:219
unsigned char * uc
Definition: translate.h:222
int datalen
actual space used in outbuf
Definition: translate.h:218
union ast_trans_pvt::@287 outbuf
int16_t * i16
Definition: translate.h:223
Descriptor of a translator.
Definition: translate.h:137
char name[80]
Definition: translate.h:138
short buf[BUFFER_SAMPLES]
Definition: codec_lpc10.c:63
struct lpc10_decoder_state * dec
Definition: codec_lpc10.c:60
union lpc10_coder_pvt::@146 lpc10
struct lpc10_encoder_state * enc
Definition: codec_lpc10.c:59
static struct test_val c
Support for translation of data formats. translate.c.
#define ast_register_translator(t)
See __ast_register_translator()
Definition: translate.h:258
int ast_unregister_translator(struct ast_translator *t)
Unregister a translator Unregisters the given translator.
Definition: translate.c:1350
struct ast_frame * ast_trans_frameout(struct ast_trans_pvt *pvt, int datalen, int samples)
generic frameout function
Definition: translate.c:439
Utility functions.