[asterisk-scf-commits] asterisk-scf/release/media_operations_core.git branch "master" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Tue Dec 20 16:45:28 CST 2011


branch "master" has been updated
       via  f25679bf3abf1e1c0e61154247a6f83a00206a1d (commit)
       via  02b503d443283568eee042feb7d2941bfe34dacc (commit)
       via  74b46389889d60c6e064101e82f1850fcb348c48 (commit)
       via  8dd22319976eb8faf4b33ea4282215c64a09b365 (commit)
       via  4c017a32acabf1ff53f3c215f8ded69a79b47065 (commit)
       via  0ddc4b71b09c3a7aa39d13870e38f03749744755 (commit)
       via  678d5dd75bc91fa4d77bfa0e23db4898388b3bf8 (commit)
       via  60bec36782e48e7a68179763169c3df7b5a9b3ce (commit)
       via  b5d108ce693a470cefbdb2a787dbf7d05cdaf6a7 (commit)
       via  cc2e607e6edafffc17fc05e0daf63ba68f635d2f (commit)
       via  6acdad7fb807677349da1e991456218b07d0cd7f (commit)
       via  5bbcf89dfb410a7a0b77d4c622173494c174e1d9 (commit)
       via  a14548fd1fcb491f9d9540cc61ba39765f197580 (commit)
       via  73e9253e50bfce0439857ef388b1ea3f106ae5ad (commit)
       via  5148184d6f4c620e22eb2fd30c51d109cd1f91a1 (commit)
       via  c12aa1d4fcdb2843e75adacc429beaffdd5f0f4c (commit)
       via  d2df3d403ce18d123b7b5a59fb6f6c30977025dc (commit)
       via  231cf95d8d2ed70f092b7c1dfe57c0d2f5ab19d6 (commit)
       via  8cbe5de390bf7efdef54c5023da247b745a8b871 (commit)
       via  81c64ac4ceafd3f936be87e6bd161fa298db1f58 (commit)
      from  8a6b2d86d8f1b54523cf81b13cd98d48867b0ea5 (commit)

Summary of changes:
 .../MediaOperationsCore/MediaOperationsCoreIf.ice  |   12 +
 src/CMakeLists.txt                                 |    4 +
 src/DSP.cpp                                        | 1270 ++++++++++++++++++++
 src/DSP.h                                          |  160 +++
 src/InbandTelephonyEvents.cpp                      |  416 +++++++
 src/InbandTelephonyEvents.h                        |   68 ++
 src/MediaOperationStateReplicatorListener.cpp      |   15 +
 src/MediaOperationsCore.cpp                        |    5 +
 8 files changed, 1950 insertions(+), 0 deletions(-)
 create mode 100644 src/DSP.cpp
 create mode 100644 src/DSP.h
 create mode 100644 src/InbandTelephonyEvents.cpp
 create mode 100644 src/InbandTelephonyEvents.h


- Log -----------------------------------------------------------------
commit f25679bf3abf1e1c0e61154247a6f83a00206a1d
Merge: 02b503d 8a6b2d8
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Dec 20 16:46:43 2011 -0600

    Merge branch 'master' of git.asterisk.org:asterisk-scf/release/media_operations_core


commit 02b503d443283568eee042feb7d2941bfe34dacc
Merge: 0b24734 74b4638
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Dec 20 14:36:42 2011 -0600

    Merge branch 'inband-events'

diff --cc slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
index ec46309,61fafd0..33e8497
--- a/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
+++ b/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
@@@ -33,9 -33,11 +33,11 @@@ module MediaOperationsCor
  module V1
  {
  
 -const string StateReplicatorComponentCategory = "SipStateReplicatorComponent";
 -const string StateReplicatorDiscoveryCategory = "SipStateReplicator";
 +const string StateReplicatorComponentCategory = "MediaOperationsCoreStateReplicatorComponent";
 +const string StateReplicatorDiscoveryCategory = "MediaOperationsCoreStateReplicator";
  
+ const string InbandTelephonyEventsDiscoveryCategory = "InbandTelephonyEvents";
+ 
  ["visitor"] local class MediaOperationStateItemVisitor
  {
  };

commit 74b46389889d60c6e064101e82f1850fcb348c48
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Oct 27 10:43:29 2011 -0500

    Combine two statements into one.

diff --git a/src/InbandTelephonyEvents.cpp b/src/InbandTelephonyEvents.cpp
index e1cebd7..def7016 100644
--- a/src/InbandTelephonyEvents.cpp
+++ b/src/InbandTelephonyEvents.cpp
@@ -392,9 +392,8 @@ MediaOperationPrx InbandTelephonyEventOperationFactory::tryFormat(const FormatSe
 void InbandTelephonyEventOperationFactory::createOrUpdateMediaOperation(
         const InbandTelephonyEventOperationStateItemPtr& item)
 {
-    InbandTelephonyEventOperationPtr operation;
-
-    operation = InbandTelephonyEventOperationPtr::dynamicCast(mAdapter->find(mAdapter->getCommunicator()->stringToIdentity(item->operationId)));
+    InbandTelephonyEventOperationPtr operation(
+            InbandTelephonyEventOperationPtr::dynamicCast(mAdapter->find(mAdapter->getCommunicator()->stringToIdentity(item->operationId))));
 
     if (operation != 0)
     {

commit 8dd22319976eb8faf4b33ea4282215c64a09b365
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Oct 26 16:19:42 2011 -0500

    Be sure to activate all servants.

diff --git a/src/InbandTelephonyEvents.cpp b/src/InbandTelephonyEvents.cpp
index 55ac901..e1cebd7 100644
--- a/src/InbandTelephonyEvents.cpp
+++ b/src/InbandTelephonyEvents.cpp
@@ -19,6 +19,8 @@
 #include <AsteriskSCF/Media/Formats/AudioFormats.h>
 #include <AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.h>
 
+#include <IceUtil/UUID.h>
+
 #include "TranslatorOperation.h"
 #include "InbandTelephonyEvents.h"
 #include "MediaOperationReplicationContext.h"
@@ -286,6 +288,12 @@ public:
         commonConstruction(sourceFormat, sinkFormat);
     }
 
+    MediaOperationPrx activate(const std::string& id)
+    {
+        mDetector->activateSource(id);
+        return TranslatorOperation::activate(id);
+    }
+
     ~InbandTelephonyEventOperation()
     {
         mDetector->deactivateSource();
@@ -306,7 +314,6 @@ private:
             throw UnsupportedMediaFormatException();
         }
         mDetector = new InbandTelephonyEventDetector(mSource, sinkAudio, sourceAudio, mLogger, mReplicationContext, mAdapter);
-        TelephonyEventSourcePrx source = mDetector->activateSource(mProxy->ice_getIdentity().name);
         mSink->setTranslator(mDetector);
     }
 
@@ -376,7 +383,7 @@ MediaOperationPrx InbandTelephonyEventOperationFactory::tryFormat(const FormatSe
                     *inFormat,
                     getProxy()->ice_getIdentity(),
                     mReplicationContext));
-        MediaOperationPrx proxy(MediaOperationPrx::uncheckedCast(mAdapter->addWithUUID(operation)));
+        MediaOperationPrx proxy(operation->activate(IceUtil::generateUUID()));
         return proxy;
     }
     return 0;
@@ -403,7 +410,7 @@ void InbandTelephonyEventOperationFactory::createOrUpdateMediaOperation(
             mReplicationContext,
             item);
 
-    MediaOperationPrx proxy = MediaOperationPrx::uncheckedCast(mAdapter->addWithUUID(operation));
+    MediaOperationPrx proxy(operation->activate(item->operationId));
 }
 
 } //end MediaOperationsCore

commit 4c017a32acabf1ff53f3c215f8ded69a79b47065
Author: Mark Michelson <mmichelson at digium.com>
Date:   Wed Oct 26 14:24:48 2011 -0500

    Switch around types so that they fall more in line with how the DSP works.

diff --git a/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice b/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
index 4227098..61fafd0 100644
--- a/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
+++ b/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
@@ -114,9 +114,6 @@ class G722MediaOperationStateItem extends TranslatorMediaOperationStateItem
 class InbandTelephonyEventOperationStateItem extends TranslatorMediaOperationStateItem
 {
     bool processingDTMF;
-    bool processingCNG;
-    bool processingCED;
-    bool processingV21;
     byte currentDTMF;
     long eventBeginTime;
 };
diff --git a/src/DSP.cpp b/src/DSP.cpp
index 2b2faad..8bddd01 100644
--- a/src/DSP.cpp
+++ b/src/DSP.cpp
@@ -1096,7 +1096,7 @@ TelephonyEventPtr DSP::process(AudioFramePtr af)
 
     if ((mPriv->mFeatures & DSP_FEATURE_FAX_DETECT)) {
         if ((mPriv->mFaxmode & DSP_FAXMODE_DETECT_CNG) && mPriv->toneDetect(&mPriv->mCNGToneState, shortdata, len)) {
-            returnEvent = new BeginCNGEvent;
+            returnEvent = new CNGEvent;
             for (x = 0; x < mPriv->mMuteFragments; x++) {
                 memset(shortdata + mPriv->mMuteData[x].start, 0, sizeof(int16_t) * (mPriv->mMuteData[x].end - mPriv->mMuteData[x].start));
             }
@@ -1104,7 +1104,7 @@ TelephonyEventPtr DSP::process(AudioFramePtr af)
         }
 
         if ((mPriv->mFaxmode & DSP_FAXMODE_DETECT_CED) && mPriv->toneDetect(&mPriv->mCEDToneState, shortdata, len)) {
-            returnEvent = new BeginCEDEvent;
+            returnEvent = new CEDEvent;
             for (x = 0; x < mPriv->mMuteFragments; x++) {
                 memset(shortdata + mPriv->mMuteData[x].start, 0, sizeof(int16_t) * (mPriv->mMuteData[x].end - mPriv->mMuteData[x].start));
             }
@@ -1112,7 +1112,7 @@ TelephonyEventPtr DSP::process(AudioFramePtr af)
         }
 
         if ((mPriv->mFaxmode & DSP_FAXMODE_DETECT_V21) && mPriv->v21Detect(&mPriv->mV21State, shortdata, len)) {
-            returnEvent = new BeginV21Event;
+            returnEvent = new V21Event;
             for (x = 0; x < mPriv->mMuteFragments; x++) {
                 memset(shortdata + mPriv->mMuteData[x].start, 0, sizeof(int16_t) * (mPriv->mMuteData[x].end - mPriv->mMuteData[x].start));
             }
@@ -1147,7 +1147,7 @@ TelephonyEventPtr DSP::process(AudioFramePtr af)
                 memmove(&mPriv->mDigitState.digitlen[0], &mPriv->mDigitState.digitlen[1], mPriv->mDigitState.current_digits * sizeof(mPriv->mDigitState.digitlen[0]));
                 mPriv->mDigitState.current_digits--;
                 mPriv->mDTMFBegan = 0;
-                returnEvent = new BeginDTMFEvent(event_digit);
+                returnEvent = new EndDTMFEvent(event_digit, 0);
             }
         }
     }
