Re: preferred / optimal MRCP implementation

101 views
Skip to first unread message

Greg Camp

unread,
Nov 28, 2012, 5:34:16 PM11/28/12
to uni...@googlegroups.com
On Wednesday, November 28, 2012 9:11:20 AM UTC-6, Greg Camp wrote:
Hello,

We have successfully been using MRCP in a custom SIP IVR communicating with a Nuance Speech Server.  In our current configuration we create the unimrcp client at the start of the program and then create / destroy voice recognition sessions throughout the life of the program as voicerec is needed.  The client is destroyed when the application shuts down.

There are, however, some small issues we are trying to track down and correct (leaking memory / threads) which leads into my question: is that the preferred / optimal way of implementing UniMRCP?  Would it be better to create a new client / session pair each time we need to perform voice recognition (which would be virtually every call) and destroy both at the end of the session?

Thanks,
Greg


Also, when each new session is created I use mrcp_client_memory_pool_get to obtain a pointer to the pool, then I call apt_subpool_create and use the subpool for all memory operations during the session.  When the session is complete the subpool is freed with apr_pool_destroy.  I am not certain if that is the best way to manage the session memory or not (i.e. all memory reclaimed when the session ends).  The other option I considered was calling apt_pool_create for each new session.  Any additional thoughts on this aspect of the implementation?

Thanks,
Greg

Arsen Chaloyan

unread,
Nov 29, 2012, 10:31:58 PM11/29/12
to uni...@googlegroups.com
Hello Greg,

Glad to hear you're successfully using UniMRCP in your IVR. See my
comments below.

On Wed, Nov 28, 2012 at 2:34 PM, Greg Camp <gcam...@gmail.com> wrote:
> On Wednesday, November 28, 2012 9:11:20 AM UTC-6, Greg Camp wrote:
>>
>> Hello,
>>
>> We have successfully been using MRCP in a custom SIP IVR communicating
>> with a Nuance Speech Server. In our current configuration we create the
>> unimrcp client at the start of the program and then create / destroy voice
>> recognition sessions throughout the life of the program as voicerec is
>> needed. The client is destroyed when the application shuts down.

That is the correct usage. You should create an instance of
mrcp_client_t and an instance of mrcp_application_t when your
application is started. These are permanent objects which should
normally be destroyed when the application terminates. As opposed to
the client/application pair, you should create a new instance of
mrcp_session_t whenever you need to perform a new recognition. You may
also issue several recognition requests per one session object.
Though, the lifetime of the session should normally match the lifetime
of the call.

>>
>> There are, however, some small issues we are trying to track down and
>> correct (leaking memory / threads) which leads into my question: is that the
>> preferred / optimal way of implementing UniMRCP? Would it be better to
>> create a new client / session pair each time we need to perform voice
>> recognition (which would be virtually every call) and destroy both at the
>> end of the session?

I'd not recommend to create a new client for every new call. There is
no such a requirement.

>>
>> Thanks,
>> Greg
>>
>
> Also, when each new session is created I use mrcp_client_memory_pool_get to
> obtain a pointer to the pool, then I call apt_subpool_create and use the
> subpool for all memory operations during the session. When the session is
> complete the subpool is freed with apr_pool_destroy. I am not certain if
> that is the best way to manage the session memory or not (i.e. all memory
> reclaimed when the session ends). The other option I considered was calling
> apt_pool_create for each new session. Any additional thoughts on this
> aspect of the implementation?
>

You may create a new pool, or a new subpool, or use the same session
pool. All these options are legitimate. If your create a new pool,
then you'll have to destroy it with apr_pool_destroy. However, if you
use a subpool, then it's not required to explicitly destroy it. The
subpool will be destroyed with the parent (session) pool, anyway.
Having said, I don't see a criminal so far which may cause memory
leaks or any other malfunctioning.

It's interesting whether you use a shared MRCP connection or establish
a new one per each session.

<offer-new-connection>false</offer-new-connection>

In case of shared MRCP connections, memory management is a bit tricky.
Memory allocated in the scope of the connection object will be
released when no more sessions are associated with that connection.
Since you're using NSS, it shouldn't be the case. NSS always seems to
force the client to establish a new connection.



> Thanks,
> Greg
>
> --
> You received this message because you are subscribed to the Google Groups
> "UniMRCP" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/unimrcp/-/C02j0cZaWVkJ.
>
> To post to this group, send email to uni...@googlegroups.com.
> To unsubscribe from this group, send email to
> unimrcp+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/unimrcp?hl=en.



--
Arsen Chaloyan
Author of UniMRCP
http://www.unimrcp.org

Greg Camp

unread,
Nov 29, 2012, 11:51:32 PM11/29/12
to uni...@googlegroups.com
Hello Arsen,

Thanks for your reply.  My comments are below.


On Thursday, November 29, 2012 9:31:58 PM UTC-6, Arsen Chaloyan wrote:
Hello Greg,

Glad to hear you're successfully using UniMRCP in your IVR. See my
comments below.

