[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