asterisk/asterisk.patch

Fri, 15 Oct 2010 18:46:25 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 15 Oct 2010 18:46:25 +0200
changeset 261
4f973c756446
child 310
73d852a30c9a
permissions
-rw-r--r--

Update copyright, file server URL, modify doc and link logic.
Now documentation is installed by default to the correct path,
and QtCreator links against Qt shared libraries instead of Qt
static libraries. This unfortunate change supports Nokia's
unfortunate decision to poorly support static linking in Qt.

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

mercurial