There was a bug in tone generator which failed to generate more digits after the first digit is played. This has been fixed in http://trac.pjsip.org/repos/ticket/444 Thanks for the patch, I'll just save it in my todo list for now (until someone asks about it again ;-). cheers, -benny On 2/11/08, Zeroflag <zeroflag at freemail.hu> wrote: > Hi, > > I want to use inband dtmf in py_pjysua. I've read about inband dtmf usage > in the FAQ, and i've extended the py_pjsua.c with a few new function. > > Here are my modification, based on PJSIP FAQ: > > // -- TONE GEN MODIFICATION FOR INBAND DTMF SUPPORT -- > > struct my_call_data > { > pj_pool_t *pool; > pjmedia_port *tonegen; > pjsua_conf_port_id toneslot; > }; > > struct my_call_data *call_init_tonegen(pjsua_call_id call_id) { > > pj_pool_t *pool; > struct my_call_data *cd; > pjsua_call_info ci; > > PJ_LOG(1, (__FILE__, "[D] Initialize tonegen for call_id: %d", call_id > ) ); > > /* > pj_pool_t* pjsua_pool_create ( const char * name, > pj_size_t init_size, > pj_size_t increment > ) > Create memory pool to be used by the application. Once application > finished using the pool, it must be released with pj_pool_release(). > > Parameters: > name Optional pool name. > init_size Initial size of the pool. > increment Increment size. > > Returns: > The pool, or NULL when there's no memory. > Python: > Python script may also create a pool object from the script: > pool = py_pjsua.pool_create(name, init_size, increment) > */ > pool = pjsua_pool_create("mycall", 512, 512); > cd = PJ_POOL_ZALLOC_T(pool, struct my_call_data); > cd->pool = pool; > > pjmedia_tonegen_create(cd->pool, 8000, 1, 160, 16, 0, &cd->tonegen); > pjsua_conf_add_port(cd->pool, cd->tonegen, &cd->toneslot); > > pjsua_call_get_info(call_id, &ci); > pjsua_conf_connect(cd->toneslot, ci.conf_slot); > > pjsua_call_set_user_data(call_id, (void*) cd); > > PJ_LOG(1, (__FILE__, "[D] Tone init done" ) ); > > return cd; > } > > void pjsua_call_inband_dtmf(pjsua_call_id call_id, const pj_str_t *digits) > { > pjmedia_tone_digit d[16]; > unsigned i, count = digits->slen; > struct my_call_data *cd; > > PJ_LOG(1, (__FILE__, "[D] Inband DTMF to call_id: %d; DIGITS: %s", > call_id, digits->ptr ) ); > > cd = (struct my_call_data*) pjsua_call_get_user_data(call_id); > > if (!cd) { > PJ_LOG(1, (__FILE__, "No tonegen found" ) ); > cd = call_init_tonegen(call_id); > } > > if (count > PJ_ARRAY_SIZE(d)) > count = PJ_ARRAY_SIZE(d); > > pj_bzero(d, sizeof(d)); > for (i=0; i<count; ++i) { > d[i].digit = digits->ptr[i]; > PJ_LOG(1, (__FILE__, "[D] DIGIT: %c", d[i].digit) ); > d[i].on_msec = 100; > d[i].off_msec = 200; > d[i].volume = 0; > } > > PJ_LOG(1, (__FILE__, "[D] Sending tone; len=%d", count) ); > pjmedia_tonegen_play_digits(cd->tonegen, count, d, 0); > } > > void call_deinit_tonegen(pjsua_call_id call_id) > { > struct my_call_data *cd; > > PJ_LOG(1, (__FILE__, "[D] Deiniting tonegen.. id: %d", call_id) ); > > cd = (struct my_call_data*) pjsua_call_get_user_data(call_id); > if (!cd) > { > PJ_LOG(1, (__FILE__, "[D] No tonegen found for id: %d", call_id) ); > return; > } > > pjsua_conf_remove_port(cd->toneslot); > pjmedia_port_destroy(cd->tonegen); > pj_pool_release(cd->pool); > > pjsua_call_set_user_data(call_id, NULL); > > PJ_LOG(1, (__FILE__, "[D] Tonegen deinited") ); > } > > /* > * py_pjsua_call_inband_dtmf > */ > static PyObject *py_pjsua_call_inband_dtmf( PyObject *pSelf, PyObject > *pArgs ) > { > > int call_id; > PyObject * sd; > pj_str_t digits; > > PJ_UNUSED_ARG(pSelf); > > if (!PyArg_ParseTuple(pArgs, "iO", &call_id, &sd)) { > return NULL; > } > digits.ptr = PyString_AsString(sd); > digits.slen = strlen(PyString_AsString(sd)); > > pjsua_call_inband_dtmf(call_id, &digits); > > return Py_BuildValue("i", 1); > } > > /* > * py_pjsua_deinit_tonegen > */ > static PyObject *py_pjsua_deinit_tonegen( PyObject *pSelf, PyObject *pArgs > ) > { > int call_id; > > PJ_UNUSED_ARG(pSelf); > > if (!PyArg_ParseTuple(pArgs, "i", &call_id)) { > return NULL; > } > > call_deinit_tonegen(call_id); > > return Py_BuildValue("i", 1); > } > > // -- TONE GEN MODIFICATION FOR INBAND DTMF SUPPORT -- > > > .. and I extended the py_pjsua_methods too. > > { > "call_inband_dtmf", py_pjsua_call_inband_dtmf, METH_VARARGS, > pjsua_call_inband_dtmf_doc > }, > { > "call_deinit_tonegen", py_pjsua_deinit_tonegen, METH_VARARGS, > pjsua_call_deinit_tonegen_doc > }, > > > It works fine, I can send inband dtmf using with python, but it works only > once. Afther the first 'py_pjsua_call_inband_dtmf' call, I have to deinit > the tonegen and reinitialize, and i don't understand why. > > > Ony the first call works: > > s = raw_input('dtmf#:') > while s != 'q': > py_pjsua.call_inband_dtmf( call_id, s.strip() ) > s = raw_input('dtmf#:') > py_pjsua.call_deinit_tonegen( call_id ) > > > > This works fine: > > s = raw_input('dtmf#:') > while s != 'q': > py_pjsua.call_deinit_tonegen( call_id ) > py_pjsua.call_inband_dtmf( call_id, s.strip() ) > s = raw_input('dtmf#:') > > > Have you any idea why I have to reinitialize the tonegenerator before each > call? > > _______________________________________________ > 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 >