Ticket #507: ticket507.patch
File ticket507.patch, 49.3 KB (added by nanang, 17 years ago) |
---|
-
pjmedia/include/pjmedia-codec/g722.h
1 /* $Id$ */ 2 /* 3 * Copyright (C)2003-2008 Benny Prijono <benny@prijono.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20 #ifndef __PJMEDIA_CODEC_G722_H__ 21 #define __PJMEDIA_CODEC_G722_H__ 22 23 #include <pjmedia-codec/types.h> 24 25 PJ_DECL(pj_status_t) pjmedia_codec_g722_init(pjmedia_endpt *endpt); 26 PJ_DECL(pj_status_t) pjmedia_codec_g722_deinit(void); 27 28 #endif /* __PJMEDIA_CODEC_G722_H__ */ 29 -
pjmedia/src/pjmedia-codec/g722.c
1 #include <pjmedia-codec/g722.h> 2 #include <pjmedia/codec.h> 3 #include <pjmedia/errno.h> 4 #include <pjmedia/endpoint.h> 5 #include <pjmedia/plc.h> 6 #include <pjmedia/port.h> 7 #include <pjmedia/silencedet.h> 8 #include <pj/assert.h> 9 #include <pj/log.h> 10 #include <pj/pool.h> 11 #include <pj/string.h> 12 #include <pj/os.h> 13 14 #if defined(PJMEDIA_HAS_G722_CODEC) && (PJMEDIA_HAS_G722_CODEC != 0) 15 16 #include "g722/g722_enc.h" 17 #include "g722/g722_dec.h" 18 19 #define THIS_FILE "g722.c" 20 21 /* Defines */ 22 #define PTIME (20) 23 #define SAMPLES_PER_FRAME (16000 * PTIME /1000) 24 #define FRAME_LEN (160) 25 #define PLC_DISABLED 1 26 27 /* Tracing */ 28 #ifndef PJ_TRACE 29 # define PJ_TRACE 0 30 #endif 31 32 #if PJ_TRACE 33 # define TRACE_(expr) PJ_LOG(4,expr) 34 #else 35 # define TRACE_(expr) 36 #endif 37 38 39 /* Prototypes for G722 factory */ 40 static pj_status_t g722_test_alloc(pjmedia_codec_factory *factory, 41 const pjmedia_codec_info *id ); 42 static pj_status_t g722_default_attr(pjmedia_codec_factory *factory, 43 const pjmedia_codec_info *id, 44 pjmedia_codec_param *attr ); 45 static pj_status_t g722_enum_codecs(pjmedia_codec_factory *factory, 46 unsigned *count, 47 pjmedia_codec_info codecs[]); 48 static pj_status_t g722_alloc_codec(pjmedia_codec_factory *factory, 49 const pjmedia_codec_info *id, 50 pjmedia_codec **p_codec); 51 static pj_status_t g722_dealloc_codec(pjmedia_codec_factory *factory, 52 pjmedia_codec *codec ); 53 54 /* Prototypes for G722 implementation. */ 55 static pj_status_t g722_codec_init(pjmedia_codec *codec, 56 pj_pool_t *pool ); 57 static pj_status_t g722_codec_open(pjmedia_codec *codec, 58 pjmedia_codec_param *attr ); 59 static pj_status_t g722_codec_close(pjmedia_codec *codec ); 60 static pj_status_t g722_codec_modify(pjmedia_codec *codec, 61 const pjmedia_codec_param *attr ); 62 static pj_status_t g722_codec_parse(pjmedia_codec *codec, 63 void *pkt, 64 pj_size_t pkt_size, 65 const pj_timestamp *ts, 66 unsigned *frame_cnt, 67 pjmedia_frame frames[]); 68 static pj_status_t g722_codec_encode(pjmedia_codec *codec, 69 const struct pjmedia_frame *input, 70 unsigned output_buf_len, 71 struct pjmedia_frame *output); 72 static pj_status_t g722_codec_decode(pjmedia_codec *codec, 73 const struct pjmedia_frame *input, 74 unsigned output_buf_len, 75 struct pjmedia_frame *output); 76 #if !PLC_DISABLED 77 static pj_status_t g722_codec_recover(pjmedia_codec *codec, 78 unsigned output_buf_len, 79 struct pjmedia_frame *output); 80 #endif 81 82 /* Definition for G722 codec operations. */ 83 static pjmedia_codec_op g722_op = 84 { 85 &g722_codec_init, 86 &g722_codec_open, 87 &g722_codec_close, 88 &g722_codec_modify, 89 &g722_codec_parse, 90 &g722_codec_encode, 91 &g722_codec_decode, 92 #if !PLC_DISABLED 93 &g722_codec_recover 94 #else 95 NULL 96 #endif 97 }; 98 99 /* Definition for G722 codec factory operations. */ 100 static pjmedia_codec_factory_op g722_factory_op = 101 { 102 &g722_test_alloc, 103 &g722_default_attr, 104 &g722_enum_codecs, 105 &g722_alloc_codec, 106 &g722_dealloc_codec 107 }; 108 109 /* G722 factory */ 110 static struct g722_codec_factory 111 { 112 pjmedia_codec_factory base; 113 pjmedia_endpt *endpt; 114 pj_pool_t *pool; 115 pj_mutex_t *mutex; 116 pjmedia_codec codec_list; 117 } g722_codec_factory; 118 119 120 /* G722 codec private data. */ 121 struct g722_data 122 { 123 g722_enc_t encoder; 124 g722_dec_t decoder; 125 pj_bool_t plc_enabled; 126 pj_bool_t vad_enabled; 127 pjmedia_silence_det *vad; 128 pj_timestamp last_tx; 129 #if !PLC_DISABLED 130 pjmedia_plc *plc; 131 #endif 132 }; 133 134 135 136 /* 137 * Initialize and register G722 codec factory to pjmedia endpoint. 138 */ 139 PJ_DEF(pj_status_t) pjmedia_codec_g722_init( pjmedia_endpt *endpt ) 140 { 141 pjmedia_codec_mgr *codec_mgr; 142 pj_status_t status; 143 144 if (g722_codec_factory.pool != NULL) 145 return PJ_SUCCESS; 146 147 /* Create G722 codec factory. */ 148 g722_codec_factory.base.op = &g722_factory_op; 149 g722_codec_factory.base.factory_data = NULL; 150 g722_codec_factory.endpt = endpt; 151 152 g722_codec_factory.pool = pjmedia_endpt_create_pool(endpt, "g722", 1000, 153 1000); 154 if (!g722_codec_factory.pool) 155 return PJ_ENOMEM; 156 157 pj_list_init(&g722_codec_factory.codec_list); 158 159 /* Create mutex. */ 160 status = pj_mutex_create_simple(g722_codec_factory.pool, "g722", 161 &g722_codec_factory.mutex); 162 if (status != PJ_SUCCESS) 163 goto on_error; 164 165 /* Get the codec manager. */ 166 codec_mgr = pjmedia_endpt_get_codec_mgr(endpt); 167 if (!codec_mgr) { 168 status = PJ_EINVALIDOP; 169 goto on_error; 170 } 171 172 /* Register codec factory to endpoint. */ 173 status = pjmedia_codec_mgr_register_factory(codec_mgr, 174 &g722_codec_factory.base); 175 if (status != PJ_SUCCESS) 176 goto on_error; 177 178 TRACE_((THIS_FILE, "G722 codec factory initialized")); 179 180 /* Done. */ 181 return PJ_SUCCESS; 182 183 on_error: 184 pj_pool_release(g722_codec_factory.pool); 185 g722_codec_factory.pool = NULL; 186 return status; 187 } 188 189 /* 190 * Unregister G722 codec factory from pjmedia endpoint and deinitialize 191 * the G722 codec library. 192 */ 193 PJ_DEF(pj_status_t) pjmedia_codec_g722_deinit(void) 194 { 195 pjmedia_codec_mgr *codec_mgr; 196 pj_status_t status; 197 198 if (g722_codec_factory.pool == NULL) 199 return PJ_SUCCESS; 200 201 /* Get the codec manager. */ 202 codec_mgr = pjmedia_endpt_get_codec_mgr(g722_codec_factory.endpt); 203 if (!codec_mgr) { 204 pj_pool_release(g722_codec_factory.pool); 205 g722_codec_factory.pool = NULL; 206 return PJ_EINVALIDOP; 207 } 208 209 /* Unregister G722 codec factory. */ 210 status = pjmedia_codec_mgr_unregister_factory(codec_mgr, 211 &g722_codec_factory.base); 212 213 /* Destroy mutex. */ 214 pj_mutex_destroy(g722_codec_factory.mutex); 215 216 /* Destroy pool. */ 217 pj_pool_release(g722_codec_factory.pool); 218 g722_codec_factory.pool = NULL; 219 220 TRACE_((THIS_FILE, "G722 codec factory shutdown")); 221 return status; 222 } 223 224 /* 225 * Check if factory can allocate the specified codec. 226 */ 227 static pj_status_t g722_test_alloc(pjmedia_codec_factory *factory, 228 const pjmedia_codec_info *info ) 229 { 230 PJ_UNUSED_ARG(factory); 231 232 /* Check payload type. */ 233 if (info->pt != PJMEDIA_RTP_PT_G722) 234 return PJMEDIA_CODEC_EUNSUP; 235 236 /* Ignore the rest, since it's static payload type. */ 237 238 return PJ_SUCCESS; 239 } 240 241 /* 242 * Generate default attribute. 243 */ 244 static pj_status_t g722_default_attr( pjmedia_codec_factory *factory, 245 const pjmedia_codec_info *id, 246 pjmedia_codec_param *attr ) 247 { 248 PJ_UNUSED_ARG(factory); 249 PJ_UNUSED_ARG(id); 250 251 pj_bzero(attr, sizeof(pjmedia_codec_param)); 252 attr->info.clock_rate = 16000; 253 attr->info.channel_cnt = 1; 254 attr->info.avg_bps = 64000; 255 attr->info.pcm_bits_per_sample = 16; 256 attr->info.frm_ptime = PTIME; 257 attr->info.pt = PJMEDIA_RTP_PT_G722; 258 259 attr->setting.frm_per_pkt = 1; 260 attr->setting.vad = 1; 261 attr->setting.plc = 0; 262 263 /* Default all other flag bits disabled. */ 264 265 return PJ_SUCCESS; 266 } 267 268 /* 269 * Enum codecs supported by this factory (i.e. only G722!). 270 */ 271 static pj_status_t g722_enum_codecs(pjmedia_codec_factory *factory, 272 unsigned *count, 273 pjmedia_codec_info codecs[]) 274 { 275 PJ_UNUSED_ARG(factory); 276 PJ_ASSERT_RETURN(codecs && *count > 0, PJ_EINVAL); 277 278 pj_bzero(&codecs[0], sizeof(pjmedia_codec_info)); 279 codecs[0].encoding_name = pj_str("G722"); 280 codecs[0].pt = PJMEDIA_RTP_PT_G722; 281 codecs[0].type = PJMEDIA_TYPE_AUDIO; 282 codecs[0].clock_rate = 16000; 283 codecs[0].channel_cnt = 1; 284 285 *count = 1; 286 287 return PJ_SUCCESS; 288 } 289 290 /* 291 * Allocate a new G722 codec instance. 292 */ 293 static pj_status_t g722_alloc_codec(pjmedia_codec_factory *factory, 294 const pjmedia_codec_info *id, 295 pjmedia_codec **p_codec) 296 { 297 pjmedia_codec *codec; 298 struct g722_data *g722_data; 299 300 PJ_ASSERT_RETURN(factory && id && p_codec, PJ_EINVAL); 301 PJ_ASSERT_RETURN(factory == &g722_codec_factory.base, PJ_EINVAL); 302 303 pj_mutex_lock(g722_codec_factory.mutex); 304 305 /* Get free nodes, if any. */ 306 if (!pj_list_empty(&g722_codec_factory.codec_list)) { 307 codec = g722_codec_factory.codec_list.next; 308 pj_list_erase(codec); 309 } else { 310 pj_status_t status; 311 312 codec = PJ_POOL_ZALLOC_T(g722_codec_factory.pool, pjmedia_codec); 313 PJ_ASSERT_RETURN(codec != NULL, PJ_ENOMEM); 314 codec->op = &g722_op; 315 codec->factory = factory; 316 317 g722_data = PJ_POOL_ZALLOC_T(g722_codec_factory.pool, struct g722_data); 318 codec->codec_data = g722_data; 319 320 #if !PLC_DISABLED 321 /* Create PLC */ 322 status = pjmedia_plc_create(g722_codec_factory.pool, 16000, 323 SAMPLES_PER_FRAME, 0, &g722_data->plc); 324 if (status != PJ_SUCCESS) { 325 pj_mutex_unlock(g722_codec_factory.mutex); 326 return status; 327 } 328 #endif 329 330 /* Create silence detector */ 331 status = pjmedia_silence_det_create(g722_codec_factory.pool, 332 16000, SAMPLES_PER_FRAME, 333 &g722_data->vad); 334 if (status != PJ_SUCCESS) { 335 pj_mutex_unlock(g722_codec_factory.mutex); 336 TRACE_((THIS_FILE, "Create silence detector failed (status = %d)", 337 status)); 338 return status; 339 } 340 } 341 342 343 pj_mutex_unlock(g722_codec_factory.mutex); 344 345 *p_codec = codec; 346 return PJ_SUCCESS; 347 } 348 349 /* 350 * Free codec. 351 */ 352 static pj_status_t g722_dealloc_codec(pjmedia_codec_factory *factory, 353 pjmedia_codec *codec ) 354 { 355 struct g722_data *g722_data; 356 int i; 357 358 PJ_ASSERT_RETURN(factory && codec, PJ_EINVAL); 359 PJ_ASSERT_RETURN(factory == &g722_codec_factory.base, PJ_EINVAL); 360 361 g722_data = (struct g722_data*) codec->codec_data; 362 363 /* Close codec, if it's not closed. */ 364 g722_codec_close(codec); 365 366 #if !PLC_DISABLED 367 /* Clear left samples in the PLC, since codec+plc will be reused 368 * next time. 369 */ 370 for (i=0; i<2; ++i) { 371 pj_int16_t frame[SAMPLES_PER_FRAME]; 372 pjmedia_zero_samples(frame, PJ_ARRAY_SIZE(frame)); 373 pjmedia_plc_save(g722_data->plc, frame); 374 } 375 #else 376 PJ_UNUSED_ARG(i); 377 #endif 378 379 /* Re-init silence_period */ 380 pj_set_timestamp32(&g722_data->last_tx, 0, 0); 381 382 /* Put in the free list. */ 383 pj_mutex_lock(g722_codec_factory.mutex); 384 pj_list_push_front(&g722_codec_factory.codec_list, codec); 385 pj_mutex_unlock(g722_codec_factory.mutex); 386 387 return PJ_SUCCESS; 388 } 389 390 /* 391 * Init codec. 392 */ 393 static pj_status_t g722_codec_init(pjmedia_codec *codec, 394 pj_pool_t *pool ) 395 { 396 PJ_UNUSED_ARG(codec); 397 PJ_UNUSED_ARG(pool); 398 return PJ_SUCCESS; 399 } 400 401 /* 402 * Open codec. 403 */ 404 static pj_status_t g722_codec_open(pjmedia_codec *codec, 405 pjmedia_codec_param *attr ) 406 { 407 struct g722_data *g722_data = (struct g722_data*) codec->codec_data; 408 pj_status_t status; 409 410 PJ_ASSERT_RETURN(codec && attr, PJ_EINVAL); 411 PJ_ASSERT_RETURN(g722_data != NULL, PJ_EINVALIDOP); 412 413 status = g722_enc_init(&g722_data->encoder); 414 if (status != PJ_SUCCESS) { 415 TRACE_((THIS_FILE, "g722_enc_init() failed, status=%d", status)); 416 pj_mutex_unlock(g722_codec_factory.mutex); 417 return PJMEDIA_CODEC_EFAILED; 418 } 419 420 status = g722_dec_init(&g722_data->decoder); 421 if (status != PJ_SUCCESS) { 422 TRACE_((THIS_FILE, "g722_dec_init() failed, status=%d", status)); 423 pj_mutex_unlock(g722_codec_factory.mutex); 424 return PJMEDIA_CODEC_EFAILED; 425 } 426 427 g722_data->vad_enabled = (attr->setting.vad != 0); 428 g722_data->plc_enabled = (attr->setting.plc != 0); 429 430 TRACE_((THIS_FILE, "G722 codec opened: vad=%d, plc=%d", 431 g722_data->vad_enabled, g722_data->plc_enabled)); 432 return PJ_SUCCESS; 433 } 434 435 /* 436 * Close codec. 437 */ 438 static pj_status_t g722_codec_close( pjmedia_codec *codec ) 439 { 440 /* The codec, encoder, and decoder will be reused, so there's 441 * nothing to do here 442 */ 443 444 PJ_UNUSED_ARG(codec); 445 446 TRACE_((THIS_FILE, "G722 codec closed")); 447 return PJ_SUCCESS; 448 } 449 450 451 /* 452 * Modify codec settings. 453 */ 454 static pj_status_t g722_codec_modify(pjmedia_codec *codec, 455 const pjmedia_codec_param *attr ) 456 { 457 struct g722_data *g722_data = (struct g722_data*) codec->codec_data; 458 459 pj_assert(g722_data != NULL); 460 461 g722_data->vad_enabled = (attr->setting.vad != 0); 462 g722_data->plc_enabled = (attr->setting.plc != 0); 463 464 TRACE_((THIS_FILE, "G722 codec modified: vad=%d, plc=%d", 465 g722_data->vad_enabled, g722_data->plc_enabled)); 466 return PJ_SUCCESS; 467 } 468 469 470 /* 471 * Get frames in the packet. 472 */ 473 static pj_status_t g722_codec_parse(pjmedia_codec *codec, 474 void *pkt, 475 pj_size_t pkt_size, 476 const pj_timestamp *ts, 477 unsigned *frame_cnt, 478 pjmedia_frame frames[]) 479 { 480 unsigned count = 0; 481 482 PJ_UNUSED_ARG(codec); 483 484 PJ_ASSERT_RETURN(frame_cnt, PJ_EINVAL); 485 486 TRACE_((THIS_FILE, "G722 parse(): input len=%d", pkt_size)); 487 488 while (pkt_size >= FRAME_LEN && count < *frame_cnt) { 489 frames[count].type = PJMEDIA_FRAME_TYPE_AUDIO; 490 frames[count].buf = pkt; 491 frames[count].size = FRAME_LEN; 492 frames[count].timestamp.u64 = ts->u64 + count * SAMPLES_PER_FRAME; 493 494 pkt = ((char*)pkt) + FRAME_LEN; 495 pkt_size -= FRAME_LEN; 496 497 ++count; 498 } 499 500 TRACE_((THIS_FILE, "G722 parse(): got %d frames", count)); 501 502 *frame_cnt = count; 503 return PJ_SUCCESS; 504 } 505 506 /* 507 * Encode frame. 508 */ 509 static pj_status_t g722_codec_encode(pjmedia_codec *codec, 510 const struct pjmedia_frame *input, 511 unsigned output_buf_len, 512 struct pjmedia_frame *output) 513 { 514 struct g722_data *g722_data = (struct g722_data*) codec->codec_data; 515 pj_status_t status; 516 517 pj_assert(g722_data != NULL); 518 PJ_ASSERT_RETURN(input && output, PJ_EINVAL); 519 520 if (output_buf_len < FRAME_LEN) 521 return PJMEDIA_CODEC_EFRMTOOSHORT; 522 523 PJ_ASSERT_RETURN(input->size/2 == SAMPLES_PER_FRAME, 524 PJMEDIA_CODEC_EPCMFRMINLEN); 525 526 /* Detect silence */ 527 if (g722_data->vad_enabled) { 528 pj_bool_t is_silence; 529 pj_int32_t silence_duration; 530 531 silence_duration = pj_timestamp_diff32(&g722_data->last_tx, 532 &input->timestamp); 533 534 is_silence = pjmedia_silence_det_detect(g722_data->vad, 535 (const pj_int16_t*) input->buf, 536 (input->size >> 1), 537 NULL); 538 if (is_silence && 539 PJMEDIA_CODEC_MAX_SILENCE_PERIOD != -1 && 540 silence_duration < PJMEDIA_CODEC_MAX_SILENCE_PERIOD) 541 { 542 output->type = PJMEDIA_FRAME_TYPE_NONE; 543 output->buf = NULL; 544 output->size = 0; 545 output->timestamp = input->timestamp; 546 return PJ_SUCCESS; 547 } else { 548 g722_data->last_tx = input->timestamp; 549 } 550 } 551 552 /* Encode to temporary buffer */ 553 status = g722_enc_encode(&g722_data->encoder, (pj_int16_t*)input->buf, 554 SAMPLES_PER_FRAME, output->buf, &output->size); 555 if (status != PJ_SUCCESS) { 556 output->size = 0; 557 output->buf = NULL; 558 output->type = PJMEDIA_FRAME_TYPE_NONE; 559 TRACE_((THIS_FILE, "G722 encode() status: %d", status)); 560 return PJMEDIA_CODEC_EFAILED; 561 } 562 563 output->type = PJMEDIA_FRAME_TYPE_AUDIO; 564 565 TRACE_((THIS_FILE, "G722 encode(): size=%d", output->size)); 566 return PJ_SUCCESS; 567 } 568 569 /* 570 * Decode frame. 571 */ 572 static pj_status_t g722_codec_decode(pjmedia_codec *codec, 573 const struct pjmedia_frame *input, 574 unsigned output_buf_len, 575 struct pjmedia_frame *output) 576 { 577 struct g722_data *g722_data = (struct g722_data*) codec->codec_data; 578 pj_status_t status; 579 580 pj_assert(g722_data != NULL); 581 PJ_ASSERT_RETURN(input && output, PJ_EINVAL); 582 583 TRACE_((THIS_FILE, "G722 decode(): inbuf=%p, insize=%d, outbuf=%p," 584 "outsize=%d", 585 input->buf, input->size, output->buf, output_buf_len)); 586 587 if (output_buf_len < SAMPLES_PER_FRAME * 2) { 588 TRACE_((THIS_FILE, "G722 decode() ERROR: PJMEDIA_CODEC_EPCMTOOSHORT")); 589 return PJMEDIA_CODEC_EPCMTOOSHORT; 590 } 591 592 if (input->size != FRAME_LEN) { 593 TRACE_((THIS_FILE, "G722 decode() ERROR: PJMEDIA_CODEC_EFRMTOOSHORT")); 594 return PJMEDIA_CODEC_EFRMTOOSHORT; 595 } 596 597 598 /* Decode */ 599 output->size = SAMPLES_PER_FRAME; 600 status = g722_dec_decode(&g722_data->decoder, input->buf, input->size, 601 (pj_int16_t*)output->buf, &output->size); 602 if (status != PJ_SUCCESS) { 603 TRACE_((THIS_FILE, "G722 decode() status: %d", status)); 604 return PJMEDIA_CODEC_EFAILED; 605 } 606 607 pj_assert(output->size == SAMPLES_PER_FRAME); 608 output->size = SAMPLES_PER_FRAME * 2; 609 output->type = PJMEDIA_FRAME_TYPE_AUDIO; 610 611 #if !PLC_DISABLED 612 if (g722_data->plc_enabled) 613 pjmedia_plc_save(g722_data->plc, output->buf); 614 #endif 615 616 TRACE_((THIS_FILE, "G722 decode done")); 617 return PJ_SUCCESS; 618 } 619 620 621 #if !PLC_DISABLED 622 /* 623 * Recover lost frame. 624 */ 625 static pj_status_t g722_codec_recover(pjmedia_codec *codec, 626 unsigned output_buf_len, 627 struct pjmedia_frame *output) 628 { 629 struct g722_data *g722_data = codec->codec_data; 630 631 PJ_ASSERT_RETURN(g722_data->plc_enabled, PJ_EINVALIDOP); 632 633 PJ_ASSERT_RETURN(output_buf_len >= SAMPLES_PER_FRAME * 2, 634 PJMEDIA_CODEC_EPCMTOOSHORT); 635 636 pjmedia_plc_generate(g722_data->plc, output->buf); 637 638 output->size = SAMPLES_PER_FRAME * 2; 639 output->type = PJMEDIA_FRAME_TYPE_AUDIO; 640 641 return PJ_SUCCESS; 642 } 643 #endif 644 645 #endif // PJMEDIA_HAS_G722_CODEC 646 No newline at end of file -
pjmedia/src/pjmedia-codec/g722/g722_dec.h
1 /* $Id$ */ 2 /* 3 * Copyright (C)2003-2008 Benny Prijono <benny@prijono.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20 #ifndef __PJMEDIA_CODEC_G722_DEC_H__ 21 #define __PJMEDIA_CODEC_G722_DEC_H__ 22 23 #include <pjmedia-codec/types.h> 24 25 /* Decoder state */ 26 typedef struct g722_dec_t { 27 /* PCM low band */ 28 int slow; 29 int detlow; 30 int spl; 31 int szl; 32 int rlt [3]; 33 int al [3]; 34 int apl [3]; 35 int plt [3]; 36 int dlt [7]; 37 int bl [7]; 38 int bpl [7]; 39 int sgl [7]; 40 int nbl; 41 42 /* PCM high band*/ 43 int shigh; 44 int dethigh; 45 int sph; 46 int szh; 47 int rh [3]; 48 int ah [3]; 49 int aph [3]; 50 int ph [3]; 51 int dh [7]; 52 int bh [7]; 53 int bph [7]; 54 int sgh [7]; 55 int nbh; 56 57 /* QMF signal history */ 58 int xd[12]; 59 int xs[12]; 60 } g722_dec_t; 61 62 63 PJ_DECL(pj_status_t) g722_dec_init(g722_dec_t *dec); 64 65 PJ_DECL(pj_status_t) g722_dec_decode(g722_dec_t *dec, 66 void *in, 67 pj_size_t in_size, 68 pj_int16_t out[], 69 pj_size_t *nsamples); 70 71 PJ_DECL(pj_status_t) g722_dec_deinit(g722_dec_t *dec); 72 73 #endif /* __PJMEDIA_CODEC_G722_DEC_H__ */ 74 -
pjmedia/src/pjmedia-codec/g722/g722_enc.c
1 #include <pjmedia/errno.h> 2 #include <pj/assert.h> 3 #include <pj/pool.h> 4 5 #include "g722_enc.h" 6 7 #if defined(PJMEDIA_HAS_G722_CODEC) && (PJMEDIA_HAS_G722_CODEC != 0) 8 9 #define SATURATE(v, max, min) \ 10 if (v>max) v = max; \ 11 else if (v<min) v = min 12 13 /* QMF tap coefficients */ 14 int g722_qmf_coeff[24] = { 15 3, -11, -11, 53, 12, -156, 16 32, 362, -210, -805, 951, 3876, 17 3876, 951, -805, -210, 362, 32, 18 -156, 12, 53, -11, -11, 3 19 }; 20 21 22 static int block1l (int xl, int sl, int detl) 23 { 24 int il ; 25 26 int i, el, sil, mil, wd, wd1, hdu ; 27 28 static int q6[32] = { 29 0, 35, 72, 110, 150, 190, 233, 276, 323, 30 370, 422, 473, 530, 587, 650, 714, 786, 31 858, 940, 1023, 1121, 1219, 1339, 1458, 32 1612, 1765, 1980, 2195, 2557, 2919, 0, 0 33 }; 34 35 static int iln[32] = { 36 0, 63, 62, 31, 30, 29, 28, 27, 26, 25, 37 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 38 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 0 39 }; 40 41 static int ilp[32] = { 42 0, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 43 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 44 40, 39, 38, 37, 36, 35, 34, 33, 32, 0 45 }; 46 47 /* SUBTRA */ 48 49 el = xl - sl ; 50 SATURATE(el, 32767, -32768); 51 52 /* QUANTL */ 53 54 sil = el >> 15 ; 55 if (sil == 0 ) wd = el ; 56 else wd = 32767 - el & 32767 ; 57 58 mil = 1 ; 59 60 for (i = 1; i < 30; i++) { 61 hdu = (q6[i] << 3) * detl; 62 wd1 = (hdu >> 15) ; 63 if (wd >= wd1) mil = (i + 1) ; 64 else break ; 65 } 66 67 if (sil == -1 ) il = iln[mil] ; 68 else il = ilp[mil] ; 69 70 return (il) ; 71 } 72 73 static int block2l (int il, int detl) 74 { 75 int dlt; 76 int ril, wd2 ; 77 static int qm4[16] = { 78 0, -20456, -12896, -8968, 79 -6288, -4240, -2584, -1200, 80 20456, 12896, 8968, 6288, 81 4240, 2584, 1200, 0 82 }; 83 84 /* INVQAL */ 85 ril = il >> 2 ; 86 wd2 = qm4[ril] ; 87 dlt = (detl * wd2) >> 15 ; 88 89 return (dlt) ; 90 } 91 92 static int block3l (g722_enc_t *enc, int il) 93 { 94 int detl; 95 int ril, il4, wd, wd1, wd2, wd3, nbpl, depl ; 96 static int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042} ; 97 static int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0}; 98 static int ilb[32] = { 99 2048, 2093, 2139, 2186, 2233, 2282, 2332, 100 2383, 2435, 2489, 2543, 2599, 2656, 2714, 101 2774, 2834, 2896, 2960, 3025, 3091, 3158, 102 3228, 3298, 3371, 3444, 3520, 3597, 3676, 103 3756, 3838, 3922, 4008 104 }; 105 106 /* LOGSCL */ 107 108 ril = il >> 2 ; 109 il4 = rl42[ril] ; 110 111 wd = (enc->nbl * 32512) >> 15 ; 112 nbpl = wd + wl[il4] ; 113 114 if (nbpl < 0) nbpl = 0 ; 115 if (nbpl > 18432) nbpl = 18432 ; 116 117 /* SCALEL */ 118 119 wd1 = (nbpl >> 6) & 31 ; 120 wd2 = nbpl >> 11 ; 121 if ((8 - wd2) < 0) wd3 = ilb[wd1] << (wd2 - 8) ; 122 else wd3 = ilb[wd1] >> (8 - wd2) ; 123 depl = wd3 << 2 ; 124 125 /* DELAYA */ 126 enc->nbl = nbpl ; 127 128 /* DELAYL */ 129 detl = depl ; 130 131 #ifdef DEBUG_VERBOSE 132 printf ("BLOCK3L il=%4d, ril=%4d, il4=%4d, nbl=%4d, wd=%4d, nbpl=%4d\n", 133 il, ril, il4, enc->nbl, wd, nbpl) ; 134 printf ("wd1=%4d, wd2=%4d, wd3=%4d, depl=%4d, detl=%4d\n", 135 wd1, wd2, wd3, depl, detl) ; 136 #endif 137 138 return (detl) ; 139 } 140 141 static int block4l (g722_enc_t *enc, int dl) 142 { 143 int sl = enc->slow; 144 int i ; 145 int wd, wd1, wd2, wd3, wd4, wd5 /*, wd6 */; 146 147 enc->dlt[0] = dl; 148 149 /* RECONS */ 150 151 enc->rlt[0] = sl + enc->dlt[0] ; 152 SATURATE(enc->rlt[0], 32767, -32768); 153 154 /* PARREC */ 155 156 enc->plt[0] = enc->dlt[0] + enc->szl ; 157 SATURATE(enc->plt[0], 32767, -32768); 158 159 /* UPPOL2 */ 160 161 enc->sgl[0] = enc->plt[0] >> 15 ; 162 enc->sgl[1] = enc->plt[1] >> 15 ; 163 enc->sgl[2] = enc->plt[2] >> 15 ; 164 165 wd1 = enc->al[1] << 2; 166 SATURATE(wd1, 32767, -32768); 167 168 if ( enc->sgl[0] == enc->sgl[1] ) wd2 = - wd1 ; 169 else wd2 = wd1 ; 170 if ( wd2 > 32767 ) wd2 = 32767; 171 172 wd2 = wd2 >> 7 ; 173 174 if ( enc->sgl[0] == enc->sgl[2] ) wd3 = 128 ; 175 else wd3 = - 128 ; 176 177 wd4 = wd2 + wd3 ; 178 wd5 = (enc->al[2] * 32512) >> 15 ; 179 180 enc->apl[2] = wd4 + wd5 ; 181 SATURATE(enc->apl[2], 12288, -12288); 182 183 /* UPPOL1 */ 184 185 enc->sgl[0] = enc->plt[0] >> 15 ; 186 enc->sgl[1] = enc->plt[1] >> 15 ; 187 188 if ( enc->sgl[0] == enc->sgl[1] ) wd1 = 192 ; 189 else wd1 = - 192 ; 190 191 wd2 = (enc->al[1] * 32640) >> 15 ; 192 193 enc->apl[1] = wd1 + wd2 ; 194 SATURATE(enc->apl[1], 32767, -32768); 195 196 wd3 = (15360 - enc->apl[2]) ; 197 SATURATE(wd3, 32767, -32768); 198 199 if ( enc->apl[1] > wd3) enc->apl[1] = wd3 ; 200 if ( enc->apl[1] < -wd3) enc->apl[1] = -wd3 ; 201 202 /* UPZERO */ 203 204 if ( enc->dlt[0] == 0 ) wd1 = 0 ; 205 else wd1 = 128 ; 206 207 enc->sgl[0] = enc->dlt[0] >> 15 ; 208 209 for ( i = 1; i < 7; i++ ) { 210 enc->sgl[i] = enc->dlt[i] >> 15 ; 211 if ( enc->sgl[i] == enc->sgl[0] ) wd2 = wd1 ; 212 else wd2 = - wd1 ; 213 wd3 = (enc->bl[i] * 32640) >> 15 ; 214 enc->bpl[i] = wd2 + wd3 ; 215 SATURATE(enc->bpl[i], 32767, -32768); 216 } 217 218 /* DELAYA */ 219 220 for ( i = 6; i > 0; i-- ) { 221 enc->dlt[i] = enc->dlt[i-1] ; 222 enc->bl[i] = enc->bpl[i] ; 223 } 224 225 for ( i = 2; i > 0; i-- ) { 226 enc->rlt[i] = enc->rlt[i-1] ; 227 enc->plt[i] = enc->plt[i-1] ; 228 enc->al[i] = enc->apl[i] ; 229 } 230 231 /* FILTEP */ 232 233 wd1 = enc->rlt[1] + enc->rlt[1]; 234 SATURATE(wd1, 32767, -32768); 235 wd1 = ( enc->al[1] * wd1 ) >> 15 ; 236 237 wd2 = enc->rlt[2] + enc->rlt[2]; 238 SATURATE(wd2, 32767, -32768); 239 wd2 = ( enc->al[2] * wd2 ) >> 15 ; 240 241 enc->spl = wd1 + wd2 ; 242 SATURATE(enc->spl, 32767, -32768); 243 244 /* FILTEZ */ 245 246 enc->szl = 0 ; 247 for (i=6; i>0; i--) { 248 wd = enc->dlt[i] + enc->dlt[i]; 249 SATURATE(wd, 32767, -32768); 250 enc->szl += (enc->bl[i] * wd) >> 15 ; 251 SATURATE(enc->szl, 32767, -32768); 252 } 253 254 /* PREDIC */ 255 256 sl = enc->spl + enc->szl ; 257 SATURATE(sl, 32767, -32768); 258 259 return (sl) ; 260 } 261 262 static int block1h (int xh, int sh, int deth) 263 { 264 int ih ; 265 266 int eh, sih, mih, wd, wd1, hdu ; 267 268 static int ihn[3] = { 0, 1, 0 } ; 269 static int ihp[3] = { 0, 3, 2 } ; 270 271 /* SUBTRA */ 272 273 eh = xh - sh ; 274 SATURATE(eh, 32767, -32768); 275 276 /* QUANTH */ 277 278 sih = eh >> 15 ; 279 if (sih == 0 ) wd = eh ; 280 else wd = 32767 - eh & 32767 ; 281 282 hdu = (564 << 3) * deth; 283 wd1 = (hdu >> 15) ; 284 if (wd >= wd1) mih = 2 ; 285 else mih = 1 ; 286 287 if (sih == -1 ) ih = ihn[mih] ; 288 else ih = ihp[mih] ; 289 290 return (ih) ; 291 } 292 293 static int block2h (int ih, int deth) 294 { 295 int dh ; 296 int wd2 ; 297 static int qm2[4] = {-7408, -1616, 7408, 1616}; 298 299 /* INVQAH */ 300 301 wd2 = qm2[ih] ; 302 dh = (deth * wd2) >> 15 ; 303 304 return (dh) ; 305 } 306 307 static int block3h (g722_enc_t *enc, int ih) 308 { 309 int deth ; 310 int ih2, wd, wd1, wd2, wd3, nbph, deph ; 311 static int wh[3] = {0, -214, 798} ; 312 static int rh2[4] = {2, 1, 2, 1} ; 313 static int ilb[32] = { 314 2048, 2093, 2139, 2186, 2233, 2282, 2332, 315 2383, 2435, 2489, 2543, 2599, 2656, 2714, 316 2774, 2834, 2896, 2960, 3025, 3091, 3158, 317 3228, 3298, 3371, 3444, 3520, 3597, 3676, 318 3756, 3838, 3922, 4008 319 }; 320 321 /* LOGSCH */ 322 323 ih2 = rh2[ih] ; 324 wd = (enc->nbh * 32512) >> 15 ; 325 nbph = wd + wh[ih2] ; 326 327 if (nbph < 0) nbph = 0 ; 328 if (nbph > 22528) nbph = 22528 ; 329 330 /* SCALEH */ 331 332 wd1 = (nbph >> 6) & 31 ; 333 wd2 = nbph >> 11 ; 334 if ((10-wd2) < 0) wd3 = ilb[wd1] << (wd2-10) ; 335 else wd3 = ilb[wd1] >> (10-wd2) ; 336 deph = wd3 << 2 ; 337 338 /* DELAYA */ 339 enc->nbh = nbph ; 340 /* DELAYH */ 341 deth = deph ; 342 343 return (deth) ; 344 } 345 346 static int block4h (g722_enc_t *enc, int d) 347 { 348 int sh = enc->shigh; 349 int i ; 350 int wd, wd1, wd2, wd3, wd4, wd5 /*, wd6 */; 351 352 enc->dh[0] = d; 353 354 /* RECONS */ 355 356 enc->rh[0] = sh + enc->dh[0] ; 357 SATURATE(enc->rh[0], 32767, -32768); 358 359 /* PARREC */ 360 361 enc->ph[0] = enc->dh[0] + enc->szh ; 362 SATURATE(enc->ph[0], 32767, -32768); 363 364 /* UPPOL2 */ 365 366 enc->sgh[0] = enc->ph[0] >> 15 ; 367 enc->sgh[1] = enc->ph[1] >> 15 ; 368 enc->sgh[2] = enc->ph[2] >> 15 ; 369 370 wd1 = enc->ah[1] << 2; 371 SATURATE(wd1, 32767, -32768); 372 373 if ( enc->sgh[0] == enc->sgh[1] ) wd2 = - wd1 ; 374 else wd2 = wd1 ; 375 if ( wd2 > 32767 ) wd2 = 32767; 376 377 wd2 = wd2 >> 7 ; 378 379 if ( enc->sgh[0] == enc->sgh[2] ) wd3 = 128 ; 380 else wd3 = - 128 ; 381 382 wd4 = wd2 + wd3 ; 383 wd5 = (enc->ah[2] * 32512) >> 15 ; 384 385 enc->aph[2] = wd4 + wd5 ; 386 SATURATE(enc->aph[2], 12288, -12288); 387 388 /* UPPOL1 */ 389 390 enc->sgh[0] = enc->ph[0] >> 15 ; 391 enc->sgh[1] = enc->ph[1] >> 15 ; 392 393 if ( enc->sgh[0] == enc->sgh[1] ) wd1 = 192 ; 394 else wd1 = - 192 ; 395 396 wd2 = (enc->ah[1] * 32640) >> 15 ; 397 398 enc->aph[1] = wd1 + wd2 ; 399 SATURATE(enc->aph[1], 32767, -32768); 400 401 wd3 = (15360 - enc->aph[2]) ; 402 SATURATE(wd3, 32767, -32768); 403 404 if ( enc->aph[1] > wd3) enc->aph[1] = wd3 ; 405 else if ( enc->aph[1] < -wd3) enc->aph[1] = -wd3 ; 406 407 /* UPZERO */ 408 409 if ( enc->dh[0] == 0 ) wd1 = 0 ; 410 else wd1 = 128 ; 411 412 enc->sgh[0] = enc->dh[0] >> 15 ; 413 414 for ( i = 1; i < 7; i++ ) { 415 enc->sgh[i] = enc->dh[i] >> 15 ; 416 if ( enc->sgh[i] == enc->sgh[0] ) wd2 = wd1 ; 417 else wd2 = - wd1 ; 418 wd3 = (enc->bh[i] * 32640) >> 15 ; 419 enc->bph[i] = wd2 + wd3 ; 420 SATURATE(enc->bph[i], 32767, -32768); 421 } 422 423 /* DELAYA */ 424 for ( i = 6; i > 0; i-- ) { 425 enc->dh[i] = enc->dh[i-1] ; 426 enc->bh[i] = enc->bph[i] ; 427 } 428 429 for ( i = 2; i > 0; i-- ) { 430 enc->rh[i] = enc->rh[i-1] ; 431 enc->ph[i] = enc->ph[i-1] ; 432 enc->ah[i] = enc->aph[i] ; 433 } 434 435 /* FILTEP */ 436 437 wd1 = enc->rh[1] + enc->rh[1]; 438 SATURATE(wd1, 32767, -32768); 439 wd1 = ( enc->ah[1] * wd1 ) >> 15 ; 440 441 wd2 = enc->rh[2] + enc->rh[2]; 442 SATURATE(wd2, 32767, -32768); 443 wd2 = ( enc->ah[2] * wd2 ) >> 15 ; 444 445 enc->sph = wd1 + wd2 ; 446 SATURATE(enc->sph, 32767, -32768); 447 448 /* FILTEZ */ 449 450 enc->szh = 0 ; 451 for (i=6; i>0; i--) { 452 wd = enc->dh[i] + enc->dh[i]; 453 SATURATE(wd, 32767, -32768); 454 enc->szh += (enc->bh[i] * wd) >> 15 ; 455 SATURATE(enc->szh, 32767, -32768); 456 } 457 458 /* PREDIC */ 459 460 sh = enc->sph + enc->szh ; 461 SATURATE(sh, 32767, -32768); 462 463 return (sh) ; 464 } 465 466 /* PROCESS PCM THROUGH THE QMF FILTER */ 467 void tx_qmf(g722_enc_t *enc, int pcm1, int pcm2, int *lo, int *hi) 468 { 469 int sumodd, sumeven; 470 int i; 471 472 pj_memmove(&enc->x[2], enc->x, 22 * sizeof(enc->x[0])); 473 enc->x[1] = pcm1; 474 enc->x[0] = pcm2; 475 476 sumodd = 0; 477 for (i=1; i<24; i+=2) sumodd += enc->x[i] * g722_qmf_coeff[i]; 478 479 sumeven = 0; 480 for (i=0; i<24; i+=2) sumeven += enc->x[i] * g722_qmf_coeff[i]; 481 482 *lo = (sumeven + sumodd) >> 13 ; 483 *hi = (sumeven - sumodd) >> 13 ; 484 485 SATURATE(*lo, 16383, -16384); 486 SATURATE(*hi, 16383, -16383); 487 } 488 489 490 PJ_DEF(pj_status_t) g722_enc_init(g722_enc_t *enc) 491 { 492 PJ_ASSERT_RETURN(enc, PJ_EINVAL); 493 494 pj_bzero(enc, sizeof(g722_enc_t)); 495 496 enc->detlow = 32; 497 enc->dethigh = 8; 498 499 return PJ_SUCCESS; 500 } 501 502 PJ_DEF(pj_status_t) g722_enc_encode( g722_enc_t *enc, 503 pj_int16_t in[], 504 pj_size_t nsamples, 505 void *out, 506 pj_size_t *out_size) 507 { 508 unsigned i; 509 int xlow, ilow, dlowt; 510 int xhigh, ihigh, dhigh; 511 pj_uint8_t *out_ = (pj_uint8_t*) out; 512 513 PJ_ASSERT_RETURN(enc && in && nsamples && out && out_size, PJ_EINVAL); 514 PJ_ASSERT_RETURN(nsamples % 2 == 0, PJ_EINVAL); 515 PJ_ASSERT_RETURN(*out_size >= (nsamples >> 1), PJ_ETOOSMALL); 516 517 for(i = 0; i < nsamples; i += 2) { 518 tx_qmf(enc, in[i], in[i+1], &xlow, &xhigh); 519 520 /* low band encoder */ 521 ilow = block1l (xlow, enc->slow, enc->detlow) ; 522 dlowt = block2l (ilow, enc->detlow) ; 523 enc->detlow = block3l (enc, ilow) ; 524 enc->slow = block4l (enc, dlowt) ; 525 526 /* high band encoder */ 527 ihigh = block1h (xhigh, enc->shigh, enc->dethigh) ; 528 dhigh = block2h (ihigh, enc->dethigh) ; 529 enc->dethigh = block3h (enc, ihigh) ; 530 enc->shigh = block4h (enc, dhigh) ; 531 532 /* bits mix low & high adpcm */ 533 out_[i/2] = (pj_uint8_t)((ihigh << 6) | ilow); 534 } 535 536 *out_size = nsamples >> 1; 537 538 return PJ_SUCCESS; 539 } 540 541 PJ_DEF(pj_status_t) g722_enc_deinit(g722_enc_t *enc) 542 { 543 pj_bzero(enc, sizeof(g722_enc_t)); 544 545 return PJ_SUCCESS; 546 } 547 548 #endif -
pjmedia/src/pjmedia-codec/g722/g722_enc.h
1 /* $Id$ */ 2 /* 3 * Copyright (C)2003-2008 Benny Prijono <benny@prijono.org> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 */ 19 20 #ifndef __PJMEDIA_CODEC_G722_ENC_H__ 21 #define __PJMEDIA_CODEC_G722_ENC_H__ 22 23 #include <pjmedia-codec/types.h> 24 25 /* Encoder state */ 26 typedef struct g722_enc_t { 27 /* PCM low band */ 28 int slow; 29 int detlow; 30 int spl; 31 int szl; 32 int rlt [3]; 33 int al [3]; 34 int apl [3]; 35 int plt [3]; 36 int dlt [7]; 37 int bl [7]; 38 int bpl [7]; 39 int sgl [7]; 40 int nbl; 41 42 /* PCM high band*/ 43 int shigh; 44 int dethigh; 45 int sph; 46 int szh; 47 int rh [3]; 48 int ah [3]; 49 int aph [3]; 50 int ph [3]; 51 int dh [7]; 52 int bh [7]; 53 int bph [7]; 54 int sgh [7]; 55 int nbh; 56 57 /* QMF signal history */ 58 int x[24]; 59 } g722_enc_t; 60 61 62 PJ_DECL(pj_status_t) g722_enc_init(g722_enc_t *enc); 63 64 PJ_DECL(pj_status_t) g722_enc_encode(g722_enc_t *enc, 65 pj_int16_t in[], 66 pj_size_t nsamples, 67 void *out, 68 pj_size_t *out_size); 69 70 PJ_DECL(pj_status_t) g722_enc_deinit(g722_enc_t *enc); 71 72 #endif /* __PJMEDIA_CODEC_G722_ENC_H__ */ 73 -
pjmedia/src/pjmedia-codec/g722/g722_dec.c
1 #include <pjmedia/errno.h> 2 #include <pj/assert.h> 3 #include <pj/pool.h> 4 5 #include "g722_dec.h" 6 7 #if defined(PJMEDIA_HAS_G722_CODEC) && (PJMEDIA_HAS_G722_CODEC != 0) 8 9 #define MODE 1 10 11 #define SATURATE(v, max, min) \ 12 if (v>max) v = max; \ 13 else if (v<min) v = min 14 15 extern int g722_qmf_coeff[24]; 16 17 18 static int block2l (int il, int detl) 19 { 20 int dlt ; 21 int ril, wd2 ; 22 static int qm4[16] = { 23 0, -20456, -12896, -8968, 24 -6288, -4240, -2584, -1200, 25 20456, 12896, 8968, 6288, 26 4240, 2584, 1200, 0 27 }; 28 29 /* INVQAL */ 30 ril = il >> 2 ; 31 wd2 = qm4[ril] ; 32 dlt = (detl * wd2) >> 15 ; 33 34 return (dlt) ; 35 } 36 37 38 static int block3l (g722_dec_t *dec, int il) 39 { 40 int detl ; 41 int ril, il4, wd, wd1, wd2, wd3, nbpl, depl ; 42 static int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042}; 43 static int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0}; 44 static int ilb[32] = { 45 2048, 2093, 2139, 2186, 2233, 2282, 2332, 46 2383, 2435, 2489, 2543, 2599, 2656, 2714, 47 2774, 2834, 2896, 2960, 3025, 3091, 3158, 48 3228, 3298, 3371, 3444, 3520, 3597, 3676, 49 3756, 3838, 3922, 4008 50 }; 51 52 /* LOGSCL */ 53 ril = il >> 2 ; 54 il4 = rl42[ril] ; 55 wd = (dec->nbl * 32512) >> 15 ; 56 nbpl = wd + wl[il4] ; 57 58 if (nbpl < 0) nbpl = 0 ; 59 if (nbpl > 18432) nbpl = 18432 ; 60 61 /* SCALEL */ 62 wd1 = (nbpl >> 6) & 31 ; 63 wd2 = nbpl >> 11 ; 64 if ((8 - wd2) < 0) wd3 = ilb[wd1] << (wd2 - 8) ; 65 else wd3 = ilb[wd1] >> (8 - wd2) ; 66 depl = wd3 << 2 ; 67 68 /* DELAYA */ 69 dec->nbl = nbpl ; 70 /* DELAYL */ 71 detl = depl ; 72 73 return (detl) ; 74 } 75 76 77 static int block4l (g722_dec_t *dec, int dl) 78 { 79 int sl = dec->slow ; 80 int i ; 81 int wd, wd1, wd2, wd3, wd4, wd5/*, wd6 */; 82 83 dec->dlt[0] = dl; 84 85 /* RECONS */ 86 dec->rlt[0] = sl + dec->dlt[0] ; 87 SATURATE(dec->rlt[0], 32767, -32768); 88 89 /* PARREC */ 90 dec->plt[0] = dec->dlt[0] + dec->szl ; 91 SATURATE(dec->plt[0], 32767, -32768); 92 93 /* UPPOL2 */ 94 dec->sgl[0] = dec->plt[0] >> 15 ; 95 dec->sgl[1] = dec->plt[1] >> 15 ; 96 dec->sgl[2] = dec->plt[2] >> 15 ; 97 98 wd1 = dec->al[1] << 2; 99 SATURATE(wd1, 32767, -32768); 100 101 if ( dec->sgl[0] == dec->sgl[1] ) wd2 = - wd1 ; 102 else wd2 = wd1 ; 103 if (wd2 > 32767) wd2 = 32767; 104 wd2 = wd2 >> 7 ; 105 106 if ( dec->sgl[0] == dec->sgl[2] ) wd3 = 128 ; 107 else wd3 = - 128 ; 108 109 wd4 = wd2 + wd3 ; 110 wd5 = (dec->al[2] * 32512) >> 15 ; 111 112 dec->apl[2] = wd4 + wd5 ; 113 SATURATE(dec->apl[2], 12288, -12288); 114 115 /* UPPOL1 */ 116 dec->sgl[0] = dec->plt[0] >> 15 ; 117 dec->sgl[1] = dec->plt[1] >> 15 ; 118 119 if ( dec->sgl[0] == dec->sgl[1] ) wd1 = 192 ; 120 else wd1 = - 192 ; 121 122 wd2 = (dec->al[1] * 32640) >> 15 ; 123 124 dec->apl[1] = wd1 + wd2 ; 125 SATURATE(dec->apl[1], 32767, -32768); 126 127 wd3 = (15360 - dec->apl[2]) ; 128 SATURATE(wd3, 32767, -32768); 129 if ( dec->apl[1] > wd3) dec->apl[1] = wd3 ; 130 if ( dec->apl[1] < -wd3) dec->apl[1] = -wd3 ; 131 132 /* UPZERO */ 133 if ( dec->dlt[0] == 0 ) wd1 = 0 ; 134 else wd1 = 128 ; 135 136 dec->sgl[0] = dec->dlt[0] >> 15 ; 137 138 for ( i = 1; i < 7; i++ ) { 139 dec->sgl[i] = dec->dlt[i] >> 15 ; 140 if ( dec->sgl[i] == dec->sgl[0] ) wd2 = wd1 ; 141 else wd2 = - wd1 ; 142 wd3 = (dec->bl[i] * 32640) >> 15 ; 143 dec->bpl[i] = wd2 + wd3 ; 144 SATURATE(dec->bpl[i], 32767, -32768); 145 } 146 147 /* DELAYA */ 148 for ( i = 6; i > 0; i-- ) { 149 dec->dlt[i] = dec->dlt[i-1] ; 150 dec->bl[i] = dec->bpl[i] ; 151 } 152 153 for ( i = 2; i > 0; i-- ) { 154 dec->rlt[i] = dec->rlt[i-1] ; 155 dec->plt[i] = dec->plt[i-1] ; 156 dec->al[i] = dec->apl[i] ; 157 } 158 159 /* FILTEP */ 160 wd1 = dec->rlt[1] << 1; 161 SATURATE(wd1, 32767, -32768); 162 wd1 = ( dec->al[1] * wd1 ) >> 15 ; 163 164 wd2 = dec->rlt[2] << 1; 165 SATURATE(wd2, 32767, -32768); 166 wd2 = ( dec->al[2] * wd2 ) >> 15 ; 167 168 dec->spl = wd1 + wd2 ; 169 SATURATE(dec->spl, 32767, -32768); 170 171 /* FILTEZ */ 172 dec->szl = 0 ; 173 for (i=6; i>0; i--) { 174 wd = dec->dlt[i] << 1; 175 SATURATE(wd, 32767, -32768); 176 dec->szl += (dec->bl[i] * wd) >> 15 ; 177 SATURATE(dec->szl, 32767, -32768); 178 } 179 180 /* PREDIC */ 181 sl = dec->spl + dec->szl ; 182 SATURATE(sl, 32767, -32768); 183 184 return (sl) ; 185 } 186 187 static int block5l (int ilr, int sl, int detl, int mode) 188 { 189 int yl ; 190 int ril, dl, wd2 = 0; 191 static int qm4[16] = { 192 0, -20456, -12896, -8968, 193 -6288, -4240, -2584, -1200, 194 20456, 12896, 8968, 6288, 195 4240, 2584, 1200, 0 196 }; 197 static int qm5[32] = { 198 -280, -280, -23352, -17560, 199 -14120, -11664, -9752, -8184, 200 -6864, -5712, -4696, -3784, 201 -2960, -2208, -1520, -880, 202 23352, 17560, 14120, 11664, 203 9752, 8184, 6864, 5712, 204 4696, 3784, 2960, 2208, 205 1520, 880, 280, -280 206 }; 207 static int qm6[64] = { 208 -136, -136, -136, -136, 209 -24808, -21904, -19008, -16704, 210 -14984, -13512, -12280, -11192, 211 -10232, -9360, -8576, -7856, 212 -7192, -6576, -6000, -5456, 213 -4944, -4464, -4008, -3576, 214 -3168, -2776, -2400, -2032, 215 -1688, -1360, -1040, -728, 216 24808, 21904, 19008, 16704, 217 14984, 13512, 12280, 11192, 218 10232, 9360, 8576, 7856, 219 7192, 6576, 6000, 5456, 220 4944, 4464, 4008, 3576, 221 3168, 2776, 2400, 2032, 222 1688, 1360, 1040, 728, 223 432, 136, -432, -136 224 }; 225 226 /* INVQBL */ 227 if (mode == 1) { 228 ril = ilr ; 229 wd2 = qm6[ril] ; 230 } 231 232 if (mode == 2) { 233 ril = ilr >> 1 ; 234 wd2 = qm5[ril] ; 235 } 236 237 if (mode == 3) { 238 ril = ilr >> 2 ; 239 wd2 = qm4[ril] ; 240 } 241 242 dl = (detl * wd2 ) >> 15 ; 243 244 /* RECONS */ 245 yl = sl + dl ; 246 SATURATE(yl, 32767, -32768); 247 248 return (yl) ; 249 } 250 251 static int block6l (int yl) 252 { 253 int rl ; 254 255 rl = yl ; 256 SATURATE(rl, 16383, -16384); 257 258 return (rl) ; 259 } 260 261 static int block2h (int ih, int deth) 262 { 263 int dh ; 264 int wd2 ; 265 static int qm2[4] = {-7408, -1616, 7408, 1616} ; 266 267 /* INVQAH */ 268 wd2 = qm2[ih] ; 269 dh = (deth * wd2) >> 15 ; 270 271 return (dh) ; 272 } 273 274 static int block3h (g722_dec_t *dec, int ih) 275 { 276 int deth ; 277 int ih2, wd, wd1, wd2, wd3, nbph, deph ; 278 static int wh[3] = {0, -214, 798} ; 279 static int rh2[4] = {2, 1, 2, 1} ; 280 static int ilb[32] = { 281 2048, 2093, 2139, 2186, 2233, 2282, 2332, 282 2383, 2435, 2489, 2543, 2599, 2656, 2714, 283 2774, 2834, 2896, 2960, 3025, 3091, 3158, 284 3228, 3298, 3371, 3444, 3520, 3597, 3676, 285 3756, 3838, 3922, 4008 286 }; 287 288 /* LOGSCH */ 289 ih2 = rh2[ih] ; 290 wd = (dec->nbh * 32512) >> 15 ; 291 nbph = wd + wh[ih2] ; 292 293 if (nbph < 0) nbph = 0 ; 294 if (nbph > 22528) nbph = 22528 ; 295 296 297 /* SCALEH */ 298 wd1 = (nbph >> 6) & 31 ; 299 wd2 = nbph >> 11 ; 300 if ((10 - wd2) < 0) wd3 = ilb[wd1] << (wd2 - 10) ; 301 else wd3 = ilb[wd1] >> (10 - wd2) ; 302 deph = wd3 << 2 ; 303 304 /* DELAYA */ 305 dec->nbh = nbph ; 306 307 /* DELAYH */ 308 deth = deph ; 309 310 return (deth) ; 311 } 312 313 static int block4h (g722_dec_t *dec, int d) 314 { 315 int sh = dec->shigh; 316 int i ; 317 int wd, wd1, wd2, wd3, wd4, wd5/*, wd6 */; 318 static int sph = 0 ; 319 static int szh = 0 ; 320 static int rh [3] = { 0, 0, 0 } ; 321 static int ah [3] = { 0, 0, 0 } ; 322 static int aph [3] = { 0, 0, 0 } ; 323 static int ph [3] = { 0, 0, 0 } ; 324 static int dh [7] = { 0, 0, 0, 0, 0, 0, 0 } ; 325 static int bh [7] = { 0, 0, 0, 0, 0, 0, 0 } ; 326 static int bph [7] = { 0, 0, 0, 0, 0, 0, 0 } ; 327 static int sg [7] = { 0, 0, 0, 0, 0, 0, 0 } ; 328 329 330 dec->dh[0] = d; 331 332 /* RECONS */ 333 dec->rh[0] = sh + dec->dh[0] ; 334 SATURATE(dec->rh[0], 32767, -32768); 335 336 /* PARREC */ 337 dec->ph[0] = dec->dh[0] + dec->szh ; 338 SATURATE(dec->ph[0], 32767, -32768); 339 340 /* UPPOL2 */ 341 dec->sgh[0] = dec->ph[0] >> 15 ; 342 dec->sgh[1] = dec->ph[1] >> 15 ; 343 dec->sgh[2] = dec->ph[2] >> 15 ; 344 345 wd1 = dec->ah[1] << 2; 346 SATURATE(wd1, 32767, -32768); 347 348 if ( dec->sgh[0] == dec->sgh[1] ) wd2 = - wd1 ; 349 else wd2 = wd1 ; 350 if (wd2 > 32767) wd2 = 32767; 351 352 wd2 = wd2 >> 7 ; 353 354 if ( dec->sgh[0] == dec->sgh[2] ) wd3 = 128 ; 355 else wd3 = - 128 ; 356 357 wd4 = wd2 + wd3 ; 358 wd5 = (dec->ah[2] * 32512) >> 15 ; 359 360 dec->aph[2] = wd4 + wd5 ; 361 SATURATE(dec->aph[2], 12288, -12288); 362 363 /* UPPOL1 */ 364 dec->sgh[0] = dec->ph[0] >> 15 ; 365 dec->sgh[1] = dec->ph[1] >> 15 ; 366 367 if ( dec->sgh[0] == dec->sgh[1] ) wd1 = 192 ; 368 else wd1 = - 192 ; 369 370 wd2 = (dec->ah[1] * 32640) >> 15 ; 371 372 dec->aph[1] = wd1 + wd2 ; 373 SATURATE(dec->aph[1], 32767, -32768); 374 //dec->aph[2]? 375 //if (aph[2] > 32767) aph[2] = 32767; 376 //if (aph[2] < -32768) aph[2] = -32768; 377 378 wd3 = (15360 - dec->aph[2]) ; 379 SATURATE(wd3, 32767, -32768); 380 if ( dec->aph[1] > wd3) dec->aph[1] = wd3 ; 381 if ( dec->aph[1] < -wd3) dec->aph[1] = -wd3 ; 382 383 /* UPZERO */ 384 if ( dec->dh[0] == 0 ) wd1 = 0 ; 385 if ( dec->dh[0] != 0 ) wd1 = 128 ; 386 387 dec->sgh[0] = dec->dh[0] >> 15 ; 388 389 for ( i = 1; i < 7; i++ ) { 390 dec->sgh[i] = dec->dh[i] >> 15 ; 391 if ( dec->sgh[i] == dec->sgh[0] ) wd2 = wd1 ; 392 else wd2 = - wd1 ; 393 wd3 = (dec->bh[i] * 32640) >> 15 ; 394 dec->bph[i] = wd2 + wd3 ; 395 } 396 397 /* DELAYA */ 398 for ( i = 6; i > 0; i-- ) { 399 dec->dh[i] = dec->dh[i-1] ; 400 dec->bh[i] = dec->bph[i] ; 401 } 402 403 for ( i = 2; i > 0; i-- ) { 404 dec->rh[i] = dec->rh[i-1] ; 405 dec->ph[i] = dec->ph[i-1] ; 406 dec->ah[i] = dec->aph[i] ; 407 } 408 409 /* FILTEP */ 410 wd1 = dec->rh[1] << 1 ; 411 SATURATE(wd1, 32767, -32768); 412 wd1 = ( dec->ah[1] * wd1 ) >> 15 ; 413 414 wd2 = dec->rh[2] << 1; 415 SATURATE(wd2, 32767, -32768); 416 wd2 = ( dec->ah[2] * wd2 ) >> 15 ; 417 418 dec->sph = wd1 + wd2 ; 419 SATURATE(dec->sph, 32767, -32768); 420 421 /* FILTEZ */ 422 dec->szh = 0 ; 423 for (i=6; i>0; i--) { 424 wd = dec->dh[i] << 1; 425 SATURATE(wd, 32767, -32768); 426 dec->szh += (dec->bh[i] * wd) >> 15 ; 427 SATURATE(dec->szh, 32767, -32768); 428 } 429 430 /* PREDIC */ 431 sh = dec->sph + dec->szh ; 432 SATURATE(sh, 32767, -32768); 433 434 return (sh) ; 435 } 436 437 static int block5h (int dh, int sh) 438 { 439 int rh ; 440 441 rh = dh + sh; 442 SATURATE(rh, 16383, -16384); 443 444 return (rh) ; 445 } 446 447 void rx_qmf(g722_dec_t *dec, int rl, int rh, int *xout1, int *xout2) 448 { 449 int i; 450 451 pj_memmove(&dec->xd[1], dec->xd, 11*sizeof(dec->xd[0])); 452 pj_memmove(&dec->xs[1], dec->xs, 11*sizeof(dec->xs[0])); 453 454 /* RECA */ 455 dec->xd[0] = rl - rh ; 456 if (dec->xd[0] > 16383) dec->xd[0] = 16383; 457 else if (dec->xd[0] < -16384) dec->xd[0] = -16384; 458 459 /* RECB */ 460 dec->xs[0] = rl + rh ; 461 if (dec->xs[0] > 16383) dec->xs[0] = 16383; 462 else if (dec->xs[0] < -16384) dec->xs[0] = -16384; 463 464 /* ACCUMC */ 465 *xout1 = 0; 466 for (i=0; i<12; ++i) *xout1 += dec->xd[i] * g722_qmf_coeff[2*i]; 467 *xout1 = *xout1 >> 12 ; 468 if (*xout1 > 16383) *xout1 = 16383 ; 469 else if (*xout1 < -16384) *xout1 = -16384 ; 470 471 /* ACCUMD */ 472 *xout2 = 0; 473 for (i=0; i<12; ++i) *xout2 += dec->xs[i] * g722_qmf_coeff[2*i+1]; 474 *xout2 = *xout2 >> 12 ; 475 if (*xout2 > 16383) *xout2 = 16383 ; 476 else if (*xout2 < -16384) *xout2 = -16384 ; 477 } 478 479 480 PJ_DEF(pj_status_t) g722_dec_init(g722_dec_t *dec) 481 { 482 PJ_ASSERT_RETURN(dec, PJ_EINVAL); 483 484 pj_bzero(dec, sizeof(g722_dec_t)); 485 486 dec->detlow = 32; 487 dec->dethigh = 8; 488 489 return PJ_SUCCESS; 490 } 491 492 PJ_DEF(pj_status_t) g722_dec_decode( g722_dec_t *dec, 493 void *in, 494 pj_size_t in_size, 495 pj_int16_t out[], 496 pj_size_t *nsamples) 497 { 498 unsigned i; 499 int ilowr, ylow, rlow, dlowt; 500 int ihigh, rhigh, dhigh; 501 int pcm1, pcm2; 502 pj_uint8_t *in_ = (pj_uint8_t*) in; 503 504 PJ_ASSERT_RETURN(dec && in && in_size && out && nsamples, PJ_EINVAL); 505 PJ_ASSERT_RETURN(*nsamples >= (in_size << 1), PJ_ETOOSMALL); 506 507 for(i = 0; i < in_size; ++i) { 508 ilowr = in_[i] & 63; 509 ihigh = (in_[i] >> 6) & 3; 510 511 /* low band decoder */ 512 ylow = block5l (ilowr, dec->slow, dec->detlow, MODE) ; 513 rlow = block6l (ylow) ; 514 dlowt = block2l (ilowr, dec->detlow) ; 515 dec->detlow = block3l (dec, ilowr) ; 516 dec->slow = block4l (dec, dlowt) ; 517 /* rlow <= output low band pcm */ 518 519 /* high band decoder */ 520 dhigh = block2h (ihigh, dec->dethigh) ; 521 rhigh = block5h (dhigh, dec->shigh) ; 522 dec->dethigh = block3h (dec, ihigh) ; 523 dec->shigh = block4h (dec, dhigh) ; 524 /* rhigh <= output high band pcm */ 525 526 rx_qmf(dec, rlow, rhigh, &pcm1, &pcm2); 527 out[i*2] = (pj_int16_t)pcm1; 528 out[i*2+1] = (pj_int16_t)pcm2; 529 } 530 531 *nsamples = in_size << 1; 532 533 return PJ_SUCCESS; 534 } 535 536 PJ_DEF(pj_status_t) g722_dec_deinit(g722_dec_t *dec) 537 { 538 pj_bzero(dec, sizeof(g722_dec_t)); 539 540 return PJ_SUCCESS; 541 } 542 543 #endif