[pjsip] Accoustic echo cancelation

Bill Gardner billg at wavearts.com
Tue Apr 12 09:42:24 EDT 2016


Please attach a complete log. - Bill

On 4/11/2016 9:31 PM, Alexandre Gonçalves wrote:
> 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 <mailto:alexandre at silvagoncalves.com>
>
> 2016-04-11 20:14 GMT+01:00 Bill Gardner <billg at wavearts.com 
> <mailto: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
>>     <mailto:alexandre at silvagoncalves.com>
>>
>>     2016-04-11 16:09 GMT+01:00 Bill Gardner <billg at wavearts.com
>>     <mailto: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 <http://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
>>>         <mailto:alexandre at silvagoncalves.com>
>>>
>>>
>>>         _______________________________________________
>>>         Visit our blog:http://blog.pjsip.org
>>>
>>>         pjsip mailing list
>>>         pjsip at lists.pjsip.org <mailto: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 <mailto: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 <mailto: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 <mailto: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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.pjsip.org/pipermail/pjsip_lists.pjsip.org/attachments/20160412/9fdf92d5/attachment-0002.html>


More information about the pjsip mailing list