Changeset 1898 for pjproject/trunk/pjmedia/src/pjmedia/conference.c
- Timestamp:
- Mar 29, 2008 12:24:20 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/src/pjmedia/conference.c
r1839 r1898 25 25 #include <pjmedia/silencedet.h> 26 26 #include <pjmedia/sound_port.h> 27 #include <pjmedia/stereo.h> 27 28 #include <pjmedia/stream.h> 28 29 #include <pj/array.h> … … 113 114 SLOT_TYPE *listener_slots;/**< Array of listeners. */ 114 115 unsigned transmitter_cnt;/**<Number of transmitters. */ 115 pjmedia_silence_det *vad; /**< VAD for this port. */116 116 117 117 /* Shortcut for port info. */ 118 118 unsigned clock_rate; /**< Port's clock rate. */ 119 119 unsigned samples_per_frame; /**< Port's samples per frame. */ 120 unsigned channel_count; /**< Port's channel count. */ 120 121 121 122 /* Calculated signal levels: */ … … 286 287 conf_port->clock_rate = port->info.clock_rate; 287 288 conf_port->samples_per_frame = port->info.samples_per_frame; 289 conf_port->channel_count = port->info.channel_count; 288 290 } else { 289 291 conf_port->port = NULL; 290 292 conf_port->clock_rate = conf->clock_rate; 291 293 conf_port->samples_per_frame = conf->samples_per_frame; 292 } 293 294 /* Create and init vad. */ 295 status = pjmedia_silence_det_create( pool, 296 conf_port->clock_rate, 297 conf_port->samples_per_frame, 298 &conf_port->vad); 299 if (status != PJ_SUCCESS) 300 return status; 301 302 /* Set fixed */ 303 pjmedia_silence_det_set_fixed(conf_port->vad, 2); 304 305 /* Set VAD name */ 306 pjmedia_silence_det_set_name(conf_port->vad, conf_port->name.ptr); 294 conf_port->channel_count = conf->channel_count; 295 } 307 296 308 297 /* If port's clock rate is different than conference's clock rate, … … 347 336 /* 348 337 * Initialize rx and tx buffer, only when port's samples per frame or 349 * port's clock rate is different then the conference bridge settings. 338 * port's clock rate or channel number is different then the conference 339 * bridge settings. 350 340 */ 351 341 if (conf_port->clock_rate != conf->clock_rate || 342 conf_port->channel_count != conf->channel_count || 352 343 conf_port->samples_per_frame != conf->samples_per_frame) 353 344 { 345 unsigned port_ptime, conf_ptime, buff_ptime; 346 347 port_ptime = conf_port->samples_per_frame / conf_port->channel_count * 348 1000 / conf_port->clock_rate; 349 conf_ptime = conf->samples_per_frame / conf->channel_count * 350 1000 / conf->clock_rate; 351 352 /* Calculate the size (in ptime) for the port buffer according to 353 * this formula: 354 * - if either ptime is an exact multiple of the other, then use 355 * the larger ptime (e.g. 20ms and 40ms, use 40ms). 356 * - if not, then the ptime is sum of both ptimes (e.g. 20ms 357 * and 30ms, use 50ms) 358 */ 359 if (port_ptime > conf_ptime) { 360 buff_ptime = conf_ptime * (port_ptime / conf_ptime); 361 if (port_ptime % conf_ptime) 362 buff_ptime += conf_ptime; 363 } else { 364 buff_ptime = port_ptime * (conf_ptime / port_ptime); 365 if (conf_ptime % port_ptime) 366 buff_ptime += port_ptime; 367 } 368 354 369 /* Create RX buffer. */ 355 conf_port->rx_buf_cap = (unsigned)(conf_port->samples_per_frame + 356 conf->samples_per_frame * 357 conf_port->clock_rate * 1.0 / 358 conf->clock_rate); 370 //conf_port->rx_buf_cap = (unsigned)(conf_port->samples_per_frame + 371 // conf->samples_per_frame * 372 // conf_port->clock_rate * 1.0 / 373 // conf->clock_rate); 374 conf_port->rx_buf_cap = conf_port->clock_rate * buff_ptime / 1000; 375 if (conf_port->channel_count > conf->channel_count) 376 conf_port->rx_buf_cap *= conf_port->channel_count; 377 else 378 conf_port->rx_buf_cap *= conf->channel_count; 379 359 380 conf_port->rx_buf_count = 0; 360 381 conf_port->rx_buf = (pj_int16_t*) … … 699 720 port_name = &strm_port->info.name; 700 721 701 /* For this version of PJMEDIA, port MUST have the same number of 702 * PCM channels. 703 */ 704 if (strm_port->info.channel_count != conf->channel_count) { 722 /* For this version of PJMEDIA, channel(s) number MUST be: 723 * - same between port & conference bridge. 724 * - monochannel on port or conference bridge. 725 */ 726 if (strm_port->info.channel_count != conf->channel_count && 727 (strm_port->info.channel_count != 1 && conf->channel_count != 1)) 728 { 705 729 pj_assert(!"Number of channels mismatch"); 706 730 return PJMEDIA_ENCCHANNEL; … … 767 791 PJ_ASSERT_RETURN(conf && pool, PJ_EINVAL); 768 792 769 /* For this version of PJMEDIA, port MUST have the same number of 770 * PCM channels. 771 */ 772 if (channel_count != conf->channel_count) { 793 /* For this version of PJMEDIA, channel(s) number MUST be: 794 * - same between port & conference bridge. 795 * - monochannel on port or conference bridge. 796 */ 797 if (channel_count != conf->channel_count && 798 (channel_count != 1 && conf->channel_count != 1)) 799 { 773 800 pj_assert(!"Number of channels mismatch"); 774 801 return PJMEDIA_ENCCHANNEL; … … 1141 1168 info->listener_slots = conf_port->listener_slots; 1142 1169 info->clock_rate = conf_port->clock_rate; 1143 info->channel_count = conf ->channel_count;1170 info->channel_count = conf_port->channel_count; 1144 1171 info->samples_per_frame = conf_port->samples_per_frame; 1145 1172 info->bits_per_sample = conf->bits_per_sample; … … 1275 1302 count)); 1276 1303 1277 /* If port's samples per frame and sampling rate matches conference 1278 * bridge's settings, get the frame directly from the port. 1304 /* 1305 * If port's samples per frame and sampling rate and channel count 1306 * matche conference bridge's settings, get the frame directly from 1307 * the port. 1279 1308 */ 1280 1309 if (cport->rx_buf_cap == 0) { … … 1296 1325 1297 1326 } else { 1327 unsigned samples_req; 1298 1328 1299 1329 /* Initialize frame type */ … … 1307 1337 /* 1308 1338 * If we don't have enough samples in rx_buf, read from the port 1309 * first. Remember that rx_buf may be in different clock rate! 1339 * first. Remember that rx_buf may be in different clock rate and 1340 * channel count! 1310 1341 */ 1311 while (cport->rx_buf_count < count * 1.0 * 1312 cport->clock_rate / conf->clock_rate) { 1342 1343 samples_req = (unsigned) (count * 1.0 * 1344 cport->clock_rate / conf->clock_rate); 1345 1346 while (cport->rx_buf_count < samples_req) { 1313 1347 1314 1348 pjmedia_frame f; … … 1337 1371 } 1338 1372 1339 cport->rx_buf_count += cport->samples_per_frame; 1373 /* Adjust channels */ 1374 if (cport->channel_count != conf->channel_count) { 1375 if (cport->channel_count == 1) { 1376 pjmedia_convert_channel_1ton(f.buf, f.buf, 1377 conf->channel_count, 1378 cport->samples_per_frame, 1379 0); 1380 cport->rx_buf_count += (cport->samples_per_frame * 1381 conf->channel_count); 1382 } else { /* conf->channel_count == 1 */ 1383 pjmedia_convert_channel_nto1(f.buf, f.buf, 1384 cport->channel_count, 1385 cport->samples_per_frame, 1386 PJMEDIA_STEREO_MIX, 0); 1387 cport->rx_buf_count += (cport->samples_per_frame / 1388 cport->channel_count); 1389 } 1390 } else { 1391 cport->rx_buf_count += cport->samples_per_frame; 1392 } 1340 1393 1341 1394 TRACE_((THIS_FILE, " rx buffer size is now %d", … … 1362 1415 cport->rx_buf_count -= src_count; 1363 1416 if (cport->rx_buf_count) { 1364 pjmedia_ copy_samples(cport->rx_buf, cport->rx_buf+src_count,1417 pjmedia_move_samples(cport->rx_buf, cport->rx_buf+src_count, 1365 1418 cport->rx_buf_count); 1366 1419 } … … 1374 1427 cport->rx_buf_count -= count; 1375 1428 if (cport->rx_buf_count) { 1376 pjmedia_ copy_samples(cport->rx_buf, cport->rx_buf+count,1429 pjmedia_move_samples(cport->rx_buf, cport->rx_buf+count, 1377 1430 cport->rx_buf_count); 1378 1431 } … … 1396 1449 pj_int32_t adj_level; 1397 1450 pj_int32_t tx_level; 1451 unsigned dst_count; 1398 1452 1399 1453 *frm_type = PJMEDIA_FRAME_TYPE_AUDIO; … … 1413 1467 /* Add sample counts to heart-beat samples */ 1414 1468 cport->tx_heart_beat += conf->samples_per_frame * cport->clock_rate / 1415 conf->clock_rate; 1469 conf->clock_rate * 1470 cport->channel_count / conf->channel_count; 1416 1471 1417 1472 /* Set frame timestamp */ … … 1477 1532 tx_level = 0; 1478 1533 1479 for (j=0; j<conf->samples_per_frame; ++j) {1480 if (adj_level != NORMAL_LEVEL) {1534 if (adj_level != NORMAL_LEVEL) { 1535 for (j=0; j<conf->samples_per_frame; ++j) { 1481 1536 pj_int32_t itemp = cport->mix_buf[j]; 1482 1537 … … 1491 1546 /* Put back in the buffer. */ 1492 1547 buf[j] = (pj_int16_t) itemp; 1493 } else { 1548 1549 tx_level += (buf[j]>=0? buf[j] : -buf[j]); 1550 } 1551 } else { 1552 for (j=0; j<conf->samples_per_frame; ++j) { 1494 1553 buf[j] = (pj_int16_t) cport->mix_buf[j]; 1554 tx_level += (buf[j]>=0? buf[j] : -buf[j]); 1495 1555 } 1496 1497 tx_level += (buf[j]>0? buf[j] : -buf[j]);1498 1556 } 1499 1557 … … 1505 1563 cport->tx_level = tx_level; 1506 1564 1507 /* If port has the same clock_rate and samples_per_frame settings as 1508 * the conference bridge, transmit the frame as is. 1565 /* If port has the same clock_rate and samples_per_frame and 1566 * number of channels as the conference bridge, transmit the 1567 * frame as is. 1509 1568 */ 1510 1569 if (cport->clock_rate == conf->clock_rate && 1511 cport->samples_per_frame == conf->samples_per_frame) 1570 cport->samples_per_frame == conf->samples_per_frame && 1571 cport->channel_count == conf->channel_count) 1512 1572 { 1513 1573 if (cport->port != NULL) { … … 1533 1593 /* If it has different clock_rate, must resample. */ 1534 1594 if (cport->clock_rate != conf->clock_rate) { 1535 1536 unsigned dst_count;1537 1538 1595 pjmedia_resample_run( cport->tx_resample, buf, 1539 1596 cport->tx_buf + cport->tx_buf_count ); 1540 1541 1597 dst_count = (unsigned)(conf->samples_per_frame * 1.0 * 1542 1598 cport->clock_rate / conf->clock_rate); 1543 cport->tx_buf_count += dst_count;1544 1545 1599 } else { 1546 1600 /* Same clock rate. … … 1549 1603 pjmedia_copy_samples( cport->tx_buf + cport->tx_buf_count, 1550 1604 buf, conf->samples_per_frame ); 1551 cport->tx_buf_count += conf->samples_per_frame; 1552 } 1605 dst_count = conf->samples_per_frame; 1606 } 1607 1608 /* Adjust channels */ 1609 if (cport->channel_count != conf->channel_count) { 1610 pj_int16_t *tx_buf = cport->tx_buf + cport->tx_buf_count; 1611 if (conf->channel_count == 1) { 1612 pjmedia_convert_channel_1ton(tx_buf, tx_buf, 1613 cport->channel_count, 1614 dst_count, 0); 1615 dst_count *= cport->channel_count; 1616 } else { /* cport->channel_count == 1 */ 1617 pjmedia_convert_channel_nto1(tx_buf, tx_buf, 1618 conf->channel_count, 1619 dst_count, PJMEDIA_STEREO_MIX, 0); 1620 dst_count /= conf->channel_count; 1621 } 1622 } 1623 1624 cport->tx_buf_count += dst_count; 1625 1626 pj_assert(cport->tx_buf_count <= cport->tx_buf_cap); 1553 1627 1554 1628 /* Transmit while we have enough frame in the tx_buf. */ … … 1590 1664 cport->tx_buf_count -= cport->samples_per_frame; 1591 1665 if (cport->tx_buf_count) { 1592 pjmedia_ copy_samples(cport->tx_buf,1666 pjmedia_move_samples(cport->tx_buf, 1593 1667 cport->tx_buf + cport->samples_per_frame, 1594 1668 cport->tx_buf_count); … … 1716 1790 * and calculate the average level at the same time. 1717 1791 */ 1718 for (j=0; j<conf->samples_per_frame; ++j) {1719 if (conf_port->rx_adj_level != NORMAL_LEVEL) {1792 if (conf_port->rx_adj_level != NORMAL_LEVEL) { 1793 for (j=0; j<conf->samples_per_frame; ++j) { 1720 1794 /* For the level adjustment, we need to store the sample to 1721 1795 * a temporary 32bit integer value to avoid overflowing the … … 1737 1811 1738 1812 p_in[j] = (pj_int16_t) itemp; 1813 level += (p_in[j]>=0? p_in[j] : -p_in[j]); 1739 1814 } 1740 1741 level += (p_in[j]>0? p_in[j] : -p_in[j]); 1742 } 1815 } else { 1816 for (j=0; j<conf->samples_per_frame; ++j) { 1817 level += (p_in[j]>=0? p_in[j] : -p_in[j]); 1818 } 1819 } 1743 1820 1744 1821 level /= conf->samples_per_frame;
Note: See TracChangeset
for help on using the changeset viewer.