inband DTMF in python

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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?



[Index of Archives]     [Asterisk Users]     [Asterisk App Development]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [Linux API]
  Powered by Linux