Echo cancelling with webrtcdsp

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Echo cancelling with webrtcdsp

mwon
I'm trying to establish an audio call to a Raspberry Pi equipped with
speakers and mic. I'm using a webrtc connection using /webrtcbin/ that
allows me to connect my browser to Raspberry Pi. The problem is that when I
send audio to the Raspberry Pi, I get echo because the Raspi Pi mic records
the speaker audio and send it back.

I'm trying to use /webrtcdsp/ with /webrtcechoprobe/ to solve the issue, but
the problem is that the probe must be positioned when the remote sound
arrives (from the browser) so that /webrtcdsp/ filter it. For these reasons
I was testing  this example
<https://github.com/centricular/gstwebrtc-demos/blob/master/sendrecv/gst/webrtc-sendrecv.c>  
with the with the following pipeline:


/  pipe1 =
      gst_parse_launch ("webrtcbin bundle-policy=max-bundle name=sendrecv "
      STUN_SERVER
      "alsasrc device=hw:1,0 buffer-time=30000  ! audioconvert ! webrtcdsp !
audioresample ! queue ! opusenc ! rtpopuspay ! "
      "queue ! " RTP_CAPS_OPUS "96 ! sendrecv. ", &error);
/



and then add the probe just after the incoming decoding bin:



/handle_media_stream (GstPad * pad, GstElement * pipe, const char
*convert_name,
    const char *sink_name)
{
  GstPad *qpad;
  GstElement *q, *conv, *resample, *sink,*probe;
  GstPadLinkReturn ret;

  g_print ("Trying to handle stream with %s ! %s", convert_name, sink_name);

  q = gst_element_factory_make ("queue", NULL);
  g_assert_nonnull (q);
  conv = gst_element_factory_make (convert_name, NULL);
  g_assert_nonnull (conv);
  probe = gst_element_factory_make ("webrtcechoprobe", NULL);
  g_assert_nonnull (probe);
  sink = gst_element_factory_make (sink_name, NULL);
  g_assert_nonnull (sink);

  gst_bin_add_many (GST_BIN (pipe), q, conv,sink, NULL);
  gst_element_sync_state_with_parent (q);
  gst_element_sync_state_with_parent (conv);
  gst_element_sync_state_with_parent (probe);
  gst_element_sync_state_with_parent (sink);
  gst_element_link_many (q, conv,probe,sink, NULL);


  qpad = gst_element_get_static_pad (q, "sink");

  ret = gst_pad_link (pad, qpad);
  g_assert_cmphex (ret, ==, GST_PAD_LINK_OK);
}/


The problem is that the example is not able to run. The initial pipeline is
not executed at all because it is missing the corresponding probe (I think),
that will be ready only when the connection is established.

Any idea on how to solve the problem?






--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Echo cancelling with webrtcdsp

Nicolas Dufresne-5


Le dim. 31 mai 2020 07 h 00, mwon <[hidden email]> a écrit :
I'm trying to establish an audio call to a Raspberry Pi equipped with
speakers and mic. I'm using a webrtc connection using /webrtcbin/ that
allows me to connect my browser to Raspberry Pi. The problem is that when I
send audio to the Raspberry Pi, I get echo because the Raspi Pi mic records
the speaker audio and send it back.

I'm trying to use /webrtcdsp/ with /webrtcechoprobe/ to solve the issue, but
the problem is that the probe must be positioned when the remote sound
arrives (from the browser) so that /webrtcdsp/ filter it. For these reasons
I was testing  this example
<https://github.com/centricular/gstwebrtc-demos/blob/master/sendrecv/gst/webrtc-sendrecv.c
with the with the following pipeline:


/  pipe1 =
      gst_parse_launch ("webrtcbin bundle-policy=max-bundle name=sendrecv "
      STUN_SERVER
      "alsasrc device=hw:1,0 buffer-time=30000  ! audioconvert ! webrtcdsp !
audioresample ! queue ! opusenc ! rtpopuspay ! "
      "queue ! " RTP_CAPS_OPUS "96 ! sendrecv. ", &error);
/



and then add the probe just after the incoming decoding bin:



