Asterisk - The Open Source Telephony Project GIT-master-27fb039
Loading...
Searching...
No Matches
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:338
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 PGresult * result
Definition cel_pgsql.c:84
size_t current
@ AST_MEDIA_TYPE_AUDIO
Definition codec.h:32
static struct ast_frame * lintolpc10_frameout(struct ast_trans_pvt *pvt)
#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)
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)
static struct ast_translator lpc10tolin
static struct ast_translator lintolpc10
static int load_module(void)
static int lpc10tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
static int lpc10_enc_new(struct ast_trans_pvt *pvt)
Definition codec_lpc10.c:67
static int unload_module(void)
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
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.
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
Asterisk module definitions.
@ AST_MODFLAG_DEFAULT
Definition module.h:329
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
Definition module.h:557
@ 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::@239 data
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Definition translate.h:213
union ast_trans_pvt::@308 outbuf
unsigned char * uc
Definition translate.h:222
int datalen
actual space used in outbuf
Definition translate.h:218
int16_t * i16
Definition translate.h:223
Descriptor of a translator.
Definition translate.h:137
char name[80]
Definition translate.h:138
union lpc10_coder_pvt::@155 lpc10
short buf[BUFFER_SAMPLES]
Definition codec_lpc10.c:63
struct lpc10_decoder_state * dec
Definition codec_lpc10.c:60
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.