Hi, Well, basically the code supposed to work as long as sipChannel variables are managed correctly (e.g: sipChannel->getPlayConf() in creating conf seems risky) and no shared variable used for each call (e.g: sipChannel->*() should return different pointer for each call). I think it is impossible to pin point the exact problem location only with such code snippet (and I wouldn't prefer to see more code snippet either). Just an opinion, I don't see any advantage of creating conf bridge for each call, since it's just wasting resources (and perhaps increasing code complexity). So I would suggest you an alternative design: - For all calls: a shared conference bridge driven by master port/null audio. - For each call: just create a separate memplayer port, add conf port for memplayer port & portChannel port to the shared conference bridge, and connect them. FYI, pjsua-lib also uses a single conference bridge to handle multiple calls simultaneously. (Btw, why not just using pjsua-lib for your app, it should be simpler). Moreover, I don't think you need to create separate thread for each call to prepare the media ports, just a normal function seems to be enough. Regards, nanang On 02/09/2008, vopjessie <jessievop at hotmail.com> wrote: > Hi Nanang, thanks a lot for your message. Let me include more code in this > message. The code i put here is called only once for each inbound. For > example, when the first inbound comes in, the code is called once in thread > A; when the second inbound comes in, the code is called once again in thread > B. Am i doing something wrong here? > > > thanks a lot! > > -Jessica > > if(pjmedia_conf_create(sipChannel->getPlayPool(), > SIP_CONNECTION_PORT_COUNT, //unsigned max_slots, > PCMU_CLOCK_RATE, //unsigned sampling_rate, > PCMU_CHANNEL_COUNT, //unsigned channel_count, > PCMU_SAMPES_PER_FRAME, //unsigned samples_per_frame, > PCMU_BITS_PER_SAMPE, //unsigned bits_per_sample, > PJMEDIA_CONF_NO_DEVICE, //unsigned options, > sipChannel->getPlayConf()//pjmedia_conf ** p_conf > ) == PJ_SUCCESS) && > // create port for audio buffer > > (pjmedia_mem_player_create(sipChannel->getPlayPool(),// > pj_pool_t * pool, > sipChannel->getPlayFrame()->buf,//const void * > buffer, > sipChannel->getPlayFrame()->size,//pj_size_t > size, > PCMU_CLOCK_RATE,//unsigned clock_rate, > PCMU_CHANNEL_COUNT,//unsigned channel_count, > PCMU_SAMPES_PER_FRAME,//unsigned > samples_per_frame, > PCMU_BITS_PER_SAMPE,//unsigned bits_per_sample, > NULL,//unsigned options, > &portBuffer//pjmedia_port ** p_port > ) == PJ_SUCCESS) && > // add port of the channel and the port of the audio buffer to the > conference bridge > (pjmedia_conf_add_port(*(sipChannel->getPlayConf()), > //pjmedia_conf *conf, > sipChannel->getPlayPool(), //pj_pool_t *pool, > portChannel, //pjmedia_port *strm_port, > NULL,//const pj_str_t *name, > &slotChannel//unsigned *p_slot) > ) == PJ_SUCCESS) && > (pjmedia_conf_add_port(*(sipChannel->getPlayConf()), > //pjmedia_conf *conf, > sipChannel->getPlayPool(), //pj_pool_t *pool, > portBuffer, //pjmedia_port *strm_port, > NULL,//const pj_str_t *name, > &slotBuffer//unsigned *p_slot) > ) == PJ_SUCCESS) && > // connect audio and channel ports > > (pjmedia_conf_connect_port(*(sipChannel->getPlayConf()), > slotBuffer, > slotChannel, > 0) == PJ_SUCCESS) && > > (pjmedia_conf_adjust_tx_level(*(sipChannel->getPlayConf()), > slotChannel, SIP_ADJUST_LEVEL) == PJ_SUCCESS) && > > (pjmedia_conf_adjust_rx_level(*(sipChannel->getPlayConf()), > slotBuffer, SIP_ADJUST_LEVEL) == PJ_SUCCESS) && > // register call back > (pjmedia_mem_player_set_eof_cb(portBuffer, > sipChannel, &fillPlayBuffer) == PJ_SUCCESS)) > { > if(sipChannel->getDeviceManager() != NULL) > { > pj_status_t status = -1; > // create master port > > if((sipChannel->getSipStatus().compare("CONFIRMED") > == 0) && > > (status=pjmedia_master_port_create(sipChannel->getPlayPool(), > portNull, > > pjmedia_conf_get_master_port(*(sipChannel->getPlayConf())), > 0, > sipChannel->getPlayMasterPort() > )) == PJ_SUCCESS) > // start the master port > status = > pjmedia_master_port_start(*(sipChannel->getPlayMasterPort())); > } > > Date: Tue, 2 Sep 2008 18:27:52 +0700 > > From: nanang@xxxxxxxxx > > To: pjsip at lists.pjsip.org > > Subject: Re: handle mutiple media flows simultaneously > > > > > Hi, > > > > Is there single memplayer instance for each call or shared by all > > calls? Just in case you are using single memplayer instance for all > > calls, but creating many conf ports for it. > > > > Btw, in which callback is above code called? why does it always create > > master port? > > > > Regards, > > nanang > > > > > > On 02/09/2008, vopjessie <jessievop at hotmail.com> wrote: > > > Hi All, my program is designed to be able to receive two calls > > > simultaneously (in different threads). When an inbound comes in, my > program > > > plays audio data stored in memory to the caller. It works well when > there is > > > only one inbound. However, when two inbounds come in simultaneously, the > > > sound quality heard by both callers is so poor that can be considered as > > > noises. When one of the inbound calls has hung up, the sound quality on > the > > > other connected inbound call becomes good again. Could someone tell me > what > > > I am doing wrong? > > > > > > > > > Thanks a lot! > > > > > > Jessica > > > > > > My code is included as follows: > > > > > > // add port of the channel and the port of the audio buffer to the > > > conference bridge > > > > > > if((pjmedia_conf_add_port(*(sipChannel->getPlayConf()), > > > //pjmedia_conf *conf, > > > sipChannel->getPlayPool(), //pj_pool_t *pool, > > > portChannel, //pjmedia_port *strm_port, > > > NULL,//const pj_str_t *name, > > > &slotChannel//unsigned *p_slot) > > > ) == PJ_SUCCESS) && > > > (pjmedia_conf_add_port(*(sipChannel->getPlayConf()), > > > //pjmedia_conf *conf, > > > sipChannel->getPlayPool(), //pj_pool_t *pool, > > > portBuffer, //pjmedia_port *strm_port, > > > NULL,//const pj_str_t *name, > > > &slotBuffer//unsigned *p_slot) > > > ) == PJ_SUCCESS) && > > > // connect audio and channel ports > > > > > > > (pjmedia_conf_connect_port(*(sipChannel->getPlayConf()), > > > slotBuffer, > > > slotChannel, > > > 0) == PJ_SUCCESS) && > > > > > > > (pjmedia_conf_adjust_tx_level(*(sipChannel->getPlayConf()), > > > slotChannel, SIP_ADJUST_LEVEL) == PJ_SUCCESS) && > > > > > > > (pjmedia_conf_adjust_rx_level(*(sipChannel->getPlayConf()), > > > slotBuffer, SIP_ADJUST_LEVEL) == PJ_SUCCESS) && > > > // register call back > > > (pjmedia_mem_player_set_eof_cb(portBuffer, > > > sipChannel, &fillPlayBuffer) == PJ_SUCCESS)) > > > { > > > pj_status_t status = -1; > > > // create master port > > > > > > if((sipChannel->getSipStatus().compare("CONFIRMED") > > > == 0) && > > > > > > > (status=pjmedia_master_port_create(sipChannel->getPlayPool(), > > > portNull, > > > > > > > pjmedia_conf_get_master_port(*(sipChannel->getPlayConf())), > > > 0, > > > sipChannel->getPlayMasterPort() > > > )) == PJ_SUCCESS) > > > // start the master port > > > status = > > > > pjmedia_master_port_start(*(sipChannel->getPlayMasterPort())); > > > } > > > > > > > > > ________________________________ > > > "?????????" ????? > > > _______________________________________________ > > > Visit our blog: http://blog.pjsip.org > > > > > > pjsip mailing list > > > pjsip at lists.pjsip.org > > > > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > > > > > > > > _______________________________________________ > > Visit our blog: http://blog.pjsip.org > > > > pjsip mailing list > > pjsip at lists.pjsip.org > > > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > > > ________________________________ > ???Hotmail???????? Windows Live Mail? ????? > _______________________________________________ > Visit our blog: http://blog.pjsip.org > > pjsip mailing list > pjsip at lists.pjsip.org > http://lists.pjsip.org/mailman/listinfo/pjsip_lists.pjsip.org > >