/handle_media_stream (GstPad * pad, GstElement * pipe, const char
*convert_name,
    const char *sink_name)
{
  GstPad *qpad;
  GstElement *q, *conv, *resample, *sink,*probe;
  GstPadLinkReturn ret;

  g_print ("Trying to handle stream with %s ! %s", convert_name, sink_name);

  q = gst_element_factory_make ("queue", NULL);
  g_assert_nonnull (q);
  conv = gst_element_factory_make (convert_name, NULL);
  g_assert_nonnull (conv);
  probe = gst_element_factory_make ("webrtcechoprobe", NULL);
  g_assert_nonnull (probe);
  sink = gst_element_factory_make (sink_name, NULL);
  g_assert_nonnull (sink);

  gst_bin_add_many (GST_BIN (pipe), q, conv,sink, NULL);
  gst_element_sync_state_with_parent (q);
  gst_element_sync_state_with_parent (conv);
  gst_element_sync_state_with_parent (probe);
  gst_element_sync_state_with_parent (sink);
  gst_element_link_many (q, conv,probe,sink, NULL);


  qpad = gst_element_get_static_pad (q, "sink");

  ret = gst_pad_link (pad, qpad);
  g_assert_cmphex (ret, ==, GST_PAD_LINK_OK);
}/


The problem is that the example is not able to run. The initial pipeline is
not executed at all because it is missing the corresponding probe (I think),
that will be ready only when the connection is established.

Any idea on how to solve the problem?

You can create the pair from the start, and then add/link the probe later.

Regards,
Nicolas




--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Echo cancelling with webrtcdsp

mwon
Hi and thanks for the reply.

Not sure how can I do it. When you say "pair" you mean "/webrtcdsp !
webrtcechoprobe/", right? How to can I add a probe connected to /webrtcdsp/
if the pipeline only runs it at the start is connected to webrtcechoprobe?
If I define the parent of the second /webrtcechoprobe/ in a later stage,
will it connect to the initial /webrtcdsp/?





--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Echo cancelling with webrtcdsp

Nicolas Dufresne-5
Le dimanche 31 mai 2020 à 19:53 -0500, mwon a écrit :
Hi and thanks for the reply. 

Not sure how can I do it. When you say "pair" you mean "/webrtcdsp !
webrtcechoprobe/", right? How to can I add a probe connected to /webrtcdsp/
if the pipeline only runs it at the start is connected to webrtcechoprobe?
If I define the parent of the second /webrtcechoprobe/ in a later stage,
will it connect to the initial /webrtcdsp/?

GstElement *dsp, *probe;

dsp = gst_element_factory_make ("webrtcdsp", NULL);
probe = gst_element_factory_make ("webrtcechoprobe", NULL);

/* Here plug the webrtcdsp ! it will be happy has there exist a probe, even if not connected to anything */


. . .

/* On some callback, plug the probe you have already created, make sure to reuse it if you need to */


Nicolas





--
Sent from: 
http://gstreamer-devel.966125.n4.nabble.com/

_______________________________________________
gstreamer-devel mailing list
[hidden email]

https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel


_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Echo cancelling with webrtcdsp

mwon
Sorry, only today I was able to return to this problem.

So, the thing is that the webrtcdsp must be placed in the initial pipeline
("pipe1") because it is the mic from the alsasrc that must "turned of",
i.e., the sound that it captures must be filtered out. These are the full
steps:


Remote audio input -> decodebin -> speakers -> mic (alsasrc) -> encode ->
remote audio output

with decodebin stop only established after the webrtc connection.



--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
Reply | Threaded
Open this post in threaded view
|

Re: Echo cancelling with webrtcdsp

Nicolas Dufresne-5
Le jeudi 04 juin 2020 à 19:15 -0500, mwon a écrit :

> Sorry, only today I was able to return to this problem.
>
> So, the thing is that the webrtcdsp must be placed in the initial pipeline
> ("pipe1") because it is the mic from the alsasrc that must "turned of",
> i.e., the sound that it captures must be filtered out. These are the full
> steps:
>
>
> Remote audio input -> decodebin -> speakers -> mic (alsasrc) -> encode ->
> remote audio output
>
> with decodebin stop only established after the webrtc connection.

What I'm trying to explain is that the relation between webrtcdsp and
webrtcechoprobe is not linked with the pipeline hiearchy. As long as
the two objects exist they will find each other. They use a global
singleton hashtable for that. Of course that open up to having the
probe in seperate pipelines, which could be a nice feature, but is not
yet supported (inter-pipeline running-time translation would be
needed).

>
>
>
> --
> Sent from: http://gstreamer-devel.966125.n4.nabble.com/
> _______________________________________________
> gstreamer-devel mailing list
> [hidden email]
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel

_______________________________________________
gstreamer-devel mailing list
[hidden email]
https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel