Ignore:
Timestamp:
May 15, 2018 8:23:44 AM (6 years ago)
Author:
ming
Message:

Closed #2113: Implement conference signal level adjustment for a specific connection

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/conference.c

    r5702 r5792  
    118118    unsigned             listener_cnt;  /**< Number of listeners.           */ 
    119119    SLOT_TYPE           *listener_slots;/**< Array of listeners.            */ 
     120    unsigned            *listener_adj_level; 
     121                                        /**< Array of listeners' level 
     122                                             adjustment.                    */ 
    120123    unsigned             transmitter_cnt;/**<Number of transmitters.        */ 
    121124 
     
    134137    unsigned             tx_adj_level;  /**< Adjustment for TX.             */ 
    135138    unsigned             rx_adj_level;  /**< Adjustment for RX.             */ 
     139    pj_int16_t          *adj_level_buf; /**< The adjustment buffer.         */ 
    136140 
    137141    /* Resample, for converting clock rate, if they're different. */ 
     
    282286 
    283287    /* 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)); 
    287290    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); 
    288296 
    289297    /* Save some port's infos, for convenience. */ 
     
    302310        conf_port->channel_count = conf->channel_count; 
    303311    } 
     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)); 
    304316 
    305317    /* If port's clock rate is different than conference's clock rate, 
     
    949961                                               unsigned src_slot, 
    950962                                               unsigned sink_slot, 
    951                                                int level ) 
     963                                               int adj_level ) 
    952964{ 
    953965    struct conf_port *src_port, *dst_port; 
     
    959971                     sink_slot<conf->max_ports, PJ_EINVAL); 
    960972 
    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); 
    963978 
    964979    pj_mutex_lock(conf->mutex); 
     
    980995    if (i == src_port->listener_cnt) { 
    981996        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; 
    9821000        ++conf->connect_cnt; 
    9831001        ++src_port->listener_cnt; 
     
    13871405    pj_mutex_unlock(conf->mutex); 
    13881406 
     1407    return PJ_SUCCESS; 
     1408} 
     1409 
     1410/* 
     1411 * Adjust level of individual connection. 
     1412 */ 
     1413PJ_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); 
    13891456    return PJ_SUCCESS; 
    13901457} 
     
    19532020        { 
    19542021            struct conf_port *listener; 
    1955             pj_int32_t *mix_buf; 
     2022            pj_int32_t *mix_buf;             
     2023            pj_int16_t *p_in_conn_leveled; 
    19562024 
    19572025            listener = conf->ports[conf_port->listener_slots[cj]]; 
     
    19622030 
    19632031            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            } 
    19642064 
    19652065            if (listener->transmitter_cnt > 1) { 
     
    19732073 
    19742074                for (k = 0; k < samples_per_frame; ++k) { 
    1975                     mix_buf[k] += p_in[k]; 
     2075                    mix_buf[k] += p_in_conn_leveled[k]; 
    19762076                    if (mix_buf[k] < mix_buf_min) 
    19772077                        mix_buf_min = mix_buf[k]; 
     
    20002100 
    20012101                for (k = 0; k < samples_per_frame; ++k) { 
    2002                     mix_buf[k] = p_in[k]; 
     2102                    mix_buf[k] = p_in_conn_leveled[k]; 
    20032103                } 
    20042104            } 
Note: See TracChangeset for help on using the changeset viewer.