diff --git a/src/InbandTelephonyEvents.cpp b/src/InbandTelephonyEvents.cpp
index 2cd64b8..55ac901 100644
--- a/src/InbandTelephonyEvents.cpp
+++ b/src/InbandTelephonyEvents.cpp
@@ -169,16 +169,6 @@ class InbandTelephonyEventOperation : public TranslatorOperation
                 throw UnsupportedMediaFormatException();
             }
 
-            //This requires some explanation...
-            //The DSP will detect the presence of certain tones. The DSP is essentially
-            //edge-triggered. In other words, it will report the beginning and end of
-            //a specific tone and let us know what it detected.
-            //
-            //The problem here is that the DSP will always report what it has found as
-            //a "Begin" event of the appropriate type. It is up to us to maintain state
-            //from the DSP's process. Thus we can properly turn the event into an end
-            //event if it is appropriate to do so.
-
             TelephonyEventPtr detectedEvent = mDSP->process(inAudio);
 
             if (!detectedEvent)
@@ -195,87 +185,26 @@ class InbandTelephonyEventOperation : public TranslatorOperation
                 return inAudio;
             }
 
-            //In all cases below, we will want to generate telephony
-            //events.
-            BeginDTMFEventPtr DTMF;
-            BeginCNGEventPtr CNG;
-            BeginCEDEventPtr CED;
-            BeginV21EventPtr v21;
-            if ((DTMF = BeginDTMFEventPtr::dynamicCast(detectedEvent)))
-            {
-                //With DTMF we get told when DTMF has begun and when it has
-                //ended. We keep track of whether we're currently handling
-                //a DTMF. If we're not, then we can just forward on the 
-                //begin event that we get back. If we are, then we need
-                //to generate an end event and unset the bool.
-                //
-                if (mStateItem->processingDTMF)
-                {
-                    //Create an EndDTMF event
-                    int duration = (int) (IceUtil::Time::now().toMilliSeconds() - mStateItem->eventBeginTime);
-                    EndDTMFEventPtr endDTMF(new EndDTMFEvent(mStateItem->currentDTMF, duration));
-                    mTelephonySource->distributeToSinks(endDTMF);
-                    mStateItem->processingDTMF = false;
-                }
-                else
-                {
-                    forwardBeginEvent(DTMF, mStateItem->processingDTMF);
-                }
-                replicateState();
-            }
-            else if ((CNG = BeginCNGEventPtr::dynamicCast(detectedEvent)))
-            {
-                //We've picked up some CNG!
-                if (mStateItem->processingCNG)
-                {
-                    //End that shizzle!
-                    int duration = (int) (IceUtil::Time::now().toMilliSeconds() - mStateItem->eventBeginTime);
-                    EndCNGEventPtr endCNG(new EndCNGEvent(duration));
-                    mTelephonySource->distributeToSinks(endCNG);
-                    mStateItem->processingCNG = false;
-                }
-                else
-                {
-                    forwardBeginEvent(CNG, mStateItem->processingCNG);
-                }
-                replicateState();
-            }
-            else if ((CED = BeginCEDEventPtr::dynamicCast(detectedEvent)))
+            BeginDTMFEventPtr beginDTMF;
+            EndDTMFEventPtr endDTMF;
+            if ((beginDTMF = BeginDTMFEventPtr::dynamicCast(detectedEvent)))
             {
-                //We've picked up some CED!
-                if (mStateItem->processingCED)
-                {
-                    //End it!
-                    int duration = (int) (IceUtil::Time::now().toMilliSeconds() - mStateItem->eventBeginTime);
-                    EndCNGEventPtr endCNG(new EndCNGEvent(duration));
-                    mTelephonySource->distributeToSinks(endCNG);
-                    mStateItem->processingCED = false;
-                }
-                else
-                {
-                    forwardBeginEvent(CED, mStateItem->processingCED);
-                }
+                mStateItem->eventBeginTime = IceUtil::Time::now().toMilliSeconds();
+                mTelephonySource->distributeToSinks(beginDTMF);
+                mStateItem->processingDTMF = true;
                 replicateState();
             }
-            else if ((v21 = BeginV21EventPtr::dynamicCast(detectedEvent)))
+            else if ((endDTMF = EndDTMFEventPtr::dynamicCast(detectedEvent)))
             {
-                //We've picked up some V.21!
-                if (mStateItem->processingV21)
-                {
-                    int duration = (int) (IceUtil::Time::now().toMilliSeconds() - mStateItem->eventBeginTime);
-                    EndCNGEventPtr endCNG(new EndCNGEvent(duration));
-                    mTelephonySource->distributeToSinks(endCNG);
-                    mStateItem->processingV21 = false;
-                }
-                else
-                {
-                    forwardBeginEvent(v21, mStateItem->processingV21);
-                }
+                endDTMF->duration = (int) (IceUtil::Time::now().toMilliSeconds() - mStateItem->eventBeginTime);
+                mTelephonySource->distributeToSinks(endDTMF);
+                mStateItem->processingDTMF = false;
                 replicateState();
             }
             else
             {
-                //Unknown event detected...weird.
+                //If another type of event was detected, then we'll want to just send it out straightaway.
+                mTelephonySource->distributeToSinks(detectedEvent);
             }
 
             //No matter what sort of telephony event was detected, we'll want to send the
@@ -294,16 +223,6 @@ class InbandTelephonyEventOperation : public TranslatorOperation
             mStateItem = newState;
         }
     private:
-        /**
-         * Convenience method to send along a begin event as detected by the
-         * DSP.
-         */
-        void forwardBeginEvent(const TelephonyEventPtr& event, bool &eventBegin)
-        {
-            mStateItem->eventBeginTime = IceUtil::Time::now().toMilliSeconds();
-            mTelephonySource->distributeToSinks(event);
-            eventBegin = true;
-        }
 
         /**
          * Convenience method to copy our current state to any replicas.

commit 0ddc4b71b09c3a7aa39d13870e38f03749744755
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Oct 25 17:20:33 2011 -0500

    Add some documentation.

diff --git a/src/InbandTelephonyEvents.cpp b/src/InbandTelephonyEvents.cpp
index 5c427ea..2cd64b8 100644
--- a/src/InbandTelephonyEvents.cpp
+++ b/src/InbandTelephonyEvents.cpp
@@ -78,6 +78,7 @@ class InbandTelephonyEventOperation : public TranslatorOperation
             }
             cb->ice_response();
         }
+
         void removeSinks_async(const AMD_TelephonyEventSource_removeSinksPtr& cb,
                 const TelephonyEventSinkSeq& sinks,
                 const Ice::Current&)
@@ -168,6 +169,16 @@ class InbandTelephonyEventOperation : public TranslatorOperation
                 throw UnsupportedMediaFormatException();
             }
 
+            //This requires some explanation...
+            //The DSP will detect the presence of certain tones. The DSP is essentially
+            //edge-triggered. In other words, it will report the beginning and end of
+            //a specific tone and let us know what it detected.
+            //
+            //The problem here is that the DSP will always report what it has found as
+            //a "Begin" event of the appropriate type. It is up to us to maintain state
+            //from the DSP's process. Thus we can properly turn the event into an end
+            //event if it is appropriate to do so.
+
             TelephonyEventPtr detectedEvent = mDSP->process(inAudio);
 
             if (!detectedEvent)
@@ -283,6 +294,10 @@ class InbandTelephonyEventOperation : public TranslatorOperation
             mStateItem = newState;
         }
     private:
+        /**
+         * Convenience method to send along a begin event as detected by the
+         * DSP.
+         */
         void forwardBeginEvent(const TelephonyEventPtr& event, bool &eventBegin)
         {
             mStateItem->eventBeginTime = IceUtil::Time::now().toMilliSeconds();
@@ -290,6 +305,9 @@ class InbandTelephonyEventOperation : public TranslatorOperation
             eventBegin = true;
         }
 
+        /**
+         * Convenience method to copy our current state to any replicas.
+         */
         void replicateState()
         {
             if (mReplicationContext->isReplicating())

commit 678d5dd75bc91fa4d77bfa0e23db4898388b3bf8
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Oct 25 17:08:35 2011 -0500

    Some cleanup mostly.

diff --git a/src/InbandTelephonyEvents.cpp b/src/InbandTelephonyEvents.cpp
index c13460a..5c427ea 100644
--- a/src/InbandTelephonyEvents.cpp
+++ b/src/InbandTelephonyEvents.cpp
@@ -120,14 +120,13 @@ class InbandTelephonyEventOperation : public TranslatorOperation
     {
     public:
         InbandTelephonyEventDetector(const TranslatorSourcePtr source,
-                const FormatPtr& inputFormat,
-                const FormatPtr& outputFormat,
+                const AudioFormatPtr& inputFormat,
+                const AudioFormatPtr& outputFormat,
                 const Logger& logger,
                 const MediaOperationReplicationContextPtr& replicationContext,
                 const Ice::ObjectAdapterPtr& adapter)
             : Translator(source, inputFormat, outputFormat, logger),
-            //XXX We can work out the sample rate from the input format.
-            mDSP(new DSP(logger)),
+            mDSP(new DSP(logger, inputFormat->sampleRate)),
             mTelephonySource(new InbandTelephonyEventSource(logger)),
             mReplicationContext(replicationContext),
             mAdapter(adapter)
@@ -328,9 +327,7 @@ public:
                replicationContext,
                new InbandTelephonyEventOperationStateItem)
     {
-        mDetector = new InbandTelephonyEventDetector(mSource, sinkFormat, sourceFormat, mLogger, replicationContext, adapter);
-        TelephonyEventSourcePrx source = mDetector->activateSource(mProxy->ice_getIdentity().name);
-        mSink->setTranslator(mDetector);
+        commonConstruction(sourceFormat, sinkFormat);
     }
 
     InbandTelephonyEventOperation(
@@ -349,9 +346,7 @@ public:
                 replicationContext,
                 item)
     {
-        mDetector = new InbandTelephonyEventDetector(mSource, sinkFormat, sourceFormat, mLogger, replicationContext, adapter);
-        TelephonyEventSourcePrx source = mDetector->activateSource(mProxy->ice_getIdentity().name);
-        mSink->setTranslator(mDetector);
+        commonConstruction(sourceFormat, sinkFormat);
     }
 
     ~InbandTelephonyEventOperation()
@@ -365,6 +360,19 @@ public:
     }
 
 private:
