[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 3 17:03:07 CDT 2011


branch "inband-events" has been updated
       via  a14548fd1fcb491f9d9540cc61ba39765f197580 (commit)
       via  73e9253e50bfce0439857ef388b1ea3f106ae5ad (commit)
      from  5148184d6f4c620e22eb2fd30c51d109cd1f91a1 (commit)

Summary of changes:
 src/DSP.cpp                             |   66 +++++---------
 src/InbandTelephonyEvents.cpp           |  146 +++++++++++++++++++++++++++++++
 src/{g722.h => InbandTelephonyEvents.h} |   28 +++---
 3 files changed, 184 insertions(+), 56 deletions(-)
 create mode 100644 src/InbandTelephonyEvents.cpp
 copy src/{g722.h => InbandTelephonyEvents.h} (52%)


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

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


-- 
asterisk-scf/integration/media_operations_core.git



More information about the asterisk-scf-commits mailing list