asterisk/asterisk.patch

Mon, 27 Apr 2009 12:19:05 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Mon, 27 Apr 2009 12:19:05 +0200
changeset 202
f29abea29121
child 310
73d852a30c9a
permissions
-rw-r--r--

Import new package spec for introduction into repository.

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