+    void commonConstruction(const FormatPtr& sourceFormat, const FormatPtr& sinkFormat)
+    {
+        AudioFormatPtr sourceAudio = AudioFormatPtr::dynamicCast(sourceFormat);
+        AudioFormatPtr sinkAudio = AudioFormatPtr::dynamicCast(sinkFormat);
+        if (!sourceAudio || !sinkAudio)
+        {
+            throw UnsupportedMediaFormatException();
+        }
+        mDetector = new InbandTelephonyEventDetector(mSource, sinkAudio, sourceAudio, mLogger, mReplicationContext, mAdapter);
+        TelephonyEventSourcePrx source = mDetector->activateSource(mProxy->ice_getIdentity().name);
+        mSink->setTranslator(mDetector);
+    }
+
     InbandTelephonyEventDetectorPtr mDetector;
 };
 
@@ -396,50 +404,47 @@ MediaOperationPrx InbandTelephonyEventOperationFactory::createMediaOperation(
     FormatSeq sourceFormats = source->getFormats();
     FormatSeq sinkFormats = sink->getFormats();
 
-    FormatSeq::iterator inSlin8 = std::find_if(sourceFormats.begin(),
-            sourceFormats.end(), FormatNameEqual(SignedLinear8Name));
+    MediaOperationPrx proxy = tryFormat(sourceFormats, sinkFormats, SignedLinear8Name);
 
-    FormatSeq::iterator outSlin8 = std::find_if(sinkFormats.begin(),
-            sinkFormats.end(), FormatNameEqual(SignedLinear8Name));
-
-    InbandTelephonyEventOperationPtr operation;
-    MediaOperationPrx proxy;
-    if (inSlin8 != sourceFormats.end() && outSlin8 != sinkFormats.end())
+    if (!proxy)
     {
-        operation = new InbandTelephonyEventOperation(
-                mAdapter,
-                mLogger,
-                *outSlin8,
-                *inSlin8,
-                getProxy()->ice_getIdentity(),
-                mReplicationContext);
-        proxy = MediaOperationPrx::uncheckedCast(mAdapter->addWithUUID(operation));
-        return proxy;
+        proxy = tryFormat(sourceFormats, sinkFormats, SignedLinear16Name);
     }
 
-    FormatSeq::iterator inSlin16 = std::find_if(sourceFormats.begin(),
-            sourceFormats.end(), FormatNameEqual(SignedLinear16Name));
-
-    FormatSeq::iterator outSlin16 = std::find_if(sinkFormats.begin(),
-            sinkFormats.end(), FormatNameEqual(SignedLinear16Name));
-
-    if (inSlin16 == sourceFormats.end() || outSlin16 == sinkFormats.end())
+    if (!proxy)
     {
         throw UnsupportedMediaFormatException();
     }
 
-    operation = new InbandTelephonyEventOperation(
-            mAdapter,
-            mLogger,
-            *outSlin16,
-            *inSlin16,
-            getProxy()->ice_getIdentity(),
-            mReplicationContext);
-
-    proxy = MediaOperationPrx::uncheckedCast(mAdapter->addWithUUID(operation));
     return proxy;
 }
 
+MediaOperationPrx InbandTelephonyEventOperationFactory::tryFormat(const FormatSeq& sourceFormats,
+        const FormatSeq& sinkFormats,
+        const std::string& name)
+{
+    FormatSeq::const_iterator inFormat = std::find_if(sourceFormats.begin(),
+            sourceFormats.end(), FormatNameEqual(name));
+
+    FormatSeq::const_iterator outFormat = std::find_if(sinkFormats.begin(),
+            sinkFormats.end(), FormatNameEqual(name));
+
+    if (inFormat != sourceFormats.end() && outFormat != sinkFormats.end())
+    {
+        InbandTelephonyEventOperationPtr operation(
+                new InbandTelephonyEventOperation(
+                    mAdapter,
+                    mLogger,
+                    *outFormat,
+                    *inFormat,
+                    getProxy()->ice_getIdentity(),
+                    mReplicationContext));
+        MediaOperationPrx proxy(MediaOperationPrx::uncheckedCast(mAdapter->addWithUUID(operation)));
+        return proxy;
+    }
+    return 0;
+}
+
 void InbandTelephonyEventOperationFactory::createOrUpdateMediaOperation(
         const InbandTelephonyEventOperationStateItemPtr& item)
 {
diff --git a/src/InbandTelephonyEvents.h b/src/InbandTelephonyEvents.h
index 8fb44e0..da2f636 100644
--- a/src/InbandTelephonyEvents.h
+++ b/src/InbandTelephonyEvents.h
@@ -48,6 +48,18 @@ public:
      * state item does not yet exist, then we will create it.
      */
     void createOrUpdateMediaOperation(const AsteriskSCF::Replication::MediaOperationsCore::V1::InbandTelephonyEventOperationStateItemPtr& item);
+private:
+
+    /**
+     * Internal method to create an operation using a specific format
+     *
+     * This method takes the supported formats from a source and a sink and checks
+     * if the name specified in formatName is supported by both the source and sink.
+     * If so, then a media operation is created using the specified format.
+     */
+    AsteriskSCF::Media::V1::MediaOperationPrx tryFormat(const AsteriskSCF::Media::V1::FormatSeq& sourceFormats,
+            const AsteriskSCF::Media::V1::FormatSeq& sinkFormats,
+            const std::string& formatName);
 };
 
 typedef IceUtil::Handle<InbandTelephonyEventOperationFactory> InbandTelephonyEventOperationFactoryPtr;

commit 60bec36782e48e7a68179763169c3df7b5a9b3ce
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Oct 25 16:07:51 2011 -0500

    Create the operation factory for inband telephony events.

diff --git a/src/InbandTelephonyEvents.cpp b/src/InbandTelephonyEvents.cpp
index ae8b4f2..c13460a 100644
--- a/src/InbandTelephonyEvents.cpp
+++ b/src/InbandTelephonyEvents.cpp
@@ -373,12 +373,11 @@ typedef IceUtil::Handle<InbandTelephonyEventOperation> InbandTelephonyEventOpera
 InbandTelephonyEventOperationFactory::InbandTelephonyEventOperationFactory(
         const Ice::ObjectAdapterPtr& adapter,
         const Logger& logger,
-        const MediaOperationReplicationContextPtr& replicationContext,
-        const std::string& name)
+        const MediaOperationReplicationContextPtr& replicationContext)
     : MediaOperationFactoryImpl(adapter,
             logger,
             replicationContext,
-            name)
+            "InbandTelephonyEventFactory")
 {
     mLocatorParams->category = MediaOperationDiscoveryCategory;
     mLocatorParams->service = InbandTelephonyEventsDiscoveryCategory;
diff --git a/src/InbandTelephonyEvents.h b/src/InbandTelephonyEvents.h
index 42dceae..8fb44e0 100644
--- a/src/InbandTelephonyEvents.h
+++ b/src/InbandTelephonyEvents.h
@@ -33,16 +33,21 @@ public:
     InbandTelephonyEventOperationFactory(
         const Ice::ObjectAdapterPtr& adapter,
         const AsteriskSCF::System::Logging::Logger& logger,
-        const MediaOperationReplicationContextPtr& replicationContext,
-        const std::string& name);
+        const MediaOperationReplicationContextPtr& replicationContext);
 
     AsteriskSCF::Media::V1::MediaOperationPrx createMediaOperation(
             const AsteriskSCF::Media::V1::StreamSourcePrx& source,
             const AsteriskSCF::Media::V1::StreamSinkPrx& sink,
             const Ice::Current&);
 
-    void createOrUpdateMediaOperation(
-            const AsteriskSCF::Replication::MediaOperationsCore::V1::InbandTelephonyEventOperationStateItemPtr& item);
+    /**
+     * Called from the state replicator listener.
+     *
+     * When state gets updated, we have to update the internal
+     * state of the operation. If the operation described by the
+     * state item does not yet exist, then we will create it.
+     */
+    void createOrUpdateMediaOperation(const AsteriskSCF::Replication::MediaOperationsCore::V1::InbandTelephonyEventOperationStateItemPtr& item);
 };
 
 typedef IceUtil::Handle<InbandTelephonyEventOperationFactory> InbandTelephonyEventOperationFactoryPtr;
diff --git a/src/MediaOperationStateReplicatorListener.cpp b/src/MediaOperationStateReplicatorListener.cpp
index 01dc0f2..d6e1d5c 100644
--- a/src/MediaOperationStateReplicatorListener.cpp
+++ b/src/MediaOperationStateReplicatorListener.cpp
@@ -63,6 +63,10 @@ void MediaOperationStateReplicatorListenerImpl::stateRemovedForItems(
         {
             mAdapter->remove(mAdapter->getCommunicator()->stringToIdentity(g722->operationId));
         }
+        void visitInbandTelephonyEventOperationStateItem(const InbandTelephonyEventOperationStateItemPtr& inband)
+        {
+            mAdapter->remove(mAdapter->getCommunicator()->stringToIdentity(inband->operationId));
+        }
         Ice::ObjectAdapterPtr mAdapter;
     };
 
