1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/asterisk/asterisk.patch Mon Apr 27 12:19:05 2009 +0200 1.3 @@ -0,0 +1,2265 @@ 1.4 +Index: cdr/cdr_sqlite.c 1.5 +diff -Nau cdr/cdr_sqlite.c.orig cdr/cdr_sqlite.c 1.6 +--- cdr/cdr_sqlite.c.orig 2007-06-14 23:50:40.000000000 +0200 1.7 ++++ cdr/cdr_sqlite.c 2009-04-24 00:30:33.000000000 +0200 1.8 +@@ -58,7 +58,7 @@ 1.9 + #define DATE_FORMAT "%Y-%m-%d %T" 1.10 + 1.11 + static char *name = "sqlite"; 1.12 +-static sqlite* db = NULL; 1.13 ++static sqlite3 *db = NULL; 1.14 + 1.15 + AST_MUTEX_DEFINE_STATIC(sqlite_lock); 1.16 + 1.17 +@@ -92,10 +92,10 @@ 1.18 + static int sqlite_log(struct ast_cdr *cdr) 1.19 + { 1.20 + int res = 0; 1.21 +- char *zErr = 0; 1.22 + struct tm tm; 1.23 + time_t t; 1.24 + char startstr[80], answerstr[80], endstr[80]; 1.25 ++ char *cdrsql = 0; 1.26 + int count; 1.27 + 1.28 + ast_mutex_lock(&sqlite_lock); 1.29 +@@ -113,7 +113,7 @@ 1.30 + strftime(endstr, sizeof(endstr), DATE_FORMAT, &tm); 1.31 + 1.32 + for(count=0; count<5; count++) { 1.33 +- res = sqlite_exec_printf(db, 1.34 ++ cdrsql = sqlite3_mprintf( 1.35 + "INSERT INTO cdr (" 1.36 + "clid,src,dst,dcontext," 1.37 + "channel,dstchannel,lastapp,lastdata, " 1.38 +@@ -138,8 +138,7 @@ 1.39 + # if LOG_USERFIELD 1.40 + ",'%q'" 1.41 + # endif 1.42 +- ")", NULL, NULL, &zErr, 1.43 +- cdr->clid, cdr->src, cdr->dst, cdr->dcontext, 1.44 ++ ")", cdr->clid, cdr->src, cdr->dst, cdr->dcontext, 1.45 + cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata, 1.46 + startstr, answerstr, endstr, 1.47 + cdr->duration, cdr->billsec, cdr->disposition, cdr->amaflags, 1.48 +@@ -151,16 +150,13 @@ 1.49 + ,cdr->userfield 1.50 + # endif 1.51 + ); 1.52 ++ res = sqlite3_exec(db, cdrsql, 0, 0, 0); 1.53 ++ sqlite3_free(cdrsql); 1.54 + if (res != SQLITE_BUSY && res != SQLITE_LOCKED) 1.55 + break; 1.56 + usleep(200); 1.57 + } 1.58 + 1.59 +- if (zErr) { 1.60 +- ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr); 1.61 +- free(zErr); 1.62 +- } 1.63 +- 1.64 + ast_mutex_unlock(&sqlite_lock); 1.65 + return res; 1.66 + } 1.67 +@@ -168,7 +164,7 @@ 1.68 + static int unload_module(void) 1.69 + { 1.70 + if (db) 1.71 +- sqlite_close(db); 1.72 ++ sqlite3_close(db); 1.73 + ast_cdr_unregister(name); 1.74 + return 0; 1.75 + } 1.76 +@@ -181,17 +177,16 @@ 1.77 + 1.78 + /* is the database there? */ 1.79 + snprintf(fn, sizeof(fn), "%s/cdr.db", ast_config_AST_LOG_DIR); 1.80 +- db = sqlite_open(fn, 0660, &zErr); 1.81 ++ sqlite3_open(fn, &db); 1.82 + if (!db) { 1.83 +- ast_log(LOG_ERROR, "cdr_sqlite: %s\n", zErr); 1.84 +- free(zErr); 1.85 ++ ast_log(LOG_ERROR, "cdr_sqlite: %s\n", sqlite3_errmsg(db)); 1.86 + return -1; 1.87 + } 1.88 + 1.89 + /* is the table there? */ 1.90 +- res = sqlite_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL); 1.91 ++ res = sqlite3_exec(db, "SELECT COUNT(AcctId) FROM cdr;", NULL, NULL, NULL); 1.92 + if (res) { 1.93 +- res = sqlite_exec(db, sql_create_table, NULL, NULL, &zErr); 1.94 ++ res = sqlite3_exec(db, sql_create_table, NULL, NULL, &zErr); 1.95 + if (res) { 1.96 + ast_log(LOG_ERROR, "cdr_sqlite: Unable to create table 'cdr': %s\n", zErr); 1.97 + free(zErr); 1.98 +@@ -210,7 +205,7 @@ 1.99 + 1.100 + err: 1.101 + if (db) 1.102 +- sqlite_close(db); 1.103 ++ sqlite3_close(db); 1.104 + return -1; 1.105 + } 1.106 + 1.107 +Index: channels/chan_sip.c 1.108 +diff -Nau channels/chan_sip.c.orig channels/chan_sip.c 1.109 +--- channels/chan_sip.c.orig 2009-04-02 19:20:22.000000000 +0200 1.110 ++++ channels/chan_sip.c 2009-04-24 00:30:33.000000000 +0200 1.111 +@@ -7469,7 +7469,7 @@ 1.112 + 1.113 + ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from)); 1.114 + c = get_in_brackets(from); 1.115 +- if (strncasecmp(c, "sip:", 4)) { 1.116 ++ if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 1.117 + ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 1.118 + return -1; 1.119 + } 1.120 +@@ -7477,7 +7477,7 @@ 1.121 + 1.122 + ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to)); 1.123 + c = get_in_brackets(to); 1.124 +- if (strncasecmp(c, "sip:", 4)) { 1.125 ++ if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) { 1.126 + ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", c); 1.127 + return -1; 1.128 + } 1.129 +@@ -8004,7 +8004,10 @@ 1.130 + of = get_in_brackets(from); 1.131 + ast_string_field_set(p, from, of); 1.132 + if (strncasecmp(of, "sip:", 4)) 1.133 +- ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 1.134 ++ if (strncasecmp(of, "sips:", 5)) 1.135 ++ ast_log(LOG_NOTICE, "From address missing 'sip:' or 'sips:', using it anyway\n"); 1.136 ++ else 1.137 ++ of += 5; 1.138 + else 1.139 + of += 4; 1.140 + /* Get just the username part */ 1.141 +@@ -8280,7 +8283,10 @@ 1.142 + 1.143 + /* Make sure it's a SIP URL */ 1.144 + if (strncasecmp(contact, "sip:", 4)) { 1.145 +- ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact); 1.146 ++ if (strncasecmp(contact, "sips:", 5)) 1.147 ++ ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip: or sips:) trying to use anyway\n", contact); 1.148 ++ else 1.149 ++ contact += 5; 1.150 + } else 1.151 + contact += 4; 1.152 + 1.153 +@@ -8409,7 +8415,10 @@ 1.154 + 1.155 + /* Make sure it's a SIP URL */ 1.156 + if (strncasecmp(curi, "sip:", 4)) { 1.157 +- ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", curi); 1.158 ++ if (strncasecmp(curi, "sips:", 5)) 1.159 ++ ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip: or sips:) trying to use anyway\n", curi); 1.160 ++ else 1.161 ++ curi += 5; 1.162 + } else 1.163 + curi += 4; 1.164 + /* Ditch q */ 1.165 +@@ -9000,9 +9009,12 @@ 1.166 + 1.167 + if (!strncasecmp(c, "sip:", 4)) { 1.168 + name = c + 4; 1.169 ++ } 1.170 ++ else if (!strncasecmp(c, "sips:", 5)) { 1.171 ++ name = c + 5; 1.172 + } else { 1.173 + name = c; 1.174 +- ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr)); 1.175 ++ 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)); 1.176 + } 1.177 + 1.178 + /* Strip off the domain name */ 1.179 +@@ -9162,10 +9174,15 @@ 1.180 + return 0; 1.181 + c = get_in_brackets(tmp); 1.182 + if (strncasecmp(c, "sip:", 4)) { 1.183 +- ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 1.184 +- return -1; 1.185 ++ if (strncasecmp(c, "sips:", 5)) { 1.186 ++ ast_log(LOG_WARNING, "Huh? Not an RDNIS SIP header (%s)?\n", c); 1.187 ++ return -1; 1.188 ++ } 1.189 ++ else 1.190 ++ c += 5; 1.191 + } 1.192 +- c += 4; 1.193 ++ else 1.194 ++ c += 4; 1.195 + a = c; 1.196 + strsep(&a, "@;"); /* trim anything after @ or ; */ 1.197 + if (sip_debug_test_pvt(p)) 1.198 +@@ -9200,10 +9217,15 @@ 1.199 + uri = get_in_brackets(tmp); 1.200 + 1.201 + if (strncasecmp(uri, "sip:", 4)) { 1.202 +- ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 1.203 +- return -1; 1.204 ++ if (strncasecmp(uri, "sips:", 5)) { 1.205 ++ ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", uri); 1.206 ++ return -1; 1.207 ++ } 1.208 ++ else 1.209 ++ uri += 5; 1.210 + } 1.211 +- uri += 4; 1.212 ++ else 1.213 ++ uri += 4; 1.214 + 1.215 + /* Now find the From: caller ID and name */ 1.216 + ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf)); 1.217 +@@ -9217,10 +9239,15 @@ 1.218 + 1.219 + if (!ast_strlen_zero(from)) { 1.220 + if (strncasecmp(from, "sip:", 4)) { 1.221 +- ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 1.222 +- return -1; 1.223 ++ if (strncasecmp(from, "sips:", 5)) { 1.224 ++ ast_log(LOG_WARNING, "Huh? Not a SIP header (%s)?\n", from); 1.225 ++ return -1; 1.226 ++ } 1.227 ++ else 1.228 ++ from += 5; 1.229 + } 1.230 +- from += 4; 1.231 ++ else 1.232 ++ from += 4; 1.233 + if ((a = strchr(from, '@'))) 1.234 + *a++ = '\0'; 1.235 + else 1.236 +@@ -9397,10 +9424,15 @@ 1.237 + ast_uri_decode(refer_to); 1.238 + 1.239 + if (strncasecmp(refer_to, "sip:", 4)) { 1.240 +- ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 1.241 +- return -3; 1.242 ++ if (strncasecmp(refer_to, "sips:", 5)) { 1.243 ++ ast_log(LOG_WARNING, "Can't transfer to non-sip: URI. (Refer-to: %s)?\n", refer_to); 1.244 ++ return -3; 1.245 ++ } 1.246 ++ else 1.247 ++ refer_to += 5; /* Skip sips: */ 1.248 + } 1.249 +- refer_to += 4; /* Skip sip: */ 1.250 ++ else 1.251 ++ refer_to += 4; /* Skip sip: */ 1.252 + 1.253 + /* Get referred by header if it exists */ 1.254 + p_referred_by = get_header(req, "Referred-By"); 1.255 +@@ -9417,9 +9449,13 @@ 1.256 + } 1.257 + 1.258 + referred_by_uri = get_in_brackets(h_referred_by); 1.259 +- if(strncasecmp(referred_by_uri, "sip:", 4)) { 1.260 +- ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 1.261 +- referred_by_uri = (char *) NULL; 1.262 ++ if (strncasecmp(referred_by_uri, "sip:", 4)) { 1.263 ++ if (strncasecmp(referred_by_uri, "sips:", 5)) { 1.264 ++ ast_log(LOG_WARNING, "Huh? Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri); 1.265 ++ referred_by_uri = (char *) NULL; 1.266 ++ } 1.267 ++ else 1.268 ++ referred_by_uri += 5; /* Skip sips: */ 1.269 + } else { 1.270 + referred_by_uri += 4; /* Skip sip: */ 1.271 + } 1.272 +@@ -9547,10 +9583,15 @@ 1.273 + ast_uri_decode(c); 1.274 + 1.275 + if (strncasecmp(c, "sip:", 4)) { 1.276 +- ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 1.277 +- return -1; 1.278 ++ if (strncasecmp(c, "sips:", 5)) { 1.279 ++ ast_log(LOG_WARNING, "Huh? Not a SIP header in Also: transfer (%s)?\n", c); 1.280 ++ return -1; 1.281 ++ } 1.282 ++ else 1.283 ++ c += 5; 1.284 + } 1.285 +- c += 4; 1.286 ++ else 1.287 ++ c += 4; 1.288 + if ((a = strchr(c, ';'))) /* Remove arguments */ 1.289 + *a = '\0'; 1.290 + 1.291 +@@ -9761,6 +9802,8 @@ 1.292 + t = uri2; 1.293 + if (!strncasecmp(t, "sip:", 4)) 1.294 + t+= 4; 1.295 ++ else if (!strncasecmp(t, "sips:", 5)) 1.296 ++ t+= 5; 1.297 + ast_string_field_set(p, exten, t); 1.298 + t = strchr(p->exten, '@'); 1.299 + if (t) 1.300 +@@ -9771,7 +9814,10 @@ 1.301 + /* save the URI part of the From header */ 1.302 + ast_string_field_set(p, from, of); 1.303 + if (strncasecmp(of, "sip:", 4)) { 1.304 +- ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n"); 1.305 ++ if (strncasecmp(of, "sips:", 5)) 1.306 ++ ast_log(LOG_NOTICE, "From address missing 'sip:' or 'sips:', using it anyway\n"); 1.307 ++ else 1.308 ++ of += 5; 1.309 + } else 1.310 + of += 4; 1.311 + /* Get just the username part */ 1.312 +@@ -12379,6 +12425,8 @@ 1.313 + if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) { 1.314 + if (!strncasecmp(s, "sip:", 4)) 1.315 + s += 4; 1.316 ++ else if (!strncasecmp(s, "sips:", 5)) 1.317 ++ s += 5; 1.318 + e = strchr(s, ';'); 1.319 + if (e) 1.320 + *e = '\0'; 1.321 +@@ -12404,6 +12452,8 @@ 1.322 + 1.323 + if (!strncasecmp(s, "sip:", 4)) 1.324 + s += 4; 1.325 ++ else if (!strncasecmp(s, "sips:", 5)) 1.326 ++ s += 5; 1.327 + if (option_debug > 1) 1.328 + ast_log(LOG_DEBUG, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain); 1.329 + if (p->owner) { 1.330 +Index: codecs/codec_g722.c 1.331 +diff -Nau codecs/codec_g722.c.orig codecs/codec_g722.c 1.332 +--- codecs/codec_g722.c.orig 1970-01-01 01:00:00.000000000 +0100 1.333 ++++ codecs/codec_g722.c 2009-04-24 00:30:33.000000000 +0200 1.334 +@@ -0,0 +1,306 @@ 1.335 ++/* 1.336 ++ * Asterisk -- An open source telephony toolkit. 1.337 ++ * 1.338 ++ * Copyright (C) 1999 - 2008, Digium, Inc. 1.339 ++ * 1.340 ++ * Matthew Fredrickson <creslin@digium.com> 1.341 ++ * Russell Bryant <russell@digium.com> 1.342 ++ * 1.343 ++ * Special thanks to Steve Underwood for the implementation 1.344 ++ * and for doing the 8khz<->g.722 direct translation code. 1.345 ++ * 1.346 ++ * See http://www.asterisk.org for more information about 1.347 ++ * the Asterisk project. Please do not directly contact 1.348 ++ * any of the maintainers of this project for assistance; 1.349 ++ * the project provides a web site, mailing lists and IRC 1.350 ++ * channels for your use. 1.351 ++ * 1.352 ++ * This program is free software, distributed under the terms of 1.353 ++ * the GNU General Public License Version 2. See the LICENSE file 1.354 ++ * at the top of the source tree. 1.355 ++ */ 1.356 ++ 1.357 ++/*! \file 1.358 ++ * 1.359 ++ * \brief codec_g722.c - translate between signed linear and ITU G.722-64kbps 1.360 ++ * 1.361 ++ * \author Matthew Fredrickson <creslin@digium.com> 1.362 ++ * \author Russell Bryant <russell@digium.com> 1.363 ++ * 1.364 ++ * \arg http://soft-switch.org/downloads/non-gpl-bits.tgz 1.365 ++ * \arg http://lists.digium.com/pipermail/asterisk-dev/2006-September/022866.html 1.366 ++ * 1.367 ++ * \ingroup codecs 1.368 ++ */ 1.369 ++ 1.370 ++#include "asterisk.h" 1.371 ++ 1.372 ++ASTERISK_FILE_VERSION(__FILE__, "$Revision: 106501 $") 1.373 ++ 1.374 ++#include "asterisk/linkedlists.h" 1.375 ++#include "asterisk/module.h" 1.376 ++#include "asterisk/config.h" 1.377 ++#include "asterisk/options.h" 1.378 ++#include "asterisk/translate.h" 1.379 ++#include "asterisk/utils.h" 1.380 ++ 1.381 ++#define BUFFER_SAMPLES 8096 /* size for the translation buffers */ 1.382 ++#define BUF_SHIFT 5 1.383 ++ 1.384 ++/* Sample frame data */ 1.385 ++ 1.386 ++#include "g722/g722.h" 1.387 ++#include "slin_g722_ex.h" 1.388 ++#include "g722_slin_ex.h" 1.389 ++ 1.390 ++struct g722_encoder_pvt { 1.391 ++ g722_encode_state_t g722; 1.392 ++}; 1.393 ++ 1.394 ++struct g722_decoder_pvt { 1.395 ++ g722_decode_state_t g722; 1.396 ++}; 1.397 ++ 1.398 ++/*! \brief init a new instance of g722_encoder_pvt. */ 1.399 ++static int lintog722_new(struct ast_trans_pvt *pvt) 1.400 ++{ 1.401 ++ struct g722_encoder_pvt *tmp = pvt->pvt; 1.402 ++ 1.403 ++ g722_encode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000); 1.404 ++ 1.405 ++ return 0; 1.406 ++} 1.407 ++ 1.408 ++static int lin16tog722_new(struct ast_trans_pvt *pvt) 1.409 ++{ 1.410 ++ struct g722_encoder_pvt *tmp = pvt->pvt; 1.411 ++ 1.412 ++ g722_encode_init(&tmp->g722, 64000, 0); 1.413 ++ 1.414 ++ return 0; 1.415 ++} 1.416 ++ 1.417 ++/*! \brief init a new instance of g722_encoder_pvt. */ 1.418 ++static int g722tolin_new(struct ast_trans_pvt *pvt) 1.419 ++{ 1.420 ++ struct g722_decoder_pvt *tmp = pvt->pvt; 1.421 ++ 1.422 ++ g722_decode_init(&tmp->g722, 64000, G722_SAMPLE_RATE_8000); 1.423 ++ 1.424 ++ return 0; 1.425 ++} 1.426 ++ 1.427 ++static int g722tolin16_new(struct ast_trans_pvt *pvt) 1.428 ++{ 1.429 ++ struct g722_decoder_pvt *tmp = pvt->pvt; 1.430 ++ 1.431 ++ g722_decode_init(&tmp->g722, 64000, 0); 1.432 ++ 1.433 ++ return 0; 1.434 ++} 1.435 ++ 1.436 ++static int g722tolin_framein(struct ast_trans_pvt *pvt, struct ast_frame *f) 1.437 ++{ 1.438 ++ struct g722_decoder_pvt *tmp = pvt->pvt; 1.439 ++ int out_samples; 1.440 ++ int in_samples; 1.441 ++ 1.442 ++ /* g722_decode expects the samples to be in the invalid samples / 2 format */ 1.443 ++ in_samples = f->samples / 2; 1.444 ++ 1.445 ++ out_samples = g722_decode(&tmp->g722, (int16_t *) &pvt->outbuf[pvt->samples * sizeof(int16_t)], 1.446 ++ (uint8_t *) f->data, in_samples); 1.447 ++ 1.448 ++ pvt->samples += out_samples; 1.449 ++ 1.450 ++ pvt->datalen += (out_samples * sizeof(int16_t)); 1.451 ++ 1.452 ++ return 0; 1.453 ++} 1.454 ++ 1.455 ++static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f) 1.456 ++{ 1.457 ++ struct g722_encoder_pvt *tmp = pvt->pvt; 1.458 ++ int outlen; 1.459 ++ 1.460 ++ outlen = g722_encode(&tmp->g722, (uint8_t *) (&pvt->outbuf[pvt->datalen]), 1.461 ++ (int16_t *) f->data, f->samples); 1.462 ++ 1.463 ++ pvt->samples += outlen * 2; 1.464 ++ 1.465 ++ pvt->datalen += outlen; 1.466 ++ 1.467 ++ return 0; 1.468 ++} 1.469 ++ 1.470 ++static struct ast_frame *g722tolin_sample(void) 1.471 ++{ 1.472 ++ static struct ast_frame f = { 1.473 ++ .frametype = AST_FRAME_VOICE, 1.474 ++ .subclass = AST_FORMAT_G722, 1.475 ++ .datalen = sizeof(g722_slin_ex), 1.476 ++ .samples = sizeof(g722_slin_ex) * 2, 1.477 ++ .src = __PRETTY_FUNCTION__, 1.478 ++ .data = g722_slin_ex, 1.479 ++ }; 1.480 ++ 1.481 ++ return &f; 1.482 ++} 1.483 ++ 1.484 ++static struct ast_frame *g722tolin16_sample(void) 1.485 ++{ 1.486 ++ static struct ast_frame f = { 1.487 ++ .frametype = AST_FRAME_VOICE, 1.488 ++ .subclass = AST_FORMAT_G722, 1.489 ++ .datalen = sizeof(slin_g722_ex), 1.490 ++ .samples = sizeof(slin_g722_ex) * 2, 1.491 ++ .src = __PRETTY_FUNCTION__, 1.492 ++ .data = slin_g722_ex, 1.493 ++ }; 1.494 ++ 1.495 ++ return &f; 1.496 ++} 1.497 ++ 1.498 ++static struct ast_frame *lintog722_sample (void) 1.499 ++{ 1.500 ++ static struct ast_frame f = { 1.501 ++ .frametype = AST_FRAME_VOICE, 1.502 ++ .subclass = AST_FORMAT_SLINEAR, 1.503 ++ .datalen = sizeof(slin_g722_ex), 1.504 ++ .samples = sizeof(slin_g722_ex) / sizeof(slin_g722_ex[0]), 1.505 ++ .src = __PRETTY_FUNCTION__, 1.506 ++ .data = slin_g722_ex, 1.507 ++ }; 1.508 ++ 1.509 ++ return &f; 1.510 ++} 1.511 ++ 1.512 ++static struct ast_frame *lin16tog722_sample (void) 1.513 ++{ 1.514 ++ static struct ast_frame f = { 1.515 ++ .frametype = AST_FRAME_VOICE, 1.516 ++ .subclass = AST_FORMAT_SLINEAR16, 1.517 ++ .datalen = sizeof(slin_g722_ex), 1.518 ++ .samples = sizeof(slin_g722_ex) / sizeof(slin_g722_ex[0]), 1.519 ++ .src = __PRETTY_FUNCTION__, 1.520 ++ .data = slin_g722_ex, 1.521 ++ }; 1.522 ++ 1.523 ++ return &f; 1.524 ++} 1.525 ++ 1.526 ++static struct ast_translator g722tolin = { 1.527 ++ .name = "g722tolin", 1.528 ++ .srcfmt = AST_FORMAT_G722, 1.529 ++ .dstfmt = AST_FORMAT_SLINEAR, 1.530 ++ .newpvt = g722tolin_new, /* same for both directions */ 1.531 ++ .framein = g722tolin_framein, 1.532 ++ .sample = g722tolin_sample, 1.533 ++ .desc_size = sizeof(struct g722_decoder_pvt), 1.534 ++ .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t), 1.535 ++ .buf_size = BUFFER_SAMPLES, 1.536 ++ .plc_samples = 160, 1.537 ++}; 1.538 ++ 1.539 ++static struct ast_translator lintog722 = { 1.540 ++ .name = "lintog722", 1.541 ++ .srcfmt = AST_FORMAT_SLINEAR, 1.542 ++ .dstfmt = AST_FORMAT_G722, 1.543 ++ .newpvt = lintog722_new, /* same for both directions */ 1.544 ++ .framein = lintog722_framein, 1.545 ++ .sample = lintog722_sample, 1.546 ++ .desc_size = sizeof(struct g722_encoder_pvt), 1.547 ++ .buffer_samples = BUFFER_SAMPLES * 2, 1.548 ++ .buf_size = BUFFER_SAMPLES, 1.549 ++}; 1.550 ++ 1.551 ++static struct ast_translator g722tolin16 = { 1.552 ++ .name = "g722tolin16", 1.553 ++ .srcfmt = AST_FORMAT_G722, 1.554 ++ .dstfmt = AST_FORMAT_SLINEAR16, 1.555 ++ .newpvt = g722tolin16_new, /* same for both directions */ 1.556 ++ .framein = g722tolin_framein, 1.557 ++ .sample = g722tolin16_sample, 1.558 ++ .desc_size = sizeof(struct g722_decoder_pvt), 1.559 ++ .buffer_samples = BUFFER_SAMPLES / sizeof(int16_t), 1.560 ++ .buf_size = BUFFER_SAMPLES, 1.561 ++ .plc_samples = 160, 1.562 ++}; 1.563 ++ 1.564 ++static struct ast_translator lin16tog722 = { 1.565 ++ .name = "lin16tog722", 1.566 ++ .srcfmt = AST_FORMAT_SLINEAR16, 1.567 ++ .dstfmt = AST_FORMAT_G722, 1.568 ++ .newpvt = lin16tog722_new, /* same for both directions */ 1.569 ++ .framein = lintog722_framein, 1.570 ++ .sample = lin16tog722_sample, 1.571 ++ .desc_size = sizeof(struct g722_encoder_pvt), 1.572 ++ .buffer_samples = BUFFER_SAMPLES * 2, 1.573 ++ .buf_size = BUFFER_SAMPLES, 1.574 ++}; 1.575 ++ 1.576 ++static int parse_config(int reload) 1.577 ++{ 1.578 ++ struct ast_variable *var; 1.579 ++ struct ast_config *cfg = ast_config_load("codecs.conf"); 1.580 ++ 1.581 ++ if (cfg == NULL) 1.582 ++ return 0; 1.583 ++ if (cfg == CONFIG_STATUS_FILEUNCHANGED) 1.584 ++ return 0; 1.585 ++ for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) { 1.586 ++ if (!strcasecmp(var->name, "genericplc")) { 1.587 ++ g722tolin.useplc = ast_true(var->value) ? 1 : 0; 1.588 ++ if (option_verbose > 2) 1.589 ++ ast_verbose(VERBOSE_PREFIX_3 "codec_g722: %susing generic PLC\n", 1.590 ++ g722tolin.useplc ? "" : "not "); 1.591 ++ } 1.592 ++ } 1.593 ++ ast_config_destroy(cfg); 1.594 ++ return 0; 1.595 ++} 1.596 ++ 1.597 ++static int reload(void) 1.598 ++{ 1.599 ++ if (parse_config(1)) 1.600 ++ return AST_MODULE_LOAD_DECLINE; 1.601 ++ return AST_MODULE_LOAD_SUCCESS; 1.602 ++} 1.603 ++ 1.604 ++static int unload_module(void) 1.605 ++{ 1.606 ++ int res = 0; 1.607 ++ 1.608 ++ res |= ast_unregister_translator(&g722tolin); 1.609 ++ res |= ast_unregister_translator(&lintog722); 1.610 ++ res |= ast_unregister_translator(&g722tolin16); 1.611 ++ res |= ast_unregister_translator(&lin16tog722); 1.612 ++ 1.613 ++ return res; 1.614 ++} 1.615 ++ 1.616 ++static int load_module(void) 1.617 ++{ 1.618 ++ int res = 0; 1.619 ++ 1.620 ++ if (parse_config(0)) 1.621 ++ return AST_MODULE_LOAD_DECLINE; 1.622 ++ 1.623 ++ res |= ast_register_translator(&g722tolin); 1.624 ++ res |= ast_register_translator(&lintog722); 1.625 ++ res |= ast_register_translator(&g722tolin16); 1.626 ++ res |= ast_register_translator(&lin16tog722); 1.627 ++ 1.628 ++ if (res) { 1.629 ++ unload_module(); 1.630 ++ return AST_MODULE_LOAD_FAILURE; 1.631 ++ } 1.632 ++ 1.633 ++ return AST_MODULE_LOAD_SUCCESS; 1.634 ++} 1.635 ++ 1.636 ++AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "ITU G.722-64kbps G722 Transcoder", 1.637 ++ .load = load_module, 1.638 ++ .unload = unload_module, 1.639 ++ .reload = reload, 1.640 ++ ); 1.641 +Index: codecs/g722/g722_decode.c 1.642 +diff -Nau codecs/g722/g722_decode.c.orig codecs/g722/g722_decode.c 1.643 +--- codecs/g722/g722_decode.c.orig 1970-01-01 01:00:00.000000000 +0100 1.644 ++++ codecs/g722/g722_decode.c 2009-04-24 00:30:33.000000000 +0200 1.645 +@@ -0,0 +1,398 @@ 1.646 ++/* 1.647 ++ * SpanDSP - a series of DSP components for telephony 1.648 ++ * 1.649 ++ * g722_decode.c - The ITU G.722 codec, decode part. 1.650 ++ * 1.651 ++ * Written by Steve Underwood <steveu@coppice.org> 1.652 ++ * 1.653 ++ * Copyright (C) 2005 Steve Underwood 1.654 ++ * 1.655 ++ * Despite my general liking of the GPL, I place my own contributions 1.656 ++ * to this code in the public domain for the benefit of all mankind - 1.657 ++ * even the slimy ones who might try to proprietize my work and use it 1.658 ++ * to my detriment. 1.659 ++ * 1.660 ++ * Based in part on a single channel G.722 codec which is: 1.661 ++ * 1.662 ++ * Copyright (c) CMU 1993 1.663 ++ * Computer Science, Speech Group 1.664 ++ * Chengxiang Lu and Alex Hauptmann 1.665 ++ * 1.666 ++ * $Id: g722_decode.c 48661 2006-12-21 00:08:21Z mattf $ 1.667 ++ */ 1.668 ++ 1.669 ++/*! \file */ 1.670 ++ 1.671 ++#ifdef HAVE_CONFIG_H 1.672 ++#include <config.h> 1.673 ++#endif 1.674 ++ 1.675 ++#include <stdio.h> 1.676 ++#include <inttypes.h> 1.677 ++#include <memory.h> 1.678 ++#include <stdlib.h> 1.679 ++#if 0 1.680 ++#include <tgmath.h> 1.681 ++#endif 1.682 ++ 1.683 ++#include "g722.h" 1.684 ++ 1.685 ++#if !defined(FALSE) 1.686 ++#define FALSE 0 1.687 ++#endif 1.688 ++#if !defined(TRUE) 1.689 ++#define TRUE (!FALSE) 1.690 ++#endif 1.691 ++ 1.692 ++static __inline__ int16_t saturate(int32_t amp) 1.693 ++{ 1.694 ++ int16_t amp16; 1.695 ++ 1.696 ++ /* Hopefully this is optimised for the common case - not clipping */ 1.697 ++ amp16 = (int16_t) amp; 1.698 ++ if (amp == amp16) 1.699 ++ return amp16; 1.700 ++ if (amp > INT16_MAX) 1.701 ++ return INT16_MAX; 1.702 ++ return INT16_MIN; 1.703 ++} 1.704 ++/*- End of function --------------------------------------------------------*/ 1.705 ++ 1.706 ++static void block4(g722_decode_state_t *s, int band, int d); 1.707 ++ 1.708 ++static void block4(g722_decode_state_t *s, int band, int d) 1.709 ++{ 1.710 ++ int wd1; 1.711 ++ int wd2; 1.712 ++ int wd3; 1.713 ++ int i; 1.714 ++ 1.715 ++ /* Block 4, RECONS */ 1.716 ++ s->band[band].d[0] = d; 1.717 ++ s->band[band].r[0] = saturate(s->band[band].s + d); 1.718 ++ 1.719 ++ /* Block 4, PARREC */ 1.720 ++ s->band[band].p[0] = saturate(s->band[band].sz + d); 1.721 ++ 1.722 ++ /* Block 4, UPPOL2 */ 1.723 ++ for (i = 0; i < 3; i++) 1.724 ++ s->band[band].sg[i] = s->band[band].p[i] >> 15; 1.725 ++ wd1 = saturate(s->band[band].a[1] << 2); 1.726 ++ 1.727 ++ wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1; 1.728 ++ if (wd2 > 32767) 1.729 ++ wd2 = 32767; 1.730 ++ wd3 = (s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128; 1.731 ++ wd3 += (wd2 >> 7); 1.732 ++ wd3 += (s->band[band].a[2]*32512) >> 15; 1.733 ++ if (wd3 > 12288) 1.734 ++ wd3 = 12288; 1.735 ++ else if (wd3 < -12288) 1.736 ++ wd3 = -12288; 1.737 ++ s->band[band].ap[2] = wd3; 1.738 ++ 1.739 ++ /* Block 4, UPPOL1 */ 1.740 ++ s->band[band].sg[0] = s->band[band].p[0] >> 15; 1.741 ++ s->band[band].sg[1] = s->band[band].p[1] >> 15; 1.742 ++ wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192; 1.743 ++ wd2 = (s->band[band].a[1]*32640) >> 15; 1.744 ++ 1.745 ++ s->band[band].ap[1] = saturate(wd1 + wd2); 1.746 ++ wd3 = saturate(15360 - s->band[band].ap[2]); 1.747 ++ if (s->band[band].ap[1] > wd3) 1.748 ++ s->band[band].ap[1] = wd3; 1.749 ++ else if (s->band[band].ap[1] < -wd3) 1.750 ++ s->band[band].ap[1] = -wd3; 1.751 ++ 1.752 ++ /* Block 4, UPZERO */ 1.753 ++ wd1 = (d == 0) ? 0 : 128; 1.754 ++ s->band[band].sg[0] = d >> 15; 1.755 ++ for (i = 1; i < 7; i++) 1.756 ++ { 1.757 ++ s->band[band].sg[i] = s->band[band].d[i] >> 15; 1.758 ++ wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1; 1.759 ++ wd3 = (s->band[band].b[i]*32640) >> 15; 1.760 ++ s->band[band].bp[i] = saturate(wd2 + wd3); 1.761 ++ } 1.762 ++ 1.763 ++ /* Block 4, DELAYA */ 1.764 ++ for (i = 6; i > 0; i--) 1.765 ++ { 1.766 ++ s->band[band].d[i] = s->band[band].d[i - 1]; 1.767 ++ s->band[band].b[i] = s->band[band].bp[i]; 1.768 ++ } 1.769 ++ 1.770 ++ for (i = 2; i > 0; i--) 1.771 ++ { 1.772 ++ s->band[band].r[i] = s->band[band].r[i - 1]; 1.773 ++ s->band[band].p[i] = s->band[band].p[i - 1]; 1.774 ++ s->band[band].a[i] = s->band[band].ap[i]; 1.775 ++ } 1.776 ++ 1.777 ++ /* Block 4, FILTEP */ 1.778 ++ wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]); 1.779 ++ wd1 = (s->band[band].a[1]*wd1) >> 15; 1.780 ++ wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]); 1.781 ++ wd2 = (s->band[band].a[2]*wd2) >> 15; 1.782 ++ s->band[band].sp = saturate(wd1 + wd2); 1.783 ++ 1.784 ++ /* Block 4, FILTEZ */ 1.785 ++ s->band[band].sz = 0; 1.786 ++ for (i = 6; i > 0; i--) 1.787 ++ { 1.788 ++ wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]); 1.789 ++ s->band[band].sz += (s->band[band].b[i]*wd1) >> 15; 1.790 ++ } 1.791 ++ s->band[band].sz = saturate(s->band[band].sz); 1.792 ++ 1.793 ++ /* Block 4, PREDIC */ 1.794 ++ s->band[band].s = saturate(s->band[band].sp + s->band[band].sz); 1.795 ++} 1.796 ++/*- End of function --------------------------------------------------------*/ 1.797 ++ 1.798 ++g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options) 1.799 ++{ 1.800 ++ if (s == NULL) 1.801 ++ { 1.802 ++ if ((s = (g722_decode_state_t *) malloc(sizeof(*s))) == NULL) 1.803 ++ return NULL; 1.804 ++ } 1.805 ++ memset(s, 0, sizeof(*s)); 1.806 ++ if (rate == 48000) 1.807 ++ s->bits_per_sample = 6; 1.808 ++ else if (rate == 56000) 1.809 ++ s->bits_per_sample = 7; 1.810 ++ else 1.811 ++ s->bits_per_sample = 8; 1.812 ++ if ((options & G722_SAMPLE_RATE_8000)) 1.813 ++ s->eight_k = TRUE; 1.814 ++ if ((options & G722_PACKED) && s->bits_per_sample != 8) 1.815 ++ s->packed = TRUE; 1.816 ++ else 1.817 ++ s->packed = FALSE; 1.818 ++ s->band[0].det = 32; 1.819 ++ s->band[1].det = 8; 1.820 ++ return s; 1.821 ++} 1.822 ++/*- End of function --------------------------------------------------------*/ 1.823 ++ 1.824 ++int g722_decode_release(g722_decode_state_t *s) 1.825 ++{ 1.826 ++ free(s); 1.827 ++ return 0; 1.828 ++} 1.829 ++/*- End of function --------------------------------------------------------*/ 1.830 ++ 1.831 ++int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len) 1.832 ++{ 1.833 ++ static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 }; 1.834 ++ static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 }; 1.835 ++ static const int ilb[32] = 1.836 ++ { 1.837 ++ 2048, 2093, 2139, 2186, 2233, 2282, 2332, 1.838 ++ 2383, 2435, 2489, 2543, 2599, 2656, 2714, 1.839 ++ 2774, 2834, 2896, 2960, 3025, 3091, 3158, 1.840 ++ 3228, 3298, 3371, 3444, 3520, 3597, 3676, 1.841 ++ 3756, 3838, 3922, 4008 1.842 ++ }; 1.843 ++ static const int wh[3] = {0, -214, 798}; 1.844 ++ static const int rh2[4] = {2, 1, 2, 1}; 1.845 ++ static const int qm2[4] = {-7408, -1616, 7408, 1616}; 1.846 ++ static const int qm4[16] = 1.847 ++ { 1.848 ++ 0, -20456, -12896, -8968, 1.849 ++ -6288, -4240, -2584, -1200, 1.850 ++ 20456, 12896, 8968, 6288, 1.851 ++ 4240, 2584, 1200, 0 1.852 ++ }; 1.853 ++ static const int qm5[32] = 1.854 ++ { 1.855 ++ -280, -280, -23352, -17560, 1.856 ++ -14120, -11664, -9752, -8184, 1.857 ++ -6864, -5712, -4696, -3784, 1.858 ++ -2960, -2208, -1520, -880, 1.859 ++ 23352, 17560, 14120, 11664, 1.860 ++ 9752, 8184, 6864, 5712, 1.861 ++ 4696, 3784, 2960, 2208, 1.862 ++ 1520, 880, 280, -280 1.863 ++ }; 1.864 ++ static const int qm6[64] = 1.865 ++ { 1.866 ++ -136, -136, -136, -136, 1.867 ++ -24808, -21904, -19008, -16704, 1.868 ++ -14984, -13512, -12280, -11192, 1.869 ++ -10232, -9360, -8576, -7856, 1.870 ++ -7192, -6576, -6000, -5456, 1.871 ++ -4944, -4464, -4008, -3576, 1.872 ++ -3168, -2776, -2400, -2032, 1.873 ++ -1688, -1360, -1040, -728, 1.874 ++ 24808, 21904, 19008, 16704, 1.875 ++ 14984, 13512, 12280, 11192, 1.876 ++ 10232, 9360, 8576, 7856, 1.877 ++ 7192, 6576, 6000, 5456, 1.878 ++ 4944, 4464, 4008, 3576, 1.879 ++ 3168, 2776, 2400, 2032, 1.880 ++ 1688, 1360, 1040, 728, 1.881 ++ 432, 136, -432, -136 1.882 ++ }; 1.883 ++ static const int qmf_coeffs[12] = 1.884 ++ { 1.885 ++ 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11, 1.886 ++ }; 1.887 ++ 1.888 ++ int dlowt; 1.889 ++ int rlow; 1.890 ++ int ihigh; 1.891 ++ int dhigh; 1.892 ++ int rhigh; 1.893 ++ int xout1; 1.894 ++ int xout2; 1.895 ++ int wd1; 1.896 ++ int wd2; 1.897 ++ int wd3; 1.898 ++ int code; 1.899 ++ int outlen; 1.900 ++ int i; 1.901 ++ int j; 1.902 ++ 1.903 ++ outlen = 0; 1.904 ++ rhigh = 0; 1.905 ++ for (j = 0; j < len; ) 1.906 ++ { 1.907 ++ if (s->packed) 1.908 ++ { 1.909 ++ /* Unpack the code bits */ 1.910 ++ if (s->in_bits < s->bits_per_sample) 1.911 ++ { 1.912 ++ s->in_buffer |= (g722_data[j++] << s->in_bits); 1.913 ++ s->in_bits += 8; 1.914 ++ } 1.915 ++ code = s->in_buffer & ((1 << s->bits_per_sample) - 1); 1.916 ++ s->in_buffer >>= s->bits_per_sample; 1.917 ++ s->in_bits -= s->bits_per_sample; 1.918 ++ } 1.919 ++ else 1.920 ++ { 1.921 ++ code = g722_data[j++]; 1.922 ++ } 1.923 ++ 1.924 ++ switch (s->bits_per_sample) 1.925 ++ { 1.926 ++ default: 1.927 ++ case 8: 1.928 ++ wd1 = code & 0x3F; 1.929 ++ ihigh = (code >> 6) & 0x03; 1.930 ++ wd2 = qm6[wd1]; 1.931 ++ wd1 >>= 2; 1.932 ++ break; 1.933 ++ case 7: 1.934 ++ wd1 = code & 0x1F; 1.935 ++ ihigh = (code >> 5) & 0x03; 1.936 ++ wd2 = qm5[wd1]; 1.937 ++ wd1 >>= 1; 1.938 ++ break; 1.939 ++ case 6: 1.940 ++ wd1 = code & 0x0F; 1.941 ++ ihigh = (code >> 4) & 0x03; 1.942 ++ wd2 = qm4[wd1]; 1.943 ++ break; 1.944 ++ } 1.945 ++ /* Block 5L, LOW BAND INVQBL */ 1.946 ++ wd2 = (s->band[0].det*wd2) >> 15; 1.947 ++ /* Block 5L, RECONS */ 1.948 ++ rlow = s->band[0].s + wd2; 1.949 ++ /* Block 6L, LIMIT */ 1.950 ++ if (rlow > 16383) 1.951 ++ rlow = 16383; 1.952 ++ else if (rlow < -16384) 1.953 ++ rlow = -16384; 1.954 ++ 1.955 ++ /* Block 2L, INVQAL */ 1.956 ++ wd2 = qm4[wd1]; 1.957 ++ dlowt = (s->band[0].det*wd2) >> 15; 1.958 ++ 1.959 ++ /* Block 3L, LOGSCL */ 1.960 ++ wd2 = rl42[wd1]; 1.961 ++ wd1 = (s->band[0].nb*127) >> 7; 1.962 ++ wd1 += wl[wd2]; 1.963 ++ if (wd1 < 0) 1.964 ++ wd1 = 0; 1.965 ++ else if (wd1 > 18432) 1.966 ++ wd1 = 18432; 1.967 ++ s->band[0].nb = wd1; 1.968 ++ 1.969 ++ /* Block 3L, SCALEL */ 1.970 ++ wd1 = (s->band[0].nb >> 6) & 31; 1.971 ++ wd2 = 8 - (s->band[0].nb >> 11); 1.972 ++ wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); 1.973 ++ s->band[0].det = wd3 << 2; 1.974 ++ 1.975 ++ block4(s, 0, dlowt); 1.976 ++ 1.977 ++ if (!s->eight_k) 1.978 ++ { 1.979 ++ /* Block 2H, INVQAH */ 1.980 ++ wd2 = qm2[ihigh]; 1.981 ++ dhigh = (s->band[1].det*wd2) >> 15; 1.982 ++ /* Block 5H, RECONS */ 1.983 ++ rhigh = dhigh + s->band[1].s; 1.984 ++ /* Block 6H, LIMIT */ 1.985 ++ if (rhigh > 16383) 1.986 ++ rhigh = 16383; 1.987 ++ else if (rhigh < -16384) 1.988 ++ rhigh = -16384; 1.989 ++ 1.990 ++ /* Block 2H, INVQAH */ 1.991 ++ wd2 = rh2[ihigh]; 1.992 ++ wd1 = (s->band[1].nb*127) >> 7; 1.993 ++ wd1 += wh[wd2]; 1.994 ++ if (wd1 < 0) 1.995 ++ wd1 = 0; 1.996 ++ else if (wd1 > 22528) 1.997 ++ wd1 = 22528; 1.998 ++ s->band[1].nb = wd1; 1.999 ++ 1.1000 ++ /* Block 3H, SCALEH */ 1.1001 ++ wd1 = (s->band[1].nb >> 6) & 31; 1.1002 ++ wd2 = 10 - (s->band[1].nb >> 11); 1.1003 ++ wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); 1.1004 ++ s->band[1].det = wd3 << 2; 1.1005 ++ 1.1006 ++ block4(s, 1, dhigh); 1.1007 ++ } 1.1008 ++ 1.1009 ++ if (s->itu_test_mode) 1.1010 ++ { 1.1011 ++ amp[outlen++] = (int16_t) (rlow << 1); 1.1012 ++ amp[outlen++] = (int16_t) (rhigh << 1); 1.1013 ++ } 1.1014 ++ else 1.1015 ++ { 1.1016 ++ if (s->eight_k) 1.1017 ++ { 1.1018 ++ amp[outlen++] = (int16_t) rlow; 1.1019 ++ } 1.1020 ++ else 1.1021 ++ { 1.1022 ++ /* Apply the receive QMF */ 1.1023 ++ for (i = 0; i < 22; i++) 1.1024 ++ s->x[i] = s->x[i + 2]; 1.1025 ++ s->x[22] = rlow + rhigh; 1.1026 ++ s->x[23] = rlow - rhigh; 1.1027 ++ 1.1028 ++ xout1 = 0; 1.1029 ++ xout2 = 0; 1.1030 ++ for (i = 0; i < 12; i++) 1.1031 ++ { 1.1032 ++ xout2 += s->x[2*i]*qmf_coeffs[i]; 1.1033 ++ xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i]; 1.1034 ++ } 1.1035 ++ amp[outlen++] = (int16_t) (xout1 >> 12); 1.1036 ++ amp[outlen++] = (int16_t) (xout2 >> 12); 1.1037 ++ } 1.1038 ++ } 1.1039 ++ } 1.1040 ++ return outlen; 1.1041 ++} 1.1042 ++/*- End of function --------------------------------------------------------*/ 1.1043 ++/*- End of file ------------------------------------------------------------*/ 1.1044 +Index: codecs/g722/g722_encode.c 1.1045 +diff -Nau codecs/g722/g722_encode.c.orig codecs/g722/g722_encode.c 1.1046 +--- codecs/g722/g722_encode.c.orig 1970-01-01 01:00:00.000000000 +0100 1.1047 ++++ codecs/g722/g722_encode.c 2009-04-24 00:30:33.000000000 +0200 1.1048 +@@ -0,0 +1,400 @@ 1.1049 ++/* 1.1050 ++ * SpanDSP - a series of DSP components for telephony 1.1051 ++ * 1.1052 ++ * g722_encode.c - The ITU G.722 codec, encode part. 1.1053 ++ * 1.1054 ++ * Written by Steve Underwood <steveu@coppice.org> 1.1055 ++ * 1.1056 ++ * Copyright (C) 2005 Steve Underwood 1.1057 ++ * 1.1058 ++ * All rights reserved. 1.1059 ++ * 1.1060 ++ * Despite my general liking of the GPL, I place my own contributions 1.1061 ++ * to this code in the public domain for the benefit of all mankind - 1.1062 ++ * even the slimy ones who might try to proprietize my work and use it 1.1063 ++ * to my detriment. 1.1064 ++ * 1.1065 ++ * Based on a single channel 64kbps only G.722 codec which is: 1.1066 ++ * 1.1067 ++ ***** Copyright (c) CMU 1993 ***** 1.1068 ++ * Computer Science, Speech Group 1.1069 ++ * Chengxiang Lu and Alex Hauptmann 1.1070 ++ * 1.1071 ++ * $Id: g722_encode.c 48661 2006-12-21 00:08:21Z mattf $ 1.1072 ++ */ 1.1073 ++ 1.1074 ++/*! \file */ 1.1075 ++ 1.1076 ++#ifdef HAVE_CONFIG_H 1.1077 ++#include <config.h> 1.1078 ++#endif 1.1079 ++ 1.1080 ++#include <stdio.h> 1.1081 ++#include <inttypes.h> 1.1082 ++#include <memory.h> 1.1083 ++#include <stdlib.h> 1.1084 ++#if 0 1.1085 ++#include <tgmath.h> 1.1086 ++#endif 1.1087 ++ 1.1088 ++#include "g722.h" 1.1089 ++ 1.1090 ++#if !defined(FALSE) 1.1091 ++#define FALSE 0 1.1092 ++#endif 1.1093 ++#if !defined(TRUE) 1.1094 ++#define TRUE (!FALSE) 1.1095 ++#endif 1.1096 ++ 1.1097 ++static __inline__ int16_t saturate(int32_t amp) 1.1098 ++{ 1.1099 ++ int16_t amp16; 1.1100 ++ 1.1101 ++ /* Hopefully this is optimised for the common case - not clipping */ 1.1102 ++ amp16 = (int16_t) amp; 1.1103 ++ if (amp == amp16) 1.1104 ++ return amp16; 1.1105 ++ if (amp > INT16_MAX) 1.1106 ++ return INT16_MAX; 1.1107 ++ return INT16_MIN; 1.1108 ++} 1.1109 ++/*- End of function --------------------------------------------------------*/ 1.1110 ++ 1.1111 ++static void block4(g722_encode_state_t *s, int band, int d) 1.1112 ++{ 1.1113 ++ int wd1; 1.1114 ++ int wd2; 1.1115 ++ int wd3; 1.1116 ++ int i; 1.1117 ++ 1.1118 ++ /* Block 4, RECONS */ 1.1119 ++ s->band[band].d[0] = d; 1.1120 ++ s->band[band].r[0] = saturate(s->band[band].s + d); 1.1121 ++ 1.1122 ++ /* Block 4, PARREC */ 1.1123 ++ s->band[band].p[0] = saturate(s->band[band].sz + d); 1.1124 ++ 1.1125 ++ /* Block 4, UPPOL2 */ 1.1126 ++ for (i = 0; i < 3; i++) 1.1127 ++ s->band[band].sg[i] = s->band[band].p[i] >> 15; 1.1128 ++ wd1 = saturate(s->band[band].a[1] << 2); 1.1129 ++ 1.1130 ++ wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1; 1.1131 ++ if (wd2 > 32767) 1.1132 ++ wd2 = 32767; 1.1133 ++ wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128); 1.1134 ++ wd3 += (s->band[band].a[2]*32512) >> 15; 1.1135 ++ if (wd3 > 12288) 1.1136 ++ wd3 = 12288; 1.1137 ++ else if (wd3 < -12288) 1.1138 ++ wd3 = -12288; 1.1139 ++ s->band[band].ap[2] = wd3; 1.1140 ++ 1.1141 ++ /* Block 4, UPPOL1 */ 1.1142 ++ s->band[band].sg[0] = s->band[band].p[0] >> 15; 1.1143 ++ s->band[band].sg[1] = s->band[band].p[1] >> 15; 1.1144 ++ wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192; 1.1145 ++ wd2 = (s->band[band].a[1]*32640) >> 15; 1.1146 ++ 1.1147 ++ s->band[band].ap[1] = saturate(wd1 + wd2); 1.1148 ++ wd3 = saturate(15360 - s->band[band].ap[2]); 1.1149 ++ if (s->band[band].ap[1] > wd3) 1.1150 ++ s->band[band].ap[1] = wd3; 1.1151 ++ else if (s->band[band].ap[1] < -wd3) 1.1152 ++ s->band[band].ap[1] = -wd3; 1.1153 ++ 1.1154 ++ /* Block 4, UPZERO */ 1.1155 ++ wd1 = (d == 0) ? 0 : 128; 1.1156 ++ s->band[band].sg[0] = d >> 15; 1.1157 ++ for (i = 1; i < 7; i++) 1.1158 ++ { 1.1159 ++ s->band[band].sg[i] = s->band[band].d[i] >> 15; 1.1160 ++ wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1; 1.1161 ++ wd3 = (s->band[band].b[i]*32640) >> 15; 1.1162 ++ s->band[band].bp[i] = saturate(wd2 + wd3); 1.1163 ++ } 1.1164 ++ 1.1165 ++ /* Block 4, DELAYA */ 1.1166 ++ for (i = 6; i > 0; i--) 1.1167 ++ { 1.1168 ++ s->band[band].d[i] = s->band[band].d[i - 1]; 1.1169 ++ s->band[band].b[i] = s->band[band].bp[i]; 1.1170 ++ } 1.1171 ++ 1.1172 ++ for (i = 2; i > 0; i--) 1.1173 ++ { 1.1174 ++ s->band[band].r[i] = s->band[band].r[i - 1]; 1.1175 ++ s->band[band].p[i] = s->band[band].p[i - 1]; 1.1176 ++ s->band[band].a[i] = s->band[band].ap[i]; 1.1177 ++ } 1.1178 ++ 1.1179 ++ /* Block 4, FILTEP */ 1.1180 ++ wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]); 1.1181 ++ wd1 = (s->band[band].a[1]*wd1) >> 15; 1.1182 ++ wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]); 1.1183 ++ wd2 = (s->band[band].a[2]*wd2) >> 15; 1.1184 ++ s->band[band].sp = saturate(wd1 + wd2); 1.1185 ++ 1.1186 ++ /* Block 4, FILTEZ */ 1.1187 ++ s->band[band].sz = 0; 1.1188 ++ for (i = 6; i > 0; i--) 1.1189 ++ { 1.1190 ++ wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]); 1.1191 ++ s->band[band].sz += (s->band[band].b[i]*wd1) >> 15; 1.1192 ++ } 1.1193 ++ s->band[band].sz = saturate(s->band[band].sz); 1.1194 ++ 1.1195 ++ /* Block 4, PREDIC */ 1.1196 ++ s->band[band].s = saturate(s->band[band].sp + s->band[band].sz); 1.1197 ++} 1.1198 ++/*- End of function --------------------------------------------------------*/ 1.1199 ++ 1.1200 ++g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options) 1.1201 ++{ 1.1202 ++ if (s == NULL) 1.1203 ++ { 1.1204 ++ if ((s = (g722_encode_state_t *) malloc(sizeof(*s))) == NULL) 1.1205 ++ return NULL; 1.1206 ++ } 1.1207 ++ memset(s, 0, sizeof(*s)); 1.1208 ++ if (rate == 48000) 1.1209 ++ s->bits_per_sample = 6; 1.1210 ++ else if (rate == 56000) 1.1211 ++ s->bits_per_sample = 7; 1.1212 ++ else 1.1213 ++ s->bits_per_sample = 8; 1.1214 ++ if ((options & G722_SAMPLE_RATE_8000)) 1.1215 ++ s->eight_k = TRUE; 1.1216 ++ if ((options & G722_PACKED) && s->bits_per_sample != 8) 1.1217 ++ s->packed = TRUE; 1.1218 ++ else 1.1219 ++ s->packed = FALSE; 1.1220 ++ s->band[0].det = 32; 1.1221 ++ s->band[1].det = 8; 1.1222 ++ return s; 1.1223 ++} 1.1224 ++/*- End of function --------------------------------------------------------*/ 1.1225 ++ 1.1226 ++int g722_encode_release(g722_encode_state_t *s) 1.1227 ++{ 1.1228 ++ free(s); 1.1229 ++ return 0; 1.1230 ++} 1.1231 ++/*- End of function --------------------------------------------------------*/ 1.1232 ++ 1.1233 ++int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len) 1.1234 ++{ 1.1235 ++ static const int q6[32] = 1.1236 ++ { 1.1237 ++ 0, 35, 72, 110, 150, 190, 233, 276, 1.1238 ++ 323, 370, 422, 473, 530, 587, 650, 714, 1.1239 ++ 786, 858, 940, 1023, 1121, 1219, 1339, 1458, 1.1240 ++ 1612, 1765, 1980, 2195, 2557, 2919, 0, 0 1.1241 ++ }; 1.1242 ++ static const int iln[32] = 1.1243 ++ { 1.1244 ++ 0, 63, 62, 31, 30, 29, 28, 27, 1.1245 ++ 26, 25, 24, 23, 22, 21, 20, 19, 1.1246 ++ 18, 17, 16, 15, 14, 13, 12, 11, 1.1247 ++ 10, 9, 8, 7, 6, 5, 4, 0 1.1248 ++ }; 1.1249 ++ static const int ilp[32] = 1.1250 ++ { 1.1251 ++ 0, 61, 60, 59, 58, 57, 56, 55, 1.1252 ++ 54, 53, 52, 51, 50, 49, 48, 47, 1.1253 ++ 46, 45, 44, 43, 42, 41, 40, 39, 1.1254 ++ 38, 37, 36, 35, 34, 33, 32, 0 1.1255 ++ }; 1.1256 ++ static const int wl[8] = 1.1257 ++ { 1.1258 ++ -60, -30, 58, 172, 334, 538, 1198, 3042 1.1259 ++ }; 1.1260 ++ static const int rl42[16] = 1.1261 ++ { 1.1262 ++ 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 1.1263 ++ }; 1.1264 ++ static const int ilb[32] = 1.1265 ++ { 1.1266 ++ 2048, 2093, 2139, 2186, 2233, 2282, 2332, 1.1267 ++ 2383, 2435, 2489, 2543, 2599, 2656, 2714, 1.1268 ++ 2774, 2834, 2896, 2960, 3025, 3091, 3158, 1.1269 ++ 3228, 3298, 3371, 3444, 3520, 3597, 3676, 1.1270 ++ 3756, 3838, 3922, 4008 1.1271 ++ }; 1.1272 ++ static const int qm4[16] = 1.1273 ++ { 1.1274 ++ 0, -20456, -12896, -8968, 1.1275 ++ -6288, -4240, -2584, -1200, 1.1276 ++ 20456, 12896, 8968, 6288, 1.1277 ++ 4240, 2584, 1200, 0 1.1278 ++ }; 1.1279 ++ static const int qm2[4] = 1.1280 ++ { 1.1281 ++ -7408, -1616, 7408, 1616 1.1282 ++ }; 1.1283 ++ static const int qmf_coeffs[12] = 1.1284 ++ { 1.1285 ++ 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11, 1.1286 ++ }; 1.1287 ++ static const int ihn[3] = {0, 1, 0}; 1.1288 ++ static const int ihp[3] = {0, 3, 2}; 1.1289 ++ static const int wh[3] = {0, -214, 798}; 1.1290 ++ static const int rh2[4] = {2, 1, 2, 1}; 1.1291 ++ 1.1292 ++ int dlow; 1.1293 ++ int dhigh; 1.1294 ++ int el; 1.1295 ++ int wd; 1.1296 ++ int wd1; 1.1297 ++ int ril; 1.1298 ++ int wd2; 1.1299 ++ int il4; 1.1300 ++ int ih2; 1.1301 ++ int wd3; 1.1302 ++ int eh; 1.1303 ++ int mih; 1.1304 ++ int i; 1.1305 ++ int j; 1.1306 ++ /* Low and high band PCM from the QMF */ 1.1307 ++ int xlow; 1.1308 ++ int xhigh; 1.1309 ++ int g722_bytes; 1.1310 ++ /* Even and odd tap accumulators */ 1.1311 ++ int sumeven; 1.1312 ++ int sumodd; 1.1313 ++ int ihigh; 1.1314 ++ int ilow; 1.1315 ++ int code; 1.1316 ++ 1.1317 ++ g722_bytes = 0; 1.1318 ++ xhigh = 0; 1.1319 ++ for (j = 0; j < len; ) 1.1320 ++ { 1.1321 ++ if (s->itu_test_mode) 1.1322 ++ { 1.1323 ++ xlow = 1.1324 ++ xhigh = amp[j++] >> 1; 1.1325 ++ } 1.1326 ++ else 1.1327 ++ { 1.1328 ++ if (s->eight_k) 1.1329 ++ { 1.1330 ++ xlow = amp[j++]; 1.1331 ++ } 1.1332 ++ else 1.1333 ++ { 1.1334 ++ /* Apply the transmit QMF */ 1.1335 ++ /* Shuffle the buffer down */ 1.1336 ++ for (i = 0; i < 22; i++) 1.1337 ++ s->x[i] = s->x[i + 2]; 1.1338 ++ s->x[22] = amp[j++]; 1.1339 ++ s->x[23] = amp[j++]; 1.1340 ++ 1.1341 ++ /* Discard every other QMF output */ 1.1342 ++ sumeven = 0; 1.1343 ++ sumodd = 0; 1.1344 ++ for (i = 0; i < 12; i++) 1.1345 ++ { 1.1346 ++ sumodd += s->x[2*i]*qmf_coeffs[i]; 1.1347 ++ sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i]; 1.1348 ++ } 1.1349 ++ xlow = (sumeven + sumodd) >> 13; 1.1350 ++ xhigh = (sumeven - sumodd) >> 13; 1.1351 ++ } 1.1352 ++ } 1.1353 ++ /* Block 1L, SUBTRA */ 1.1354 ++ el = saturate(xlow - s->band[0].s); 1.1355 ++ 1.1356 ++ /* Block 1L, QUANTL */ 1.1357 ++ wd = (el >= 0) ? el : -(el + 1); 1.1358 ++ 1.1359 ++ for (i = 1; i < 30; i++) 1.1360 ++ { 1.1361 ++ wd1 = (q6[i]*s->band[0].det) >> 12; 1.1362 ++ if (wd < wd1) 1.1363 ++ break; 1.1364 ++ } 1.1365 ++ ilow = (el < 0) ? iln[i] : ilp[i]; 1.1366 ++ 1.1367 ++ /* Block 2L, INVQAL */ 1.1368 ++ ril = ilow >> 2; 1.1369 ++ wd2 = qm4[ril]; 1.1370 ++ dlow = (s->band[0].det*wd2) >> 15; 1.1371 ++ 1.1372 ++ /* Block 3L, LOGSCL */ 1.1373 ++ il4 = rl42[ril]; 1.1374 ++ wd = (s->band[0].nb*127) >> 7; 1.1375 ++ s->band[0].nb = wd + wl[il4]; 1.1376 ++ if (s->band[0].nb < 0) 1.1377 ++ s->band[0].nb = 0; 1.1378 ++ else if (s->band[0].nb > 18432) 1.1379 ++ s->band[0].nb = 18432; 1.1380 ++ 1.1381 ++ /* Block 3L, SCALEL */ 1.1382 ++ wd1 = (s->band[0].nb >> 6) & 31; 1.1383 ++ wd2 = 8 - (s->band[0].nb >> 11); 1.1384 ++ wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); 1.1385 ++ s->band[0].det = wd3 << 2; 1.1386 ++ 1.1387 ++ block4(s, 0, dlow); 1.1388 ++ 1.1389 ++ if (s->eight_k) 1.1390 ++ { 1.1391 ++ /* Just leave the high bits as zero */ 1.1392 ++ code = (0xC0 | ilow) >> (8 - s->bits_per_sample); 1.1393 ++ } 1.1394 ++ else 1.1395 ++ { 1.1396 ++ /* Block 1H, SUBTRA */ 1.1397 ++ eh = saturate(xhigh - s->band[1].s); 1.1398 ++ 1.1399 ++ /* Block 1H, QUANTH */ 1.1400 ++ wd = (eh >= 0) ? eh : -(eh + 1); 1.1401 ++ wd1 = (564*s->band[1].det) >> 12; 1.1402 ++ mih = (wd >= wd1) ? 2 : 1; 1.1403 ++ ihigh = (eh < 0) ? ihn[mih] : ihp[mih]; 1.1404 ++ 1.1405 ++ /* Block 2H, INVQAH */ 1.1406 ++ wd2 = qm2[ihigh]; 1.1407 ++ dhigh = (s->band[1].det*wd2) >> 15; 1.1408 ++ 1.1409 ++ /* Block 3H, LOGSCH */ 1.1410 ++ ih2 = rh2[ihigh]; 1.1411 ++ wd = (s->band[1].nb*127) >> 7; 1.1412 ++ s->band[1].nb = wd + wh[ih2]; 1.1413 ++ if (s->band[1].nb < 0) 1.1414 ++ s->band[1].nb = 0; 1.1415 ++ else if (s->band[1].nb > 22528) 1.1416 ++ s->band[1].nb = 22528; 1.1417 ++ 1.1418 ++ /* Block 3H, SCALEH */ 1.1419 ++ wd1 = (s->band[1].nb >> 6) & 31; 1.1420 ++ wd2 = 10 - (s->band[1].nb >> 11); 1.1421 ++ wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2); 1.1422 ++ s->band[1].det = wd3 << 2; 1.1423 ++ 1.1424 ++ block4(s, 1, dhigh); 1.1425 ++ code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample); 1.1426 ++ } 1.1427 ++ 1.1428 ++ if (s->packed) 1.1429 ++ { 1.1430 ++ /* Pack the code bits */ 1.1431 ++ s->out_buffer |= (code << s->out_bits); 1.1432 ++ s->out_bits += s->bits_per_sample; 1.1433 ++ if (s->out_bits >= 8) 1.1434 ++ { 1.1435 ++ g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF); 1.1436 ++ s->out_bits -= 8; 1.1437 ++ s->out_buffer >>= 8; 1.1438 ++ } 1.1439 ++ } 1.1440 ++ else 1.1441 ++ { 1.1442 ++ g722_data[g722_bytes++] = (uint8_t) code; 1.1443 ++ } 1.1444 ++ } 1.1445 ++ return g722_bytes; 1.1446 ++} 1.1447 ++/*- End of function --------------------------------------------------------*/ 1.1448 ++/*- End of file ------------------------------------------------------------*/ 1.1449 +Index: codecs/g722/g722.h 1.1450 +diff -Nau codecs/g722/g722.h.orig codecs/g722/g722.h 1.1451 +--- codecs/g722/g722.h.orig 1970-01-01 01:00:00.000000000 +0100 1.1452 ++++ codecs/g722/g722.h 2009-04-24 00:30:33.000000000 +0200 1.1453 +@@ -0,0 +1,148 @@ 1.1454 ++/* 1.1455 ++ * SpanDSP - a series of DSP components for telephony 1.1456 ++ * 1.1457 ++ * g722.h - The ITU G.722 codec. 1.1458 ++ * 1.1459 ++ * Written by Steve Underwood <steveu@coppice.org> 1.1460 ++ * 1.1461 ++ * Copyright (C) 2005 Steve Underwood 1.1462 ++ * 1.1463 ++ * Despite my general liking of the GPL, I place my own contributions 1.1464 ++ * to this code in the public domain for the benefit of all mankind - 1.1465 ++ * even the slimy ones who might try to proprietize my work and use it 1.1466 ++ * to my detriment. 1.1467 ++ * 1.1468 ++ * Based on a single channel G.722 codec which is: 1.1469 ++ * 1.1470 ++ ***** Copyright (c) CMU 1993 ***** 1.1471 ++ * Computer Science, Speech Group 1.1472 ++ * Chengxiang Lu and Alex Hauptmann 1.1473 ++ * 1.1474 ++ * $Id: g722.h 48959 2006-12-25 06:42:15Z rizzo $ 1.1475 ++ */ 1.1476 ++ 1.1477 ++ 1.1478 ++/*! \file */ 1.1479 ++ 1.1480 ++#if !defined(_G722_H_) 1.1481 ++#define _G722_H_ 1.1482 ++ 1.1483 ++/*! \page g722_page G.722 encoding and decoding 1.1484 ++\section g722_page_sec_1 What does it do? 1.1485 ++The G.722 module is a bit exact implementation of the ITU G.722 specification for all three 1.1486 ++specified bit rates - 64000bps, 56000bps and 48000bps. It passes the ITU tests. 1.1487 ++ 1.1488 ++To allow fast and flexible interworking with narrow band telephony, the encoder and decoder 1.1489 ++support an option for the linear audio to be an 8k samples/second stream. In this mode the 1.1490 ++codec is considerably faster, and still fully compatible with wideband terminals using G.722. 1.1491 ++ 1.1492 ++\section g722_page_sec_2 How does it work? 1.1493 ++???. 1.1494 ++*/ 1.1495 ++ 1.1496 ++enum 1.1497 ++{ 1.1498 ++ G722_SAMPLE_RATE_8000 = 0x0001, 1.1499 ++ G722_PACKED = 0x0002 1.1500 ++}; 1.1501 ++ 1.1502 ++#ifndef INT16_MAX 1.1503 ++#define INT16_MAX 32767 1.1504 ++#endif 1.1505 ++#ifndef INT16_MIN 1.1506 ++#define INT16_MIN (-32768) 1.1507 ++#endif 1.1508 ++ 1.1509 ++typedef struct 1.1510 ++{ 1.1511 ++ /*! TRUE if the operating in the special ITU test mode, with the band split filters 1.1512 ++ disabled. */ 1.1513 ++ int itu_test_mode; 1.1514 ++ /*! TRUE if the G.722 data is packed */ 1.1515 ++ int packed; 1.1516 ++ /*! TRUE if encode from 8k samples/second */ 1.1517 ++ int eight_k; 1.1518 ++ /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */ 1.1519 ++ int bits_per_sample; 1.1520 ++ 1.1521 ++ /*! Signal history for the QMF */ 1.1522 ++ int x[24]; 1.1523 ++ 1.1524 ++ struct 1.1525 ++ { 1.1526 ++ int s; 1.1527 ++ int sp; 1.1528 ++ int sz; 1.1529 ++ int r[3]; 1.1530 ++ int a[3]; 1.1531 ++ int ap[3]; 1.1532 ++ int p[3]; 1.1533 ++ int d[7]; 1.1534 ++ int b[7]; 1.1535 ++ int bp[7]; 1.1536 ++ int sg[7]; 1.1537 ++ int nb; 1.1538 ++ int det; 1.1539 ++ } band[2]; 1.1540 ++ 1.1541 ++ unsigned int in_buffer; 1.1542 ++ int in_bits; 1.1543 ++ unsigned int out_buffer; 1.1544 ++ int out_bits; 1.1545 ++} g722_encode_state_t; 1.1546 ++ 1.1547 ++typedef struct 1.1548 ++{ 1.1549 ++ /*! TRUE if the operating in the special ITU test mode, with the band split filters 1.1550 ++ disabled. */ 1.1551 ++ int itu_test_mode; 1.1552 ++ /*! TRUE if the G.722 data is packed */ 1.1553 ++ int packed; 1.1554 ++ /*! TRUE if decode to 8k samples/second */ 1.1555 ++ int eight_k; 1.1556 ++ /*! 6 for 48000kbps, 7 for 56000kbps, or 8 for 64000kbps. */ 1.1557 ++ int bits_per_sample; 1.1558 ++ 1.1559 ++ /*! Signal history for the QMF */ 1.1560 ++ int x[24]; 1.1561 ++ 1.1562 ++ struct 1.1563 ++ { 1.1564 ++ int s; 1.1565 ++ int sp; 1.1566 ++ int sz; 1.1567 ++ int r[3]; 1.1568 ++ int a[3]; 1.1569 ++ int ap[3]; 1.1570 ++ int p[3]; 1.1571 ++ int d[7]; 1.1572 ++ int b[7]; 1.1573 ++ int bp[7]; 1.1574 ++ int sg[7]; 1.1575 ++ int nb; 1.1576 ++ int det; 1.1577 ++ } band[2]; 1.1578 ++ 1.1579 ++ unsigned int in_buffer; 1.1580 ++ int in_bits; 1.1581 ++ unsigned int out_buffer; 1.1582 ++ int out_bits; 1.1583 ++} g722_decode_state_t; 1.1584 ++ 1.1585 ++#ifdef __cplusplus 1.1586 ++extern "C" { 1.1587 ++#endif 1.1588 ++ 1.1589 ++g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options); 1.1590 ++int g722_encode_release(g722_encode_state_t *s); 1.1591 ++int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len); 1.1592 ++ 1.1593 ++g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options); 1.1594 ++int g722_decode_release(g722_decode_state_t *s); 1.1595 ++int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len); 1.1596 ++ 1.1597 ++#ifdef __cplusplus 1.1598 ++} 1.1599 ++#endif 1.1600 ++ 1.1601 ++#endif 1.1602 +Index: codecs/g722/Makefile 1.1603 +diff -Nau codecs/g722/Makefile.orig codecs/g722/Makefile 1.1604 +--- codecs/g722/Makefile.orig 1970-01-01 01:00:00.000000000 +0100 1.1605 ++++ codecs/g722/Makefile 2009-04-24 00:30:33.000000000 +0200 1.1606 +@@ -0,0 +1,18 @@ 1.1607 ++LIB=libg722.a 1.1608 ++CFLAGS+=-fPIC 1.1609 ++ 1.1610 ++include $(ASTTOPDIR)/Makefile.rules 1.1611 ++ 1.1612 ++OBJS=g722_encode.o g722_decode.o 1.1613 ++ 1.1614 ++all: $(LIB) 1.1615 ++ 1.1616 ++$(LIB): $(OBJS) 1.1617 ++ $(ECHO_PREFIX) echo " [AR] $^ -> $@" 1.1618 ++ $(CMD_PREFIX) $(AR) cr $@ $^ 1.1619 ++ $(CMD_PREFIX) $(RANLIB) $@ 1.1620 ++ 1.1621 ++clean: 1.1622 ++ rm -f $(LIB) *.o 1.1623 ++ rm -f .*.o.d 1.1624 ++ rm -f *.s *.i 1.1625 +Index: codecs/g722_slin_ex.h 1.1626 +diff -Nau codecs/g722_slin_ex.h.orig codecs/g722_slin_ex.h 1.1627 +--- codecs/g722_slin_ex.h.orig 1970-01-01 01:00:00.000000000 +0100 1.1628 ++++ codecs/g722_slin_ex.h 2009-04-24 00:30:33.000000000 +0200 1.1629 +@@ -0,0 +1,25 @@ 1.1630 ++/*! \file 1.1631 ++ * \brief g722_slin_ex.h -- 1.1632 ++ * 1.1633 ++ * 4-bit ADPCM data, 20 milliseconds worth at 8 kHz. 1.1634 ++ * 1.1635 ++ * Source: g723.example 1.1636 ++ * 1.1637 ++ * Copyright (C) 2001-2005, Digium Inc. 1.1638 ++ * 1.1639 ++ * Distributed under the terms of the GNU General Public License 1.1640 ++ * 1.1641 ++ */ 1.1642 ++ 1.1643 ++static unsigned char g722_slin_ex[] = { 1.1644 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.1645 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.1646 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.1647 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.1648 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.1649 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.1650 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.1651 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.1652 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1.1653 ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 1.1654 ++}; 1.1655 +Index: codecs/Makefile 1.1656 +diff -Nau codecs/Makefile.orig codecs/Makefile 1.1657 +--- codecs/Makefile.orig 2008-03-26 17:42:35.000000000 +0100 1.1658 ++++ codecs/Makefile 2009-04-24 00:30:33.000000000 +0200 1.1659 +@@ -31,6 +31,7 @@ 1.1660 + 1.1661 + LIBILBC:=ilbc/libilbc.a 1.1662 + LIBLPC10:=lpc10/liblpc10.a 1.1663 ++LIBG722:=g722/libg722.a 1.1664 + 1.1665 + all: _all 1.1666 + 1.1667 +@@ -45,6 +46,7 @@ 1.1668 + $(MAKE) -C gsm clean 1.1669 + $(MAKE) -C lpc10 clean 1.1670 + $(MAKE) -C ilbc clean 1.1671 ++ $(MAKE) -C g722 clean 1.1672 + 1.1673 + gsm/lib/libgsm.a: 1.1674 + @mkdir -p gsm/lib 1.1675 +@@ -59,3 +61,8 @@ 1.1676 + @$(MAKE) -C ilbc all ASTCFLAGS="$(filter-out -Wmissing-prototypes -Wmissing-declarations,$(ASTCFLAGS)) $(AST_NO_STRICT_OVERFLOW)" 1.1677 + 1.1678 + $(if $(filter codec_ilbc,$(EMBEDDED_MODS)),modules.link,codec_ilbc.so): $(LIBILBC) 1.1679 ++ 1.1680 ++$(LIBG722): 1.1681 ++ @$(MAKE) -C g722 all 1.1682 ++ 1.1683 ++$(if $(filter codec_g722,$(EMBEDDED_MODS)),modules.link,codec_g722.so): $(LIBG722) 1.1684 +Index: codecs/slin_g722_ex.h 1.1685 +diff -Nau codecs/slin_g722_ex.h.orig codecs/slin_g722_ex.h 1.1686 +--- codecs/slin_g722_ex.h.orig 1970-01-01 01:00:00.000000000 +0100 1.1687 ++++ codecs/slin_g722_ex.h 2009-04-24 00:30:33.000000000 +0200 1.1688 +@@ -0,0 +1,25 @@ 1.1689 ++/*! \file 1.1690 ++ * \brief slin_g722_ex.h -- 1.1691 ++ * 1.1692 ++ * Signed 16-bit audio data, 10 milliseconds worth at 8 kHz. 1.1693 ++ * 1.1694 ++ * Source: g723.example 1.1695 ++ * 1.1696 ++ * Copyright (C) 2001-2005, Digium Inc. 1.1697 ++ * 1.1698 ++ * Distributed under the terms of the GNU General Public License 1.1699 ++ * 1.1700 ++ */ 1.1701 ++ 1.1702 ++static signed short slin_g722_ex[] = { 1.1703 ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 1.1704 ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 1.1705 ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 1.1706 ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 1.1707 ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 1.1708 ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 1.1709 ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 1.1710 ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 1.1711 ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 1.1712 ++ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 1.1713 ++}; 1.1714 +Index: configure 1.1715 +diff -Nau configure.orig configure 1.1716 +--- configure.orig 2009-02-18 21:06:45.000000000 +0100 1.1717 ++++ configure 2009-04-24 00:30:33.000000000 +0200 1.1718 +@@ -11143,6 +11143,61 @@ 1.1719 + 1.1720 + fi 1.1721 + 1.1722 ++{ echo "$as_me:$LINENO: checking for tm_gmtoff in struct tm" >&5 1.1723 ++echo $ECHO_N "checking for tm_gmtoff in struct tm... $ECHO_C" >&6; } 1.1724 ++if test "${ac_cv_struct_tm_gmtoff+set}" = set; then 1.1725 ++ echo $ECHO_N "(cached) $ECHO_C" >&6 1.1726 ++else 1.1727 ++ cat >conftest.$ac_ext <<_ACEOF 1.1728 ++/* confdefs.h. */ 1.1729 ++_ACEOF 1.1730 ++cat confdefs.h >>conftest.$ac_ext 1.1731 ++cat >>conftest.$ac_ext <<_ACEOF 1.1732 ++/* end confdefs.h. */ 1.1733 ++$ac_includes_default 1.1734 ++#include <sys/types.h> 1.1735 ++#include <$ac_cv_struct_tm> 1.1736 ++int main() { 1.1737 ++struct tm tm; tm.tm_gmtoff; 1.1738 ++; return 0; } 1.1739 ++_ACEOF 1.1740 ++rm -f conftest.$ac_objext 1.1741 ++if { (ac_try="$ac_compile" 1.1742 ++case "(($ac_try" in 1.1743 ++ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; 1.1744 ++ *) ac_try_echo=$ac_try;; 1.1745 ++esac 1.1746 ++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 1.1747 ++ (eval "$ac_compile") 2>conftest.er1 1.1748 ++ ac_status=$? 1.1749 ++ grep -v '^ *+' conftest.er1 >conftest.err 1.1750 ++ rm -f conftest.er1 1.1751 ++ cat conftest.err >&5 1.1752 ++ echo "$as_me:$LINENO: \$? = $ac_status" >&5 1.1753 ++ (exit $ac_status); } && { 1.1754 ++ test -z "$ac_c_werror_flag" || 1.1755 ++ test ! -s conftest.err 1.1756 ++ } && test -s conftest.$ac_objext; then 1.1757 ++ ac_cv_struct_tm_gmtoff=yes 1.1758 ++else 1.1759 ++ echo "$as_me: failed program was:" >&5 1.1760 ++sed 's/^/| /' conftest.$ac_ext >&5 1.1761 ++ 1.1762 ++ ac_cv_struct_tm_gmtoff=no 1.1763 ++fi 1.1764 ++ 1.1765 ++rm -f conftest* 1.1766 ++fi 1.1767 ++{ echo "$as_me:$LINENO: result: $ac_cv_struct_tm_gmtoff" >&5 1.1768 ++echo "${ECHO_T}$ac_cv_struct_tm_gmtoff" >&6; } 1.1769 ++if test $ac_cv_struct_tm_gmtoff = yes; then 1.1770 ++ 1.1771 ++cat >>confdefs.h <<\_ACEOF 1.1772 ++#define TM_GMTOFF 1 1.1773 ++_ACEOF 1.1774 ++ 1.1775 ++fi 1.1776 ++ 1.1777 + { echo "$as_me:$LINENO: checking for working volatile" >&5 1.1778 + echo $ECHO_N "checking for working volatile... $ECHO_C" >&6; } 1.1779 + if test "${ac_cv_c_volatile+set}" = set; then 1.1780 +Index: include/asterisk/config.h 1.1781 +diff -Nau include/asterisk/config.h.orig include/asterisk/config.h 1.1782 +--- include/asterisk/config.h.orig 2009-02-18 19:30:38.000000000 +0100 1.1783 ++++ include/asterisk/config.h 2009-04-24 00:30:33.000000000 +0200 1.1784 +@@ -33,6 +33,8 @@ 1.1785 + 1.1786 + struct ast_category; 1.1787 + 1.1788 ++#define CONFIG_STATUS_FILEUNCHANGED (void *)-1 1.1789 ++ 1.1790 + struct ast_variable { 1.1791 + char *name; 1.1792 + char *value; 1.1793 +Index: include/asterisk/frame.h 1.1794 +diff -Nau include/asterisk/frame.h.orig include/asterisk/frame.h 1.1795 +--- include/asterisk/frame.h.orig 2009-03-05 19:22:16.000000000 +0100 1.1796 ++++ include/asterisk/frame.h 2009-04-24 00:30:33.000000000 +0200 1.1797 +@@ -260,6 +260,8 @@ 1.1798 + #define AST_FORMAT_G726 (1 << 11) 1.1799 + /*! G.722 */ 1.1800 + #define AST_FORMAT_G722 (1 << 12) 1.1801 ++/*! Raw 16-bit Signed Linear (16000 Hz) PCM */ 1.1802 ++#define AST_FORMAT_SLINEAR16 (1 << 15) 1.1803 + /*! Unsupported audio bits */ 1.1804 + #define AST_FORMAT_AUDIO_UNDEFINED ((1 << 13) | (1 << 14) | (1 << 15)) 1.1805 + /*! Maximum audio format */ 1.1806 +Index: main/editline/np/vis.h 1.1807 +diff -Nau main/editline/np/vis.h.orig main/editline/np/vis.h 1.1808 +--- main/editline/np/vis.h.orig 2006-08-21 04:11:39.000000000 +0200 1.1809 ++++ main/editline/np/vis.h 2009-04-24 00:30:33.000000000 +0200 1.1810 +@@ -76,6 +76,22 @@ 1.1811 + 1.1812 + #include <sys/cdefs.h> 1.1813 + 1.1814 ++/* correct nonportable unsigned type usage */ 1.1815 ++#if !defined(__FreeBSD__) && !defined(__linux__) 1.1816 ++#ifndef u_int64_t 1.1817 ++#define u_int64_t unsigned long long 1.1818 ++#endif 1.1819 ++#ifndef u_int32_t 1.1820 ++#define u_int32_t unsigned int 1.1821 ++#endif 1.1822 ++#ifndef u_int16_t 1.1823 ++#define u_int16_t unsigned short 1.1824 ++#endif 1.1825 ++#ifndef u_int6_t 1.1826 ++#define u_int8_t unsigned char 1.1827 ++#endif 1.1828 ++#endif 1.1829 ++ 1.1830 + __BEGIN_DECLS 1.1831 + char *vis __P((char *, int, int, int)); 1.1832 + char *svis __P((char *, int, int, int, const char *)); 1.1833 +Index: main/stdtime/localtime.c 1.1834 +diff -Nau main/stdtime/localtime.c.orig main/stdtime/localtime.c 1.1835 +--- main/stdtime/localtime.c.orig 2008-09-27 17:00:48.000000000 +0200 1.1836 ++++ main/stdtime/localtime.c 2009-04-24 00:30:33.000000000 +0200 1.1837 +@@ -1134,9 +1134,9 @@ 1.1838 + */ 1.1839 + result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); 1.1840 + tmp->tm_isdst = ttisp->tt_isdst; 1.1841 +-#ifndef SOLARIS /* Solaris doesn't have this element */ 1.1842 ++#ifdef TM_GMTOFF 1.1843 + tmp->tm_gmtoff = ttisp->tt_gmtoff; 1.1844 +-#endif 1.1845 ++#endif /* defined TM_GMTOFF */ 1.1846 + #ifdef TM_ZONE 1.1847 + tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; 1.1848 + #endif /* defined TM_ZONE */ 1.1849 +Index: Makefile.moddir_rules 1.1850 +diff -Nau Makefile.moddir_rules.orig Makefile.moddir_rules 1.1851 +--- Makefile.moddir_rules.orig 2008-11-26 19:36:24.000000000 +0100 1.1852 ++++ Makefile.moddir_rules 2009-04-24 00:30:33.000000000 +0200 1.1853 +@@ -69,7 +69,9 @@ 1.1854 + rm -f modules.link 1.1855 + 1.1856 + install:: all 1.1857 ++ifneq ($(LOADABLE_MODS),) 1.1858 + for x in $(LOADABLE_MODS:%=%.so); do $(INSTALL) -m 755 $$x $(DESTDIR)$(MODULES_DIR) ; done 1.1859 ++endif 1.1860 + 1.1861 + uninstall:: 1.1862 + 1.1863 +Index: res/res_features.c 1.1864 +diff -Nau res/res_features.c.orig res/res_features.c 1.1865 +--- res/res_features.c.orig 2009-03-03 19:27:09.000000000 +0100 1.1866 ++++ res/res_features.c 2009-04-24 00:30:33.000000000 +0200 1.1867 +@@ -732,6 +732,10 @@ 1.1868 + snprintf(args, len, "%s|%s|m", S_OR(touch_format, "wav"), touch_filename); 1.1869 + } 1.1870 + 1.1871 ++ for( x = 0; x < strlen(touch_filename); x++) { 1.1872 ++ if (touch_filename[x] == '/') 1.1873 ++ touch_filename[x] = '-'; 1.1874 ++ } 1.1875 + for( x = 0; x < strlen(args); x++) { 1.1876 + if (args[x] == '/') 1.1877 + args[x] = '-'; 1.1878 +@@ -2774,6 +2778,293 @@ 1.1879 + } 1.1880 + } 1.1881 + 1.1882 ++static char mandescr_bridge[] = 1.1883 ++"Description: Bridge together two channels already in the PBX\n" 1.1884 ++"Variables: ( Headers marked with * are required )\n" 1.1885 ++" *Channel1: Channel to Bridge to Channel2\n" 1.1886 ++" *Channel2: Channel to Bridge to Channel1\n" 1.1887 ++" Tone: (Yes|No) Play courtesy tone to Channel 2\n" 1.1888 ++"\n"; 1.1889 ++ 1.1890 ++/*! 1.1891 ++ * \brief Actual bridge 1.1892 ++ * \param chan 1.1893 ++ * \param tmpchan 1.1894 ++ * 1.1895 ++ * Stop hold music, lock both channels, masq channels, 1.1896 ++ * after bridge return channel to next priority. 1.1897 ++*/ 1.1898 ++static void do_bridge_masquerade(struct ast_channel *chan, struct ast_channel *tmpchan) 1.1899 ++{ 1.1900 ++ ast_moh_stop(chan); 1.1901 ++ ast_channel_lock(chan); 1.1902 ++ ast_setstate(tmpchan, chan->_state); 1.1903 ++ tmpchan->readformat = chan->readformat; 1.1904 ++ tmpchan->writeformat = chan->writeformat; 1.1905 ++ ast_channel_masquerade(tmpchan, chan); 1.1906 ++ ast_channel_lock(tmpchan); 1.1907 ++ ast_do_masquerade(tmpchan); 1.1908 ++ /* when returning from bridge, the channel will continue at the next priority */ 1.1909 ++ ast_explicit_goto(tmpchan, chan->context, chan->exten, chan->priority + 1); 1.1910 ++ ast_channel_unlock(tmpchan); 1.1911 ++ ast_channel_unlock(chan); 1.1912 ++} 1.1913 ++ 1.1914 ++/*! 1.1915 ++ * \brief Bridge channels together 1.1916 ++ * \param s 1.1917 ++ * \param m 1.1918 ++ * 1.1919 ++ * Make sure valid channels were specified, 1.1920 ++ * send errors if any of the channels could not be found/locked, answer channels if needed, 1.1921 ++ * create the placeholder channels and grab the other channels 1.1922 ++ * make the channels compatible, send error if we fail doing so 1.1923 ++ * setup the bridge thread object and start the bridge. 1.1924 ++ * 1.1925 ++ * \retval 0 on success or on incorrect use. 1.1926 ++ * \retval 1 on failure to bridge channels. 1.1927 ++*/ 1.1928 ++static int action_bridge(struct mansession *s, const struct message *m) 1.1929 ++{ 1.1930 ++ const char *channela = astman_get_header(m, "Channel1"); 1.1931 ++ const char *channelb = astman_get_header(m, "Channel2"); 1.1932 ++ const char *playtone = astman_get_header(m, "Tone"); 1.1933 ++ struct ast_channel *chana = NULL, *chanb = NULL; 1.1934 ++ struct ast_channel *tmpchana = NULL, *tmpchanb = NULL; 1.1935 ++ struct ast_bridge_thread_obj *tobj = NULL; 1.1936 ++ 1.1937 ++ /* make sure valid channels were specified */ 1.1938 ++ if (!ast_strlen_zero(channela) && !ast_strlen_zero(channelb)) { 1.1939 ++ chana = ast_get_channel_by_name_prefix_locked(channela, strlen(channela)); 1.1940 ++ chanb = ast_get_channel_by_name_prefix_locked(channelb, strlen(channelb)); 1.1941 ++ if (chana) 1.1942 ++ ast_channel_unlock(chana); 1.1943 ++ if (chanb) 1.1944 ++ ast_channel_unlock(chanb); 1.1945 ++ 1.1946 ++ /* send errors if any of the channels could not be found/locked */ 1.1947 ++ if (!chana) { 1.1948 ++ char buf[256]; 1.1949 ++ snprintf(buf, sizeof(buf), "Channel1 does not exist: %s", channela); 1.1950 ++ astman_send_error(s, m, buf); 1.1951 ++ return 0; 1.1952 ++ } 1.1953 ++ if (!chanb) { 1.1954 ++ char buf[256]; 1.1955 ++ snprintf(buf, sizeof(buf), "Channel2 does not exist: %s", channelb); 1.1956 ++ astman_send_error(s, m, buf); 1.1957 ++ return 0; 1.1958 ++ } 1.1959 ++ } else { 1.1960 ++ astman_send_error(s, m, "Missing channel parameter in request"); 1.1961 ++ return 0; 1.1962 ++ } 1.1963 ++ 1.1964 ++ /* Answer the channels if needed */ 1.1965 ++ if (chana->_state != AST_STATE_UP) 1.1966 ++ ast_answer(chana); 1.1967 ++ if (chanb->_state != AST_STATE_UP) 1.1968 ++ ast_answer(chanb); 1.1969 ++ 1.1970 ++ /* create the placeholder channels and grab the other channels */ 1.1971 ++ if (!(tmpchana = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 1.1972 ++ NULL, NULL, 0, "Bridge/%s", chana->name))) { 1.1973 ++ astman_send_error(s, m, "Unable to create temporary channel!"); 1.1974 ++ return 1; 1.1975 ++ } 1.1976 ++ 1.1977 ++ if (!(tmpchanb = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 1.1978 ++ NULL, NULL, 0, "Bridge/%s", chanb->name))) { 1.1979 ++ astman_send_error(s, m, "Unable to create temporary channels!"); 1.1980 ++ ast_channel_free(tmpchana); 1.1981 ++ return 1; 1.1982 ++ } 1.1983 ++ 1.1984 ++ do_bridge_masquerade(chana, tmpchana); 1.1985 ++ do_bridge_masquerade(chanb, tmpchanb); 1.1986 ++ 1.1987 ++ /* make the channels compatible, send error if we fail doing so */ 1.1988 ++ if (ast_channel_make_compatible(tmpchana, tmpchanb)) { 1.1989 ++ ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for manager bridge\n", tmpchana->name, tmpchanb->name); 1.1990 ++ astman_send_error(s, m, "Could not make channels compatible for manager bridge"); 1.1991 ++ ast_hangup(tmpchana); 1.1992 ++ ast_hangup(tmpchanb); 1.1993 ++ return 1; 1.1994 ++ } 1.1995 ++ 1.1996 ++ /* setup the bridge thread object and start the bridge */ 1.1997 ++ if (!(tobj = ast_calloc(1, sizeof(*tobj)))) { 1.1998 ++ ast_log(LOG_WARNING, "Unable to spawn a new bridge thread on %s and %s: %s\n", tmpchana->name, tmpchanb->name, strerror(errno)); 1.1999 ++ astman_send_error(s, m, "Unable to spawn a new bridge thread"); 1.2000 ++ ast_hangup(tmpchana); 1.2001 ++ ast_hangup(tmpchanb); 1.2002 ++ return 1; 1.2003 ++ } 1.2004 ++ 1.2005 ++ tobj->chan = tmpchana; 1.2006 ++ tobj->peer = tmpchanb; 1.2007 ++ 1.2008 ++ if (ast_true(playtone)) { 1.2009 ++ if (!ast_strlen_zero(xfersound) && !ast_streamfile(tmpchanb, xfersound, tmpchanb->language)) { 1.2010 ++ if (ast_waitstream(tmpchanb, "") < 0) 1.2011 ++ ast_log(LOG_WARNING, "Failed to play a courtesy tone on chan %s\n", tmpchanb->name); 1.2012 ++ } 1.2013 ++ } 1.2014 ++ 1.2015 ++ ast_bridge_call_thread_launch(tobj); 1.2016 ++ 1.2017 ++ astman_send_ack(s, m, "Launched bridge thread with success"); 1.2018 ++ 1.2019 ++ return 0; 1.2020 ++} 1.2021 ++ 1.2022 ++static char *app_bridge = "Bridge"; 1.2023 ++static char *bridge_synopsis = "Bridge two channels"; 1.2024 ++static char *bridge_descrip = 1.2025 ++"Usage: Bridge(channel[,options])\n" 1.2026 ++" Allows the ability to bridge two channels via the dialplan.\n" 1.2027 ++"The current channel is bridged to the specified 'channel'.\n" 1.2028 ++" Options:\n" 1.2029 ++" p - Play a courtesy tone to 'channel'.\n" 1.2030 ++"This application sets the following channel variable upon completion:\n" 1.2031 ++" BRIDGERESULT The result of the bridge attempt as a text string, one of\n" 1.2032 ++" SUCCESS | FAILURE | LOOP | NONEXISTENT | INCOMPATIBLE\n"; 1.2033 ++ 1.2034 ++enum { 1.2035 ++ BRIDGE_OPT_PLAYTONE = (1 << 0), 1.2036 ++}; 1.2037 ++ 1.2038 ++AST_APP_OPTIONS(bridge_exec_options, BEGIN_OPTIONS 1.2039 ++ AST_APP_OPTION('p', BRIDGE_OPT_PLAYTONE) 1.2040 ++END_OPTIONS ); 1.2041 ++ 1.2042 ++/*! 1.2043 ++ * \brief Bridge channels 1.2044 ++ * \param chan 1.2045 ++ * \param data channel to bridge with. 1.2046 ++ * 1.2047 ++ * Split data, check we aren't bridging with ourself, check valid channel, 1.2048 ++ * answer call if not already, check compatible channels, setup bridge config 1.2049 ++ * now bridge call, if transfered party hangs up return to PBX extension. 1.2050 ++*/ 1.2051 ++static int bridge_exec(struct ast_channel *chan, void *data) 1.2052 ++{ 1.2053 ++ struct ast_channel *current_dest_chan, *final_dest_chan; 1.2054 ++ char *tmp_data = NULL; 1.2055 ++ struct ast_flags opts = { 0, }; 1.2056 ++ struct ast_bridge_config bconfig = { { 0, }, }; 1.2057 ++ 1.2058 ++ AST_DECLARE_APP_ARGS(args, 1.2059 ++ AST_APP_ARG(dest_chan); 1.2060 ++ AST_APP_ARG(options); 1.2061 ++ ); 1.2062 ++ 1.2063 ++ if (ast_strlen_zero(data)) { 1.2064 ++ ast_log(LOG_WARNING, "Bridge require at least 1 argument specifying the other end of the bridge\n"); 1.2065 ++ return -1; 1.2066 ++ } 1.2067 ++ 1.2068 ++ tmp_data = ast_strdupa(data); 1.2069 ++ AST_STANDARD_APP_ARGS(args, tmp_data); 1.2070 ++ if (!ast_strlen_zero(args.options)) 1.2071 ++ ast_app_parse_options(bridge_exec_options, &opts, NULL, args.options); 1.2072 ++ 1.2073 ++ /* avoid bridge with ourselves */ 1.2074 ++ if (!strncmp(chan->name, args.dest_chan, 1.2075 ++ strlen(chan->name) < strlen(args.dest_chan) ? 1.2076 ++ strlen(chan->name) : strlen(args.dest_chan))) { 1.2077 ++ ast_log(LOG_WARNING, "Unable to bridge channel %s with itself\n", chan->name); 1.2078 ++ manager_event(EVENT_FLAG_CALL, "BridgeExec", 1.2079 ++ "Response: Failed\r\n" 1.2080 ++ "Reason: Unable to bridge channel to itself\r\n" 1.2081 ++ "Channel1: %s\r\n" 1.2082 ++ "Channel2: %s\r\n", 1.2083 ++ chan->name, args.dest_chan); 1.2084 ++ pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "LOOP"); 1.2085 ++ return 0; 1.2086 ++ } 1.2087 ++ 1.2088 ++ /* make sure we have a valid end point */ 1.2089 ++ if (!(current_dest_chan = ast_get_channel_by_name_prefix_locked(args.dest_chan, 1.2090 ++ strlen(args.dest_chan)))) { 1.2091 ++ ast_log(LOG_WARNING, "Bridge failed because channel %s does not exist or we " 1.2092 ++ "cannot get its lock\n", args.dest_chan); 1.2093 ++ manager_event(EVENT_FLAG_CALL, "BridgeExec", 1.2094 ++ "Response: Failed\r\n" 1.2095 ++ "Reason: Cannot grab end point\r\n" 1.2096 ++ "Channel1: %s\r\n" 1.2097 ++ "Channel2: %s\r\n", chan->name, args.dest_chan); 1.2098 ++ pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "NONEXISTENT"); 1.2099 ++ return 0; 1.2100 ++ } 1.2101 ++ ast_channel_unlock(current_dest_chan); 1.2102 ++ 1.2103 ++ /* answer the channel if needed */ 1.2104 ++ if (current_dest_chan->_state != AST_STATE_UP) 1.2105 ++ ast_answer(current_dest_chan); 1.2106 ++ 1.2107 ++ /* try to allocate a place holder where current_dest_chan will be placed */ 1.2108 ++ if (!(final_dest_chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, 1.2109 ++ NULL, NULL, 0, "Bridge/%s", current_dest_chan->name))) { 1.2110 ++ ast_log(LOG_WARNING, "Cannot create placeholder channel for chan %s\n", args.dest_chan); 1.2111 ++ manager_event(EVENT_FLAG_CALL, "BridgeExec", 1.2112 ++ "Response: Failed\r\n" 1.2113 ++ "Reason: cannot create placeholder\r\n" 1.2114 ++ "Channel1: %s\r\n" 1.2115 ++ "Channel2: %s\r\n", chan->name, args.dest_chan); 1.2116 ++ } 1.2117 ++ do_bridge_masquerade(current_dest_chan, final_dest_chan); 1.2118 ++ 1.2119 ++ /* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */ 1.2120 ++ /* try to make compatible, send error if we fail */ 1.2121 ++ if (ast_channel_make_compatible(chan, final_dest_chan) < 0) { 1.2122 ++ ast_log(LOG_WARNING, "Could not make channels %s and %s compatible for bridge\n", chan->name, final_dest_chan->name); 1.2123 ++ manager_event(EVENT_FLAG_CALL, "BridgeExec", 1.2124 ++ "Response: Failed\r\n" 1.2125 ++ "Reason: Could not make channels compatible for bridge\r\n" 1.2126 ++ "Channel1: %s\r\n" 1.2127 ++ "Channel2: %s\r\n", chan->name, final_dest_chan->name); 1.2128 ++ ast_hangup(final_dest_chan); /* may be we should return this channel to the PBX? */ 1.2129 ++ pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "INCOMPATIBLE"); 1.2130 ++ return 0; 1.2131 ++ } 1.2132 ++ 1.2133 ++ /* Report that the bridge will be successfull */ 1.2134 ++ manager_event(EVENT_FLAG_CALL, "BridgeExec", 1.2135 ++ "Response: Success\r\n" 1.2136 ++ "Channel1: %s\r\n" 1.2137 ++ "Channel2: %s\r\n", chan->name, final_dest_chan->name); 1.2138 ++ 1.2139 ++ /* we have 2 valid channels to bridge, now it is just a matter of setting up the bridge config and starting the bridge */ 1.2140 ++ if (ast_test_flag(&opts, BRIDGE_OPT_PLAYTONE) && !ast_strlen_zero(xfersound)) { 1.2141 ++ if (!ast_streamfile(final_dest_chan, xfersound, final_dest_chan->language)) { 1.2142 ++ if (ast_waitstream(final_dest_chan, "") < 0) 1.2143 ++ ast_log(LOG_WARNING, "Failed to play courtesy tone on %s\n", final_dest_chan->name); 1.2144 ++ } 1.2145 ++ } 1.2146 ++ 1.2147 ++ /* do the bridge */ 1.2148 ++ ast_bridge_call(chan, final_dest_chan, &bconfig); 1.2149 ++ 1.2150 ++ /* the bridge has ended, set BRIDGERESULT to SUCCESS. If the other channel has not been hung up, return it to the PBX */ 1.2151 ++ pbx_builtin_setvar_helper(chan, "BRIDGERESULT", "SUCCESS"); 1.2152 ++ if (!ast_check_hangup(final_dest_chan)) { 1.2153 ++ ast_log(LOG_EVENT, "starting new PBX in %s,%s,%d for chan %s\n", 1.2154 ++ final_dest_chan->context, final_dest_chan->exten, 1.2155 ++ final_dest_chan->priority, final_dest_chan->name); 1.2156 ++ 1.2157 ++ if (ast_pbx_start(final_dest_chan) != AST_PBX_SUCCESS) { 1.2158 ++ ast_log(LOG_WARNING, "FAILED continuing PBX on dest chan %s\n", final_dest_chan->name); 1.2159 ++ ast_hangup(final_dest_chan); 1.2160 ++ } else 1.2161 ++ ast_log(LOG_EVENT, "SUCCESS continuing PBX on chan %s\n", final_dest_chan->name); 1.2162 ++ } else { 1.2163 ++ ast_log(LOG_EVENT, "hangup chan %s since the other endpoint has hung up\n", final_dest_chan->name); 1.2164 ++ ast_hangup(final_dest_chan); 1.2165 ++ } 1.2166 ++ 1.2167 ++ return 0; 1.2168 ++} 1.2169 + 1.2170 + static int load_config(void) 1.2171 + { 1.2172 +@@ -3034,6 +3325,8 @@ 1.2173 + { 1.2174 + int res; 1.2175 + 1.2176 ++ ast_register_application(app_bridge, bridge_exec, bridge_synopsis, bridge_descrip); 1.2177 ++ 1.2178 + memset(parking_ext, 0, sizeof(parking_ext)); 1.2179 + memset(parking_con, 0, sizeof(parking_con)); 1.2180 + 1.2181 +@@ -3048,6 +3341,7 @@ 1.2182 + ast_manager_register("ParkedCalls", 0, manager_parking_status, "List parked calls" ); 1.2183 + ast_manager_register2("Park", EVENT_FLAG_CALL, manager_park, 1.2184 + "Park a channel", mandescr_park); 1.2185 ++ ast_manager_register2("Bridge", EVENT_FLAG_CALL, action_bridge, "Bridge two channels already in the PBX", mandescr_bridge); 1.2186 + } 1.2187 + 1.2188 + res |= ast_devstate_prov_add("Park", metermaidstate); 1.2189 +Index: apps/app_voicemail.c 1.2190 +diff -Nau apps/app_voicemail.c.orig apps/app_voicemail.c 1.2191 +--- apps/app_voicemail.c.orig 2009-04-25 02:38:20.343758775 +0200 1.2192 ++++ apps/app_voicemail.c 2009-04-25 19:56:25.287569363 +0200 1.2193 +@@ -115,6 +115,7 @@ 1.2194 + static char imapport[8]; 1.2195 + static char imapflags[128]; 1.2196 + static char imapfolder[64]; 1.2197 ++static int imapsubfold = 0; 1.2198 + static char authuser[32]; 1.2199 + static char authpassword[42]; 1.2200 + 1.2201 +@@ -4313,6 +4314,7 @@ 1.2202 + /* we must use mbox(x) folder names, and copy the message there */ 1.2203 + /* simple. huh? */ 1.2204 + char sequence[10]; 1.2205 ++ char folder[256]; 1.2206 + /* get the real IMAP message number for this message */ 1.2207 + snprintf(sequence, sizeof(sequence), "%ld", vms->msgArray[msg]); 1.2208 + if (option_debug > 2) 1.2209 +@@ -4323,11 +4325,21 @@ 1.2210 + } else if (box == 0) { 1.2211 + mail_clearflag(vms->mailstream, sequence, "\\Seen"); 1.2212 + } 1.2213 +- if (!strcasecmp(mbox(0), vms->curbox) && (box == 0 || box == 1)) { 1.2214 ++ if ((!strcasecmp(mbox(0), vms->curbox) || \ 1.2215 ++ !strcasecmp(mbox(1), vms->curbox)) && \ 1.2216 ++ (box == 0 || box == 1)) { /* Don't copy data, just change Seen flag */ 1.2217 + ast_mutex_unlock(&vms->lock); 1.2218 + return 0; 1.2219 +- } else { 1.2220 +- int res = !mail_copy(vms->mailstream,sequence,(char *) mbox(box)); 1.2221 ++ } else if (box > 1) { /* Do copy data using INBOX or subfolder */ 1.2222 ++ if (imapsubfold == 1) 1.2223 ++ snprintf(folder, sizeof(folder), "%s%c%s", imapfolder, delimiter, mbox(box)); 1.2224 ++ else 1.2225 ++ strncpy(folder, mbox(box), sizeof(folder)); 1.2226 ++ int res = !mail_copy(vms->mailstream,sequence,folder); 1.2227 ++ ast_mutex_unlock(&vms->lock); 1.2228 ++ return res; 1.2229 ++ } else { /* Copy data to INBOX delegating new/old status to Seen flag */ 1.2230 ++ int res = !mail_copy(vms->mailstream,sequence,imapfolder); 1.2231 + ast_mutex_unlock(&vms->lock); 1.2232 + return res; 1.2233 + } 1.2234 +@@ -7686,6 +7698,10 @@ 1.2235 + #ifndef IMAP_STORAGE 1.2236 + } else if (!cmd) { 1.2237 + vms.deleted[vms.curmsg] = 1; 1.2238 ++#else 1.2239 ++ } else if (!cmd && (folder_int(vms.curbox) > 1 || box > 1)) { 1.2240 ++ vms.deleted[vms.curmsg] = 1; /* Enforce deletion after */ 1.2241 ++ deleted = 1; /* successful copy op */ 1.2242 + #endif 1.2243 + } else { 1.2244 + vms.deleted[vms.curmsg] = 0; 1.2245 +@@ -8198,6 +8214,7 @@ 1.2246 + const char *imap_port; 1.2247 + const char *imap_flags; 1.2248 + const char *imap_folder; 1.2249 ++ const char *imap_use_subfold; 1.2250 + const char *auth_user; 1.2251 + const char *auth_password; 1.2252 + const char *expunge_on_hangup; 1.2253 +@@ -8342,6 +8359,15 @@ 1.2254 + } else { 1.2255 + ast_copy_string(imapfolder,"INBOX", sizeof(imapfolder)); 1.2256 + } 1.2257 ++ /* IMAP saved (sub)folder location policy */ 1.2258 ++ if ((imap_use_subfold = ast_variable_retrieve(cfg, "general", "imapsubfold"))) { 1.2259 ++ if (ast_false(imap_use_subfold)) 1.2260 ++ imapsubfold = 0; 1.2261 ++ else 1.2262 ++ imapsubfold = 1; 1.2263 ++ } else { 1.2264 ++ imapsubfold = 0; 1.2265 ++ } 1.2266 + 1.2267 + /* There is some very unorthodox casting done here. This is due 1.2268 + * to the way c-client handles the argument passed in. It expects a