- Timestamp:
- May 15, 2018 8:23:44 AM (7 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/conference.h
r3664 r5792 72 72 unsigned listener_cnt; /**< Number of listeners. */ 73 73 unsigned *listener_slots; /**< Array of listeners. */ 74 unsigned *listener_adj_level; /**< Array of listeners' level 75 adjustment */ 74 76 unsigned transmitter_cnt; /**< Number of transmitter. */ 75 77 unsigned clock_rate; /**< Clock rate of the port. */ … … 296 298 297 299 /** 298 * Enable unidirectional audio from the specified source slot to the 299 * specified sink slot. 300 * Enable unidirectional audio from the specified source slot to the specified 301 * sink slot. 302 * Application may adjust the level to make signal transmitted from the source 303 * slot to the sink slot either louder or more quiet. The level adjustment is 304 * calculated with this formula: 305 * <b><tt>output = input * (adj_level+128) / 128</tt></b>. Using this, zero 306 * indicates no adjustment, the value -128 will mute the signal, and the value 307 * of +128 will make the signal 100% louder, +256 will make it 200% louder, 308 * etc. 309 * 310 * The level adjustment will apply to a specific connection only (i.e. only 311 * for the signal from the source to the sink), as compared to 312 * pjmedia_conf_adjust_tx_level()/pjmedia_conf_adjust_rx_level() which 313 * applies to all signals from/to that port. The signal adjustment 314 * will be cumulative, in this following order: 315 * signal from the source will be adjusted with the level specified 316 * in pjmedia_conf_adjust_rx_level(), then with the level specified 317 * via this API, and finally with the level specified to the sink's 318 * pjmedia_conf_adjust_tx_level(). 300 319 * 301 320 * @param conf The conference bridge. 302 321 * @param src_slot Source slot. 303 322 * @param sink_slot Sink slot. 304 * @param level This argument is reserved for future improvements 305 * where it is possible to adjust the level of signal 306 * transmitted in a specific connection. For now, 307 * this argument MUST be zero. 323 * @param adj_level Adjustment level, which must be greater than or equal 324 * to -128. A value of zero means there is no level 325 * adjustment to be made, the value -128 will mute the 326 * signal, and the value of +128 will make the signal 327 * 100% louder, +256 will make it 200% louder, etc. 328 * See the function description for the formula. 308 329 * 309 330 * @return PJ_SUCCES on success. … … 312 333 unsigned src_slot, 313 334 unsigned sink_slot, 314 int level );335 int adj_level ); 315 336 316 337 … … 497 518 498 519 520 /** 521 * Adjust the level of signal to be transmitted from the source slot to the 522 * sink slot. 523 * Application may adjust the level to make signal transmitted from the source 524 * slot to the sink slot either louder or more quiet. The level adjustment is 525 * calculated with this formula: 526 * <b><tt>output = input * (adj_level+128) / 128</tt></b>. Using this, zero 527 * indicates no adjustment, the value -128 will mute the signal, and the value 528 * of +128 will make the signal 100% louder, +256 will make it 200% louder, 529 * etc. 530 * 531 * The level adjustment value will stay with the connection until the 532 * connection is removed or new adjustment value is set. The current level 533 * adjustment value is reported in the media port info when the 534 * #pjmedia_conf_get_port_info() function is called. 535 * 536 * @param conf The conference bridge. 537 * @param src_slot Source slot. 538 * @param sink_slot Sink slot. 539 * @param adj_level Adjustment level, which must be greater than or equal 540 * to -128. A value of zero means there is no level 541 * adjustment to be made, the value -128 will mute the 542 * signal, and the value of +128 will make the signal 543 * 100% louder, +256 will make it 200% louder, etc. 544 * See the function description for the formula. 545 * 546 * @return PJ_SUCCESS on success. 547 */ 548 PJ_DECL(pj_status_t) pjmedia_conf_adjust_conn_level( pjmedia_conf *conf, 549 unsigned src_slot, 550 unsigned sink_slot, 551 int adj_level ); 552 553 499 554 500 555 PJ_END_DECL -
pjproject/trunk/pjmedia/src/pjmedia/conference.c
r5702 r5792 118 118 unsigned listener_cnt; /**< Number of listeners. */ 119 119 SLOT_TYPE *listener_slots;/**< Array of listeners. */ 120 unsigned *listener_adj_level; 121 /**< Array of listeners' level 122 adjustment. */ 120 123 unsigned transmitter_cnt;/**<Number of transmitters. */ 121 124 … … 134 137 unsigned tx_adj_level; /**< Adjustment for TX. */ 135 138 unsigned rx_adj_level; /**< Adjustment for RX. */ 139 pj_int16_t *adj_level_buf; /**< The adjustment buffer. */ 136 140 137 141 /* Resample, for converting clock rate, if they're different. */ … … 282 286 283 287 /* Create transmit flag array */ 284 conf_port->listener_slots = (SLOT_TYPE*) 285 pj_pool_zalloc(pool, 286 conf->max_ports * sizeof(SLOT_TYPE)); 288 conf_port->listener_slots = (SLOT_TYPE*) pj_pool_zalloc(pool, 289 conf->max_ports * sizeof(SLOT_TYPE)); 287 290 PJ_ASSERT_RETURN(conf_port->listener_slots, PJ_ENOMEM); 291 292 /* Create adjustment level array */ 293 conf_port->listener_adj_level = (unsigned *) pj_pool_zalloc(pool, 294 conf->max_ports * sizeof(unsigned)); 295 PJ_ASSERT_RETURN(conf_port->listener_adj_level, PJ_ENOMEM); 288 296 289 297 /* Save some port's infos, for convenience. */ … … 302 310 conf_port->channel_count = conf->channel_count; 303 311 } 312 313 /* Create adjustment level buffer. */ 314 conf_port->adj_level_buf = (pj_int16_t*) pj_pool_zalloc(pool, 315 conf->samples_per_frame * sizeof(pj_int16_t)); 304 316 305 317 /* If port's clock rate is different than conference's clock rate, … … 949 961 unsigned src_slot, 950 962 unsigned sink_slot, 951 int level )963 int adj_level ) 952 964 { 953 965 struct conf_port *src_port, *dst_port; … … 959 971 sink_slot<conf->max_ports, PJ_EINVAL); 960 972 961 /* For now, level MUST be zero. */ 962 PJ_ASSERT_RETURN(level == 0, PJ_EINVAL); 973 /* Value must be from -128 to +127 */ 974 /* Disabled, you can put more than +127, at your own risk: 975 PJ_ASSERT_RETURN(adj_level >= -128 && adj_level <= 127, PJ_EINVAL); 976 */ 977 PJ_ASSERT_RETURN(adj_level >= -128, PJ_EINVAL); 963 978 964 979 pj_mutex_lock(conf->mutex); … … 980 995 if (i == src_port->listener_cnt) { 981 996 src_port->listener_slots[src_port->listener_cnt] = sink_slot; 997 /* Set normalized adjustment level. */ 998 src_port->listener_adj_level[src_port->listener_cnt] = adj_level + 999 NORMAL_LEVEL; 982 1000 ++conf->connect_cnt; 983 1001 ++src_port->listener_cnt; … … 1387 1405 pj_mutex_unlock(conf->mutex); 1388 1406 1407 return PJ_SUCCESS; 1408 } 1409 1410 /* 1411 * Adjust level of individual connection. 1412 */ 1413 PJ_DEF(pj_status_t) pjmedia_conf_adjust_conn_level( pjmedia_conf *conf, 1414 unsigned src_slot, 1415 unsigned sink_slot, 1416 int adj_level ) 1417 { 1418 struct conf_port *src_port, *dst_port; 1419 unsigned i; 1420 1421 /* Check arguments */ 1422 PJ_ASSERT_RETURN(conf && src_slot<conf->max_ports && 1423 sink_slot<conf->max_ports, PJ_EINVAL); 1424 1425 /* Value must be from -128 to +127 */ 1426 /* Disabled, you can put more than +127, at your own risk: 1427 PJ_ASSERT_RETURN(adj_level >= -128 && adj_level <= 127, PJ_EINVAL); 1428 */ 1429 PJ_ASSERT_RETURN(adj_level >= -128, PJ_EINVAL); 1430 1431 pj_mutex_lock(conf->mutex); 1432 1433 /* Ports must be valid. */ 1434 src_port = conf->ports[src_slot]; 1435 dst_port = conf->ports[sink_slot]; 1436 if (!src_port || !dst_port) { 1437 pj_mutex_unlock(conf->mutex); 1438 return PJ_EINVAL; 1439 } 1440 1441 /* Check if connection has been made */ 1442 for (i=0; i<src_port->listener_cnt; ++i) { 1443 if (src_port->listener_slots[i] == sink_slot) 1444 break; 1445 } 1446 1447 if (i == src_port->listener_cnt) { 1448 /* connection hasn't been made */ 1449 pj_mutex_unlock(conf->mutex); 1450 return PJ_EINVAL; 1451 } 1452 /* Set normalized adjustment level. */ 1453 src_port->listener_adj_level[i] = adj_level + NORMAL_LEVEL; 1454 1455 pj_mutex_unlock(conf->mutex); 1389 1456 return PJ_SUCCESS; 1390 1457 } … … 1953 2020 { 1954 2021 struct conf_port *listener; 1955 pj_int32_t *mix_buf; 2022 pj_int32_t *mix_buf; 2023 pj_int16_t *p_in_conn_leveled; 1956 2024 1957 2025 listener = conf->ports[conf_port->listener_slots[cj]]; … … 1962 2030 1963 2031 mix_buf = listener->mix_buf; 2032 2033 /* apply connection level, if not normal */ 2034 if (conf_port->listener_adj_level[cj] != NORMAL_LEVEL) { 2035 unsigned k = 0; 2036 for (; k < conf->samples_per_frame; ++k) { 2037 /* For the level adjustment, we need to store the sample to 2038 * a temporary 32bit integer value to avoid overflowing the 2039 * 16bit sample storage. 2040 */ 2041 pj_int32_t itemp; 2042 2043 itemp = p_in[k]; 2044 /*itemp = itemp * adj / NORMAL_LEVEL;*/ 2045 /* bad code (signed/unsigned badness): 2046 * itemp = (itemp * conf_port->listsener_adj_level) >> 7; 2047 */ 2048 itemp *= conf_port->listener_adj_level[cj]; 2049 itemp >>= 7; 2050 2051 /* Clip the signal if it's too loud */ 2052 if (itemp > MAX_LEVEL) itemp = MAX_LEVEL; 2053 else if (itemp < MIN_LEVEL) itemp = MIN_LEVEL; 2054 2055 conf_port->adj_level_buf[k] = (pj_int16_t)itemp; 2056 } 2057 2058 /* take the leveled frame */ 2059 p_in_conn_leveled = conf_port->adj_level_buf; 2060 } else { 2061 /* take the frame as-is */ 2062 p_in_conn_leveled = p_in; 2063 } 1964 2064 1965 2065 if (listener->transmitter_cnt > 1) { … … 1973 2073 1974 2074 for (k = 0; k < samples_per_frame; ++k) { 1975 mix_buf[k] += p_in [k];2075 mix_buf[k] += p_in_conn_leveled[k]; 1976 2076 if (mix_buf[k] < mix_buf_min) 1977 2077 mix_buf_min = mix_buf[k]; … … 2000 2100 2001 2101 for (k = 0; k < samples_per_frame; ++k) { 2002 mix_buf[k] = p_in [k];2102 mix_buf[k] = p_in_conn_leveled[k]; 2003 2103 } 2004 2104 } -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r5788 r5792 6614 6614 6615 6615 /** 6616 * This structure specifies the parameters for conference ports connection. 6617 * Use pjsua_conf_connect_param_default() to initialize this structure with 6618 * default values. 6619 */ 6620 typedef struct pjsua_conf_connect_param 6621 { 6622 /* 6623 * Signal level adjustment from the source to the sink to make it 6624 * louder or quieter. Value 1.0 means no level adjustment, 6625 * while value 0 means to mute the port. 6626 * 6627 * Default: 1.0 6628 */ 6629 float level; 6630 6631 } pjsua_conf_connect_param; 6632 6633 6634 /** 6635 * Initialize pjsua_conf_connect_param with default values. 6636 * 6637 * @param prm The parameter. 6638 */ 6639 PJ_DECL(void) pjsua_conf_connect_param_default(pjsua_conf_connect_param *prm); 6640 6641 6642 /** 6616 6643 * Get maxinum number of conference ports. 6617 6644 * … … 6704 6731 PJ_DECL(pj_status_t) pjsua_conf_connect(pjsua_conf_port_id source, 6705 6732 pjsua_conf_port_id sink); 6733 6734 /** 6735 * Establish unidirectional media flow from source to sink. One source 6736 * may transmit to multiple destinations/sink. And if multiple 6737 * sources are transmitting to the same sink, the media will be mixed 6738 * together. Source and sink may refer to the same ID, effectively 6739 * looping the media. 6740 * 6741 * Signal level from the source to the sink can be adjusted by making 6742 * it louder or quieter via the parameter param. The level adjustment 6743 * will apply to a specific connection only (i.e. only for the signal 6744 * from the source to the sink), as compared to 6745 * pjsua_conf_adjust_tx_level()/pjsua_conf_adjust_rx_level() which 6746 * applies to all signals from/to that port. The signal adjustment 6747 * will be cumulative, in this following order: 6748 * signal from the source will be adjusted with the level specified 6749 * in pjsua_conf_adjust_rx_level(), then with the level specified 6750 * via this API, and finally with the level specified to the sink's 6751 * pjsua_conf_adjust_tx_level(). 6752 * 6753 * If bidirectional media flow is desired, application needs to call 6754 * this function twice, with the second one having the arguments 6755 * reversed. 6756 * 6757 * @param source Port ID of the source media/transmitter. 6758 * @param sink Port ID of the destination media/received. 6759 * @param prm Conference port connection param. If set to 6760 * NULL, default values will be used. 6761 * 6762 * @return PJ_SUCCESS on success, or the appropriate error code. 6763 */ 6764 PJ_DECL(pj_status_t) pjsua_conf_connect2(pjsua_conf_port_id source, 6765 pjsua_conf_port_id sink, 6766 const pjsua_conf_connect_param *prm); 6706 6767 6707 6768 -
pjproject/trunk/pjsip/include/pjsua2/media.hpp
r5717 r5792 193 193 }; 194 194 195 struct AudioMediaTransmitParam 196 { 197 /** 198 * Signal level adjustment. Value 1.0 means no level adjustment, 199 * while value 0 means to mute the port. 200 * 201 * Default: 1.0 202 */ 203 float level; 204 205 public: 206 /** 207 * Default constructor 208 */ 209 AudioMediaTransmitParam(); 210 }; 211 195 212 /** 196 213 * Audio Media. … … 228 245 */ 229 246 void startTransmit(const AudioMedia &sink) const throw(Error); 247 248 /** 249 * Establish unidirectional media flow to sink. This media port 250 * will act as a source, and it may transmit to multiple destinations/sink. 251 * And if multiple sources are transmitting to the same sink, the media 252 * will be mixed together. Source and sink may refer to the same Media, 253 * effectively looping the media. 254 * 255 * Signal level from this source to the sink can be adjusted by making 256 * it louder or quieter via the parameter param. The level adjustment 257 * will apply to a specific connection only (i.e. only for signal 258 * from this source to the sink), as compared to 259 * adjustTxLevel()/adjustRxLevel() which applies to all signals from/to 260 * this media port. The signal adjustment 261 * will be cumulative, in this following order: 262 * signal from this source will be adjusted with the level specified 263 * in adjustTxLevel(), then with the level specified via this API, 264 * and finally with the level specified to the sink's adjustRxLevel(). 265 * 266 * If bidirectional media flow is desired, application needs to call 267 * this method twice, with the second one called from the opposite source 268 * media. 269 * 270 * @param sink The destination Media. 271 * @param param The parameter. 272 */ 273 void startTransmit2(const AudioMedia &sink, 274 const AudioMediaTransmitParam ¶m) const 275 throw(Error); 230 276 231 277 /** -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_aud.c
r5748 r5792 715 715 } 716 716 717 PJ_DEF(void) pjsua_conf_connect_param_default(pjsua_conf_connect_param *prm) 718 { 719 pj_bzero(prm, sizeof(*prm)); 720 prm->level = 1.0; 721 } 722 717 723 /* 718 724 * Get maxinum number of conference ports. … … 825 831 PJ_DEF(pj_status_t) pjsua_conf_connect( pjsua_conf_port_id source, 826 832 pjsua_conf_port_id sink) 833 { 834 pjsua_conf_connect_param prm; 835 836 pjsua_conf_connect_param_default(&prm); 837 return pjsua_conf_connect2(source, sink, &prm); 838 } 839 840 /* 841 * Establish unidirectional media flow from souce to sink, with signal 842 * level adjustment. 843 */ 844 PJ_DEF(pj_status_t) pjsua_conf_connect2( pjsua_conf_port_id source, 845 pjsua_conf_port_id sink, 846 const pjsua_conf_connect_param *prm) 827 847 { 828 848 pj_status_t status = PJ_SUCCESS; … … 958 978 959 979 if (status == PJ_SUCCESS) { 960 status = pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 0); 980 pjsua_conf_connect_param cc_param; 981 982 if (!prm) 983 pjsua_conf_connect_param_default(&cc_param); 984 else 985 pj_memcpy(&cc_param, prm, sizeof(cc_param)); 986 status = pjmedia_conf_connect_port(pjsua_var.mconf, source, sink, 987 (int)((cc_param.level-1) * 128)); 961 988 } 962 989 -
pjproject/trunk/pjsip/src/pjsua2/media.cpp
r5724 r5792 118 118 119 119 /////////////////////////////////////////////////////////////////////////////// 120 AudioMediaTransmitParam::AudioMediaTransmitParam() 121 : level(1.0) 122 { 123 } 124 120 125 AudioMedia::AudioMedia() 121 126 : Media(PJMEDIA_TYPE_AUDIO), id(PJSUA_INVALID_ID), mediaPool(NULL) … … 197 202 { 198 203 PJSUA2_CHECK_EXPR( pjsua_conf_connect(id, sink.id) ); 204 } 205 206 void AudioMedia::startTransmit2(const AudioMedia &sink, 207 const AudioMediaTransmitParam ¶m) const 208 throw(Error) 209 { 210 pjsua_conf_connect_param pj_param; 211 212 pjsua_conf_connect_param_default(&pj_param); 213 pj_param.level = param.level; 214 PJSUA2_CHECK_EXPR( pjsua_conf_connect2(id, sink.id, &pj_param) ); 199 215 } 200 216
Note: See TracChangeset
for help on using the changeset viewer.