[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