[pjsip] Accoustic echo cancelation

Alexandre Gonçalves alexandre at silvagoncalves.com
Mon Apr 11 21:31:54 EDT 2016


I followed your suggestion, and indeed the EC is created:

00:14:30.374    ec0x16adf18  ...Creating AEC
00:14:30.382    ec0x16adf18  ...AEC created, clock_rate=16000, channel=1,
samples per frame=320, tail length=200 ms, latency=0 ms


However the logs about speex are still appearing:

01:23:25.435   tsx0x171eca4  .Incoming Response msg 401/REGISTER/cseq=762
(rdata0x16cb26c) in state Completed
01:23:25.454          speex !warning: Had to discard a playback frame (your
application is buggy and/or got xruns)
01:23:25.501          speex  warning: Auto-filling the buffer (your
application is buggy and/or got xruns)
01:23:25.517          speex  warning: Had to discard a playback frame (your
application is buggy and/or got xruns)
01:23:25.771          speex !warning: No playback frame available (your
application is buggy and/or got xruns)
01:23:25.774          speex !warning: internal playback buffer corruption?
01:23:25.774          speex !warning: Auto-filling the buffer (your
application is buggy and/or got xruns)
01:23:26.380          speex !warning: Auto-filling the buffer (your
application is buggy and/or got xruns)
01:23:26.444          speex  warning: Had to discard a playback frame (your
application is buggy and/or got xruns)
01:23:27.799          speex  warning: Auto-filling the buffer (your
application is buggy and/or got xruns)
01:23:27.851          speex  warning: Had to discard a playback frame (your
application is buggy and/or got xruns)
01:23:28.181   tsx0x16ce62c !Timeout timer event
01:23:28.185   tsx0x16ce62c  .State changed from Completed to Terminated,
event=TIMER
01:23:28.191   tsx0x16ce62c  Timeout timer event
01:23:28.193   tsx0x16ce62c  .State changed from Terminated to Destroyed,
event=TIMER
01:23:28.194   tsx0x16ce62c  Transaction destroyed!
01:23:28.206          speex !warning: Auto-filling the buffer (your
application is buggy and/or got xruns)
01:23:28.287          speex  warning: Had to discard a playback frame (your
application is buggy and/or got xruns)
01:23:28.583          speex  warning: Had to discard a playback frame (your
application is buggy and/or got xruns)
01:23:28.616          speex  warning: Auto-filling the buffer (your
application is buggy and/or got xruns)
01:23:28.807          speex  warning: Had to discard a playback frame (your
application is buggy and/or got xruns)
01:23:29.739          speex  warning: Auto-filling the buffer (your
application is buggy and/or got xruns)
01:23:29.827          speex  warning: Had to discard a playback frame (your
application is buggy and/or got xruns)
01:23:30.378   tsx0x171eca4 !Timeout timer event
01:23:30.380   tsx0x171eca4  .State changed from Completed to Terminated,
event=TIMER
01:23:30.385   tsx0x171eca4  Timeout timer event
01:23:30.386   tsx0x171eca4  .State changed from Terminated to Destroyed,
event=TIMER
01:23:30.388  tdta0x16d74a0  ..Destroying txdata Request msg
REGISTER/cseq=762 (tdta0x16d74a0)
01:23:30.398   tsx0x171eca4  Transaction destroyed!
01:23:31.944          speex !warning: Auto-filling the buffer (your
application is buggy and/or got xruns)
01:23:32.134          speex  warning: Had to discard a playback frame (your
application is buggy and/or got xruns)
01:23:32.280          speex  warning: Auto-filling the buffer (your
application is buggy and/or got xruns)
01:23:32.312          speex  warning: Had to discard a playback frame (your
application is buggy and/or got xruns)
01:23:32.517   silencedet.c  Starting silence (level=9 threshold=22)


There is still echo, in other words on the remote party I hear my own voice.

Regards.


*Alexandre Gonçalves*

............................................................................................................................
Email: alexandre at silvagoncalves.com

2016-04-11 20:14 GMT+01:00 Bill Gardner <billg at wavearts.com>:

