[asterisk-scf-commits] asterisk-scf/integration/media_operations_core.git branch "inband-events" updated.

Commits to the Asterisk SCF project code repositories asterisk-scf-commits at lists.digium.com
Mon Oct 17 16:43:23 CDT 2011


branch "inband-events" has been updated
       via  cc2e607e6edafffc17fc05e0daf63ba68f635d2f (commit)
      from  6acdad7fb807677349da1e991456218b07d0cd7f (commit)

Summary of changes:
 .../MediaOperationsCore/MediaOperationsCoreIf.ice  |   13 ++
 src/CMakeLists.txt                                 |    2 +
 src/DSP.cpp                                        |    4 +-
 src/DSP.h                                          |    2 +-
 src/InbandTelephonyEvents.cpp                      |  217 ++++++++++++++++----
 src/InbandTelephonyEvents.h                        |    6 +-
 6 files changed, 195 insertions(+), 49 deletions(-)


- Log -----------------------------------------------------------------
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);
 

-----------------------------------------------------------------------


-- 
asterisk-scf/integration/media_operations_core.git



More information about the asterisk-scf-commits mailing list