Pickup Talk_Detect events inside a channel

I am working on a system that we have a need to detect a user speaking, execute some code and delay the audio by 3 seconds. We are currently trying to use talk_detect and the Jitterbuffer to accomplish this.

We have our dialplan triggering the talk_detect on the originating channel and is showing the ChannelTalkingStarted and ChannelTalkingFinished AMI events. We’ve been trying to pick these events up inside our channel so we can execute some code but are having issues picking it up. Is there a way to monitor for these AMI events on a channel and execute our code?

You can subscribe to the channel stasis topic using a stasis message router and then would receive callbacks when the given messages occur on the channel. There’s usage of the stasis message router in various places, with ast_channel_talking_start and ast_channel_talking_stop being the message types.

1 Like

Can this also be accomplished via an Asterisk Application?

What are you actually trying to achieve? If you were running an application, you wouldn’t be able to process the audio in other ways at the same time, on the same channel. Whilst one could run it on a spying channel, that is getting a bit too complicated to justify an the development of an application.

There is a special case application, used before you are doing anything with the audio, which attempts to detect speech as part of answering machine detection. If that is what you are trying to do, you should use that application, in its entirety.

I assume the talk detect events are really intended to be used by a system managing a conference, so it can control muting and indicate who is speaking.

HI,

Thank you for your response. We are new to the Asterisk program (All our old engineers left a long time ago).

The original code that was developed as part of our system was all developed inside a custom channel driver. This channel driver would handle all of the timing, buffering of voice frames, and key-up of the remote device on the hardware side of the channel driver.

With new new work that is ongoing, the custom channel driver has been removed. A new commercial channel driver for an Amtelco E&M board has replaced it. With this new configuration , we have two options, the first was to port all of the existing custom code to the new commercial channel driver and rebuild, or, better yet was to use the audio hooks and other functions in Asterisk to handle the processing that needs to be accomplished. An example of this was that our custom code had a whole section for VOX/VAD audio detection, but replacing this with the Talk_Detect offloaded a lot of porting and makes the solution a lot simpler to implement.

The process we are trying to build is as follows:

A SIP phone calls an E&M channel. Once the call is established, when the SIP user talks two things happen:

  1. The talk detect triggers (Talk_Detect)
  2. The voice starts buffering on the channel (Jitterbuffer)

When the Talk detect is triggered, “Something” (This is where I am lost between applications vs. Stasis, vs. other Asterisk type components) detects the ChannelTalkingStarted message and:

  1. tells the channel driver to Key up (This key up process takes 3 seconds, thus the voice buffer)
  2. Tells the Frame_Drop function to drop audio frames from the opposite direction, towards the SIP user.

Now the audio path is setup for the buffer as it starts releasing the audio frames back out to the bridge and on to the E&M channel.

One the voice stops, The reverse happens:
When the Talk detect is un-triggered (ChannelTalkingFinished)

  1. Wait 3 Second for buffer to finish output
  2. tells the channel driver to Key down
  3. Tells the Frame_Drop function to process all traffic again

That’s what we are trying to do, and having the proper path on how to work with the framework would go a log way to help, or, if the framework can not handle this, it tells us to put the code back in the new channel driver.

My gut feeling is that this needs to be done within a custom channel driver, as you are currently trying re-purpose too many features that weren’t intended to handle such cases.

I suspect you could create a wrapper channel driver, in which, say, read is just repeated onto the proprietary driver, but write goes through the delay line and talk detection processing, before calling the underlying write method.

Incidentally, 3 seconds seems rather a long time to key up a transmitter, even allowing for CTCSS, or the digital equivalent, at the receiver. I would have thought it would be fairly uncomfortable to use; it’s probably more than that for Apollo on the Moon, even allowing for the pip tones.

Hi David, I like the idea of a wrapper channel driver. Is there a mechanism in the dial plan in incorporate a wrapper, or would this all be done on the code side?

It would require code to be written.

Is there an existing Asterisk Function, audio hook, or program code that you could recommend as a framework to start developing a wrapper?I would think and Audiohook would be the correct approach, but the community would know best.

I was assuming you would call the driver as a subroutine of the wrapper. However that is really developer, not end user stuff and its not something I’ve tried, so I don’t know what details are waiting to trip you up.