> Try removing your code that creates the EC, then run again and see if the
> log shows that an EC was created. - Bill
>
>
> On 4/11/2016 11:16 AM, Alexandre Gonçalves wrote:
>
> Yes it does. The device is handsfree.
>
> Thanks.
>
> *Alexandre Gonçalves*
>
>
> ............................................................................................................................
> Email:  <alexandre at silvagoncalves.com>alexandre at silvagoncalves.com
>
> 2016-04-11 16:09 GMT+01:00 Bill Gardner <billg at wavearts.com>:
>
>> Hi Alexandre,
>>
>> I don't know what the problem is, but you shouldn't need to create a
>> separate EC object. pjsua_init will create an echo canceller and connect it
>> to the sound port.
>>
>> Does the call work without EC?
>>
>> Regards,
>>
>> Bill
>>
>> On 4/11/2016 10:33 AM, Alexandre Gonçalves wrote:
>>
>> Hello,
>>
>> I've made a small C application to run on a linux machine, based on
>> "Simple PJSUA" example.
>>
>> What I need to add is echo cancellation, and I tryed to do it like the
>> code attached:
>>
>> But according to the logs I get it seems that something is missing. I
>> suspect it's the manipulation of the capture and playback frames, but I
>> have no idea how to do it!
>>
>>
>> #include <pjsua-lib/pjsua.h>
>> #define THIS_FILE "APP"
>>
>> #define SIP_DOMAIN "raspbx"
>> #define SIP_USER "511"
>> #define SIP_PASSWD "aaa511"
>> #define SIP_REALM "asterisk"
>> #define SIP_SCHEME "digest"
>>
>>
>>
>> pjmedia_echo_state *ec;
>> pjmedia_frame play_frame, rec_frame;
>>
>> /* Callback called by the library upon receiving incoming call */
>> static void on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,
>>         pjsip_rx_data *rdata) {
>>     pjsua_call_info ci;
>>
>>     PJ_UNUSED_ARG(acc_id);
>>     PJ_UNUSED_ARG(rdata);
>>
>>     pjsua_call_get_info(call_id, &ci);
>>
>>     PJ_LOG(2, (THIS_FILE, "Incoming call from %.*s!!",
>>             (int) ci.remote_info.slen,
>>             ci.remote_info.ptr));
>>
>>     /* Automatically answer incoming calls with 200/OK */
>>     pjsua_call_answer(call_id, 200, NULL, NULL);
>> }
>>
>> /* Callback called by the library when call's state has changed */
>> static void on_call_state(pjsua_call_id call_id, pjsip_event *e) {
>>     pjsua_call_info ci;
>>
>>     PJ_UNUSED_ARG(e);
>>
>>     pjsua_call_get_info(call_id, &ci);
>>     PJ_LOG(2, (THIS_FILE, "Call %d state=%.*s", call_id,
>>             (int) ci.state_text.slen,
>>             ci.state_text.ptr));
>>
>> }
>>
>> /* Callback called by the library when call's media state has changed */
>> static void on_call_media_state(pjsua_call_id call_id) {
>>     pjsua_call_info ci;
>>
>>     pjsua_call_get_info(call_id, &ci);
>>
>>     if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) {
>>         // When media is active, connect call to sound device.
>>         pjsua_conf_connect(ci.conf_slot, 0);
>>         pjsua_conf_connect(0, ci.conf_slot);
>>     }
>> }
>>
>> /* Display error and exit application */
>> static void error_exit(const char *title, pj_status_t status) {
>>     pjsua_perror(THIS_FILE, title, status);
>>     pjsua_destroy();
>>     exit(1);
>> }
>>
>> /*
>>  * main()
>>  *
>>  * argv[1] may contain URL to call.
>>  */
>> int main(int argc, char *argv[]) {
>>     pjsua_acc_id acc_id;
>>     pj_status_t status;
>>
>>
>>
>>     /* Create pjsua first! */
>>     status = pjsua_create();
>>     if (status != PJ_SUCCESS) error_exit("Error in pjsua_create()",
>> status);
>>
>>
>>     /* Init pjsua */
>>     {
>>         pjsua_config cfg;
>>         pjsua_logging_config log_cfg;
>>         pjsua_media_config media_cfg;
>>
>>         pjsua_config_default(&cfg);
>>         cfg.cb.on_incoming_call = &on_incoming_call;
>>         cfg.cb.on_call_media_state = &on_call_media_state;
>>         cfg.cb.on_call_state = &on_call_state;
>>         cfg.max_calls = 1;
>>
>>         pjsua_logging_config_default(&log_cfg);
>>         log_cfg.console_level = 6;
>>
>>         pjsua_media_config_default(&media_cfg);
>>         media_cfg.ec_options = PJMEDIA_ECHO_DEFAULT;
>>         media_cfg.ec_tail_len = 250;
>>
>>
>>         status = pjsua_init(&cfg, &log_cfg, &media_cfg);
>>         // status = pjsua_init(&cfg, &log_cfg, NULL);
>>
>>         if (status != PJ_SUCCESS) error_exit("Error in pjsua_init()",
>> status);
>>
>>         pj_pool_t *pool = pjsua_pool_create("my_echo", 1000, 1000);
>>         status = pjmedia_echo_create(pool, 16000, 320, 500, 500,
>> PJMEDIA_ECHO_DEFAULT, &ec);
>>         play_frame.buf = pj_pool_alloc(pool, 320);
>>         rec_frame.buf = pj_pool_alloc(pool, 320);
>>
>>     }
>>
>>     /* Add UDP transport. */
>>     {
>>         pjsua_transport_config cfg;
>>
>>         pjsua_transport_config_default(&cfg);
>>         cfg.port = 5060;
>>         status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL);
>>         if (status != PJ_SUCCESS) error_exit("Error creating transport",
>> status);
>>     }
>>
>>     /* Initialization is done, now start pjsua */
>>     status = pjsua_start();
>>     if (status != PJ_SUCCESS) error_exit("Error starting pjsua", status);
>>
>>     /* Register to SIP server by creating SIP account. */
>>     {
>>         pjsua_acc_config cfg;
>>
>>         pjsua_acc_config_default(&cfg);
>>         cfg.id = pj_str("sip:" SIP_USER "@" SIP_DOMAIN);
>>         cfg.reg_uri = pj_str("sip:" SIP_DOMAIN);
>>         cfg.cred_count = 1;
>>         cfg.cred_info[0].realm = pj_str(SIP_REALM);
>>         cfg.cred_info[0].scheme = pj_str(SIP_SCHEME);
>>         cfg.cred_info[0].username = pj_str(SIP_USER);
>>         cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
>>         cfg.cred_info[0].data = pj_str(SIP_PASSWD);
>>
>>         status = pjsua_acc_add(&cfg, PJ_TRUE, &acc_id);
>>         if (status != PJ_SUCCESS) error_exit("Error adding account",
>> status);
>>     }
>>
>>     if (argc > 1) {
>>         pj_str_t uri = pj_str(argv[1]);
>>         status = pjsua_call_make_call(acc_id, &uri, 0, NULL, NULL, NULL);
>>         if (status != PJ_SUCCESS) error_exit("Error making call", status);
>>     }
>>
>>
>>     char option[10];
>>     while (1) {
>>
>>         if (fgets(option, sizeof (option), stdin) == NULL) {
>>             puts("EOF while reading stdin, will quit now..");
>>             break;
>>         }
>>
>>         if (option[0] == 'q')
>>             break;
>>
>>     }
>>
>>     /* Destroy pjsua */
>>     pjsua_destroy();
>>
>>     return 0;
>> }
>>
>>
>> The logs:
>>
>> 16:10:45.203          speex !warning: No playback frame available (your
>> application is buggy and/or got xruns)
>> 16:10:45.207          speex !warning: Auto-filling the buffer (your
>> application is buggy and/or got xruns)
>> 16:10:45.216          speex !warning: internal playback buffer corruption?
>> 16:10:45.221          speex !warning: Auto-filling the buffer (your
>> application is buggy and/or got xruns)
>> 16:10:45.279          speex  warning: Had to discard a playback frame
>> (your application is buggy and/or got xruns)
>> 16:10:45.393          speex  warning: Auto-filling the buffer (your
>> application is buggy and/or got xruns)
>> 16:10:45.462          speex  warning: Had to discard a playback frame
>> (your application is buggy and/or got xruns)
>> 16:10:45.522          speex  warning: Auto-filling the buffer (your
>> application is buggy and/or got xruns)
>> 16:10:45.562          speex  warning: Had to discard a playback frame
>> (your application is buggy and/or got xruns)
>>
>>
>> Pjsip version: 2.4
>>
>>
>> Can anyone help out?
>>
>>
>> Thanks.
>>
>>
>>
>>
>> *Alexandre Gonçalves*
>>
>>
>> ............................................................................................................................
>> Email:  <alexandre at silvagoncalves.com>alexandre at silvagoncalves.com
>>
>>
>> _______________________________________________
>> Visit our blog: http://blog.pjsip.org
>>
>> pjsip mailing listpjsip at lists.pjsip.orghttp://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
>>
>>
>
>
> _______________________________________________
> Visit our blog: http://blog.pjsip.org
>
> pjsip mailing listpjsip at lists.pjsip.orghttp://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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20160412/3b6a6557/attachment-0002.html>


More information about the pjsip mailing list