Fri, 15 Oct 2010 19:06:09 +0200
Correct shared library and plugin link logic, as well as informal text.
Update file server URL, update build resource estimations, correct RPATH
logic, allow for qmake(1) static to shared library changes via CONFIG
argument, correct documentation broken title and index links, correct
shared library install path, install only one set of (correct) plugins,
install the designer shared library (as required by QtCreator), announce
features related to shared linking using qmake(1), and correclty
substitute hard coded paths in prl and la library files.
1 Index: cdr/cdr_sqlite.c
2 diff -Nau cdr/cdr_sqlite.c.orig cdr/cdr_sqlite.c
3 --- cdr/cdr_sqlite.c.orig 2007-06-14 23:50:40.000000000 +0200
4 +++ cdr/cdr_sqlite.c 2009-04-24 00:30:33.000000000 +0200
5 @@ -58,7 +58,7 @@
6 #define DATE_FORMAT "%Y-%m-%d %T"
8 static char *name = "sqlite";
9 -static sqlite* db = NULL;
10 +static sqlite3 *db = NULL;
12 AST_MUTEX_DEFINE_STATIC(sqlite_lock);
14 @@ -92,10 +92,10 @@
15 static int sqlite_log(struct ast_cdr *cdr)
16 {
17 int res = 0;
18 - char *zErr = 0;
19 struct tm tm;
20 time_t t;
21 char startstr[80], answerstr[80], endstr[80];
22 + char *cdrsql = 0;
23 int count;
25 ast_mutex_lock(&sqlite_lock);
26 @@ -113,7 +113,7 @@
27 strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm);
29 for(count=0; count<5; count++) {
30 - res = sqlite_exec_printf(db,
31 + cdrsql = sqlite3_mprintf(
32 "INSERT INTO cdr ("
33 "clid,src,dst,dcontext,"
34 "channel,dstchannel,lastapp,lastdata, "
35 @@ -138,8 +138,7 @@
36 # if LOG_USERFIELD
37 ",'%q'"
38 # endif
39 - ")", NULL, NULL, &zErr,
40 - cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
41 + ")", cdr->clid, cdr->src, cdr->dst, cdr->dcontext,
42 cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata,
43 startstr, answerstr, endstr,
44 cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags,
45 @@ -151,16 +150,13 @@
46 ,cdr->userfield
47 # endif
48 );
49 + res = sqlite3_exec(db, cdrsql, 0, 0, 0);
50 + sqlite3_free(cdrsql);
51 if (res != SQLITE_BUSY && res != SQLITE_LOCKED)
52 break;
53 usleep(200);
54 }
56 - if (zErr) {
57 - ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
58 - free(zErr);
59 - }
60 -
61 ast_mutex_unlock(&sqlite_lock);
62 return res;
63 }
64 @@ -168,7 +164,7 @@
65 static int unload_module(void)
66 {
67 if (db)
68 - sqlite_close(db);
69 + sqlite3_close(db);
70 ast_cdr_unregister(name);
71 return 0;
72 }
73 @@ -181,17 +177,16 @@
75 /* is the database there? */
76 snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR);
77 - db = sqlite_open(fn, 0660, &zErr);
78 + sqlite3_open(fn, &db);
79 if (!db) {
80 - ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr);
81 - free(zErr);
82 + ast_log(LOG_ERROR, "cdr_sqlite: %s\n", sqlite3_errmsg(db));
83 return -1;
84 }
86 /* is the table there? */
87 - res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
88 + res = sqlite3_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL);
89 if (res) {
90 - res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr);
91 + res = sqlite3_exec(db, sql_create_table, NULL, NULL, &zErr);
92 if (res) {
93 ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr);
94 free(zErr);
95 @@ -210,7 +205,7 @@
97 err:
98 if (db)
99 - sqlite_close(db);
100 + sqlite3_close(db);
101 return -1;
102 }
104 Index: channels/chan_sip.c
105 diff -Nau channels/chan_sip.c.orig channels/chan_sip.c
106 --- channels/chan_sip.c.orig 2009-04-02 19:20:22.000000000 +0200
107 +++ channels/chan_sip.c 2009-04-24 00:30:33.000000000 +0200
108 @@ -7469,7 +7469,7 @@
110 ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
111 c = get_in_brackets(from);
112 - if (strncasecmp(c, "sip:", 4)) {
113 + if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
114 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c);
115 return -1;
116 }
117 @@ -7477,7 +7477,7 @@
119 ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
120 c = get_in_brackets(to);
121 - if (strncasecmp(c, "sip:", 4)) {
122 + if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
123 ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c);
124 return -1;
125 }
126 @@ -8004,7 +8004,10 @@
127 of = get_in_brackets(from);
128 ast_string_field_set(p, from, of);
129 if (strncasecmp(of, "sip:", 4))
130 - ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
131 + if (strncasecmp(of, "sips:", 5))
132 + ast_log(LOG_NOTICE, "From address missing 'sip:' or 'sips:', using it anyway\n");
133 + else
134 + of += 5;
135 else
136 of += 4;
137 /* Get just the username part */
138 @@ -8280,7 +8283,10 @@
140 /* Make sure it's a SIP URL */
141 if (strncasecmp(contact, "sip:", 4)) {
142 - ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
143 + if (strncasecmp(contact, "sips:", 5))
144 + ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip: or sips:) trying to use anyway\n", contact);
145 + else
146 + contact += 5;
147 } else
148 contact += 4;
150 @@ -8409,7 +8415,10 @@
152 /* Make sure it's a SIP URL */
153 if (strncasecmp(curi, "sip:", 4)) {
154 - ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi);
155 + if (strncasecmp(curi, "sips:", 5))
156 + ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip: or sips:) trying to use anyway\n", curi);
157 + else
158 + curi += 5;
159 } else
160 curi += 4;
161 /* Ditch q */
162 @@ -9000,9 +9009,12 @@
164 if (!strncasecmp(c, "sip:", 4)) {
165 name = c + 4;
166 + }
167 + else if (!strncasecmp(c, "sips:", 5)) {
168 + name = c + 5;
169 } else {
170 name = c;
171 - ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
172 + ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip: or sips:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
173 }
175 /* Strip off the domain name */
176 @@ -9162,10 +9174,15 @@
177 return 0;
178 c = get_in_brackets(tmp);
179 if (strncasecmp(c, "sip:", 4)) {
180 - ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c);
181 - return -1;
182 + if (strncasecmp(c, "sips:", 5)) {
183 + ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c);
184 + return -1;
185 + }
186 + else
187 + c += 5;
188 }
189 - c += 4;
190 + else
191 + c += 4;
192 a = c;
193 strsep(&a, "@;"); /* trim anything after @ or ; */
194 if (sip_debug_test_pvt(p))
195 @@ -9200,10 +9217,15 @@
196 uri = get_in_brackets(tmp);
198 if (strncasecmp(uri, "sip:", 4)) {
199 - ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri);
200 - return -1;
201 + if (strncasecmp(uri, "sips:", 5)) {
202 + ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri);
203 + return -1;
204 + }
205 + else
206 + uri += 5;
207 }
208 - uri += 4;
209 + else
210 + uri += 4;
212 /* Now find the From: caller ID and name */
213 ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
214 @@ -9217,10 +9239,15 @@
216 if (!ast_strlen_zero(from)) {
217 if (strncasecmp(from, "sip:", 4)) {
218 - ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from);
219 - return -1;
220 + if (strncasecmp(from, "sips:", 5)) {
221 + ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from);
222 + return -1;
223 + }
224 + else
225 + from += 5;
226 }
227 - from += 4;
228 + else
229 + from += 4;
230 if ((a = strchr(from, '@')))
231 *a++ = '\0';
232 else
233 @@ -9397,10 +9424,15 @@
234 ast_uri_decode(refer_to);
236 if (strncasecmp(refer_to, "sip:", 4)) {
237 - ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to);
238 - return -3;
239 + if (strncasecmp(refer_to, "sips:", 5)) {
240 + ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to);
241 + return -3;
242 + }
243 + else
244 + refer_to += 5; /* Skip sips: */
245 }
246 - refer_to += 4; /* Skip sip: */
247 + else
248 + refer_to += 4; /* Skip sip: */
250 /* Get referred by header if it exists */
251 p_referred_by = get_header(req, "Referred-By");
252 @@ -9417,9 +9449,13 @@
253 }
255 referred_by_uri = get_in_brackets(h_referred_by);
256 - if(strncasecmp(referred_by_uri, "sip:", 4)) {
257 - ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
258 - referred_by_uri = (char *) NULL;
259 + if (strncasecmp(referred_by_uri, "sip:", 4)) {
260 + if (strncasecmp(referred_by_uri, "sips:", 5)) {
261 + ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
262 + referred_by_uri = (char *) NULL;
263 + }
264 + else
265 + referred_by_uri += 5; /* Skip sips: */
266 } else {
267 referred_by_uri += 4; /* Skip sip: */
268 }
269 @@ -9547,10 +9583,15 @@
270 ast_uri_decode(c);
272 if (strncasecmp(c, "sip:", 4)) {
273 - ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c);
274 - return -1;
275 + if (strncasecmp(c, "sips:", 5)) {
276 + ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c);
277 + return -1;
278 + }
279 + else
280 + c += 5;
281 }
282 - c += 4;
283 + else
284 + c += 4;
285 if ((a = strchr(c, ';'))) /* Remove arguments */
286 *a = '\0';
288 @@ -9761,6 +9802,8 @@
289 t = uri2;
290 if (!strncasecmp(t, "sip:", 4))
291 t+= 4;
292 + else if (!strncasecmp(t, "sips:", 5))
293 + t+= 5;
294 ast_string_field_set(p, exten, t);
295 t = strchr(p->exten, '@');
296 if (t)
297 @@ -9771,7 +9814,10 @@
298 /* save the URI part of the From header */
299 ast_string_field_set(p, from, of);
300 if (strncasecmp(of, "sip:", 4)) {
301 - ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
302 + if (strncasecmp(of, "sips:", 5))
303 + ast_log(LOG_NOTICE, "From address missing 'sip:' or 'sips:', using it anyway\n");
304 + else
305 + of += 5;
306 } else
307 of += 4;
308 /* Get just the username part */
309 @@ -12379,6 +12425,8 @@
310 if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
311 if (!strncasecmp(s, "sip:", 4))
312 s += 4;
313 + else if (!strncasecmp(s, "sips:", 5))
314 + s += 5;
315 e = strchr(s, ';');
316 if (e)
317 *e = '\0';
318 @@ -12404,6 +12452,8 @@
320 if (!strncasecmp(s, "sip:", 4))
321 s += 4;
322 + else if (!strncasecmp(s, "sips:", 5))
323 + s += 5;
324 if (option_debug > 1)
325 ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
326 if (p->owner) {
327 Index: codecs/codec_g722.c
328 diff -Nau codecs/codec_g722.c.orig codecs/codec_g722.c
329 --- codecs/codec_g722.c.orig 1970-01-01 01:00:00.000000000 +0100
330 +++ codecs/codec_g722.c 2009-04-24 00:30:33.000000000 +0200
331 @@ -0,0 +1,306 @@
332 +/*
333 + * Asterisk -- An open source telephony toolkit.
334 + *
335 + * Copyright (C) 1999 - 2008, Digium, Inc.
336 + *
337 + * Matthew Fredrickson <creslin@digium.com>
338 + * Russell Bryant <russell@digium.com>
339 + *
340 + * Special thanks to Steve Underwood for the implementation
341 + * and for doing the 8khz<->g.722 direct translation code.
342 + *
343 + * See http://www.asterisk.org for more information about
344 + * the Asterisk project. Please do not directly contact
345 + * any of the maintainers of this project for assistance;
346 + * the project provides a web site, mailing lists and IRC
347 + * channels for your use.
348 + *
349 + * This program is free software, distributed under the terms of
350 + * the GNU General Public License Version 2. See the LICENSE file
351 + * at the top of the source tree.
352 + */
353 +
354 +/*! \file
355 + *
356 + * \brief codec_g722.c - translate between signed linear and ITU G.722-64kbps
357 + *
358 + * \author Matthew Fredrickson <creslin@digium.com>
359 + * \author Russell Bryant <russell@digium.com>
360 + *
361 + * \arg http://soft-switch.org/downloads/non-gpl-bits.tgz
362 + * \arg http://lists.digium.com/pipermail/asterisk-dev/2006-September/022866.html
363 + *
364 + * \ingroup codecs
365 + */
366 +
367 +#include "asterisk.h"
368 +
369 +ASTERISK_FILE_VERSION(__FILE__, "$Revision: 106501 $")
370 +
371 +#include "asterisk/linkedlists.h"
372 +#include "asterisk/module.h"
373 +#include "asterisk/config.h"
374 +#include "asterisk/options.h"
375 +#include "asterisk/translate.h"
376 +#include "asterisk/utils.h"
377 +
378 +#define BUFFER_SAMPLES 8096 /* size for the translation buffers */
379 +#define BUF_SHIFT 5
380 +
381 +/* Sample frame data */
382 +
383 +#include "g722/g722.h"
384 +#include "slin_g722_ex.h"
385 +#include "g722_slin_ex.h"
386 +
387 +struct g722_encoder_pvt {
388 + g722_encode_state_t g722;
389 +};
390 +
391 +struct g722_decoder_pvt {
392 + g722_decode_state_t g722;
393 +};
394 +
395 +/*! \brief init a new instance of g722_encoder_pvt. */
396 +static int lintog722_new(struct ast_trans_pvt *pvt)
397 +{
398 + struct g722_encoder_pvt *tmp = pvt->pvt;
399 +
400 + g722_encode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
401 +
402 + return 0;
403 +}
404 +
405 +static int lin16tog722_new(struct ast_trans_pvt *pvt)
406 +{
407 + struct g722_encoder_pvt *tmp = pvt->pvt;
408 +
409 + g722_encode_init(&tmp->g722, 64000, 0);
410 +
411 + return 0;
412 +}
413 +
414 +/*! \brief init a new instance of g722_encoder_pvt. */
415 +static int g722tolin_new(struct ast_trans_pvt *pvt)
416 +{
417 + struct g722_decoder_pvt *tmp = pvt->pvt;
418 +
419 + g722_decode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000);
420 +
421 + return 0;
422 +}
423 +
424 +static int g722tolin16_new(struct ast_trans_pvt *pvt)
425 +{
426 + struct g722_decoder_pvt *tmp = pvt->pvt;
427 +
428 + g722_decode_init(&tmp->g722, 64000, 0);
429 +
430 + return 0;
431 +}
432 +
433 +static int g722tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
434 +{
435 + struct g722_decoder_pvt *tmp = pvt->pvt;
436 + int out_samples;
437 + int in_samples;
438 +
439 + /* g722_decode expects the samples to be in the invalid samples / 2 format */
440 + in_samples = f->samples / 2;
441 +
442 + out_samples = g722_decode(&tmp->g722, (int16_t *) &pvt->outbuf[pvt->samples * sizeof(int16_t)],
443 + (uint8_t *) f->data, in_samples);
444 +
445 + pvt->samples += out_samples;
446 +
447 + pvt->datalen += (out_samples * sizeof(int16_t));
448 +
449 + return 0;
450 +}
451 +
452 +static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
453 +{
454 + struct g722_encoder_pvt *tmp = pvt->pvt;
455 + int outlen;
456 +
457 + outlen = g722_encode(&tmp->g722, (uint8_t *) (&pvt->outbuf[pvt->datalen]),
458 + (int16_t *) f->data, f->samples);
459 +
460 + pvt->samples += outlen * 2;
461 +
462 + pvt->datalen += outlen;
463 +
464 + return 0;
465 +}
466 +
467 +static struct ast_frame *g722tolin_sample(void)
468 +{
469 + static struct ast_frame f = {
470 + .frametype = AST_FRAME_VOICE,
471 + .subclass = AST_FORMAT_G722,
472 + .datalen = sizeof(g722_slin_ex),
473 + .samples = sizeof(g722_slin_ex) * 2,
474 + .src = __PRETTY_FUNCTION__,
475 + .data = g722_slin_ex,
476 + };
477 +
478 + return &f;
479 +}
480 +
481 +static struct ast_frame *g722tolin16_sample(void)
482 +{
483 + static struct ast_frame f = {
484 + .frametype = AST_FRAME_VOICE,
485 + .subclass = AST_FORMAT_G722,
486 + .datalen = sizeof(slin_g722_ex),
487 + .samples = sizeof(slin_g722_ex) * 2,
488 + .src = __PRETTY_FUNCTION__,
489 + .data = slin_g722_ex,
490 + };
491 +
492 + return &f;
493 +}
494 +
495 +static struct ast_frame *lintog722_sample (void)
496 +{
497 + static struct ast_frame f = {
498 + .frametype = AST_FRAME_VOICE,
499 + .subclass = AST_FORMAT_SLINEAR,
500 + .datalen = sizeof(slin_g722_ex),
501 + .samples = sizeof(slin_g722_ex) / sizeof(slin_g722_ex[0]),
502 + .src = __PRETTY_FUNCTION__,
503 + .data = slin_g722_ex,
504 + };
505 +
506 + return &f;
507 +}
508 +
509 +static struct ast_frame *lin16tog722_sample (void)
510 +{
511 + static struct ast_frame f = {
512 + .frametype = AST_FRAME_VOICE,
513 + .subclass = AST_FORMAT_SLINEAR16,
514 + .datalen = sizeof(slin_g722_ex),
515 + .samples = sizeof(slin_g722_ex) / sizeof(slin_g722_ex[0]),
516 + .src = __PRETTY_FUNCTION__,
517 + .data = slin_g722_ex,
518 + };
519 +
520 + return &f;
521 +}
522 +
523 +static struct ast_translator g722tolin = {
524 + .name = "g722tolin",
525 + .srcfmt = AST_FORMAT_G722,
526 + .dstfmt = AST_FORMAT_SLINEAR,
527 + .newpvt = g722tolin_new, /* same for both directions */
528 + .framein = g722tolin_framein,
529 + .sample = g722tolin_sample,
530 + .desc_size = sizeof(struct g722_decoder_pvt),
531 + .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
532 + .buf_size = BUFFER_SAMPLES,
533 + .plc_samples = 160,
534 +};
535 +
536 +static struct ast_translator lintog722 = {
537 + .name = "lintog722",
538 + .srcfmt = AST_FORMAT_SLINEAR,
539 + .dstfmt = AST_FORMAT_G722,
540 + .newpvt = lintog722_new, /* same for both directions */
541 + .framein = lintog722_framein,
542 + .sample = lintog722_sample,
543 + .desc_size = sizeof(struct g722_encoder_pvt),
544 + .buffer_samples = BUFFER_SAMPLES * 2,
545 + .buf_size = BUFFER_SAMPLES,
546 +};
547 +
548 +static struct ast_translator g722tolin16 = {
549 + .name = "g722tolin16",
550 + .srcfmt = AST_FORMAT_G722,
551 + .dstfmt = AST_FORMAT_SLINEAR16,
552 + .newpvt = g722tolin16_new, /* same for both directions */
553 + .framein = g722tolin_framein,
554 + .sample = g722tolin16_sample,
555 + .desc_size = sizeof(struct g722_decoder_pvt),
556 + .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t),
557 + .buf_size = BUFFER_SAMPLES,
558 + .plc_samples = 160,
559 +};
560 +
561 +static struct ast_translator lin16tog722 = {
562 + .name = "lin16tog722",
563 + .srcfmt = AST_FORMAT_SLINEAR16,
564 + .dstfmt = AST_FORMAT_G722,
565 + .newpvt = lin16tog722_new, /* same for both directions */
566 + .framein = lintog722_framein,
567 + .sample = lin16tog722_sample,
568 + .desc_size = sizeof(struct g722_encoder_pvt),
569 + .buffer_samples = BUFFER_SAMPLES * 2,
570 + .buf_size = BUFFER_SAMPLES,
571 +};
572 +
573 +static int parse_config(int reload)
574 +{
575 + struct ast_variable *var;
576 + struct ast_config *cfg = ast_config_load("codecs.conf");
577 +
578 + if (cfg == NULL)
579 + return 0;
580 + if (cfg == CONFIG_STATUS_FILEUNCHANGED)
581 + return 0;
582 + for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
583 + if (!strcasecmp(var->name, "genericplc")) {
584 + g722tolin.useplc = ast_true(var->value) ? 1 : 0;
585 + if (option_verbose > 2)
586 + ast_verbose(VERBOSE_PREFIX_3 "codec_g722: %susing generic PLC\n",
587 + g722tolin.useplc ? "" : "not ");
588 + }
589 + }
590 + ast_config_destroy(cfg);
591 + return 0;
592 +}
593 +
594 +static int reload(void)
595 +{
596 + if (parse_config(1))
597 + return AST_MODULE_LOAD_DECLINE;
598 + return AST_MODULE_LOAD_SUCCESS;
599 +}
600 +
601 +static int unload_module(void)
602 +{
603 + int res = 0;
604 +
605 + res |= ast_unregister_translator(&g722tolin);
606 + res |= ast_unregister_translator(&lintog722);
607 + res |= ast_unregister_translator(&g722tolin16);
608 + res |= ast_unregister_translator(&lin16tog722);
609 +
610 + return res;
611 +}
612 +
613 +static int load_module(void)
614 +{
615 + int res = 0;
616 +
617 + if (parse_config(0))
618 + return AST_MODULE_LOAD_DECLINE;
619 +
620 + res |= ast_register_translator(&g722tolin);
621 + res |= ast_register_translator(&lintog722);
622 + res |= ast_register_translator(&g722tolin16);
623 + res |= ast_register_translator(&lin16tog722);
624 +
625 + if (res) {
626 + unload_module();
627 + return AST_MODULE_LOAD_FAILURE;
628 + }
629 +
630 + return AST_MODULE_LOAD_SUCCESS;
631 +}
632 +
633 +AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ITU G.722-64kbps G722 Transcoder",
634 + .load = load_module,
635 + .unload = unload_module,
636 + .reload = reload,
637 + );
638 Index: codecs/g722/g722_decode.c
639 diff -Nau codecs/g722/g722_decode.c.orig codecs/g722/g722_decode.c
640 --- codecs/g722/g722_decode.c.orig 1970-01-01 01:00:00.000000000 +0100
641 +++ codecs/g722/g722_decode.c 2009-04-24 00:30:33.000000000 +0200
642 @@ -0,0 +1,398 @@
643 +/*
644 + * SpanDSP - a series of DSP components for telephony
645 + *
646 + * g722_decode.c - The ITU G.722 codec, decode part.
647 + *
648 + * Written by Steve Underwood <steveu@coppice.org>
649 + *
650 + * Copyright (C) 2005 Steve Underwood
651 + *
652 + * Despite my general liking of the GPL, I place my own contributions
653 + * to this code in the public domain for the benefit of all mankind -
654 + * even the slimy ones who might try to proprietize my work and use it
655 + * to my detriment.
656 + *
657 + * Based in part on a single channel G.722 codec which is:
658 + *
659 + * Copyright (c) CMU 1993
660 + * Computer Science, Speech Group
661 + * Chengxiang Lu and Alex Hauptmann
662 + *
663 + * $Id: g722_decode.c 48661 2006-12-21 00:08:21Z mattf $
664 + */
665 +
666 +/*! \file */
667 +
668 +#ifdef HAVE_CONFIG_H
669 +#include <config.h>
670 +#endif
671 +
672 +#include <stdio.h>
673 +#include <inttypes.h>
674 +#include <memory.h>
675 +#include <stdlib.h>
676 +#if 0
677 +#include <tgmath.h>
678 +#endif
679 +
680 +#include "g722.h"
681 +
682 +#if !defined(FALSE)
683 +#define FALSE 0
684 +#endif
685 +#if !defined(TRUE)
686 +#define TRUE (!FALSE)
687 +#endif
688 +
689 +static __inline__ int16_t saturate(int32_t amp)
690 +{
691 + int16_t amp16;
692 +
693 + /* Hopefully this is optimised for the common case - not clipping */
694 + amp16 = (int16_t) amp;
695 + if (amp == amp16)
696 + return amp16;
697 + if (amp > INT16_MAX)
698 + return INT16_MAX;
699 + return INT16_MIN;
700 +}
701 +/*- End of function --------------------------------------------------------*/
702 +
703 +static void block4(g722_decode_state_t *s, int band, int d);
704 +
705 +static void block4(g722_decode_state_t *s, int band, int d)
706 +{
707 + int wd1;
708 + int wd2;
709 + int wd3;
710 + int i;
711 +
712 + /* Block 4, RECONS */
713 + s->band[band].d[0] = d;
714 + s->band[band].r[0] = saturate(s->band[band].s + d);
715 +
716 + /* Block 4, PARREC */
717 + s->band[band].p[0] = saturate(s->band[band].sz + d);
718 +
719 + /* Block 4, UPPOL2 */
720 + for (i = 0; i < 3; i++)
721 + s->band[band].sg[i] = s->band[band].p[i] >> 15;
722 + wd1 = saturate(s->band[band].a[1] << 2);
723 +
724 + wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
725 + if (wd2 > 32767)
726 + wd2 = 32767;
727 + wd3 = (s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128;
728 + wd3 += (wd2 >> 7);
729 + wd3 += (s->band[band].a[2]*32512) >> 15;
730 + if (wd3 > 12288)
731 + wd3 = 12288;
732 + else if (wd3 < -12288)
733 + wd3 = -12288;
734 + s->band[band].ap[2] = wd3;
735 +
736 + /* Block 4, UPPOL1 */
737 + s->band[band].sg[0] = s->band[band].p[0] >> 15;
738 + s->band[band].sg[1] = s->band[band].p[1] >> 15;
739 + wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
740 + wd2 = (s->band[band].a[1]*32640) >> 15;
741 +
742 + s->band[band].ap[1] = saturate(wd1 + wd2);
743 + wd3 = saturate(15360 - s->band[band].ap[2]);
744 + if (s->band[band].ap[1] > wd3)
745 + s->band[band].ap[1] = wd3;
746 + else if (s->band[band].ap[1] < -wd3)
747 + s->band[band].ap[1] = -wd3;
748 +
749 + /* Block 4, UPZERO */
750 + wd1 = (d == 0) ? 0 : 128;
751 + s->band[band].sg[0] = d >> 15;
752 + for (i = 1; i < 7; i++)
753 + {
754 + s->band[band].sg[i] = s->band[band].d[i] >> 15;
755 + wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
756 + wd3 = (s->band[band].b[i]*32640) >> 15;
757 + s->band[band].bp[i] = saturate(wd2 + wd3);
758 + }
759 +
760 + /* Block 4, DELAYA */
761 + for (i = 6; i > 0; i--)
762 + {
763 + s->band[band].d[i] = s->band[band].d[i - 1];
764 + s->band[band].b[i] = s->band[band].bp[i];
765 + }
766 +
767 + for (i = 2; i > 0; i--)
768 + {
769 + s->band[band].r[i] = s->band[band].r[i - 1];
770 + s->band[band].p[i] = s->band[band].p[i - 1];
771 + s->band[band].a[i] = s->band[band].ap[i];
772 + }
773 +
774 + /* Block 4, FILTEP */
775 + wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
776 + wd1 = (s->band[band].a[1]*wd1) >> 15;
777 + wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
778 + wd2 = (s->band[band].a[2]*wd2) >> 15;
779 + s->band[band].sp = saturate(wd1 + wd2);
780 +
781 + /* Block 4, FILTEZ */
782 + s->band[band].sz = 0;
783 + for (i = 6; i > 0; i--)
784 + {
785 + wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
786 + s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
787 + }
788 + s->band[band].sz = saturate(s->band[band].sz);
789 +
790 + /* Block 4, PREDIC */
791 + s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
792 +}
793 +/*- End of function --------------------------------------------------------*/
794 +
795 +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options)
796 +{
797 + if (s == NULL)
798 + {
799 + if ((s = (g722_decode_state_t *) malloc(sizeof(*s))) == NULL)
800 + return NULL;
801 + }
802 + memset(s, 0, sizeof(*s));
803 + if (rate == 48000)
804 + s->bits_per_sample = 6;
805 + else if (rate == 56000)
806 + s->bits_per_sample = 7;
807 + else
808 + s->bits_per_sample = 8;
809 + if ((options & G722_SAMPLE_RATE_8000))
810 + s->eight_k = TRUE;
811 + if ((options & G722_PACKED) && s->bits_per_sample != 8)
812 + s->packed = TRUE;
813 + else
814 + s->packed = FALSE;
815 + s->band[0].det = 32;
816 + s->band[1].det = 8;
817 + return s;
818 +}
819 +/*- End of function --------------------------------------------------------*/
820 +
821 +int g722_decode_release(g722_decode_state_t *s)
822 +{
823 + free(s);
824 + return 0;
825 +}
826 +/*- End of function --------------------------------------------------------*/
827 +
828 +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len)
829 +{
830 + static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };
831 + static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 };
832 + static const int ilb[32] =
833 + {
834 + 2048, 2093, 2139, 2186, 2233, 2282, 2332,
835 + 2383, 2435, 2489, 2543, 2599, 2656, 2714,
836 + 2774, 2834, 2896, 2960, 3025, 3091, 3158,
837 + 3228, 3298, 3371, 3444, 3520, 3597, 3676,
838 + 3756, 3838, 3922, 4008
839 + };
840 + static const int wh[3] = {0, -214, 798};
841 + static const int rh2[4] = {2, 1, 2, 1};
842 + static const int qm2[4] = {-7408, -1616, 7408, 1616};
843 + static const int qm4[16] =
844 + {
845 + 0, -20456, -12896, -8968,
846 + -6288, -4240, -2584, -1200,
847 + 20456, 12896, 8968, 6288,
848 + 4240, 2584, 1200, 0
849 + };
850 + static const int qm5[32] =
851 + {
852 + -280, -280, -23352, -17560,
853 + -14120, -11664, -9752, -8184,
854 + -6864, -5712, -4696, -3784,
855 + -2960, -2208, -1520, -880,
856 + 23352, 17560, 14120, 11664,
857 + 9752, 8184, 6864, 5712,
858 + 4696, 3784, 2960, 2208,
859 + 1520, 880, 280, -280
860 + };
861 + static const int qm6[64] =
862 + {
863 + -136, -136, -136, -136,
864 + -24808, -21904, -19008, -16704,
865 + -14984, -13512, -12280, -11192,
866 + -10232, -9360, -8576, -7856,
867 + -7192, -6576, -6000, -5456,
868 + -4944, -4464, -4008, -3576,
869 + -3168, -2776, -2400, -2032,
870 + -1688, -1360, -1040, -728,
871 + 24808, 21904, 19008, 16704,
872 + 14984, 13512, 12280, 11192,
873 + 10232, 9360, 8576, 7856,
874 + 7192, 6576, 6000, 5456,
875 + 4944, 4464, 4008, 3576,
876 + 3168, 2776, 2400, 2032,
877 + 1688, 1360, 1040, 728,
878 + 432, 136, -432, -136
879 + };
880 + static const int qmf_coeffs[12] =
881 + {
882 + 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
883 + };
884 +
885 + int dlowt;
886 + int rlow;
887 + int ihigh;
888 + int dhigh;
889 + int rhigh;
890 + int xout1;
891 + int xout2;
892 + int wd1;
893 + int wd2;
894 + int wd3;
895 + int code;
896 + int outlen;
897 + int i;
898 + int j;
899 +
900 + outlen = 0;
901 + rhigh = 0;
902 + for (j = 0; j < len; )
903 + {
904 + if (s->packed)
905 + {
906 + /* Unpack the code bits */
907 + if (s->in_bits < s->bits_per_sample)
908 + {
909 + s->in_buffer |= (g722_data[j++] << s->in_bits);
910 + s->in_bits += 8;
911 + }
912 + code = s->in_buffer & ((1 << s->bits_per_sample) - 1);
913 + s->in_buffer >>= s->bits_per_sample;
914 + s->in_bits -= s->bits_per_sample;
915 + }
916 + else
917 + {
918 + code = g722_data[j++];
919 + }
920 +
921 + switch (s->bits_per_sample)
922 + {
923 + default:
924 + case 8:
925 + wd1 = code & 0x3F;
926 + ihigh = (code >> 6) & 0x03;
927 + wd2 = qm6[wd1];
928 + wd1 >>= 2;
929 + break;
930 + case 7:
931 + wd1 = code & 0x1F;
932 + ihigh = (code >> 5) & 0x03;
933 + wd2 = qm5[wd1];
934 + wd1 >>= 1;
935 + break;
936 + case 6:
937 + wd1 = code & 0x0F;
938 + ihigh = (code >> 4) & 0x03;
939 + wd2 = qm4[wd1];
940 + break;
941 + }
942 + /* Block 5L, LOW BAND INVQBL */
943 + wd2 = (s->band[0].det*wd2) >> 15;
944 + /* Block 5L, RECONS */
945 + rlow = s->band[0].s + wd2;
946 + /* Block 6L, LIMIT */
947 + if (rlow > 16383)
948 + rlow = 16383;
949 + else if (rlow < -16384)
950 + rlow = -16384;
951 +
952 + /* Block 2L, INVQAL */
953 + wd2 = qm4[wd1];
954 + dlowt = (s->band[0].det*wd2) >> 15;
955 +
956 + /* Block 3L, LOGSCL */
957 + wd2 = rl42[wd1];
958 + wd1 = (s->band[0].nb*127) >> 7;
959 + wd1 += wl[wd2];
960 + if (wd1 < 0)
961 + wd1 = 0;
962 + else if (wd1 > 18432)
963 + wd1 = 18432;
964 + s->band[0].nb = wd1;
965 +
966 + /* Block 3L, SCALEL */
967 + wd1 = (s->band[0].nb >> 6) & 31;
968 + wd2 = 8 - (s->band[0].nb >> 11);
969 + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
970 + s->band[0].det = wd3 << 2;
971 +
972 + block4(s, 0, dlowt);
973 +
974 + if (!s->eight_k)
975 + {
976 + /* Block 2H, INVQAH */
977 + wd2 = qm2[ihigh];
978 + dhigh = (s->band[1].det*wd2) >> 15;
979 + /* Block 5H, RECONS */
980 + rhigh = dhigh + s->band[1].s;
981 + /* Block 6H, LIMIT */
982 + if (rhigh > 16383)
983 + rhigh = 16383;
984 + else if (rhigh < -16384)
985 + rhigh = -16384;
986 +
987 + /* Block 2H, INVQAH */
988 + wd2 = rh2[ihigh];
989 + wd1 = (s->band[1].nb*127) >> 7;
990 + wd1 += wh[wd2];
991 + if (wd1 < 0)
992 + wd1 = 0;
993 + else if (wd1 > 22528)
994 + wd1 = 22528;
995 + s->band[1].nb = wd1;
996 +
997 + /* Block 3H, SCALEH */
998 + wd1 = (s->band[1].nb >> 6) & 31;
999 + wd2 = 10 - (s->band[1].nb >> 11);
1000 + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
1001 + s->band[1].det = wd3 << 2;
1002 +
1003 + block4(s, 1, dhigh);
1004 + }
1005 +
1006 + if (s->itu_test_mode)
1007 + {
1008 + amp[outlen++] = (int16_t) (rlow << 1);
1009 + amp[outlen++] = (int16_t) (rhigh << 1);
1010 + }
1011 + else
1012 + {
1013 + if (s->eight_k)
1014 + {
1015 + amp[outlen++] = (int16_t) rlow;
1016 + }
1017 + else
1018 + {
1019 + /* Apply the receive QMF */
1020 + for (i = 0; i < 22; i++)
1021 + s->x[i] = s->x[i + 2];
1022 + s->x[22] = rlow + rhigh;
1023 + s->x[23] = rlow - rhigh;
1024 +
1025 + xout1 = 0;
1026 + xout2 = 0;
1027 + for (i = 0; i < 12; i++)
1028 + {
1029 + xout2 += s->x[2*i]*qmf_coeffs[i];
1030 + xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
1031 + }
1032 + amp[outlen++] = (int16_t) (xout1 >> 12);
1033 + amp[outlen++] = (int16_t) (xout2 >> 12);
1034 + }
1035 + }
1036 + }
1037 + return outlen;
1038 +}
1039 +/*- End of function --------------------------------------------------------*/
1040 +/*- End of file ------------------------------------------------------------*/
1041 Index: codecs/g722/g722_encode.c
1042 diff -Nau codecs/g722/g722_encode.c.orig codecs/g722/g722_encode.c
1043 --- codecs/g722/g722_encode.c.orig 1970-01-01 01:00:00.000000000 +0100
1044 +++ codecs/g722/g722_encode.c 2009-04-24 00:30:33.000000000 +0200
1045 @@ -0,0 +1,400 @@
1046 +/*
1047 + * SpanDSP - a series of DSP components for telephony
1048 + *
1049 + * g722_encode.c - The ITU G.722 codec, encode part.
1050 + *
1051 + * Written by Steve Underwood <steveu@coppice.org>
1052 + *
1053 + * Copyright (C) 2005 Steve Underwood
1054 + *
1055 + * All rights reserved.
1056 + *
1057 + * Despite my general liking of the GPL, I place my own contributions
1058 + * to this code in the public domain for the benefit of all mankind -
1059 + * even the slimy ones who might try to proprietize my work and use it
1060 + * to my detriment.
1061 + *
1062 + * Based on a single channel 64kbps only G.722 codec which is:
1063 + *
1064 + ***** Copyright (c) CMU 1993 *****
1065 + * Computer Science, Speech Group
1066 + * Chengxiang Lu and Alex Hauptmann
1067 + *
1068 + * $Id: g722_encode.c 48661 2006-12-21 00:08:21Z mattf $
1069 + */
1070 +
1071 +/*! \file */
1072 +
1073 +#ifdef HAVE_CONFIG_H
1074 +#include <config.h>
1075 +#endif
1076 +
1077 +#include <stdio.h>
1078 +#include <inttypes.h>
1079 +#include <memory.h>
1080 +#include <stdlib.h>
1081 +#if 0
1082 +#include <tgmath.h>
1083 +#endif
1084 +
1085 +#include "g722.h"
1086 +
1087 +#if !defined(FALSE)
1088 +#define FALSE 0
1089 +#endif
1090 +#if !defined(TRUE)
1091 +#define TRUE (!FALSE)
1092 +#endif
1093 +
1094 +static __inline__ int16_t saturate(int32_t amp)
1095 +{
1096 + int16_t amp16;
1097 +
1098 + /* Hopefully this is optimised for the common case - not clipping */
1099 + amp16 = (int16_t) amp;
1100 + if (amp == amp16)
1101 + return amp16;
1102 + if (amp > INT16_MAX)
1103 + return INT16_MAX;
1104 + return INT16_MIN;
1105 +}
1106 +/*- End of function --------------------------------------------------------*/
1107 +
1108 +static void block4(g722_encode_state_t *s, int band, int d)
1109 +{
1110 + int wd1;
1111 + int wd2;
1112 + int wd3;
1113 + int i;
1114 +
1115 + /* Block 4, RECONS */
1116 + s->band[band].d[0] = d;
1117 + s->band[band].r[0] = saturate(s->band[band].s + d);
1118 +
1119 + /* Block 4, PARREC */
1120 + s->band[band].p[0] = saturate(s->band[band].sz + d);
1121 +
1122 + /* Block 4, UPPOL2 */
1123 + for (i = 0; i < 3; i++)
1124 + s->band[band].sg[i] = s->band[band].p[i] >> 15;
1125 + wd1 = saturate(s->band[band].a[1] << 2);
1126 +
1127 + wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
1128 + if (wd2 > 32767)
1129 + wd2 = 32767;
1130 + wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128);
1131 + wd3 += (s->band[band].a[2]*32512) >> 15;
1132 + if (wd3 > 12288)
1133 + wd3 = 12288;
1134 + else if (wd3 < -12288)
1135 + wd3 = -12288;
1136 + s->band[band].ap[2] = wd3;
1137 +
1138 + /* Block 4, UPPOL1 */
1139 + s->band[band].sg[0] = s->band[band].p[0] >> 15;
1140 + s->band[band].sg[1] = s->band[band].p[1] >> 15;
1141 + wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
1142 + wd2 = (s->band[band].a[1]*32640) >> 15;
1143 +
1144 + s->band[band].ap[1] = saturate(wd1 + wd2);
1145 + wd3 = saturate(15360 - s->band[band].ap[2]);
1146 + if (s->band[band].ap[1] > wd3)
1147 + s->band[band].ap[1] = wd3;
1148 + else if (s->band[band].ap[1] < -wd3)
1149 + s->band[band].ap[1] = -wd3;
1150 +
1151 + /* Block 4, UPZERO */
1152 + wd1 = (d == 0) ? 0 : 128;
1153 + s->band[band].sg[0] = d >> 15;
1154 + for (i = 1; i < 7; i++)
1155 + {
1156 + s->band[band].sg[i] = s->band[band].d[i] >> 15;
1157 + wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
1158 + wd3 = (s->band[band].b[i]*32640) >> 15;
1159 + s->band[band].bp[i] = saturate(wd2 + wd3);
1160 + }
1161 +
1162 + /* Block 4, DELAYA */
1163 + for (i = 6; i > 0; i--)
1164 + {
1165 + s->band[band].d[i] = s->band[band].d[i - 1];
1166 + s->band[band].b[i] = s->band[band].bp[i];
1167 + }
1168 +
1169 + for (i = 2; i > 0; i--)
1170 + {
1171 + s->band[band].r[i] = s->band[band].r[i - 1];
1172 + s->band[band].p[i] = s->band[band].p[i - 1];
1173 + s->band[band].a[i] = s->band[band].ap[i];
1174 + }
1175 +
1176 + /* Block 4, FILTEP */
1177 + wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
1178 + wd1 = (s->band[band].a[1]*wd1) >> 15;
1179 + wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
1180 + wd2 = (s->band[band].a[2]*wd2) >> 15;
1181 + s->band[band].sp = saturate(wd1 + wd2);
1182 +
1183 + /* Block 4, FILTEZ */
1184 + s->band[band].sz = 0;
1185 + for (i = 6; i > 0; i--)
1186 + {
1187 + wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
1188 + s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
1189 + }
1190 + s->band[band].sz = saturate(s->band[band].sz);
1191 +
1192 + /* Block 4, PREDIC */
1193 + s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
1194 +}
1195 +/*- End of function --------------------------------------------------------*/
1196 +
1197 +g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options)
1198 +{
1199 + if (s == NULL)
1200 + {
1201 + if ((s = (g722_encode_state_t *) malloc(sizeof(*s))) == NULL)
1202 + return NULL;
1203 + }
1204 + memset(s, 0, sizeof(*s));
1205 + if (rate == 48000)
1206 + s->bits_per_sample = 6;
1207 + else if (rate == 56000)
1208 + s->bits_per_sample = 7;
1209 + else
1210 + s->bits_per_sample = 8;
1211 + if ((options & G722_SAMPLE_RATE_8000))
1212 + s->eight_k = TRUE;
1213 + if ((options & G722_PACKED) && s->bits_per_sample != 8)
1214 + s->packed = TRUE;
1215 + else
1216 + s->packed = FALSE;
1217 + s->band[0].det = 32;
1218 + s->band[1].det = 8;
1219 + return s;
1220 +}
1221 +/*- End of function --------------------------------------------------------*/
1222 +
1223 +int g722_encode_release(g722_encode_state_t *s)
1224 +{
1225 + free(s);
1226 + return 0;
1227 +}
1228 +/*- End of function --------------------------------------------------------*/
1229 +
1230 +int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len)
1231 +{
1232 + static const int q6[32] =
1233 + {
1234 + 0, 35, 72, 110, 150, 190, 233, 276,
1235 + 323, 370, 422, 473, 530, 587, 650, 714,
1236 + 786, 858, 940, 1023, 1121, 1219, 1339, 1458,
1237 + 1612, 1765, 1980, 2195, 2557, 2919, 0, 0
1238 + };
1239 + static const int iln[32] =
1240 + {
1241 + 0, 63, 62, 31, 30, 29, 28, 27,
1242 + 26, 25, 24, 23, 22, 21, 20, 19,
1243 + 18, 17, 16, 15, 14, 13, 12, 11,
1244 + 10, 9, 8, 7, 6, 5, 4, 0
1245 + };
1246 + static const int ilp[32] =
1247 + {
1248 + 0, 61, 60, 59, 58, 57, 56, 55,
1249 + 54, 53, 52, 51, 50, 49, 48, 47,
1250 + 46, 45, 44, 43, 42, 41, 40, 39,
1251 + 38, 37, 36, 35, 34, 33, 32, 0
1252 + };
1253 + static const int wl[8] =
1254 + {
1255 + -60, -30, 58, 172, 334, 538, 1198, 3042
1256 + };
1257 + static const int rl42[16] =
1258 + {
1259 + 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0
1260 + };
1261 + static const int ilb[32] =
1262 + {
1263 + 2048, 2093, 2139, 2186, 2233, 2282, 2332,
1264 + 2383, 2435, 2489, 2543, 2599, 2656, 2714,
1265 + 2774, 2834, 2896, 2960, 3025, 3091, 3158,
1266 + 3228, 3298, 3371, 3444, 3520, 3597, 3676,
1267 + 3756, 3838, 3922, 4008
1268 + };
1269 + static const int qm4[16] =
1270 + {
1271 + 0, -20456, -12896, -8968,
1272 + -6288, -4240, -2584, -1200,
1273 + 20456, 12896, 8968, 6288,
1274 + 4240, 2584, 1200, 0
1275 + };
1276 + static const int qm2[4] =
1277 + {
1278 + -7408, -1616, 7408, 1616
1279 + };
1280 + static const int qmf_coeffs[12] =
1281 + {
1282 + 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
1283 + };
1284 + static const int ihn[3] = {0, 1, 0};
1285 + static const int ihp[3] = {0, 3, 2};
1286 + static const int wh[3] = {0, -214, 798};
1287 + static const int rh2[4] = {2, 1, 2, 1};
1288 +
1289 + int dlow;
1290 + int dhigh;
1291 + int el;
1292 + int wd;
1293 + int wd1;
1294 + int ril;
1295 + int wd2;
1296 + int il4;
1297 + int ih2;
1298 + int wd3;
1299 + int eh;
1300 + int mih;
1301 + int i;
1302 + int j;
1303 + /* Low and high band PCM from the QMF */
1304 + int xlow;
1305 + int xhigh;
1306 + int g722_bytes;
1307 + /* Even and odd tap accumulators */
1308 + int sumeven;
1309 + int sumodd;
1310 + int ihigh;
1311 + int ilow;
1312 + int code;
1313 +
1314 + g722_bytes = 0;
1315 + xhigh = 0;
1316 + for (j = 0; j < len; )
1317 + {
1318 + if (s->itu_test_mode)
1319 + {
1320 + xlow =
1321 + xhigh = amp[j++] >> 1;
1322 + }
1323 + else
1324 + {
1325 + if (s->eight_k)
1326 + {
1327 + xlow = amp[j++];
1328 + }
1329 + else
1330 + {
1331 + /* Apply the transmit QMF */
1332 + /* Shuffle the buffer down */
1333 + for (i = 0; i < 22; i++)
1334 + s->x[i] = s->x[i + 2];
1335 + s->x[22] = amp[j++];
1336 + s->x[23] = amp[j++];
1337 +
1338 + /* Discard every other QMF output */
1339 + sumeven = 0;
1340 + sumodd = 0;
1341 + for (i = 0; i < 12; i++)
1342 + {
1343 + sumodd += s->x[2*i]*qmf_coeffs[i];
1344 + sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i];
1345 + }
1346 + xlow = (sumeven + sumodd) >> 13;
1347 + xhigh = (sumeven - sumodd) >> 13;
1348 + }
1349 + }
1350 + /* Block 1L, SUBTRA */
1351 + el = saturate(xlow - s->band[0].s);
1352 +
1353 + /* Block 1L, QUANTL */
1354 + wd = (el >= 0) ? el : -(el + 1);
1355 +
1356 + for (i = 1; i < 30; i++)
1357 + {
1358 + wd1 = (q6[i]*s->band[0].det) >> 12;
1359 + if (wd < wd1)
1360 + break;
1361 + }
1362 + ilow = (el < 0) ? iln[i] : ilp[i];
1363 +
1364 + /* Block 2L, INVQAL */
1365 + ril = ilow >> 2;
1366 + wd2 = qm4[ril];
1367 + dlow = (s->band[0].det*wd2) >> 15;
1368 +
1369 + /* Block 3L, LOGSCL */
1370 + il4 = rl42[ril];
1371 + wd = (s->band[0].nb*127) >> 7;
1372 + s->band[0].nb = wd + wl[il4];
1373 + if (s->band[0].nb < 0)
1374 + s->band[0].nb = 0;
1375 + else if (s->band[0].nb > 18432)
1376 + s->band[0].nb = 18432;
1377 +
1378 + /* Block 3L, SCALEL */
1379 + wd1 = (s->band[0].nb >> 6) & 31;
1380 + wd2 = 8 - (s->band[0].nb >> 11);
1381 + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
1382 + s->band[0].det = wd3 << 2;
1383 +
1384 + block4(s, 0, dlow);
1385 +
1386 + if (s->eight_k)
1387 + {
1388 + /* Just leave the high bits as zero */
1389 + code = (0xC0 | ilow) >> (8 - s->bits_per_sample);
1390 + }
1391 + else
1392 + {
1393 + /* Block 1H, SUBTRA */
1394 + eh = saturate(xhigh - s->band[1].s);
1395 +
1396 + /* Block 1H, QUANTH */
1397 + wd = (eh >= 0) ? eh : -(eh + 1);
1398 + wd1 = (564*s->band[1].det) >> 12;
1399 + mih = (wd >= wd1) ? 2 : 1;
1400 + ihigh = (eh < 0) ? ihn[mih] : ihp[mih];
1401 +
1402 + /* Block 2H, INVQAH */
1403 + wd2 = qm2[ihigh];
1404 + dhigh = (s->band[1].det*wd2) >> 15;
1405 +
1406 + /* Block 3H, LOGSCH */
1407 + ih2 = rh2[ihigh];
1408 + wd = (s->band[1].nb*127) >> 7;
1409 + s->band[1].nb = wd + wh[ih2];
1410 + if (s->band[1].nb < 0)
1411 + s->band[1].nb = 0;
1412 + else if (s->band[1].nb > 22528)
1413 + s->band[1].nb = 22528;
1414 +
1415 + /* Block 3H, SCALEH */
1416 + wd1 = (s->band[1].nb >> 6) & 31;
1417 + wd2 = 10 - (s->band[1].nb >> 11);
1418 + wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
1419 + s->band[1].det = wd3 << 2;
1420 +
1421 + block4(s, 1, dhigh);
1422 + code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample);
1423 + }
1424 +
1425 + if (s->packed)
1426 + {
1427 + /* Pack the code bits */
1428 + s->out_buffer |= (code << s->out_bits);
1429 + s->out_bits += s->bits_per_sample;
1430 + if (s->out_bits >= 8)
1431 + {
1432 + g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF);
1433 + s->out_bits -= 8;
1434 + s->out_buffer >>= 8;
1435 + }
1436 + }
1437 + else
1438 + {
1439 + g722_data[g722_bytes++] = (uint8_t) code;
1440 + }
1441 + }
1442 + return g722_bytes;
1443 +}
1444 +/*- End of function --------------------------------------------------------*/
1445 +/*- End of file ------------------------------------------------------------*/
1446 Index: codecs/g722/g722.h
1447 diff -Nau codecs/g722/g722.h.orig codecs/g722/g722.h
1448 --- codecs/g722/g722.h.orig 1970-01-01 01:00:00.000000000 +0100
1449 +++ codecs/g722/g722.h 2009-04-24 00:30:33.000000000 +0200
1450 @@ -0,0 +1,148 @@
1451 +/*
1452 + * SpanDSP - a series of DSP components for telephony
1453 + *
1454 + * g722.h - The ITU G.722 codec.
1455 + *
1456 + * Written by Steve Underwood <steveu@coppice.org>
1457 + *
1458 + * Copyright (C) 2005 Steve Underwood
1459 + *
1460 + * Despite my general liking of the GPL, I place my own contributions
1461 + * to this code in the public domain for the benefit of all mankind -
1462 + * even the slimy ones who might try to proprietize my work and use it
1463 + * to my detriment.
1464 + *
1465 + * Based on a single channel G.722 codec which is:
1466 + *
1467 + ***** Copyright (c) CMU 1993 *****
1468 + * Computer Science, Speech Group
1469 + * Chengxiang Lu and Alex Hauptmann
1470 + *
1471 + * $Id: g722.h 48959 2006-12-25 06:42:15Z rizzo $
1472 + */
1473 +
1474 +
1475 +/*! \file */
1476 +
1477 +#if !defined(_G722_H_)
1478 +#define _G722_H_
1479 +
1480 +/*! \page g722_page G.722 encoding and decoding
1481 +\section g722_page_sec_1 What does it do?
1482 +The G.722 module is a bit exact implementation of the ITU G.722 specification for all three
1483 +specified bit rates - 64000bps, 56000bps and 48000bps. It passes the ITU tests.
1484 +
1485 +To allow fast and flexible interworking with narrow band telephony, the encoder and decoder
1486 +support an option for the linear audio to be an 8k samples/second stream. In this mode the
1487 +codec is considerably faster, and still fully compatible with wideband terminals using G.722.
1488 +
1489 +\section g722_page_sec_2 How does it work?
1490 +???.
1491 +*/
1492 +
1493 +enum
1494 +{
1495 + G722_SAMPLE_RATE_8000 = 0x0001,
1496 + G722_PACKED = 0x0002
1497 +};
1498 +
1499 +#ifndef INT16_MAX
1500 +#define INT16_MAX 32767
1501 +#endif
1502 +#ifndef INT16_MIN
1503 +#define INT16_MIN (-32768)
1504 +#endif
1505 +
1506 +typedef struct
1507 +{
1508 + /*! TRUE if the operating in the special ITU test mode, with the band split filters
1509 + disabled. */
1510 + int itu_test_mode;
1511 + /*! TRUE if the G.722 data is packed */
1512 + int packed;
1513 + /*! TRUE if encode from 8k samples/second */
1514 + int eight_k;
1515 + /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
1516 + int bits_per_sample;
1517 +
1518 + /*! Signal history for the QMF */
1519 + int x[24];
1520 +
1521 + struct
1522 + {
1523 + int s;
1524 + int sp;
1525 + int sz;
1526 + int r[3];
1527 + int a[3];
1528 + int ap[3];
1529 + int p[3];
1530 + int d[7];
1531 + int b[7];
1532 + int bp[7];
1533 + int sg[7];
1534 + int nb;
1535 + int det;
1536 + } band[2];
1537 +
1538 + unsigned int in_buffer;
1539 + int in_bits;
1540 + unsigned int out_buffer;
1541 + int out_bits;
1542 +} g722_encode_state_t;
1543 +
1544 +typedef struct
1545 +{
1546 + /*! TRUE if the operating in the special ITU test mode, with the band split filters
1547 + disabled. */
1548 + int itu_test_mode;
1549 + /*! TRUE if the G.722 data is packed */
1550 + int packed;
1551 + /*! TRUE if decode to 8k samples/second */
1552 + int eight_k;
1553 + /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */
1554 + int bits_per_sample;
1555 +
1556 + /*! Signal history for the QMF */
1557 + int x[24];
1558 +
1559 + struct
1560 + {
1561 + int s;
1562 + int sp;
1563 + int sz;
1564 + int r[3];
1565 + int a[3];
1566 + int ap[3];
1567 + int p[3];
1568 + int d[7];
1569 + int b[7];
1570 + int bp[7];
1571 + int sg[7];
1572 + int nb;
1573 + int det;
1574 + } band[2];
1575 +
1576 + unsigned int in_buffer;
1577 + int in_bits;
1578 + unsigned int out_buffer;
1579 + int out_bits;
1580 +} g722_decode_state_t;
1581 +
1582 +#ifdef __cplusplus
1583 +extern "C" {
1584 +#endif
1585 +
1586 +g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options);
1587 +int g722_encode_release(g722_encode_state_t *s);
1588 +int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len);
1589 +
1590 +g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options);
1591 +int g722_decode_release(g722_decode_state_t *s);
1592 +int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len);
1593 +
1594 +#ifdef __cplusplus
1595 +}
1596 +#endif
1597 +
1598 +#endif
1599 Index: codecs/g722/Makefile
1600 diff -Nau codecs/g722/Makefile.orig codecs/g722/Makefile
1601 --- codecs/g722/Makefile.orig 1970-01-01 01:00:00.000000000 +0100
1602 +++ codecs/g722/Makefile 2009-04-24 00:30:33.000000000 +0200
1603 @@ -0,0 +1,18 @@
1604 +LIB=libg722.a
1605 +CFLAGS+=-fPIC
1606 +
1607 +include $(ASTTOPDIR)/Makefile.rules
1608 +
1609 +OBJS=g722_encode.o g722_decode.o
1610 +
1611 +all: $(LIB)
1612 +
1613 +$(LIB): $(OBJS)
1614 + $(ECHO_PREFIX) echo " [AR] $^ -> $@"
1615 + $(CMD_PREFIX) $(AR) cr $@ $^
1616 + $(CMD_PREFIX) $(RANLIB) $@
1617 +
1618 +clean:
1619 + rm -f $(LIB) *.o
1620 + rm -f .*.o.d
1621 + rm -f *.s *.i
1622 Index: codecs/g722_slin_ex.h
1623 diff -Nau codecs/g722_slin_ex.h.orig codecs/g722_slin_ex.h
1624 --- codecs/g722_slin_ex.h.orig 1970-01-01 01:00:00.000000000 +0100
1625 +++ codecs/g722_slin_ex.h 2009-04-24 00:30:33.000000000 +0200
1626 @@ -0,0 +1,25 @@
1627 +/*! \file
1628 + * \brief g722_slin_ex.h --
1629 + *
1630 + * 4-bit ADPCM data, 20 milliseconds worth at 8 kHz.
1631 + *
1632 + * Source: g723.example
1633 + *
1634 + * Copyright (C) 2001-2005, Digium Inc.
1635 + *
1636 + * Distributed under the terms of the GNU General Public License
1637 + *
1638 + */
1639 +
1640 +static unsigned char g722_slin_ex[] = {
1641 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1642 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1643 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1644 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1645 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1646 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1647 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1648 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1649 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1650 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1651 +};
1652 Index: codecs/Makefile
1653 diff -Nau codecs/Makefile.orig codecs/Makefile
1654 --- codecs/Makefile.orig 2008-03-26 17:42:35.000000000 +0100
1655 +++ codecs/Makefile 2009-04-24 00:30:33.000000000 +0200
1656 @@ -31,6 +31,7 @@
1658 LIBILBC:=ilbc/libilbc.a
1659 LIBLPC10:=lpc10/liblpc10.a
1660 +LIBG722:=g722/libg722.a
1662 all: _all
1664 @@ -45,6 +46,7 @@
1665 $(MAKE) -C gsm clean
1666 $(MAKE) -C lpc10 clean
1667 $(MAKE) -C ilbc clean
1668 + $(MAKE) -C g722 clean
1670 gsm/lib/libgsm.a:
1671 @mkdir -p gsm/lib
1672 @@ -59,3 +61,8 @@
1673 @$(MAKE) -C ilbc all ASTCFLAGS="$(filter-out -Wmissing-prototypes -Wmissing-declarations,$(ASTCFLAGS)) $(AST_NO_STRICT_OVERFLOW)"
1675 $(if $(filter codec_ilbc,$(EMBEDDED_MODS)),modules.link,codec_ilbc.so): $(LIBILBC)
1676 +
1677 +$(LIBG722):
1678 + @$(MAKE) -C g722 all
1679 +
1680 +$(if $(filter codec_g722,$(EMBEDDED_MODS)),modules.link,codec_g722.so): $(LIBG722)
1681 Index: codecs/slin_g722_ex.h
1682 diff -Nau codecs/slin_g722_ex.h.orig codecs/slin_g722_ex.h
1683 --- codecs/slin_g722_ex.h.orig 1970-01-01 01:00:00.000000000 +0100
1684 +++ codecs/slin_g722_ex.h 2009-04-24 00:30:33.000000000 +0200
1685 @@ -0,0 +1,25 @@
1686 +/*! \file
1687 + * \brief slin_g722_ex.h --
1688 + *
1689 + * Signed 16-bit audio data, 10 milliseconds worth at 8 kHz.
1690 + *
1691 + * Source: g723.example
1692 + *
1693 + * Copyright (C) 2001-2005, Digium Inc.
1694 + *
1695 + * Distributed under the terms of the GNU General Public License
1696 + *
1697 + */
1698 +
1699 +static signed short slin_g722_ex[] = {
1700 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1701 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1702 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1703 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1704 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1705 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1706 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1707 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1708 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
1709 + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
1710 +};
1711 Index: configure
1712 diff -Nau configure.orig configure
1713 --- configure.orig 2009-02-18 21:06:45.000000000 +0100
1714 +++ configure 2009-04-24 00:30:33.000000000 +0200
1715 @@ -11143,6 +11143,61 @@
1717 fi
1719 +{ echo "$as_me:$LINENO: checking for tm_gmtoff in struct tm" >&5
1720 +echo $ECHO_N "checking for tm_gmtoff in struct tm... $ECHO_C" >&6; }
1721 +if test "${ac_cv_struct_tm_gmtoff+set}" = set; then
1722 + echo $ECHO_N "(cached) $ECHO_C" >&6
1723 +else
1724 + cat >conftest.$ac_ext <<_ACEOF
1725 +/* confdefs.h. */
1726 +_ACEOF
1727 +cat confdefs.h >>conftest.$ac_ext
1728 +cat >>conftest.$ac_ext <<_ACEOF
1729 +/* end confdefs.h. */
1730 +$ac_includes_default
1731 +#include <sys/types.h>
1732 +#include <$ac_cv_struct_tm>
1733 +int main() {
1734 +struct tm tm; tm.tm_gmtoff;
1735 +; return 0; }
1736 +_ACEOF
1737 +rm -f conftest.$ac_objext
1738 +if { (ac_try="$ac_compile"
1739 +case "(($ac_try" in
1740 + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
1741 + *) ac_try_echo=$ac_try;;
1742 +esac
1743 +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
1744 + (eval "$ac_compile") 2>conftest.er1
1745 + ac_status=$?
1746 + grep -v '^ *+' conftest.er1 >conftest.err
1747 + rm -f conftest.er1
1748 + cat conftest.err >&5
1749 + echo "$as_me:$LINENO: \$? = $ac_status" >&5
1750 + (exit $ac_status); } && {
1751 + test -z "$ac_c_werror_flag" ||
1752 + test ! -s conftest.err
1753 + } && test -s conftest.$ac_objext; then
1754 + ac_cv_struct_tm_gmtoff=yes
1755 +else
1756 + echo "$as_me: failed program was:" >&5
1757 +sed 's/^/| /' conftest.$ac_ext >&5
1758 +
1759 + ac_cv_struct_tm_gmtoff=no
1760 +fi
1761 +
1762 +rm -f conftest*
1763 +fi
1764 +{ echo "$as_me:$LINENO: result: $ac_cv_struct_tm_gmtoff" >&5
1765 +echo "${ECHO_T}$ac_cv_struct_tm_gmtoff" >&6; }
1766 +if test $ac_cv_struct_tm_gmtoff = yes; then
1767 +
1768 +cat >>confdefs.h <<\_ACEOF
1769 +#define TM_GMTOFF 1
1770 +_ACEOF
1771 +
1772 +fi
1773 +
1774 { echo "$as_me:$LINENO: checking for working volatile" >&5
1775 echo $ECHO_N "checking for working volatile... $ECHO_C" >&6; }
1776 if test "${ac_cv_c_volatile+set}" = set; then
1777 Index: include/asterisk/config.h
1778 diff -Nau include/asterisk/config.h.orig include/asterisk/config.h
1779 --- include/asterisk/config.h.orig 2009-02-18 19:30:38.000000000 +0100
1780 +++ include/asterisk/config.h 2009-04-24 00:30:33.000000000 +0200
1781 @@ -33,6 +33,8 @@
1783 struct ast_category;
1785 +#define CONFIG_STATUS_FILEUNCHANGED (void *)-1
1786 +
1787 struct ast_variable {
1788 char *name;
1789 char *value;
1790 Index: include/asterisk/frame.h
1791 diff -Nau include/asterisk/frame.h.orig include/asterisk/frame.h
1792 --- include/asterisk/frame.h.orig 2009-03-05 19:22:16.000000000 +0100
1793 +++ include/asterisk/frame.h 2009-04-24 00:30:33.000000000 +0200
1794 @@ -260,6 +260,8 @@
1795 #define AST_FORMAT_G726 (1 << 11)
1796 /*! G.722 */
1797 #define AST_FORMAT_G722 (1 << 12)
1798 +/*! Raw 16-bit Signed Linear (16000 Hz) PCM */
1799 +#define AST_FORMAT_SLINEAR16 (1 << 15)
1800 /*! Unsupported audio bits */
1801 #define AST_FORMAT_AUDIO_UNDEFINED ((1 << 13) | (1 << 14) | (1 << 15))
1802 /*! Maximum audio format */
1803 Index: main/editline/np/vis.h
1804 diff -Nau main/editline/np/vis.h.orig main/editline/np/vis.h
1805 --- main/editline/np/vis.h.orig 2006-08-21 04:11:39.000000000 +0200
1806 +++ main/editline/np/vis.h 2009-04-24 00:30:33.000000000 +0200
1807 @@ -76,6 +76,22 @@
1809 #include <sys/cdefs.h>
1811 +/* correct nonportable unsigned type usage */
1812 +#if !defined(__FreeBSD__) && !defined(__linux__)
1813 +#ifndef u_int64_t
1814 +#define u_int64_t unsigned long long
1815 +#endif
1816 +#ifndef u_int32_t
1817 +#define u_int32_t unsigned int
1818 +#endif
1819 +#ifndef u_int16_t
1820 +#define u_int16_t unsigned short
1821 +#endif
1822 +#ifndef u_int6_t
1823 +#define u_int8_t unsigned char
1824 +#endif
1825 +#endif
1826 +
1827 __BEGIN_DECLS
1828 char *vis __P((char *, int, int, int));
1829 char *svis __P((char *, int, int, int, const char *));
1830 Index: main/stdtime/localtime.c
1831 diff -Nau main/stdtime/localtime.c.orig main/stdtime/localtime.c
1832 --- main/stdtime/localtime.c.orig 2008-09-27 17:00:48.000000000 +0200
1833 +++ main/stdtime/localtime.c 2009-04-24 00:30:33.000000000 +0200
1834 @@ -1134,9 +1134,9 @@
1835 */
1836 result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
1837 tmp->tm_isdst = ttisp->tt_isdst;
1838 -#ifndef SOLARIS /* Solaris doesn't have this element */
1839 +#ifdef TM_GMTOFF
1840 tmp->tm_gmtoff = ttisp->tt_gmtoff;
1841 -#endif
1842 +#endif /* defined TM_GMTOFF */
1843 #ifdef TM_ZONE
1844 tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind];
1845 #endif /* defined TM_ZONE */
1846 Index: Makefile.moddir_rules
1847 diff -Nau Makefile.moddir_rules.orig Makefile.moddir_rules
1848 --- Makefile.moddir_rules.orig 2008-11-26 19:36:24.000000000 +0100
1849 +++ Makefile.moddir_rules 2009-04-24 00:30:33.000000000 +0200
1850 @@ -69,7 +69,9 @@
1851 rm -f modules.link
1853 install:: all
1854 +ifneq ($(LOADABLE_MODS),)
1855 for x in $(LOADABLE_MODS:%=%.so); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; done
1856 +endif
1858 uninstall::
1860 Index: res/res_features.c
1861 diff -Nau res/res_features.c.orig res/res_features.c
1862 --- res/res_features.c.orig 2009-03-03 19:27:09.000000000 +0100
1863 +++ res/res_features.c 2009-04-24 00:30:33.000000000 +0200
1864 @@ -732,6 +732,10 @@
1865 snprintf(args, len, "%s|%s|m", S_OR(touch_format, "wav"), touch_filename);
1866 }
1868 + for( x = 0; x < strlen(touch_filename); x++) {
1869 + if (touch_filename[x] == '/')
1870 + touch_filename[x] = '-';
1871 + }
1872 for( x = 0; x < strlen(args); x++) {
1873 if (args[x] == '/')
1874 args[x] = '-';
1875 @@ -2774,6 +2778,293 @@
1876 }
1877 }
1879 +static char mandescr_bridge[] =
1880 +"Description: Bridge together two channels already in the PBX\n"
1881 +"Variables: ( Headers marked with * are required )\n"
1882 +" *Channel1: Channel to Bridge to Channel2\n"
1883 +" *Channel2: Channel to Bridge to Channel1\n"
1884 +" Tone: (Yes|No) Play courtesy tone to Channel 2\n"
1885 +"\n";
1886 +
1887 +/*!
1888 + * \brief Actual bridge
1889 + * \param chan
1890 + * \param tmpchan
1891 + *
1892 + * Stop hold music, lock both channels, masq channels,
1893 + * after bridge return channel to next priority.
1894 +*/
1895 +static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan)
1896 +{
1897 + ast_moh_stop(chan);
1898 + ast_channel_lock(chan);
1899 + ast_setstate(tmpchan, chan->_state);
1900 + tmpchan->readformat = chan->readformat;
1901 + tmpchan->writeformat = chan->writeformat;
1902 + ast_channel_masquerade(tmpchan, chan);
1903 + ast_channel_lock(tmpchan);
1904 + ast_do_masquerade(tmpchan);
1905 + /* when returning from bridge, the channel will continue at the next priority */
1906 + ast_explicit_goto(tmpchan, chan->context, chan->exten, chan->priority + 1);
1907 + ast_channel_unlock(tmpchan);
1908 + ast_channel_unlock(chan);
1909 +}
1910 +
1911 +/*!
1912 + * \brief Bridge channels together
1913 + * \param s
1914 + * \param m
1915 + *
1916 + * Make sure valid channels were specified,
1917 + * send errors if any of the channels could not be found/locked, answer channels if needed,
1918 + * create the placeholder channels and grab the other channels
1919 + * make the channels compatible, send error if we fail doing so
1920 + * setup the bridge thread object and start the bridge.
1921 + *
1922 + * \retval 0 on success or on incorrect use.
1923 + * \retval 1 on failure to bridge channels.
1924 +*/
1925 +static int action_bridge(struct mansession *s, const struct message *m)
1926 +{
1927 + const char *channela = astman_get_header(m, "Channel1");
1928 + const char *channelb = astman_get_header(m, "Channel2");
1929 + const char *playtone = astman_get_header(m, "Tone");
1930 + struct ast_channel *chana = NULL, *chanb = NULL;
1931 + struct ast_channel *tmpchana = NULL, *tmpchanb = NULL;
1932 + struct ast_bridge_thread_obj *tobj = NULL;
1933 +
1934 + /* make sure valid channels were specified */
1935 + if (!ast_strlen_zero(channela) && !ast_strlen_zero(channelb)) {
1936 + chana = ast_get_channel_by_name_prefix_locked(channela, strlen(channela));
1937 + chanb = ast_get_channel_by_name_prefix_locked(channelb, strlen(channelb));
1938 + if (chana)
1939 + ast_channel_unlock(chana);
1940 + if (chanb)
1941 + ast_channel_unlock(chanb);
1942 +
1943 + /* send errors if any of the channels could not be found/locked */
1944 + if (!chana) {
1945 + char buf[256];
1946 + snprintf(buf, sizeof(buf), "Channel1 does not exist: %s", channela);
1947 + astman_send_error(s, m, buf);
1948 + return 0;
1949 + }
1950 + if (!chanb) {
1951 + char buf[256];
1952 + snprintf(buf, sizeof(buf), "Channel2 does not exist: %s", channelb);
1953 + astman_send_error(s, m, buf);
1954 + return 0;
1955 + }
1956 + } else {
1957 + astman_send_error(s, m, "Missing channel parameter in request");
1958 + return 0;
1959 + }
1960 +
1961 + /* Answer the channels if needed */
1962 + if (chana->_state != AST_STATE_UP)
1963 + ast_answer(chana);
1964 + if (chanb->_state != AST_STATE_UP)
1965 + ast_answer(chanb);
1966 +
1967 + /* create the placeholder channels and grab the other channels */
1968 + if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
1969 + NULL, NULL, 0, "Bridge/%s", chana->name))) {
1970 + astman_send_error(s, m, "Unable to create temporary channel!");
1971 + return 1;
1972 + }
1973 +
1974 + if (!(tmpchanb = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
1975 + NULL, NULL, 0, "Bridge/%s", chanb->name))) {
1976 + astman_send_error(s, m, "Unable to create temporary channels!");
1977 + ast_channel_free(tmpchana);
1978 + return 1;
1979 + }
1980 +
1981 + do_bridge_masquerade(chana, tmpchana);
1982 + do_bridge_masquerade(chanb, tmpchanb);
1983 +
1984 + /* make the channels compatible, send error if we fail doing so */
1985 + if (ast_channel_make_compatible(tmpchana, tmpchanb)) {
1986 + ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for manager bridge\n", tmpchana->name, tmpchanb->name);
1987 + astman_send_error(s, m, "Could not make channels compatible for manager bridge");
1988 + ast_hangup(tmpchana);
1989 + ast_hangup(tmpchanb);
1990 + return 1;
1991 + }
1992 +
1993 + /* setup the bridge thread object and start the bridge */
1994 + if (!(tobj = ast_calloc(1, sizeof(*tobj)))) {
1995 + ast_log(LOG_WARNING, "Unable to spawn a new bridge thread on %s and %s: %s\n", tmpchana->name, tmpchanb->name, strerror(errno));
1996 + astman_send_error(s, m, "Unable to spawn a new bridge thread");
1997 + ast_hangup(tmpchana);
1998 + ast_hangup(tmpchanb);
1999 + return 1;
2000 + }
2001 +
2002 + tobj->chan = tmpchana;
2003 + tobj->peer = tmpchanb;
2004 +
2005 + if (ast_true(playtone)) {
2006 + if (!ast_strlen_zero(xfersound) && !ast_streamfile(tmpchanb, xfersound, tmpchanb->language)) {
2007 + if (ast_waitstream(tmpchanb, "") < 0)
2008 + ast_log(LOG_WARNING, "Failed to play a courtesy tone on chan %s\n", tmpchanb->name);
2009 + }
2010 + }
2011 +
2012 + ast_bridge_call_thread_launch(tobj);
2013 +
2014 + astman_send_ack(s, m, "Launched bridge thread with success");
2015 +
2016 + return 0;
2017 +}
2018 +
2019 +static char *app_bridge = "Bridge";
2020 +static char *bridge_synopsis = "Bridge two channels";
2021 +static char *bridge_descrip =
2022 +"Usage: Bridge(channel[,options])\n"
2023 +" Allows the ability to bridge two channels via the dialplan.\n"
2024 +"The current channel is bridged to the specified 'channel'.\n"
2025 +" Options:\n"
2026 +" p - Play a courtesy tone to 'channel'.\n"
2027 +"This application sets the following channel variable upon completion:\n"
2028 +" BRIDGERESULT The result of the bridge attempt as a text string, one of\n"
2029 +" SUCCESS | FAILURE | LOOP | NONEXISTENT | INCOMPATIBLE\n";
2030 +
2031 +enum {
2032 + BRIDGE_OPT_PLAYTONE = (1 << 0),
2033 +};
2034 +
2035 +AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS
2036 + AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE)
2037 +END_OPTIONS );
2038 +
2039 +/*!
2040 + * \brief Bridge channels
2041 + * \param chan
2042 + * \param data channel to bridge with.
2043 + *
2044 + * Split data, check we aren't bridging with ourself, check valid channel,
2045 + * answer call if not already, check compatible channels, setup bridge config
2046 + * now bridge call, if transfered party hangs up return to PBX extension.
2047 +*/
2048 +static int bridge_exec(struct ast_channel *chan, void *data)
2049 +{
2050 + struct ast_channel *current_dest_chan, *final_dest_chan;
2051 + char *tmp_data = NULL;
2052 + struct ast_flags opts = { 0, };
2053 + struct ast_bridge_config bconfig = { { 0, }, };
2054 +
2055 + AST_DECLARE_APP_ARGS(args,
2056 + AST_APP_ARG(dest_chan);
2057 + AST_APP_ARG(options);
2058 + );
2059 +
2060 + if (ast_strlen_zero(data)) {
2061 + ast_log(LOG_WARNING, "Bridge require at least 1 argument specifying the other end of the bridge\n");
2062 + return -1;
2063 + }
2064 +
2065 + tmp_data = ast_strdupa(data);
2066 + AST_STANDARD_APP_ARGS(args, tmp_data);
2067 + if (!ast_strlen_zero(args.options))
2068 + ast_app_parse_options(bridge_exec_options, &opts, NULL, args.options);
2069 +
2070 + /* avoid bridge with ourselves */
2071 + if (!strncmp(chan->name, args.dest_chan,
2072 + strlen(chan->name) < strlen(args.dest_chan) ?
2073 + strlen(chan->name) : strlen(args.dest_chan))) {
2074 + ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", chan->name);
2075 + manager_event(EVENT_FLAG_CALL, "BridgeExec",
2076 + "Response: Failed\r\n"
2077 + "Reason: Unable to bridge channel to itself\r\n"
2078 + "Channel1: %s\r\n"
2079 + "Channel2: %s\r\n",
2080 + chan->name, args.dest_chan);
2081 + pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP");
2082 + return 0;
2083 + }
2084 +
2085 + /* make sure we have a valid end point */
2086 + if (!(current_dest_chan = ast_get_channel_by_name_prefix_locked(args.dest_chan,
2087 + strlen(args.dest_chan)))) {
2088 + ast_log(LOG_WARNING, "Bridge failed because channel %s does not exist or we "
2089 + "cannot get its lock\n", args.dest_chan);
2090 + manager_event(EVENT_FLAG_CALL, "BridgeExec",
2091 + "Response: Failed\r\n"
2092 + "Reason: Cannot grab end point\r\n"
2093 + "Channel1: %s\r\n"
2094 + "Channel2: %s\r\n", chan->name, args.dest_chan);
2095 + pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT");
2096 + return 0;
2097 + }
2098 + ast_channel_unlock(current_dest_chan);
2099 +
2100 + /* answer the channel if needed */
2101 + if (current_dest_chan->_state != AST_STATE_UP)
2102 + ast_answer(current_dest_chan);
2103 +
2104 + /* try to allocate a place holder where current_dest_chan will be placed */
2105 + if (!(final_dest_chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
2106 + NULL, NULL, 0, "Bridge/%s", current_dest_chan->name))) {
2107 + ast_log(LOG_WARNING, "Cannot create placeholder channel for chan %s\n", args.dest_chan);
2108 + manager_event(EVENT_FLAG_CALL, "BridgeExec",
2109 + "Response: Failed\r\n"
2110 + "Reason: cannot create placeholder\r\n"
2111 + "Channel1: %s\r\n"
2112 + "Channel2: %s\r\n", chan->name, args.dest_chan);
2113 + }
2114 + do_bridge_masquerade(current_dest_chan, final_dest_chan);
2115 +
2116 + /* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */
2117 + /* try to make compatible, send error if we fail */
2118 + if (ast_channel_make_compatible(chan, final_dest_chan) < 0) {
2119 + ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, final_dest_chan->name);
2120 + manager_event(EVENT_FLAG_CALL, "BridgeExec",
2121 + "Response: Failed\r\n"
2122 + "Reason: Could not make channels compatible for bridge\r\n"
2123 + "Channel1: %s\r\n"
2124 + "Channel2: %s\r\n", chan->name, final_dest_chan->name);
2125 + ast_hangup(final_dest_chan); /* may be we should return this channel to the PBX? */
2126 + pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "INCOMPATIBLE");
2127 + return 0;
2128 + }
2129 +
2130 + /* Report that the bridge will be successfull */
2131 + manager_event(EVENT_FLAG_CALL, "BridgeExec",
2132 + "Response: Success\r\n"
2133 + "Channel1: %s\r\n"
2134 + "Channel2: %s\r\n", chan->name, final_dest_chan->name);
2135 +
2136 + /* we have 2 valid channels to bridge, now it is just a matter of setting up the bridge config and starting the bridge */
2137 + if (ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE) && !ast_strlen_zero(xfersound)) {
2138 + if (!ast_streamfile(final_dest_chan, xfersound, final_dest_chan->language)) {
2139 + if (ast_waitstream(final_dest_chan, "") < 0)
2140 + ast_log(LOG_WARNING, "Failed to play courtesy tone on %s\n", final_dest_chan->name);
2141 + }
2142 + }
2143 +
2144 + /* do the bridge */
2145 + ast_bridge_call(chan, final_dest_chan, &bconfig);
2146 +
2147 + /* the bridge has ended, set BRIDGERESULT to SUCCESS. If the other channel has not been hung up, return it to the PBX */
2148 + pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS");
2149 + if (!ast_check_hangup(final_dest_chan)) {
2150 + ast_log(LOG_EVENT, "starting new PBX in %s,%s,%d for chan %s\n",
2151 + final_dest_chan->context, final_dest_chan->exten,
2152 + final_dest_chan->priority, final_dest_chan->name);
2153 +
2154 + if (ast_pbx_start(final_dest_chan) != AST_PBX_SUCCESS) {
2155 + ast_log(LOG_WARNING, "FAILED continuing PBX on dest chan %s\n", final_dest_chan->name);
2156 + ast_hangup(final_dest_chan);
2157 + } else
2158 + ast_log(LOG_EVENT, "SUCCESS continuing PBX on chan %s\n", final_dest_chan->name);
2159 + } else {
2160 + ast_log(LOG_EVENT, "hangup chan %s since the other endpoint has hung up\n", final_dest_chan->name);
2161 + ast_hangup(final_dest_chan);
2162 + }
2163 +
2164 + return 0;
2165 +}
2167 static int load_config(void)
2168 {
2169 @@ -3034,6 +3325,8 @@
2170 {
2171 int res;
2173 + ast_register_application(app_bridge, bridge_exec, bridge_synopsis, bridge_descrip);
2174 +
2175 memset(parking_ext, 0, sizeof(parking_ext));
2176 memset(parking_con, 0, sizeof(parking_con));
2178 @@ -3048,6 +3341,7 @@
2179 ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" );
2180 ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park,
2181 "Park a channel", mandescr_park);
2182 + ast_manager_register2("Bridge", EVENT_FLAG_CALL, action_bridge, "Bridge two channels already in the PBX", mandescr_bridge);
2183 }
2185 res |= ast_devstate_prov_add("Park", metermaidstate);
2186 Index: apps/app_voicemail.c
2187 diff -Nau apps/app_voicemail.c.orig apps/app_voicemail.c
2188 --- apps/app_voicemail.c.orig 2009-04-25 02:38:20.343758775 +0200
2189 +++ apps/app_voicemail.c 2009-04-25 19:56:25.287569363 +0200
2190 @@ -115,6 +115,7 @@
2191 static char imapport[8];
2192 static char imapflags[128];
2193 static char imapfolder[64];
2194 +static int imapsubfold = 0;
2195 static char authuser[32];
2196 static char authpassword[42];
2198 @@ -4313,6 +4314,7 @@
2199 /* we must use mbox(x) folder names, and copy the message there */
2200 /* simple. huh? */
2201 char sequence[10];
2202 + char folder[256];
2203 /* get the real IMAP message number for this message */
2204 snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]);
2205 if (option_debug > 2)
2206 @@ -4323,11 +4325,21 @@
2207 } else if (box == 0) {
2208 mail_clearflag(vms->mailstream, sequence, "\\Seen");
2209 }
2210 - if (!strcasecmp(mbox(0), vms->curbox) && (box == 0 || box == 1)) {
2211 + if ((!strcasecmp(mbox(0), vms->curbox) || \
2212 + !strcasecmp(mbox(1), vms->curbox)) && \
2213 + (box == 0 || box == 1)) { /* Don't copy data, just change Seen flag */
2214 ast_mutex_unlock(&vms->lock);
2215 return 0;
2216 - } else {
2217 - int res = !mail_copy(vms->mailstream,sequence,(char *) mbox(box));
2218 + } else if (box > 1) { /* Do copy data using INBOX or subfolder */
2219 + if (imapsubfold == 1)
2220 + snprintf(folder, sizeof(folder), "%s%c%s", imapfolder, delimiter, mbox(box));
2221 + else
2222 + strncpy(folder, mbox(box), sizeof(folder));
2223 + int res = !mail_copy(vms->mailstream,sequence,folder);
2224 + ast_mutex_unlock(&vms->lock);
2225 + return res;
2226 + } else { /* Copy data to INBOX delegating new/old status to Seen flag */
2227 + int res = !mail_copy(vms->mailstream,sequence,imapfolder);
2228 ast_mutex_unlock(&vms->lock);
2229 return res;
2230 }
2231 @@ -7686,6 +7698,10 @@
2232 #ifndef IMAP_STORAGE
2233 } else if (!cmd) {
2234 vms.deleted[vms.curmsg] = 1;
2235 +#else
2236 + } else if (!cmd && (folder_int(vms.curbox) > 1 || box > 1)) {
2237 + vms.deleted[vms.curmsg] = 1; /* Enforce deletion after */
2238 + deleted = 1; /* successful copy op */
2239 #endif
2240 } else {
2241 vms.deleted[vms.curmsg] = 0;
2242 @@ -8198,6 +8214,7 @@
2243 const char *imap_port;
2244 const char *imap_flags;
2245 const char *imap_folder;
2246 + const char *imap_use_subfold;
2247 const char *auth_user;
2248 const char *auth_password;
2249 const char *expunge_on_hangup;
2250 @@ -8342,6 +8359,15 @@
2251 } else {
2252 ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder));
2253 }
2254 + /* IMAP saved (sub)folder location policy */
2255 + if ((imap_use_subfold = ast_variable_retrieve(cfg, "general", "imapsubfold"))) {
2256 + if (ast_false(imap_use_subfold))
2257 + imapsubfold = 0;
2258 + else
2259 + imapsubfold = 1;
2260 + } else {
2261 + imapsubfold = 0;
2262 + }
2264 /* There is some very unorthodox casting done here. This is due
2265 * to the way c-client handles the argument passed in. It expects a