On Wed, Nov 28, 2012 at 2:34 PM, Greg Camp <gcam...@gmail.com> wrote:
> On Wednesday, November 28, 2012 9:11:20 AM UTC-6, Greg Camp wrote:
>>
>> Hello,
>>
>> We have successfully been using MRCP in a custom SIP IVR communicating
>> with a Nuance Speech Server.  In our current configuration we create the
>> unimrcp client at the start of the program and then create / destroy voice
>> recognition sessions throughout the life of the program as voicerec is
>> needed.  The client is destroyed when the application shuts down.

That is the correct usage. You should create an instance of
mrcp_client_t and an instance of mrcp_application_t when your
application is started. These are permanent objects which should
normally be destroyed when the application terminates. As opposed to
the client/application pair, you should create a new instance of
mrcp_session_t whenever you need to perform a new recognition. You may
also issue several recognition requests per one session object.
Though, the lifetime of the session should normally match the lifetime
of the call.

This is the method we are using at the moment and since you have
validated the method we will continue to utilize it.
 
>>
>> There are, however, some small issues we are trying to track down and
>> correct (leaking memory / threads) which leads into my question: is that the
>> preferred / optimal way of implementing UniMRCP?  Would it be better to
>> create a new client / session pair each time we need to perform voice
>> recognition (which would be virtually every call) and destroy both at the
>> end of the session?

I'd not recommend to create a new client for every new call. There is
no such a requirement.

I believe we isolated the thread issue. I was not handling the "on_terminate_event"
for any unexpected channel / session terminations. It turns out that in certain
situations where there was no audio input (e.g. an answering machine was reached
on an outbound call) the Nuance server will disconnect after approximately 60 seconds.
I have looked for a timer setting that we might be hitting but have yet to find anything.
In any case, as long as we have a live person speaking for Nuance to perform a
recognition, we do not get disconnected. And now that we handle the unexpected
termination all threads are being properly cleaned up.


>>
>> Thanks,
>> Greg
>>
>
> Also, when each new session is created I use mrcp_client_memory_pool_get to
> obtain a pointer to the pool, then I call apt_subpool_create and use the
> subpool for all memory operations during the session.  When the session is
> complete the subpool is freed with apr_pool_destroy.  I am not certain if
> that is the best way to manage the session memory or not (i.e. all memory
> reclaimed when the session ends).  The other option I considered was calling
> apt_pool_create for each new session.  Any additional thoughts on this
> aspect of the implementation?
>

You may create a new pool, or a new subpool, or use the same session
pool. All these options are legitimate. If your create a new pool,
then you'll have to destroy it with apr_pool_destroy. However, if you
use a subpool, then it's not required to explicitly destroy it. The
subpool will be destroyed with the parent (session) pool, anyway.
Having said, I don't see a criminal so far which may cause memory
leaks or any other malfunctioning.

I think our memory problem was that we were using the client/application
pool for our sessions and that was the cause of continual memory usage.
We now have implemented creating a new pool for each session that is
freed when the session is destroyed. This seems to manage memory in
a reasonable manner.
 

It's interesting whether you use a shared MRCP connection or establish
a new one per each session.

<offer-new-connection>false</offer-new-connection>

In case of shared MRCP connections, memory management is a bit tricky.
Memory allocated in the scope of the connection object will be
released when no more sessions are associated with that connection.
Since you're using NSS, it shouldn't be the case. NSS always seems to
force the client to establish a new connection.

Interesting. We are using the default of "false" as you show above.

> Thanks,
> Greg

Arsen Chaloyan

unread,
Nov 30, 2012, 7:55:53 PM11/30/12
to uni...@googlegroups.com
Hello Greg,

See below
OK.
Yes, when you get an unexpected session termination event which is
caused by a SIP BYE from the server, just terminate the session as you
normally do.

If you want to modify the timer setting, look for
session.mrcp2.sip.sessionTimeout in NSSserver.cfg.
Oh, I didn't notice you meant the client/application pool. That was
definitely wrong. You may create/destroy or own pool, or just use the
session pool

mrcp_application_session_pool_get()

>>
>>
>> It's interesting whether you use a shared MRCP connection or establish
>> a new one per each session.
>>
>> <offer-new-connection>false</offer-new-connection>
>>
>> In case of shared MRCP connections, memory management is a bit tricky.
>> Memory allocated in the scope of the connection object will be
>> released when no more sessions are associated with that connection.
>> Since you're using NSS, it shouldn't be the case. NSS always seems to
>> force the client to establish a new connection.
>
>
> Interesting. We are using the default of "false" as you show above.

Whatever you offer "false (shared)" or "true (new)", NSS will respond
with "new" in the SDP answer, so it doesn't matter.


>
>> > Thanks,
>> > Greg
>> >
>>
>> --
>> Arsen Chaloyan
>> Author of UniMRCP
>> http://www.unimrcp.org
>
> --
> You received this message because you are subscribed to the Google Groups
> "UniMRCP" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/unimrcp/-/tgcxIxj2mCUJ.
>
> To post to this group, send email to uni...@googlegroups.com.
> To unsubscribe from this group, send email to
> unimrcp+u...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/unimrcp?hl=en.



Reply all
Reply to author
Forward
0 new messages