CAF: Working With Cmc Mixers

From TBwiki
Revision as of 13:43, 17 January 2012 by Abrassard (Talk | contribs)
Jump to: navigation, search

Contents

Audio Mixers Definition

Audio mixers are used to mix audio from multiple call legs and provide mixed output to each call leg. At any time during a call flow the application can join call legs to one (or multiple) audio mixer.

TMedia concepts and density

Please read the following page for general information about TMedia Mixers: [Audio Mixers]

CTBCMCMixer class

An audio mixer is represented by an instance of the CTBCMCMixer class. Call legs ([CTBCMCLeg]) can be joined to this audio mixer as talkers, listeners, or both.

In addition to call legs joining/unjoining, the CTBCMCMixer class allows some media functions such as playing audio files or tones to all listeners of the mixer, or recording all active talkers of the mixer.

Other member functions are available to retrieve (and change in some cases) the mixer attributes, and the way different call legs are joined to the mixer (talker/listener)

It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, ISDN, SS7, Media only, etc).


Caveats
  • Do not confuse the base class CTBCMCMixer with the class CTBCAFMixer. The later is an implementation class specialized to be used by the ITBCAFCallFlow interface when dealing with multiple legs and mixers.

Command Flow for Mixer Actions in CAF

All actions requested on a mixer are executed asynchronously. For each action DoSomething() on a mixer, a corresponding OnDoSomethingResponse() event will be received on the mixer once Toolpack starts processing the command. If the OnSomethingResponse() function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function OnMixerError() will be called. In some cases, when the action is completed, an event will be received on the mixer (OnSomethingDone() for example).


For example, to play a digit sequence, one would call MixerPlayDigit(). It would then almost immediately receive the OnMixerPlayDigitResponse() event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the mixer. Once the digits play is completed, the user will receive an OnMixerDigitPlayingDone() event.


Mixer Creation

Creating a mixer is always done through the definition of a mixer attribute. The values entered in the mixer attribute will define how the mixer behaves, and will influence resource reservation.

Preparing Mixer Attributes

The class CTBCMC_MIXER_ATTRIBUTE defines available attributes to configure an audio mixer. Default parameters are provided for standard usage, though parameters may be changed to control the behavior more precisely. Example mixer attributes are:

  • Reserve IVR resource (else add it dynamically when needed)
  • Reserve talker slots (else add talker slots dynamically when needed)
  • Maximum number of active "loudest" speakers

Note: Please refer to header file tbcmc_mixer.hpp for a more complete documentation on all available mixer attributes.

Once a mixer is created, Toolpack will manage reservation of DSP resources on a TMedia, and will manage connecting legs to the mixer (listeners, or talkers). When call legs are joined or unjoined from the mixer, Toolpack will automatically re-size the DSP resource if appropriate (unless reserved talker resources have been requested, for example). And thus, the application does not have to deal with resource management distribution among TMedia units, but only make sure that the total number of talkers (or reserved talker slots) does not exceed the DSP capacity of the TMedia units.

The following code snippet shows how to build the attributes.

 PTRCTBCMC_MIXER_ATTRIBUTE ptrMixerAttribute;

 ptrMixerAttribute = tbnew CTBCMC_MIXER_ATTRIBUTE();

 ptrMixerAttribute->mfReserveIvr                  = TBX_TRUE;
 ptrMixerAttribute->mun32NbReservedActiveMembers  = 10;

Creating the Mixer

Once the mixer attributes have been filled, creating the mixer in Toolpack is only a matter of creating a CTBCMCMixer object and calling MixerCreate on it. At that moment a message is sent to Toolpack system to allocate the mixer on the hardware.

 pCallMixer = new CTBCMCMixer( 0 /* or MixerId from OnMixerSync() */, ptrMixerAttribute, this, &mLegMutex );
 pCallMixer ->MixerCreate();

Once the mixer has finished being allocated on hardware, the function OnMixerCreated() will be called.


Mixer Termination

Terminating a mixer is a 2 steps process:

  1. Call MixerTerminate()
  2. Ask for mixer object free upon OnMixerTerminated() callback function

When MixerTerminate() is called, the Toolpack framework will start destroying the mixer (including unjoining any call leg that was joined to it). Once the mixer hardware resources have been deallocated, Toolpack will call OnMixerTerminated(). Receiving that event means that the mixer no more exists in Toolpack, and the object can thus be freed. Any time after OnMixerTerminated() (or within that function), the application is responsible to call method FreeMixer, which will eventually cause the mixer's ITBCMCFreeListener interface function 'Free' to be called. The ITBCMCFreeListener to use can be specified either in the CTBCMCMixer constructor and by calling SetFreeListener(). The mixer can be it's own FreeListener, in which it just 'delete' itself. An application specific FreeListener can be used for cases where other action needs to be taken before the mixer is deleted. An example could be the case where the mixer object was allocated from a pool and it should be returned to that pool instead of being deleted.


In some situation, it is possible that mixer termination be initiated by Toolpack. This can happen in the event of sudden media resource unavailability on hardware. In that cases, the callback OnMixerTerminating is called. On reception of this event, the application should initiate termination as shown above (starting with MixerTerminate, as usual).

In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the OnMixerTerminated() event directly without prior call to MixerTerminate from the application. This event indicates that the mixer already no more exist on the Toolpack side and the user should free its object by calling FreeMixer() on it.

Mixer Synchronization on Failover

When a Toolpack application is restarted, or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs, links and mixers:

  • Callback OnCallLegSync() lists all legs that were retrieved from Toolpack
  • Callback OnLinkSync() lists all joined leg pairs that were retrieved from Toolpack
  • Callback OnMixerSync() lists all mixers that were retrieved from Toolpack, along with list of legs joined to each mixer.

The course of action to take when receiving a leg or mixer synchronization event depends on the ability of the application to resynchronize or rebuild its own states.

A typical re-synchronization scenario would be similar to:

  • Application receives all OnCallLegSync() callbacks, for each a new object of type CTBCMCLeg is created
  • Application receives all OnLinkSync() callbacks, and for each re-builds the association between the CTBCMCLeg by calling function SetJoined() of one of the legs.
  • Application receives all OnMixerSync() callbacks, and for each a new object of type CTBCMCMixer is created. Context of each leg joined to this mixer is retrieved, and re-associated to the mixer using function MixerSetJoined() of the mixer
  • Any leg, link or mixer that the application does not wish to keep is destroyed (RefuseLeg, RefuseLink, RefuseMixer)

Tip: The helper class CTBCAFCallLegResync has been created to simplify re-synchronizing legs. It can create and accumulate re-synchronized legs, and automatically destroy them when appropriate.

  • Call function AllocateCallLeg() for each synchronized leg
  • For legs that must not be destroyed after re-synchronization, call RemoveCallLeg() to remove them from this CTBCAFCallLegResync object. Application now has the ownership of the leg, and can pass it to SetJoined() or MixerSetJoined().
  • Upon OnCmcLibReady(), application must destroy CTBCAFCallLegResync. The destructor of this class will properly refuse all legs that have been created with AllocateCallLeg(), and not removed by RemoveCallLeg().

You can refer to the code of the "SimpleCall" application for an example (search for variable mpCallLegResync).

When all legs, links and mixers have been synchronized, Toolpack sends the OnCmcLibReady() event indicating that active resources synchronization is complete. Event OnSyncDone() is also called on each re-synchronized leg, and OnMixerSyncDone() on each re-synchronized mixer.

Personal tools