diff --git a/src/MediaOperationsCore.cpp b/src/MediaOperationsCore.cpp
index 296d41b..91b33c0 100644
--- a/src/MediaOperationsCore.cpp
+++ b/src/MediaOperationsCore.cpp
@@ -26,6 +26,7 @@
 #include "ulaw_alaw.h"
 #include "resample.h"
 #include "g722.h"
+#include "InbandTelephonyEvents.h"
 
 using namespace AsteriskSCF::System::Logging;
 
@@ -195,6 +196,10 @@ private:
         lg(Debug) << "Creating G.722 Factory";
         createAndRegisterFactory(new G722Factory(getServiceAdapter(), lg,
                     boost::static_pointer_cast<MediaOperationReplicationContext>(getReplicationContext())));
+
+        lg(Debug) << "Creating Inband Telephony Event Detector Factory";
+        createAndRegisterFactory(new InbandTelephonyEventOperationFactory(getServiceAdapter(), lg,
+                    boost::static_pointer_cast<MediaOperationReplicationContext>(getReplicationContext())));
     }
 
     void locateStateReplicator()

commit b5d108ce693a470cefbdb2a787dbf7d05cdaf6a7
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Oct 25 14:31:54 2011 -0500

    Work towards proper state replication in place.

diff --git a/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice b/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
index 4a65e41..4227098 100644
--- a/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
+++ b/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
@@ -36,6 +36,8 @@ module V1
 const string StateReplicatorComponentCategory = "SipStateReplicatorComponent";
 const string StateReplicatorDiscoveryCategory = "SipStateReplicator";
 
+const string InbandTelephonyEventsDiscoveryCategory = "InbandTelephonyEvents";
+
 ["visitor"] local class MediaOperationStateItemVisitor
 {
 };
diff --git a/src/InbandTelephonyEvents.cpp b/src/InbandTelephonyEvents.cpp
index 9c7b014..ae8b4f2 100644
--- a/src/InbandTelephonyEvents.cpp
+++ b/src/InbandTelephonyEvents.cpp
@@ -123,17 +123,37 @@ class InbandTelephonyEventOperation : public TranslatorOperation
                 const FormatPtr& inputFormat,
                 const FormatPtr& outputFormat,
                 const Logger& logger,
-                const MediaOperationReplicationContextPtr& replicationContext)
+                const MediaOperationReplicationContextPtr& replicationContext,
+                const Ice::ObjectAdapterPtr& adapter)
             : Translator(source, inputFormat, outputFormat, logger),
             //XXX We can work out the sample rate from the input format.
             mDSP(new DSP(logger)),
             mTelephonySource(new InbandTelephonyEventSource(logger)),
-            mReplicationContext(replicationContext)
+            mReplicationContext(replicationContext),
+            mAdapter(adapter)
         {
             mDSP->setFeatures(DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT);
             mDSP->setDigitmode(DSP_DIGITMODE_DTMF);
         }
 
+        TelephonyEventSourcePrx activateSource(const std::string& id)
+        {
+            std::string ourID = id + ".TelephonyEventSource";
+            mProxy = TelephonyEventSourcePrx::uncheckedCast(mAdapter->add(mTelephonySource, mAdapter->getCommunicator()->stringToIdentity(ourID)));
+            return mProxy;
+        };
+
+        void deactivateSource()
+        {
+            try
+            {
+                mAdapter->remove(mProxy->ice_getIdentity());
+            }
+            catch (const std::exception&)
+            {
+            }
+        };
+
         FramePtr translate(const FramePtr inFrame)
         {
             if (inFrame->mediaFormat->name != mInputFormat->name)
@@ -252,6 +272,17 @@ class InbandTelephonyEventOperation : public TranslatorOperation
             //audio on to the next set of stuff
             return inAudio;
         };
+
+        /**
+         * Update the state for the operation
+         *
+         * This is called by the state replicator listener when state for the
+         * primary operation changes.
+         */
+        void updateState(const InbandTelephonyEventOperationStateItemPtr& newState)
+        {
+            mStateItem = newState;
+        }
     private:
         void forwardBeginEvent(const TelephonyEventPtr& event, bool &eventBegin)
         {
@@ -274,8 +305,12 @@ class InbandTelephonyEventOperation : public TranslatorOperation
         InbandTelephonyEventSourcePtr mTelephonySource;
         InbandTelephonyEventOperationStateItemPtr mStateItem;
         MediaOperationReplicationContextPtr mReplicationContext;
+        Ice::ObjectAdapterPtr mAdapter;
+        TelephonyEventSourcePrx mProxy;
     };
 
+    typedef IceUtil::Handle<InbandTelephonyEventDetector> InbandTelephonyEventDetectorPtr;
+
 public:
     InbandTelephonyEventOperation(
            const Ice::ObjectAdapterPtr& adapter,
@@ -293,8 +328,44 @@ public:
                replicationContext,
                new InbandTelephonyEventOperationStateItem)
     {
-        mSink->setTranslator(new InbandTelephonyEventDetector(mSource, sinkFormat, sourceFormat, mLogger, replicationContext));
+        mDetector = new InbandTelephonyEventDetector(mSource, sinkFormat, sourceFormat, mLogger, replicationContext, adapter);
+        TelephonyEventSourcePrx source = mDetector->activateSource(mProxy->ice_getIdentity().name);
+        mSink->setTranslator(mDetector);
+    }
+
+    InbandTelephonyEventOperation(
+            const Ice::ObjectAdapterPtr& adapter,
+            const Logger& logger,
+            const FormatPtr& sourceFormat,
+            const FormatPtr& sinkFormat,
+            const MediaOperationReplicationContextPtr& replicationContext,
+            const InbandTelephonyEventOperationStateItemPtr& item)
+        : TranslatorOperation(
+                adapter,
+                logger,
+                sourceFormat,
+                sinkFormat,
+                item->factoryId,
+                replicationContext,
+                item)
+    {
+        mDetector = new InbandTelephonyEventDetector(mSource, sinkFormat, sourceFormat, mLogger, replicationContext, adapter);
+        TelephonyEventSourcePrx source = mDetector->activateSource(mProxy->ice_getIdentity().name);
+        mSink->setTranslator(mDetector);
     }
+
+    ~InbandTelephonyEventOperation()
+    {
+        mDetector->deactivateSource();
+    }
+
+    void updateState(const InbandTelephonyEventOperationStateItemPtr& newState)
+    {
+        mDetector->updateState(newState);
+    }
+
+private:
+    InbandTelephonyEventDetectorPtr mDetector;
 };
 
 typedef IceUtil::Handle<InbandTelephonyEventOperation> InbandTelephonyEventOperationPtr;
@@ -310,8 +381,7 @@ InbandTelephonyEventOperationFactory::InbandTelephonyEventOperationFactory(
             name)
 {
     mLocatorParams->category = MediaOperationDiscoveryCategory;
-    //XXX This should be some named constant
-    mLocatorParams->service = "InbandTelephonyEvents";
+    mLocatorParams->service = InbandTelephonyEventsDiscoveryCategory;
 };
 
 MediaOperationPrx InbandTelephonyEventOperationFactory::createMediaOperation(
@@ -371,5 +441,29 @@ MediaOperationPrx InbandTelephonyEventOperationFactory::createMediaOperation(
     return proxy;
 }
 
+void InbandTelephonyEventOperationFactory::createOrUpdateMediaOperation(
+        const InbandTelephonyEventOperationStateItemPtr& item)
+{
+    InbandTelephonyEventOperationPtr operation;
+
+    operation = InbandTelephonyEventOperationPtr::dynamicCast(mAdapter->find(mAdapter->getCommunicator()->stringToIdentity(item->operationId)));
+
+    if (operation != 0)
+    {
+        operation->updateState(item);
+        return;
+    }
+
+    operation = new InbandTelephonyEventOperation(
+            mAdapter,
+            mLogger,
+            item->sourceFormat,
+            item->sinkFormat,
+            mReplicationContext,
+            item);
+
+    MediaOperationPrx proxy = MediaOperationPrx::uncheckedCast(mAdapter->addWithUUID(operation));
+}
+
 } //end MediaOperationsCore
 } //end AsteriskSCF
diff --git a/src/InbandTelephonyEvents.h b/src/InbandTelephonyEvents.h
index e76e47d..42dceae 100644
--- a/src/InbandTelephonyEvents.h
+++ b/src/InbandTelephonyEvents.h
@@ -40,7 +40,12 @@ public:
             const AsteriskSCF::Media::V1::StreamSourcePrx& source,
             const AsteriskSCF::Media::V1::StreamSinkPrx& sink,
             const Ice::Current&);
+
+    void createOrUpdateMediaOperation(
+            const AsteriskSCF::Replication::MediaOperationsCore::V1::InbandTelephonyEventOperationStateItemPtr& item);
 };
 
+typedef IceUtil::Handle<InbandTelephonyEventOperationFactory> InbandTelephonyEventOperationFactoryPtr;
+
 } // end MediaOperationsCore
 } // end AsteriskSCF
diff --git a/src/MediaOperationStateReplicatorListener.cpp b/src/MediaOperationStateReplicatorListener.cpp
index 2943d21..01dc0f2 100644
--- a/src/MediaOperationStateReplicatorListener.cpp
+++ b/src/MediaOperationStateReplicatorListener.cpp
@@ -19,6 +19,7 @@
 #include "ulaw_alaw.h"
 #include "resample.h"
 #include "g722.h"
