- Timestamp:
- Aug 13, 2008 6:21:03 PM (16 years ago)
- Location:
- pjproject/trunk/pjmedia/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/echo_suppress.c
r2208 r2212 244 244 float best_corr; /* Best correlation so far. */ 245 245 246 unsigned sum_rec_level; /* Running sum of level in rec_hist */ 247 float rec_corr; /* Running corr in rec_hist. */ 248 249 unsigned sum_play_level0; /* Running sum of level for first pos */ 250 float play_corr0; /* Running corr for first pos . */ 251 246 252 float *min_factor; /* Array of minimum scaling factor */ 247 253 float *avg_factor; /* Array of average scaling factor */ … … 354 360 ec->residue = 0; 355 361 ec->running_cnt = 0; 362 ec->sum_rec_level = ec->sum_play_level0 = 0; 363 ec->rec_corr = ec->play_corr0 = 0; 356 364 } 357 365 … … 376 384 ec->residue = 0; 377 385 ec->running_cnt = 0; 386 ec->sum_rec_level = ec->sum_play_level0 = 0; 387 ec->rec_corr = ec->play_corr0 = 0; 378 388 379 389 PJ_LOG(4,(THIS_FILE, "Echo suppressor soft reset. Re-learning..")); … … 404 414 { 405 415 int prev_index; 406 unsigned i, frm_level, sum_rec_level; 407 float rec_corr; 416 unsigned i, j, frm_level, sum_play_level, ulaw; 417 pj_uint16_t old_rec_frm_level, old_play_frm_level; 418 float play_corr; 408 419 409 420 ++ec->update_cnt; … … 415 426 ++frm_level; /* to avoid division by zero */ 416 427 428 /* Save the oldest frame level for later */ 429 old_play_frm_level = ec->play_hist[0]; 430 417 431 /* Push current frame level to the back of the play history */ 418 432 pj_array_erase(ec->play_hist, sizeof(pj_uint16_t), ec->play_hist_cnt, 0); … … 423 437 ++frm_level; /* to avoid division by zero */ 424 438 439 /* Save the oldest frame level for later */ 440 old_rec_frm_level = ec->rec_hist[0]; 441 425 442 /* Push to the back of the rec history */ 426 443 pj_array_erase(ec->rec_hist, sizeof(pj_uint16_t), ec->templ_cnt, 0); … … 438 455 439 456 /* Calculate rec signal pattern */ 440 rec_corr = 0; 441 sum_rec_level = 0; 442 for (i=0; i < ec->templ_cnt-1; ++i) { 443 float corr; 444 corr = (float)ec->rec_hist[i+1] / ec->rec_hist[i]; 445 rec_corr += corr; 446 sum_rec_level += ec->rec_hist[i]; 447 } 448 sum_rec_level += ec->rec_hist[i]; 457 if (ec->sum_rec_level == 0) { 458 /* Buffer has just been filled up, do full calculation */ 459 ec->rec_corr = 0; 460 ec->sum_rec_level = 0; 461 for (i=0; i < ec->templ_cnt-1; ++i) { 462 float corr; 463 corr = (float)ec->rec_hist[i+1] / ec->rec_hist[i]; 464 ec->rec_corr += corr; 465 ec->sum_rec_level += ec->rec_hist[i]; 466 } 467 ec->sum_rec_level += ec->rec_hist[i]; 468 } else { 469 /* Update from previous calculation */ 470 ec->sum_rec_level = ec->sum_rec_level - old_rec_frm_level + 471 ec->rec_hist[ec->templ_cnt-1]; 472 ec->rec_corr = ec->rec_corr - ((float)ec->rec_hist[0] / 473 old_rec_frm_level) + 474 ((float)ec->rec_hist[ec->templ_cnt-1] / 475 ec->rec_hist[ec->templ_cnt-2]); 476 } 449 477 450 478 /* Iterate through the play history and calculate the signal correlation … … 453 481 * to detect echo. 454 482 */ 455 for (i=0; i < ec->tail_cnt; ++i) { 456 unsigned j, end, sum_play_level, ulaw; 457 float play_corr = 0, corr_diff; 458 483 /* 484 * First phase: do full calculation for the first position 485 */ 486 if (ec->sum_play_level0 == 0) { 487 /* Buffer has just been filled up, do full calculation */ 459 488 sum_play_level = 0; 460 for (j=i, end=i+ec->templ_cnt-1; j<end; ++j) { 489 play_corr = 0; 490 for (j=0; j<ec->templ_cnt-1; ++j) { 461 491 float corr; 462 492 corr = (float)ec->play_hist[j+1] / ec->play_hist[j]; … … 465 495 } 466 496 sum_play_level += ec->play_hist[j]; 497 ec->sum_play_level0 = sum_play_level; 498 ec->play_corr0 = play_corr; 499 } else { 500 /* Update from previous calculation */ 501 ec->sum_play_level0 = ec->sum_play_level0 - old_play_frm_level + 502 ec->play_hist[ec->templ_cnt-1]; 503 ec->play_corr0 = ec->play_corr0 - ((float)ec->play_hist[0] / 504 old_play_frm_level) + 505 ((float)ec->play_hist[ec->templ_cnt-1] / 506 ec->play_hist[ec->templ_cnt-2]); 507 sum_play_level = ec->sum_play_level0; 508 play_corr = ec->play_corr0; 509 } 510 ec->tmp_corr[0] = FABS(play_corr - ec->rec_corr); 511 ec->tmp_factor[0] = (float)ec->sum_rec_level / sum_play_level; 512 513 /* Bail out if remote isn't talking */ 514 ulaw = pjmedia_linear2ulaw(sum_play_level/ec->templ_cnt) ^ 0xFF; 515 if (ulaw < MIN_SIGNAL_ULAW) { 516 echo_supp_set_state(ec, ST_REM_SILENT, ulaw); 517 return; 518 } 519 /* Bail out if local user is talking */ 520 if (ec->sum_rec_level > sum_play_level) { 521 echo_supp_set_state(ec, ST_LOCAL_TALK, ulaw); 522 return; 523 } 524 525 /* 526 * Second phase: do incremental calculation for the rest of positions 527 */ 528 for (i=1; i < ec->tail_cnt; ++i) { 529 unsigned end; 530 531 end = i + ec->templ_cnt; 532 533 sum_play_level = sum_play_level - ec->play_hist[i-1] + 534 ec->play_hist[end-1]; 535 play_corr = play_corr - ((float)ec->play_hist[i]/ec->play_hist[i-1]) + 536 ((float)ec->play_hist[end-1]/ec->play_hist[end-2]); 467 537 468 538 /* Bail out if remote isn't talking */ … … 474 544 475 545 /* Bail out if local user is talking */ 476 if ( sum_rec_level >=sum_play_level) {546 if (ec->sum_rec_level > sum_play_level) { 477 547 echo_supp_set_state(ec, ST_LOCAL_TALK, ulaw); 478 548 return; … … 482 552 // disabled: not a good idea if mic throws out loud echo 483 553 /* Also bail out if we suspect there's a doubletalk */ 484 ulaw = pjmedia_linear2ulaw( sum_rec_level/ec->templ_cnt) ^ 0xFF;554 ulaw = pjmedia_linear2ulaw(ec->sum_rec_level/ec->templ_cnt) ^ 0xFF; 485 555 if (ulaw > MIN_SIGNAL_ULAW) { 486 556 echo_supp_set_state(ec, ST_DOUBLETALK, ulaw); … … 490 560 491 561 /* Calculate correlation and save to temporary array */ 492 corr_diff = FABS(play_corr - rec_corr); 493 ec->tmp_corr[i] = corr_diff; 562 ec->tmp_corr[i] = FABS(play_corr - ec->rec_corr); 494 563 495 564 /* Also calculate the gain factor between mic and speaker level */ 496 ec->tmp_factor[i] = (float) sum_rec_level / sum_play_level;565 ec->tmp_factor[i] = (float)ec->sum_rec_level / sum_play_level; 497 566 pj_assert(ec->tmp_factor[i] < 1); 498 567 } … … 653 722 factor = 1.0; 654 723 echo_supp_set_state(ec, ST_LOCAL_TALK, rec_level); 655 } else if (rec_level > =play_level) {724 } else if (rec_level > play_level) { 656 725 /* Seems that both are talking. Scale the mic signal 657 726 * down a little bit to reduce echo, while allowing both … … 689 758 factor = (factor + ec->last_factor) / 2; 690 759 else 691 factor = (factor + ec->last_factor* 9) / 10;760 factor = (factor + ec->last_factor*19) / 20; 692 761 693 762 /* Amplify frame */ -
pjproject/trunk/pjmedia/src/test/mips_test.c
r2192 r2212 52 52 */ 53 53 54 //# define CPU_MHZ (2666)55 //# define CPU_IPS (CPU_MHZ * MEGA * 3.039) /* P4 2.6GHz */56 57 # define CPU_MHZ 70058 # define CPU_IPS (700 * MEGA * 2.708) /* P3 700Mhz */54 # define CPU_MHZ (2666) 55 # define CPU_IPS (3.039 * CPU_MHZ * MEGA) /* P4 2.6GHz */ 56 57 //# define CPU_MHZ 700 58 //# define CPU_IPS (700 * MEGA * 2.708) /* P3 700Mhz */ 59 59 60 60 //# define CPU_MHZ 180 61 61 //# define CPU_IPS (CPU_MHZ * MEGA * 1.1) /* ARM926EJ-S */ 62 63 //# define CPU_MHZ 312 64 //# define CPU_IPS (CPU_MHZ * MEGA * 1.282) /* Dell Axim PDA */ 65 62 66 #endif 63 67 … … 357 361 358 362 #define THIS_FILE "mips_test.c" 359 #define DURATION 1000363 #define DURATION 5000 360 364 #define PTIME 20 /* MUST be 20! */ 361 365 #define MEGA 1000000 … … 1264 1268 pj_status_t status; 1265 1269 1266 PJ_UNUSED_ARG(flags);1267 1270 PJ_UNUSED_ARG(te); 1268 1271 … … 1273 1276 1274 1277 status = pjmedia_echo_port_create(pool, gen_port, ec_tail_msec, 0, 1275 0, &ec_port);1278 flags, &ec_port); 1276 1279 if (status != PJ_SUCCESS) 1277 1280 return NULL; … … 1288 1291 struct test_entry *te) 1289 1292 { 1293 flags = 0; 1290 1294 return ec_create(100, pool, clock_rate, channel_count, samples_per_frame, 1291 1295 flags, te); … … 1300 1304 struct test_entry *te) 1301 1305 { 1306 flags = 0; 1302 1307 return ec_create(128, pool, clock_rate, channel_count, samples_per_frame, 1303 1308 flags, te); … … 1312 1317 struct test_entry *te) 1313 1318 { 1319 flags = 0; 1314 1320 return ec_create(200, pool, clock_rate, channel_count, samples_per_frame, 1315 1321 flags, te); … … 1324 1330 struct test_entry *te) 1325 1331 { 1332 flags = 0; 1326 1333 return ec_create(256, pool, clock_rate, channel_count, samples_per_frame, 1327 1334 flags, te); … … 1337 1344 struct test_entry *te) 1338 1345 { 1346 flags = 0; 1339 1347 return ec_create(400, pool, clock_rate, channel_count, samples_per_frame, 1340 1348 flags, te); … … 1349 1357 struct test_entry *te) 1350 1358 { 1359 flags = 0; 1351 1360 return ec_create(500, pool, clock_rate, channel_count, samples_per_frame, 1352 1361 flags, te); … … 1361 1370 struct test_entry *te) 1362 1371 { 1372 flags = 0; 1363 1373 return ec_create(512, pool, clock_rate, channel_count, samples_per_frame, 1364 1374 flags, te); … … 1373 1383 struct test_entry *te) 1374 1384 { 1385 flags = 0; 1375 1386 return ec_create(600, pool, clock_rate, channel_count, samples_per_frame, 1376 1387 flags, te); … … 1385 1396 struct test_entry *te) 1386 1397 { 1398 flags = 0; 1399 return ec_create(800, pool, clock_rate, channel_count, samples_per_frame, 1400 flags, te); 1401 } 1402 1403 1404 1405 /* Echo suppressor with 100ms tail length */ 1406 static pjmedia_port* es_create_100(pj_pool_t *pool, 1407 unsigned clock_rate, 1408 unsigned channel_count, 1409 unsigned samples_per_frame, 1410 unsigned flags, 1411 struct test_entry *te) 1412 { 1413 flags = PJMEDIA_ECHO_SIMPLE; 1414 return ec_create(100, pool, clock_rate, channel_count, samples_per_frame, 1415 flags, te); 1416 } 1417 1418 /* Echo suppressor with 128ms tail length */ 1419 static pjmedia_port* es_create_128(pj_pool_t *pool, 1420 unsigned clock_rate, 1421 unsigned channel_count, 1422 unsigned samples_per_frame, 1423 unsigned flags, 1424 struct test_entry *te) 1425 { 1426 flags = PJMEDIA_ECHO_SIMPLE; 1427 return ec_create(128, pool, clock_rate, channel_count, samples_per_frame, 1428 flags, te); 1429 } 1430 1431 /* Echo suppressor with 200ms tail length */ 1432 static pjmedia_port* es_create_200(pj_pool_t *pool, 1433 unsigned clock_rate, 1434 unsigned channel_count, 1435 unsigned samples_per_frame, 1436 unsigned flags, 1437 struct test_entry *te) 1438 { 1439 flags = PJMEDIA_ECHO_SIMPLE; 1440 return ec_create(200, pool, clock_rate, channel_count, samples_per_frame, 1441 flags, te); 1442 } 1443 1444 /* Echo suppressor with 256ms tail length */ 1445 static pjmedia_port* es_create_256(pj_pool_t *pool, 1446 unsigned clock_rate, 1447 unsigned channel_count, 1448 unsigned samples_per_frame, 1449 unsigned flags, 1450 struct test_entry *te) 1451 { 1452 flags = PJMEDIA_ECHO_SIMPLE; 1453 return ec_create(256, pool, clock_rate, channel_count, samples_per_frame, 1454 flags, te); 1455 } 1456 1457 1458 /* Echo suppressor with 400ms tail length */ 1459 static pjmedia_port* es_create_400(pj_pool_t *pool, 1460 unsigned clock_rate, 1461 unsigned channel_count, 1462 unsigned samples_per_frame, 1463 unsigned flags, 1464 struct test_entry *te) 1465 { 1466 flags = PJMEDIA_ECHO_SIMPLE; 1467 return ec_create(400, pool, clock_rate, channel_count, samples_per_frame, 1468 flags, te); 1469 } 1470 1471 /* Echo suppressor with 500ms tail length */ 1472 static pjmedia_port* es_create_500(pj_pool_t *pool, 1473 unsigned clock_rate, 1474 unsigned channel_count, 1475 unsigned samples_per_frame, 1476 unsigned flags, 1477 struct test_entry *te) 1478 { 1479 flags = PJMEDIA_ECHO_SIMPLE; 1480 return ec_create(500, pool, clock_rate, channel_count, samples_per_frame, 1481 flags, te); 1482 } 1483 1484 /* Echo suppressor with 512ms tail length */ 1485 static pjmedia_port* es_create_512(pj_pool_t *pool, 1486 unsigned clock_rate, 1487 unsigned channel_count, 1488 unsigned samples_per_frame, 1489 unsigned flags, 1490 struct test_entry *te) 1491 { 1492 flags = PJMEDIA_ECHO_SIMPLE; 1493 return ec_create(512, pool, clock_rate, channel_count, samples_per_frame, 1494 flags, te); 1495 } 1496 1497 /* Echo suppressor with 600ms tail length */ 1498 static pjmedia_port* es_create_600(pj_pool_t *pool, 1499 unsigned clock_rate, 1500 unsigned channel_count, 1501 unsigned samples_per_frame, 1502 unsigned flags, 1503 struct test_entry *te) 1504 { 1505 flags = PJMEDIA_ECHO_SIMPLE; 1506 return ec_create(600, pool, clock_rate, channel_count, samples_per_frame, 1507 flags, te); 1508 } 1509 1510 /* Echo suppressor with 800ms tail length */ 1511 static pjmedia_port* es_create_800(pj_pool_t *pool, 1512 unsigned clock_rate, 1513 unsigned channel_count, 1514 unsigned samples_per_frame, 1515 unsigned flags, 1516 struct test_entry *te) 1517 { 1518 flags = PJMEDIA_ECHO_SIMPLE; 1387 1519 return ec_create(800, pool, clock_rate, channel_count, samples_per_frame, 1388 1520 flags, te); … … 2129 2261 { "echo canceller 600ms tail len", OP_GET_PUT, K8|K16, &ec_create_600}, 2130 2262 { "echo canceller 800ms tail len", OP_GET_PUT, K8|K16, &ec_create_800}, 2263 { "echo suppressor 100ms tail len", OP_GET_PUT, K8|K16, &es_create_100}, 2264 { "echo suppressor 128ms tail len", OP_GET_PUT, K8|K16, &es_create_128}, 2265 { "echo suppressor 200ms tail len", OP_GET_PUT, K8|K16, &es_create_200}, 2266 { "echo suppressor 256ms tail len", OP_GET_PUT, K8|K16, &es_create_256}, 2267 { "echo suppressor 400ms tail len", OP_GET_PUT, K8|K16, &es_create_400}, 2268 { "echo suppressor 500ms tail len", OP_GET_PUT, K8|K16, &es_create_500}, 2269 { "echo suppressor 512ms tail len", OP_GET_PUT, K8|K16, &es_create_512}, 2270 { "echo suppressor 600ms tail len", OP_GET_PUT, K8|K16, &es_create_600}, 2271 { "echo suppressor 800ms tail len", OP_GET_PUT, K8|K16, &es_create_800}, 2131 2272 { "tone generator with single freq", OP_GET, K8|K16, &create_tonegen1}, 2132 2273 { "tone generator with dual freq", OP_GET, K8|K16, &create_tonegen2}, … … 2196 2337 pj_elapsed_usec(&tzero, ×[1])) / 2; 2197 2338 2339 usec = usec / (DURATION / 1000); 2340 2198 2341 mips = (float)(CPU_IPS * usec / 1000000.0 / 1000000); 2199 2342 cpu_pct = (float)(100.0 * usec / 1000000);
Note: See TracChangeset
for help on using the changeset viewer.