+#include "InbandTelephonyEvents.h"
 
 namespace AsteriskSCF
 {
@@ -105,6 +106,16 @@ void MediaOperationStateReplicatorListenerImpl::stateSet(
             createTranslationMediaOperation(factory, g722);
         }
 
+        void visitInbandTelephonyEventOperationStateItemPtr(const InbandTelephonyEventOperationStateItemPtr& inband)
+        {
+            InbandTelephonyEventOperationFactoryPtr factory = InbandTelephonyEventOperationFactoryPtr::dynamicCast(mAdapter->find(inband->factoryId));
+            if (!factory)
+            {
+                return;
+            }
+            factory->createOrUpdateMediaOperation(inband);
+        }
+
         void createTranslationMediaOperation(const TranslatorOperationFactoryPtr& factory,
                 const TranslatorMediaOperationStateItemPtr& item)
         {

commit cc2e607e6edafffc17fc05e0daf63ba68f635d2f
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Oct 17 16:31:48 2011 -0500

    Get things going a bit more.
    
    This adds appropriate state-tracking information, as well as sending appropriate
    stuff to the registered telephony event sinks.

diff --git a/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice b/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
index 313bc60..4a65e41 100644
--- a/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
+++ b/slice/AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.ice
@@ -106,6 +106,19 @@ class G722MediaOperationStateItem extends TranslatorMediaOperationStateItem
 {
 };
 
+/**
+ * State item for Inband telephony event detectors
+ */
+class InbandTelephonyEventOperationStateItem extends TranslatorMediaOperationStateItem
+{
+    bool processingDTMF;
+    bool processingCNG;
+    bool processingCED;
+    bool processingV21;
+    byte currentDTMF;
+    long eventBeginTime;
+};
+
 interface MediaOperationStateReplicatorListener
 {
     void stateRemoved(Ice::StringSeq itemKeys);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 74026b1..80d07d0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -23,6 +23,8 @@ astscf_component_add_files(MediaOperationsCore g722/g722_decode.c)
 astscf_component_add_files(MediaOperationsCore g722/g722.h)
 astscf_component_add_files(MediaOperationsCore DSP.cpp)
 astscf_component_add_files(MediaOperationsCore DSP.h)
+astscf_component_add_files(MediaOperationsCore InbandTelephonyEvents.cpp)
+astscf_component_add_files(MediaOperationsCore InbandTelephonyEvents.h)
 astscf_component_add_files(MediaOperationsCore MediaOperationFactoryImpl.h)
 astscf_component_add_files(MediaOperationsCore MediaOperationFactoryImpl.cpp)
 astscf_component_add_files(MediaOperationsCore MediaOperationsCore.cpp)
diff --git a/src/DSP.cpp b/src/DSP.cpp
index fd0cc4a..2b2faad 100644
--- a/src/DSP.cpp
+++ b/src/DSP.cpp
@@ -334,7 +334,7 @@ static inline int pair_there(float p1, float p2, float i1, float i2, float e)
 class DSPPriv : public IceUtil::Shared
 {
 public:
-    DSPPriv(Logger& logger, unsigned int sampleRate) :
+    DSPPriv(const Logger& logger, unsigned int sampleRate) :
         mLogger(logger),
         mThreshold(DEFAULT_THRESHOLD),
         mFeatures(DSP_FEATURE_SILENCE_SUPPRESS),
@@ -1165,7 +1165,7 @@ unsigned int DSP::getSampleRate()
     return mPriv->mSampleRate;
 }
 
-DSP::DSP(Logger& logger, unsigned int sampleRate)
+DSP::DSP(const Logger& logger, unsigned int sampleRate)
     : mPriv(new DSPPriv(logger, sampleRate))
 {
 }
diff --git a/src/DSP.h b/src/DSP.h
index 3bafdda..d301f80 100644
--- a/src/DSP.h
+++ b/src/DSP.h
@@ -93,7 +93,7 @@ public:
     /*! \brief Allocates a new dsp with a specific internal sample rate used
      * during processing. */
 
-    DSP(AsteriskSCF::System::Logging::Logger& logger, unsigned int sampleRate = 8000);
+    DSP(const AsteriskSCF::System::Logging::Logger& logger, unsigned int sampleRate = 8000);
     
     ~DSP();
     
diff --git a/src/InbandTelephonyEvents.cpp b/src/InbandTelephonyEvents.cpp
index d878d25..9c7b014 100644
--- a/src/InbandTelephonyEvents.cpp
+++ b/src/InbandTelephonyEvents.cpp
@@ -14,8 +14,42 @@
  * at the top of the source tree.
  */
 
-#include <InbandTelephonyEvents.h>
 #include <AsteriskSCF/Helpers/ProxyHelper.h>
+#include <AsteriskSCF/SessionCommunications/TelephonyEventsIf.h>
+#include <AsteriskSCF/Media/Formats/AudioFormats.h>
+#include <AsteriskSCF/Replication/MediaOperationsCore/MediaOperationsCoreIf.h>
+
+#include "TranslatorOperation.h"
+#include "InbandTelephonyEvents.h"
+#include "MediaOperationReplicationContext.h"
+#include "DSP.h"
+
+using namespace AsteriskSCF::Media::V1;
+using namespace AsteriskSCF::SessionCommunications::V1;
+using namespace AsteriskSCF::System::Logging;
+using namespace AsteriskSCF::Media::Formats::Audio::V1;
+using namespace AsteriskSCF::Replication::MediaOperationsCore::V1;
+
+namespace
+{
+
+class FormatNameEqual
+{
+public:
+    FormatNameEqual(const std::string& formatName)
+        : mFormatName(formatName)
+    {
+    };
+
+    bool operator() (const FormatPtr& format)
+    {
+        return mFormatName == format->name;
+    }
+private:
+    const std::string mFormatName;
+};
+
+};
 
 namespace AsteriskSCF
 {
@@ -23,14 +57,14 @@ namespace AsteriskSCF
 namespace MediaOperationsCore
 {
 
-using namespace AsteriskSCF::Media::V1;
-using namespace AsteriskSCF::SessionCommunications::V1;
-
 class InbandTelephonyEventOperation : public TranslatorOperation
 {
     class InbandTelephonyEventSource : public TelephonyEventSource
     {
     public:
+        InbandTelephonyEventSource(const Logger& logger)
+            : mLogger(logger) { }
+
         void addSinks_async(const AMD_TelephonyEventSource_addSinksPtr& cb,
                 const TelephonyEventSinkSeq& sinks,
                 const Ice::Current&)
@@ -54,25 +88,47 @@ class InbandTelephonyEventOperation : public TranslatorOperation
             }
             cb->ice_response();
         }
-        TelephonyEventSinkSeq getSinks_async(const AMD_TelephonyEventSource_getSinksPtr& cb,
+
+        void getSinks_async(const AMD_TelephonyEventSource_getSinksPtr& cb,
                 const Ice::Current&)
         {
             cb->ice_response(mSinks);
         }
+
+        void distributeToSinks(const TelephonyEventPtr& event)
+        {
+            for (TelephonyEventSinkSeq::iterator iter = mSinks.begin(); iter != mSinks.end(); ++iter)
+            {
+                try
+                {
+                    (*iter)->write(event);
+                }
+                catch (const std::exception&)
+                {
+                    mLogger(Error) << "Exception caught attempting to write telephony event to sink.";
+                }
+            }
+        }
     private:
         TelephonyEventSinkSeq mSinks;
+        Logger mLogger;
     };
 
+    typedef IceUtil::Handle<InbandTelephonyEventSource> InbandTelephonyEventSourcePtr;
+
     class InbandTelephonyEventDetector : public Translator
     {
     public:
         InbandTelephonyEventDetector(const TranslatorSourcePtr source,
                 const FormatPtr& inputFormat,
                 const FormatPtr& outputFormat,
-                const Logger& logger)
+                const Logger& logger,
+                const MediaOperationReplicationContextPtr& replicationContext)
             : Translator(source, inputFormat, outputFormat, logger),
             //XXX We can work out the sample rate from the input format.
-            mDSP(new DSP())
+            mDSP(new DSP(logger)),
+            mTelephonySource(new InbandTelephonyEventSource(logger)),
+            mReplicationContext(replicationContext)
         {
             mDSP->setFeatures(DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT);
             mDSP->setDigitmode(DSP_DIGITMODE_DTMF);
@@ -99,8 +155,11 @@ class InbandTelephonyEventOperation : public TranslatorOperation
             {
                 //No event was processed. If we are in the midst of processing DTMF though,
                 //we need to send a continuation frame.
-                if (mProcessingDTMF)
+                if (mStateItem->processingDTMF)
                 {
+                    int duration = (int) (IceUtil::Time::now().toMilliSeconds() - mStateItem->eventBeginTime);
+                    ContinueDTMFEventPtr continueDTMF(new ContinueDTMFEvent(mStateItem->currentDTMF, duration));
+                    mTelephonySource->distributeToSinks(continueDTMF);
                 }
 
                 return inAudio;
@@ -108,11 +167,11 @@ class InbandTelephonyEventOperation : public TranslatorOperation
 
             //In all cases below, we will want to generate telephony
             //events.
-            BeginDTMFPtr DTMF;
-            BeginCNGPtr CNG;
-            BeginCEDPtr CED;
-            BeginV21Ptr v21;
-            if ((DTMF = BeginDTMFPtr::dynamicCast(detectedEvent)))
+            BeginDTMFEventPtr DTMF;
+            BeginCNGEventPtr CNG;
+            BeginCEDEventPtr CED;
+            BeginV21EventPtr v21;
+            if ((DTMF = BeginDTMFEventPtr::dynamicCast(detectedEvent)))
             {
                 //With DTMF we get told when DTMF has begun and when it has
                 //ended. We keep track of whether we're currently handling
@@ -120,58 +179,69 @@ class InbandTelephonyEventOperation : public TranslatorOperation
                 //begin event that we get back. If we are, then we need
                 //to generate an end event and unset the bool.
                 //
-                if (mProcessingDTMF)
+                if (mStateItem->processingDTMF)
                 {
                     //Create an EndDTMF event
-                    mProcessingDTMF = false;
+                    int duration = (int) (IceUtil::Time::now().toMilliSeconds() - mStateItem->eventBeginTime);
+                    EndDTMFEventPtr endDTMF(new EndDTMFEvent(mStateItem->currentDTMF, duration));
+                    mTelephonySource->distributeToSinks(endDTMF);
+                    mStateItem->processingDTMF = false;
                 }
                 else
                 {
-                    //Send on the BeginDTMF event
-                    mProcessingDTMF = true;
+                    forwardBeginEvent(DTMF, mStateItem->processingDTMF);
                 }
+                replicateState();
             }
-            else if ((CNG = BeginCNGPtr::dynamicCast(detectedEvent)))
+            else if ((CNG = BeginCNGEventPtr::dynamicCast(detectedEvent)))
             {
                 //We've picked up some CNG!
-                if (mProcessingCNG)
+                if (mStateItem->processingCNG)
                 {
                     //End that shizzle!
-                    mProcessingCNG = false;
+                    int duration = (int) (IceUtil::Time::now().toMilliSeconds() - mStateItem->eventBeginTime);
+                    EndCNGEventPtr endCNG(new EndCNGEvent(duration));
+                    mTelephonySource->distributeToSinks(endCNG);
+                    mStateItem->processingCNG = false;
                 }
                 else
                 {
-                    //Send the begin event
-                    mProcessingCNG = true;
+                    forwardBeginEvent(CNG, mStateItem->processingCNG);
                 }
+                replicateState();
             }
-            else if ((CED = BeginCEDPtr::dynamicCast(detectedEvent)))
+            else if ((CED = BeginCEDEventPtr::dynamicCast(detectedEvent)))
             {
                 //We've picked up some CED!
-                if (mProcessingCED)
+                if (mStateItem->processingCED)
                 {
                     //End it!
-                    mProcessingCED = false;
+                    int duration = (int) (IceUtil::Time::now().toMilliSeconds() - mStateItem->eventBeginTime);
+                    EndCNGEventPtr endCNG(new EndCNGEvent(duration));
+                    mTelephonySource->distributeToSinks(endCNG);
+                    mStateItem->processingCED = false;
                 }
                 else
                 {
-                    //Forward the begin!
-                    mProcessingCED = true;
+                    forwardBeginEvent(CED, mStateItem->processingCED);
                 }
+                replicateState();
             }
-            else if ((v21 = BeginV21Ptr::dynamicCast(detectedEvent)))
+            else if ((v21 = BeginV21EventPtr::dynamicCast(detectedEvent)))
             {
                 //We've picked up some V.21!
-                if (mProcessingV21)
+                if (mStateItem->processingV21)
                 {
-                    //STOP!!!
-                    mProcessingV21 = false;
+                    int duration = (int) (IceUtil::Time::now().toMilliSeconds() - mStateItem->eventBeginTime);
+                    EndCNGEventPtr endCNG(new EndCNGEvent(duration));
+                    mTelephonySource->distributeToSinks(endCNG);
+                    mStateItem->processingV21 = false;
                 }
                 else
                 {
-                    //Send it on!
-                    mProcessingV21 = true;
+                    forwardBeginEvent(v21, mStateItem->processingV21);
                 }
+                replicateState();
             }
             else
             {
@@ -180,19 +250,39 @@ class InbandTelephonyEventOperation : public TranslatorOperation
 
             //No matter what sort of telephony event was detected, we'll want to send the
             //audio on to the next set of stuff
-            return inFrame;
+            return inAudio;
         };
     private:
-        bool mProcessingDTMF;
-        bool mProcessingCNG;
-        bool mProcessingCED;
-        bool mProcessingV21;
+        void forwardBeginEvent(const TelephonyEventPtr& event, bool &eventBegin)
+        {
+            mStateItem->eventBeginTime = IceUtil::Time::now().toMilliSeconds();
+            mTelephonySource->distributeToSinks(event);
+            eventBegin = true;
+        }
+
+        void replicateState()
+        {
+            if (mReplicationContext->isReplicating())
+            {
+                MediaOperationStateItemSeq items;
+                items.push_back(mStateItem);
+                mReplicationContext->getReplicator()->setState(items);
+            }
+        }
+
+        DSPPtr mDSP;
+        InbandTelephonyEventSourcePtr mTelephonySource;
+        InbandTelephonyEventOperationStateItemPtr mStateItem;
+        MediaOperationReplicationContextPtr mReplicationContext;
     };
+
 public:
     InbandTelephonyEventOperation(
            const Ice::ObjectAdapterPtr& adapter,
            const Logger& logger,
-           const Ice::Identity& id,
+           const FormatPtr& sourceFormat,
+           const FormatPtr& sinkFormat,
+           const Ice::Identity& factoryId,
            const MediaOperationReplicationContextPtr& replicationContext)
        : TranslatorOperation(
                adapter,
@@ -203,9 +293,12 @@ public:
                replicationContext,
                new InbandTelephonyEventOperationStateItem)
     {
+        mSink->setTranslator(new InbandTelephonyEventDetector(mSource, sinkFormat, sourceFormat, mLogger, replicationContext));
     }
 };
 
+typedef IceUtil::Handle<InbandTelephonyEventOperation> InbandTelephonyEventOperationPtr;
+
 InbandTelephonyEventOperationFactory::InbandTelephonyEventOperationFactory(
         const Ice::ObjectAdapterPtr& adapter,
         const Logger& logger,
@@ -216,7 +309,7 @@ InbandTelephonyEventOperationFactory::InbandTelephonyEventOperationFactory(
             replicationContext,
             name)
 {
-    mLocatorParams->category = MediaOperationDiscoveryFactory;
+    mLocatorParams->category = MediaOperationDiscoveryCategory;
     //XXX This should be some named constant
     mLocatorParams->service = "InbandTelephonyEvents";
 };
@@ -231,14 +324,50 @@ MediaOperationPrx InbandTelephonyEventOperationFactory::createMediaOperation(
         throw UnsupportedMediaFormatException();
     }
 
-    InbandTelephonyEventOperationPtr operation(
-            new InbandTelephonyEventOperation(
+    FormatSeq sourceFormats = source->getFormats();
+    FormatSeq sinkFormats = sink->getFormats();
+
+    FormatSeq::iterator inSlin8 = std::find_if(sourceFormats.begin(),
+            sourceFormats.end(), FormatNameEqual(SignedLinear8Name));
+
+    FormatSeq::iterator outSlin8 = std::find_if(sinkFormats.begin(),
+            sinkFormats.end(), FormatNameEqual(SignedLinear8Name));
+
+    InbandTelephonyEventOperationPtr operation;
+    MediaOperationPrx proxy;
+    if (inSlin8 != sourceFormats.end() && outSlin8 != sinkFormats.end())
+    {
+        operation = new InbandTelephonyEventOperation(
                 mAdapter,
                 mLogger,
+                *outSlin8,
+                *inSlin8,
                 getProxy()->ice_getIdentity(),
-                mReplicationContext));
+                mReplicationContext);
+        proxy = MediaOperationPrx::uncheckedCast(mAdapter->addWithUUID(operation));
+        return proxy;
+    }
+
+    FormatSeq::iterator inSlin16 = std::find_if(sourceFormats.begin(),
+            sourceFormats.end(), FormatNameEqual(SignedLinear16Name));
+
+    FormatSeq::iterator outSlin16 = std::find_if(sinkFormats.begin(),
+            sinkFormats.end(), FormatNameEqual(SignedLinear16Name));
+
+    if (inSlin16 == sourceFormats.end() || outSlin16 == sinkFormats.end())
+    {
+        throw UnsupportedMediaFormatException();
+    }
+
+    operation = new InbandTelephonyEventOperation(
+            mAdapter,
+            mLogger,
+            *outSlin16,
+            *inSlin16,
+            getProxy()->ice_getIdentity(),
+            mReplicationContext);
 
-    MediaOperationPrx proxy = MediaOperationPrx::uncheckedCast(mAdapter->addWithUUID(operation));
+    proxy = MediaOperationPrx::uncheckedCast(mAdapter->addWithUUID(operation));
     return proxy;
 }
 
diff --git a/src/InbandTelephonyEvents.h b/src/InbandTelephonyEvents.h
index 9db6d2e..e76e47d 100644
--- a/src/InbandTelephonyEvents.h
+++ b/src/InbandTelephonyEvents.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include "MediaOperationFactoryImpl.h"
+
 #include <AsteriskSCF/Media/MediaOperationIf.h>
 #include <AsteriskSCF/Media/MediaIf.h>
 
@@ -25,12 +27,12 @@ namespace AsteriskSCF
 namespace MediaOperationsCore
 {
 
-class InbandTelephonyEventOperationFactory : public AsteriskSCF::Media::V1::MediaOperationFactoryImpl
+class InbandTelephonyEventOperationFactory : public MediaOperationFactoryImpl
 {
 public:
     InbandTelephonyEventOperationFactory(
         const Ice::ObjectAdapterPtr& adapter,
-        const Logger& logger,
+        const AsteriskSCF::System::Logging::Logger& logger,
         const MediaOperationReplicationContextPtr& replicationContext,
         const std::string& name);
 

commit 6acdad7fb807677349da1e991456218b07d0cd7f
Author: Mark Michelson <mmichelson at digium.com>
Date:   Tue Oct 11 18:33:10 2011 -0500

    Add initial telephony source implementation.

diff --git a/src/InbandTelephonyEvents.cpp b/src/InbandTelephonyEvents.cpp
index 1c485fc..d878d25 100644
--- a/src/InbandTelephonyEvents.cpp
+++ b/src/InbandTelephonyEvents.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <InbandTelephonyEvents.h>
+#include <AsteriskSCF/Helpers/ProxyHelper.h>
 
 namespace AsteriskSCF
 {
@@ -23,9 +24,45 @@ namespace MediaOperationsCore
 {
 
 using namespace AsteriskSCF::Media::V1;
+using namespace AsteriskSCF::SessionCommunications::V1;
 
 class InbandTelephonyEventOperation : public TranslatorOperation
 {
+    class InbandTelephonyEventSource : public TelephonyEventSource
+    {
+    public:
+        void addSinks_async(const AMD_TelephonyEventSource_addSinksPtr& cb,
+                const TelephonyEventSinkSeq& sinks,
+                const Ice::Current&)
+        {
+            for (TelephonyEventSinkSeq::const_iterator i = sinks.begin(); i != sinks.end(); ++i)
+            {
+                if (std::find_if(mSinks.begin(), mSinks.end(), IdentityComparePredicate<TelephonyEventSinkPrx>(*i)) == mSinks.end())
+                {
+                    mSinks.push_back(*i);
+                }
+            }
+            cb->ice_response();
+        }
+        void removeSinks_async(const AMD_TelephonyEventSource_removeSinksPtr& cb,
+                const TelephonyEventSinkSeq& sinks,
+                const Ice::Current&)
+        {
+            for (TelephonyEventSinkSeq::const_iterator i = sinks.begin(); i != sinks.end(); ++i)
+            {
+                mSinks.erase(remove_if(mSinks.begin(), mSinks.end(), IdentityComparePredicate<TelephonyEventSinkPrx>(*i)), mSinks.end());
+            }
+            cb->ice_response();
+        }
+        TelephonyEventSinkSeq getSinks_async(const AMD_TelephonyEventSource_getSinksPtr& cb,
+                const Ice::Current&)
+        {
+            cb->ice_response(mSinks);
+        }
+    private:
+        TelephonyEventSinkSeq mSinks;
+    };
+
     class InbandTelephonyEventDetector : public Translator
     {
     public:
@@ -60,7 +97,12 @@ class InbandTelephonyEventOperation : public TranslatorOperation
 
             if (!detectedEvent)
             {
-                //No event detected. No biggie. Just pass the audio on unchanged.
+                //No event was processed. If we are in the midst of processing DTMF though,
+                //we need to send a continuation frame.
+                if (mProcessingDTMF)
+                {
+                }
+
                 return inAudio;
             }
 
@@ -133,11 +175,7 @@ class InbandTelephonyEventOperation : public TranslatorOperation
             }
             else
             {
-                //No event was processed. If we are in the midst of processing DTMF though,
-                //we need to send a continuation frame.
-                if (mProcessingDTMF)
-                {
-                }
+                //Unknown event detected...weird.
             }
 
             //No matter what sort of telephony event was detected, we'll want to send the

commit 5bbcf89dfb410a7a0b77d4c622173494c174e1d9
Author: Mark Michelson <mmichelson at digium.com>
Date:   Thu Oct 6 18:36:53 2011 -0500

    Get some skeleton in place for processing the telephony events returned by the DSP.

diff --git a/src/InbandTelephonyEvents.cpp b/src/InbandTelephonyEvents.cpp
index ca87c69..1c485fc 100644
--- a/src/InbandTelephonyEvents.cpp
+++ b/src/InbandTelephonyEvents.cpp
@@ -28,6 +28,7 @@ class InbandTelephonyEventOperation : public TranslatorOperation
 {
     class InbandTelephonyEventDetector : public Translator
     {
+    public:
         InbandTelephonyEventDetector(const TranslatorSourcePtr source,
                 const FormatPtr& inputFormat,
                 const FormatPtr& outputFormat,
@@ -36,6 +37,8 @@ class InbandTelephonyEventOperation : public TranslatorOperation
             //XXX We can work out the sample rate from the input format.
             mDSP(new DSP())
         {
+            mDSP->setFeatures(DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_FAX_DETECT);
+            mDSP->setDigitmode(DSP_DIGITMODE_DTMF);
         }
 
         FramePtr translate(const FramePtr inFrame)
@@ -64,29 +67,88 @@ class InbandTelephonyEventOperation : public TranslatorOperation
             //In all cases below, we will want to generate telephony
             //events.
             BeginDTMFPtr DTMF;
+            BeginCNGPtr CNG;
+            BeginCEDPtr CED;
+            BeginV21Ptr v21;
             if ((DTMF = BeginDTMFPtr::dynamicCast(detectedEvent)))
             {
-                //We've picked up some DTMF!
+                //With DTMF we get told when DTMF has begun and when it has
+                //ended. We keep track of whether we're currently handling
+                //a DTMF. If we're not, then we can just forward on the 
+                //begin event that we get back. If we are, then we need
+                //to generate an end event and unset the bool.
+                //
+                if (mProcessingDTMF)
+                {
+                    //Create an EndDTMF event
+                    mProcessingDTMF = false;
+                }
+                else
+                {
+                    //Send on the BeginDTMF event
+                    mProcessingDTMF = true;
+                }
             }
-
-            BeginCNGPtr CNG;
-            if ((CNG = BeginCNGPtr::dynamicCast(detectedEvent)))
+            else if ((CNG = BeginCNGPtr::dynamicCast(detectedEvent)))
             {
                 //We've picked up some CNG!
+                if (mProcessingCNG)
+                {
+                    //End that shizzle!
+                    mProcessingCNG = false;
+                }
+                else
+                {
+                    //Send the begin event
+                    mProcessingCNG = true;
+                }
             }
-            
-            BeginCEDPtr CED;
-            if ((CED = BeginCEDPtr::dynamicCast(detectedEvent)))
+            else if ((CED = BeginCEDPtr::dynamicCast(detectedEvent)))
             {
                 //We've picked up some CED!
+                if (mProcessingCED)
+                {
+                    //End it!
+                    mProcessingCED = false;
+                }
+                else
+                {
+                    //Forward the begin!
+                    mProcessingCED = true;
+                }
             }
-
-            BeginV21Ptr v21;
-            if ((v21 = BeginV21Ptr::dynamicCast(detectedEvent)))
+            else if ((v21 = BeginV21Ptr::dynamicCast(detectedEvent)))
             {
                 //We've picked up some V.21!
+                if (mProcessingV21)
+                {
+                    //STOP!!!
+                    mProcessingV21 = false;
+                }
+                else
+                {
+                    //Send it on!
+                    mProcessingV21 = true;
+                }
             }
+            else
+            {
+                //No event was processed. If we are in the midst of processing DTMF though,
+                //we need to send a continuation frame.
+                if (mProcessingDTMF)
+                {
+                }
+            }
+
+            //No matter what sort of telephony event was detected, we'll want to send the
+            //audio on to the next set of stuff
+            return inFrame;
         };
+    private:
+        bool mProcessingDTMF;
+        bool mProcessingCNG;
+        bool mProcessingCED;
+        bool mProcessingV21;
     };
 public:
     InbandTelephonyEventOperation(

commit a14548fd1fcb491f9d9540cc61ba39765f197580
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Oct 3 17:03:42 2011 -0500

    Add some initial code for InbandTelephonyEvents.
    
    I realized after a bit that I can essentially treat this like a
    translator, and use its setup for me even though this doesn't actually
    translate anything.
    
    I need to figure out a way to get some TelephonyEvent sink into the
    "translator" here so that I can get the detected events to the
    appropriate places.

diff --git a/src/InbandTelephonyEvents.cpp b/src/InbandTelephonyEvents.cpp
new file mode 100644
index 0000000..ca87c69
--- /dev/null
+++ b/src/InbandTelephonyEvents.cpp
@@ -0,0 +1,146 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#include <InbandTelephonyEvents.h>
+
+namespace AsteriskSCF
+{
+
+namespace MediaOperationsCore
+{
+
+using namespace AsteriskSCF::Media::V1;
+
+class InbandTelephonyEventOperation : public TranslatorOperation
+{
+    class InbandTelephonyEventDetector : public Translator
+    {
+        InbandTelephonyEventDetector(const TranslatorSourcePtr source,
+                const FormatPtr& inputFormat,
+                const FormatPtr& outputFormat,
+                const Logger& logger)
+            : Translator(source, inputFormat, outputFormat, logger),
+            //XXX We can work out the sample rate from the input format.
+            mDSP(new DSP())
+        {
+        }
+
+        FramePtr translate(const FramePtr inFrame)
+        {
+            if (inFrame->mediaFormat->name != mInputFormat->name)
+            {
+                mLogger(Error) << "Format incorrect for detecting inband telephony events";
+                throw UnsupportedMediaFormatException();
+            }
+
+            AudioFramePtr inAudio = AudioFramePtr::dynamicCast(inFrame);
+            if (!inAudio)
+            {
+                mLogger(Error) << "Attempting to detect inband telephony events in a non-audio stream?";
+                throw UnsupportedMediaFormatException();
+            }
+
+            TelephonyEventPtr detectedEvent = mDSP->process(inAudio);
+
+            if (!detectedEvent)
+            {
+                //No event detected. No biggie. Just pass the audio on unchanged.
+                return inAudio;
+            }
+
+            //In all cases below, we will want to generate telephony
+            //events.
+            BeginDTMFPtr DTMF;
+            if ((DTMF = BeginDTMFPtr::dynamicCast(detectedEvent)))
+            {
+                //We've picked up some DTMF!
+            }
+
+            BeginCNGPtr CNG;
+            if ((CNG = BeginCNGPtr::dynamicCast(detectedEvent)))
+            {
+                //We've picked up some CNG!
+            }
+            
+            BeginCEDPtr CED;
+            if ((CED = BeginCEDPtr::dynamicCast(detectedEvent)))
+            {
+                //We've picked up some CED!
+            }
+
+            BeginV21Ptr v21;
+            if ((v21 = BeginV21Ptr::dynamicCast(detectedEvent)))
+            {
+                //We've picked up some V.21!
+            }
+        };
+    };
+public:
+    InbandTelephonyEventOperation(
+           const Ice::ObjectAdapterPtr& adapter,
+           const Logger& logger,
+           const Ice::Identity& id,
+           const MediaOperationReplicationContextPtr& replicationContext)
+       : TranslatorOperation(
+               adapter,
+               logger,
+               sourceFormat,
+               sinkFormat,
+               factoryId,
+               replicationContext,
+               new InbandTelephonyEventOperationStateItem)
+    {
+    }
+};
+
+InbandTelephonyEventOperationFactory::InbandTelephonyEventOperationFactory(
+        const Ice::ObjectAdapterPtr& adapter,
+        const Logger& logger,
+        const MediaOperationReplicationContextPtr& replicationContext,
+        const std::string& name)
+    : MediaOperationFactoryImpl(adapter,
+            logger,
+            replicationContext,
+            name)
+{
+    mLocatorParams->category = MediaOperationDiscoveryFactory;
+    //XXX This should be some named constant
+    mLocatorParams->service = "InbandTelephonyEvents";
+};
+
+MediaOperationPrx InbandTelephonyEventOperationFactory::createMediaOperation(
+            const StreamSourcePrx& source,
+            const StreamSinkPrx& sink,
+            const Ice::Current&)
+{
+    if (sink == 0 || source == 0)
+    {
+        throw UnsupportedMediaFormatException();
+    }
+
+    InbandTelephonyEventOperationPtr operation(
+            new InbandTelephonyEventOperation(
+                mAdapter,
+                mLogger,
+                getProxy()->ice_getIdentity(),
+                mReplicationContext));
+
+    MediaOperationPrx proxy = MediaOperationPrx::uncheckedCast(mAdapter->addWithUUID(operation));
+    return proxy;
+}
+
+} //end MediaOperationsCore
+} //end AsteriskSCF
diff --git a/src/InbandTelephonyEvents.h b/src/InbandTelephonyEvents.h
new file mode 100644
index 0000000..9db6d2e
--- /dev/null
+++ b/src/InbandTelephonyEvents.h
@@ -0,0 +1,44 @@
+/*
+ * Asterisk SCF -- An open-source communications framework.
+ *
+ * Copyright (C) 2011, Digium, Inc.
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk SCF project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE.txt file
+ * at the top of the source tree.
+ */
+
+#pragma once
+
+#include <AsteriskSCF/Media/MediaOperationIf.h>
+#include <AsteriskSCF/Media/MediaIf.h>
+
+namespace AsteriskSCF
+{
+
+namespace MediaOperationsCore
+{
+
+class InbandTelephonyEventOperationFactory : public AsteriskSCF::Media::V1::MediaOperationFactoryImpl
+{
+public:
+    InbandTelephonyEventOperationFactory(
+        const Ice::ObjectAdapterPtr& adapter,
+        const Logger& logger,
+        const MediaOperationReplicationContextPtr& replicationContext,
+        const std::string& name);
+
+    AsteriskSCF::Media::V1::MediaOperationPrx createMediaOperation(
+            const AsteriskSCF::Media::V1::StreamSourcePrx& source,
+            const AsteriskSCF::Media::V1::StreamSinkPrx& sink,
+            const Ice::Current&);
+};
+
+} // end MediaOperationsCore
+} // end AsteriskSCF

commit 73e9253e50bfce0439857ef388b1ea3f106ae5ad
Author: Mark Michelson <mmichelson at digium.com>
Date:   Mon Oct 3 15:02:33 2011 -0500

    This actually compiles at this point.
    
    The DTMF detection is a bit odd and needs to be documented properly.

diff --git a/src/DSP.cpp b/src/DSP.cpp
index 71567b5..fd0cc4a 100644
--- a/src/DSP.cpp
+++ b/src/DSP.cpp
@@ -241,7 +241,6 @@ static const float mf_tones[] = {
 };
 static const char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
 static const char bell_mf_positions[] = "1247C-358A--69*---0B----#";
-static int thresholds[THRESHOLD_MAX];
 
 static inline void goertzel_sample(goertzel_state_t *s, short sample)
 {
@@ -332,7 +331,7 @@ static inline int pair_there(float p1, float p2, float i1, float i2, float e)
  * of samples preceeding and following the block where tone was detected.
 */
 
-class DSPPriv
+class DSPPriv : public IceUtil::Shared
 {
 public:
     DSPPriv(Logger& logger, unsigned int sampleRate) :
@@ -1068,11 +1067,10 @@ public:
 
 TelephonyEventPtr DSP::process(AudioFramePtr af)
 {
-    int digit = 0, fax_digit = 0;
-    int x;
+    int digit = 0;
+    size_t x;
     short *shortdata;
     int len;
-    struct ast_frame *outf = NULL;
 
     if (!af) {
         //XXX Throw an exception
@@ -1094,17 +1092,31 @@ TelephonyEventPtr DSP::process(AudioFramePtr af)
     /* Initially we do not want to mute anything */
     mPriv->mMuteFragments = 0;
 
+    TelephonyEventPtr returnEvent = 0;
+
     if ((mPriv->mFeatures & DSP_FEATURE_FAX_DETECT)) {
         if ((mPriv->mFaxmode & DSP_FAXMODE_DETECT_CNG) && mPriv->toneDetect(&mPriv->mCNGToneState, shortdata, len)) {
-            fax_digit = 'f';
+            returnEvent = new BeginCNGEvent;
+            for (x = 0; x < mPriv->mMuteFragments; x++) {
+                memset(shortdata + mPriv->mMuteData[x].start, 0, sizeof(int16_t) * (mPriv->mMuteData[x].end - mPriv->mMuteData[x].start));
+            }
+            return returnEvent;
         }
 
         if ((mPriv->mFaxmode & DSP_FAXMODE_DETECT_CED) && mPriv->toneDetect(&mPriv->mCEDToneState, shortdata, len)) {
-            fax_digit = 'e';
+            returnEvent = new BeginCEDEvent;
+            for (x = 0; x < mPriv->mMuteFragments; x++) {
+                memset(shortdata + mPriv->mMuteData[x].start, 0, sizeof(int16_t) * (mPriv->mMuteData[x].end - mPriv->mMuteData[x].start));
+            }
+            return returnEvent;
         }
 
-        if ((mPriv->mFaxmode & DSP_FAXMODE_DETECT_V21) && mPriv->v21_detect(&mPriv->mV21State, shortdata, len)) {
-            fax_digit = 'g';
+        if ((mPriv->mFaxmode & DSP_FAXMODE_DETECT_V21) && mPriv->v21Detect(&mPriv->mV21State, shortdata, len)) {
+            returnEvent = new BeginV21Event;
+            for (x = 0; x < mPriv->mMuteFragments; x++) {
+                memset(shortdata + mPriv->mMuteData[x].start, 0, sizeof(int16_t) * (mPriv->mMuteData[x].end - mPriv->mMuteData[x].start));
+            }
+            return returnEvent;
         }
     }
 
@@ -1115,67 +1127,37 @@ TelephonyEventPtr DSP::process(AudioFramePtr af)
             digit = mPriv->DTMFDetect(&mPriv->mDigitState, shortdata, len, (mPriv->mDigitmode & DSP_DIGITMODE_NOQUELCH) == 0, (mPriv->mDigitmode & DSP_DIGITMODE_RELAXDTMF));
 
         if (mPriv->mDigitState.current_digits) {
-            int event = 0, event_len = 0;
             char event_digit = 0;
 
             if (!mPriv->mDTMFBegan) {
                 /* We have not reported DTMF_BEGIN for anything yet */
 
                 if (mPriv->mFeatures & DSP_FEATURE_DIGIT_DETECT) {
-                    event = AST_FRAME_DTMF_BEGIN;
                     event_digit = mPriv->mDigitState.digits[0];
                 }
                 mPriv->mDTMFBegan = 1;
+                returnEvent = new BeginDTMFEvent(event_digit);
 
             } else if (mPriv->mDigitState.current_digits > 1 || digit != mPriv->mDigitState.digits[0]) {
                 /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
                 if (mPriv->mFeatures & DSP_FEATURE_DIGIT_DETECT) {
-                    event = AST_FRAME_DTMF_END;
                     event_digit = mPriv->mDigitState.digits[0];
-                    event_len = mPriv->mDigitState.digitlen[0] * 1000 / mPriv->mSampleRate;
                 }
                 memmove(&mPriv->mDigitState.digits[0], &mPriv->mDigitState.digits[1], mPriv->mDigitState.current_digits);
                 memmove(&mPriv->mDigitState.digitlen[0], &mPriv->mDigitState.digitlen[1], mPriv->mDigitState.current_digits * sizeof(mPriv->mDigitState.digitlen[0]));
                 mPriv->mDigitState.current_digits--;
                 mPriv->mDTMFBegan = 0;
-            }
-
-            if (event) {
-                memset(&mPriv->f, 0, sizeof(mPriv->f));
-                mPriv->f.frametype = event;
-                mPriv->f.subclass.integer = event_digit;
-                mPriv->f.len = event_len;
-                outf = &mPriv->f;
-                goto done;
+                returnEvent = new BeginDTMFEvent(event_digit);
             }
         }
     }
 
-    if (fax_digit) {
-        /* Fax was detected - digit is either 'f' or 'e' */
-
-        memset(&mPriv->f, 0, sizeof(mPriv->f));
-        mPriv->f.frametype = AST_FRAME_DTMF;
-        mPriv->f.subclass.integer = fax_digit;
-        outf = &mPriv->f;
-        goto done;
-    }
-
-done:
     /* Mute fragment of the frame */
     for (x = 0; x < mPriv->mMuteFragments; x++) {
         memset(shortdata + mPriv->mMuteData[x].start, 0, sizeof(int16_t) * (mPriv->mMuteData[x].end - mPriv->mMuteData[x].start));
     }
 
-    if (outf) {
-        if (chan) {
-            ast_queue_frame(chan, af);
-        }
-        ast_frfree(af);
-        return ast_frisolate(outf);
-    } else {
-        return af;
-    }
+    return returnEvent;
 }
 
 unsigned int DSP::getSampleRate()

commit 5148184d6f4c620e22eb2fd30c51d109cd1f91a1
Author: Mark Michelson <mmichelson at digium.com>
Date:   Fri Sep 30 17:47:55 2011 -0500

    Fix up some compiler errors.
    
    Biggest thing left is DSP::process. It's going to suck a bit.

diff --git a/src/DSP.cpp b/src/DSP.cpp
index 86a53d3..71567b5 100644
--- a/src/DSP.cpp
+++ b/src/DSP.cpp
@@ -564,7 +564,7 @@ public:
     
             for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
                 /* signed 32 bit int should be enough to suqare any possible signed 16 bit value */
-                s->energy += (int32_t) *ptr * (int32_t) *ptr;
+                s->energy += (float) ((int32_t) *ptr * (int32_t) *ptr);
     
                 goertzel_sample(&s->tone, *ptr);
             }
@@ -579,8 +579,8 @@ public:
             tone_energy = goertzel_result(&s->tone);
     
             /* Scale to make comparable */
-            tone_energy *= 2.0;
-            s->energy *= s->block_size;
+            tone_energy *= 2.0f;
+            s->energy *= (float) s->block_size;
     
             mLogger(Trace) << "tone " << s->freq << ", Ew=" << tone_energy << ", Et=" << s->energy << ", s/n=" << tone_energy / (s->energy - tone_energy);
             hit = 0;
@@ -666,7 +666,7 @@ public:
     
             for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
                 /* signed 32 bit int should be enough to suqare any possible signed 16 bit value */
... 6147 lines suppressed ...


-- 
asterisk-scf/release/media_operations_core.git



More information about the asterisk-scf-commits mailing list