--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sipvoipprovider/src/svpaudioutility.cpp Wed Sep 01 12:29:57 2010 +0100
@@ -0,0 +1,656 @@
+/*
+* Copyright (c) 2006-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Provides static utility functions for SVP
+*
+*/
+
+
+#include <mceaudiostream.h>
+#include <mcertpsource.h>
+#include <mceaudiocodec.h>
+#include <mcespeakersink.h>
+#include <mcemicsource.h>
+#include <AudioPreference.h>
+#include "svpaudioutility.h"
+#include "svplogger.h"
+#include "svpconsts.h"
+#include "svpsessionbase.h"
+#include "svpemergencysession.h"
+#include "svpholdcontext.h"
+#include "svpholdcontroller.h"
+
+// LOCAL CONSTANTS
+// Constants for VoIP uplink audio preferences, renamed for better
+// readability and to clarify between IB/OB DTMF's.
+// See <audiopreference.h> for more information.
+// Inband signalling uplink preference (i.e inband DTMF)
+const TUint KSVPAudioPrefUplinkIbDtmf = KAudioPrefVoipAudioUplinkNonSignal;
+// Outband signalling uplink preference (i.e outband DTMF)
+const TUint KSVPAudioPrefUplinkOobDtmf = KAudioPrefVoipAudioUplink;
+
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::IsDownlinkStream
+// ---------------------------------------------------------------------------
+//
+TBool SVPAudioUtility::IsDownlinkStream( CMceAudioStream& aStream )
+ {
+ SVPDEBUG2( "SVPAudioUtility::IsDownlinkStream source: 0x%x", aStream.Source() );
+
+ if ( aStream.Source() && KMceRTPSource == aStream.Source()->Type() )
+ {
+ SVPDEBUG1( "SVPAudioUtility::IsDownlinkStream RTP SOURCE => DOWNLINK" );
+ return ETrue;
+ }
+ else
+ {
+ SVPDEBUG1( "SVPAudioUtility::IsDownlinkStream EFalse" );
+
+ return EFalse;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::SetPriorityCodecValuesL
+// ---------------------------------------------------------------------------
+//
+TBool SVPAudioUtility::SetPriorityCodecValuesL(
+ CMceAudioStream& aAudioInStream,
+ CMceAudioStream& aAudioOutStream )
+ {
+ SVPDEBUG1("SVPAudioUtility::SetPriorityCodecValuesL In");
+
+ // set MMF codec priorities for all codecs in both streams
+ const TInt inCodecCount = aAudioInStream.Codecs().Count();
+ SVPDEBUG2(
+ "SVPAudioUtility::SetPriorityCodecValuesL codeccount IN: %d",
+ inCodecCount )
+
+ const TInt outCodecCount = aAudioOutStream.Codecs().Count();
+ SVPDEBUG2(
+ "SVPAudioUtility::SetPriorityCodecValuesL codeccount OUT: %d",
+ outCodecCount )
+
+ const TBool inDtmf = SVPAudioUtility::SetDtmfPriorityL( aAudioInStream );
+ const TBool outDtmf = SVPAudioUtility::SetDtmfPriorityL( aAudioOutStream );
+
+ // inDtmf and outDtmf _must_ match. Either inband (both EFalse) or outband
+ // (both ETrue).
+ if ( inDtmf != outDtmf )
+ {
+ SVPDEBUG1("SVPAudioUtility::SetPriorityCodecValuesL KErrNotFound");
+ User::Leave( KErrNotFound );
+ }
+
+ SVPDEBUG1( "SVPAudioUtility::SetPriorityCodecValuesL set IN priorities" );
+
+ SetAudioCodecPrioritiesL( aAudioInStream, KAudioPrefVoipAudioDownlink );
+
+ // Check which version of DTMF's are we using, inband or outband.
+ TBool outband( EFalse );
+ TUint uplinkPreference = KSVPAudioPrefUplinkIbDtmf;
+ if ( inDtmf && outDtmf )
+ {
+ SVPDEBUG1(
+ "SVPAudioUtility::SetPriorityCodecValuesL change to OOB DTMF" );
+
+ uplinkPreference = KSVPAudioPrefUplinkOobDtmf;
+ outband = ETrue;
+ }
+ // else inband used.
+
+ SVPDEBUG1( "SVPAudioUtility::SetPriorityCodecValuesL set OUT priorities" );
+
+ SetAudioCodecPrioritiesL( aAudioOutStream, uplinkPreference );
+
+ SVPDEBUG1( "SVPAudioUtility::SetPriorityCodecValuesL Out" );
+
+ return outband;
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::SetDtmfPriorityL
+// ---------------------------------------------------------------------------
+//
+TBool SVPAudioUtility::SetDtmfPriorityL( CMceAudioStream& aAudioStream )
+ {
+ SVPDEBUG1( "SVPAudioUtility::SetDtmfPriorityL In" );
+
+ const RPointerArray<CMceAudioCodec>& codecs = aAudioStream.Codecs();
+ TInt codCount( codecs.Count() );
+
+ // loop through codecs in in stream
+ while ( codCount )
+ {
+ codCount--;
+
+ SVPDEBUG2( "SVPAudioUtility::SetDtmfPriorityL, round: %d", codCount );
+
+ // Check if codec is DTMF, note the return values of CompareF
+ if( !codecs[ codCount ]->SdpName().CompareF( KTELEVENT ) )
+ {
+ SVPDEBUG1( "SVPAudioUtility::SetDtmfPriorityL ETrue" );
+
+ SVPDEBUG2( "SVPAudioUtility::SetDtmfPriorityL curr.prio: %d",
+ codecs[codCount]->MMFPriority() )
+ SVPDEBUG2( "SVPAudioUtility::SetDtmfPriorityL curr.pref: 0x%x",
+ codecs[codCount]->MMFPriorityPreference() )
+
+ // Set the priorities.
+ codecs[ codCount ]->SetMMFPriorityL( KAudioPriorityDTMFString );
+ codecs[ codCount ]->SetMMFPriorityPreferenceL( KAudioDTMFString );
+ return ETrue;
+ }
+ }
+
+ SVPDEBUG1( "SVPAudioUtility::SetDtmfPriorityL EFalse" );
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::SetAudioCodecPrioritiesL
+// ---------------------------------------------------------------------------
+//
+void SVPAudioUtility::SetAudioCodecPrioritiesL(
+ CMceAudioStream& aAudioStream,
+ TUint aAudioPref )
+ {
+ SVPDEBUG2( "SVPAudioUtility::SetAudioCodecPrioritiesL aAudioPref: 0x%x",
+ aAudioPref );
+
+ const RPointerArray<CMceAudioCodec>& codecs = aAudioStream.Codecs();
+ TInt codCount( codecs.Count() );
+
+ // loop through codecs in in stream
+ while ( codCount )
+ {
+ codCount--;
+
+ SVPDEBUG2( "SVPAudioUtility::SetAudioCodecPrioritiesL, round: %d",
+ codCount );
+
+ // Handle only real audio codecs.
+ if( codecs[ codCount ]->SdpName().CompareF( KTELEVENT ) )
+ {
+ SVPDEBUG2( "SVPAudioUtility::SetAudioCodecPrioritiesL curr.prio: %d",
+ codecs[codCount]->MMFPriority() )
+ SVPDEBUG2( "SVPAudioUtility::SetAudioCodecPrioritiesL curr.pref: 0x%x",
+ codecs[codCount]->MMFPriorityPreference() )
+
+ // Priority is always the same for VoIP.
+ codecs[ codCount ]->SetMMFPriorityL( KAudioPriorityPhoneCall );
+ codecs[ codCount ]->SetMMFPriorityPreferenceL( aAudioPref );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::SetAudioCodecPrioritiesL
+// ---------------------------------------------------------------------------
+//
+void SVPAudioUtility::SetAudioStreamPrioritiesL(
+ CMceMediaStream& aMediaStream,
+ CMceMediaStream& aBoundStream )
+ {
+ SVPDEBUG1( "SVPAudioUtility::SetAudioStreamPrioritiesL In" );
+
+ if ( KMceAudio != aMediaStream.Type() ||
+ KMceAudio != aBoundStream.Type() )
+ {
+ SVPDEBUG1( "SVPAudioUtility::SetAudioStreamPrioritiesL KErrArgument" );
+ SVPDEBUG2( "SVPAudioUtility::SetAudioStreamPrioritiesL media.Type: %u",
+ aMediaStream.Type() );
+ SVPDEBUG2( "SVPAudioUtility::SetAudioStreamPrioritiesL bound.Type: %u",
+ aBoundStream.Type() );
+
+ User::Leave( KErrArgument );
+ }
+ // else stream types are OK, thus we proceed.
+
+ // Set the codec MMF priorities here, first get the audiostreams.
+ CMceAudioStream& stream = static_cast<CMceAudioStream&>( aMediaStream );
+ CMceAudioStream& bound = static_cast<CMceAudioStream&>( aBoundStream );
+
+ if ( SVPAudioUtility::IsDownlinkStream( stream ) )
+ {
+ SVPAudioUtility::SetPriorityCodecValuesL( stream, bound );
+ }
+ else
+ {
+ SVPAudioUtility::SetPriorityCodecValuesL( bound, stream );
+ }
+
+ SVPDEBUG1( "SVPAudioUtility::SetAudioStreamPrioritiesL Out" );
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::EnableSpeakerSinkL
+// ---------------------------------------------------------------------------
+//
+void SVPAudioUtility::EnableSpeakerSinkL(
+ const RPointerArray< CMceMediaSink >& aSink )
+ {
+ TInt snkCount( aSink.Count() );
+ while ( snkCount )
+ {
+ snkCount--;
+ if ( KMceSpeakerSink == aSink[ snkCount ]->Type() &&
+ !aSink[ snkCount ]->IsEnabled() )
+ {
+ SVPDEBUG1( "SVPAudioUtility::EnableSpeakerSinkL Speaker found" );
+
+ aSink[ snkCount ]->EnableL();
+
+ SVPDEBUG1( "SVPAudioUtility::EnableSpeakerSinkL Speaker ENABLED" );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::DisableSpeakerSinkL
+// ---------------------------------------------------------------------------
+//
+void SVPAudioUtility::DisableSpeakerSinkL(
+ const RPointerArray< CMceMediaSink >& aSink )
+ {
+ TInt snkCount( aSink.Count() );
+ while ( snkCount )
+ {
+ snkCount--;
+ if ( KMceSpeakerSink == aSink[ snkCount ]->Type() &&
+ aSink[ snkCount ]->IsEnabled() )
+ {
+ SVPDEBUG1( "SVPAudioUtility::DisableSpeakerSinkL Speaker found" );
+
+ aSink[ snkCount ]->DisableL();
+
+ SVPDEBUG1( "SVPAudioUtility::DisableSpeakerSinkL Speaker DISABLED" );
+ }
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::EnableMicSourceL
+// ---------------------------------------------------------------------------
+//
+void SVPAudioUtility::EnableMicSourceL( CMceMediaSource& aMicSource )
+ {
+ if ( KMceMicSource == aMicSource.Type() && !aMicSource.IsEnabled() )
+ {
+ SVPDEBUG1("SVPAudioUtility::EnableMicSourceL Mic found");
+
+ aMicSource.EnableL();
+
+ SVPDEBUG1("SVPAudioUtility::EnableMicSourceL Mic ENABLED");
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::DisableMicSourceL
+// ---------------------------------------------------------------------------
+//
+void SVPAudioUtility::DisableMicSourceL( CMceMediaSource& aMicSource )
+ {
+ if ( KMceMicSource == aMicSource.Type() && aMicSource.IsEnabled() )
+ {
+ SVPDEBUG1( "SVPAudioUtility::DisableMicSourceL Mic found" );
+
+ aMicSource.DisableL();
+
+ SVPDEBUG1( "SVPAudioUtility::DisableMicSourceL Mic DISABLED" );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::EnableSpeakerSinksL
+// ---------------------------------------------------------------------------
+//
+void SVPAudioUtility::EnableSpeakerSinksL(
+ const RPointerArray< CMceMediaStream >& aStreams )
+ {
+ SVPDEBUG1("SVPAudioUtility::EnableSpeakerSinksL In");
+
+ TInt index( aStreams.Count() );
+ while( index-- )
+ {
+ if ( KMceAudio == aStreams[ index ]->Type() )
+ {
+ EnableSpeakerSinkL( aStreams[ index ]->Sinks() );
+ }
+
+ if ( KMceAudio == aStreams[ index ]->BoundStreamL().Type() )
+ {
+ EnableSpeakerSinkL( aStreams[ index ]->BoundStreamL().Sinks() );
+ }
+ }
+
+ SVPDEBUG1("SVPAudioUtility::EnableSpeakerSinksL Out");
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::DisableMicSourceL
+// ---------------------------------------------------------------------------
+//
+void SVPAudioUtility::DisableMicSourceL( CMceMediaStream& aStream )
+ {
+ SVPDEBUG1("SVPAudioUtility::DisableMicSourceL CMceMediaStream In");
+
+ CMceMediaSource* source = NULL;
+ source = aStream.Source();
+ if ( source )
+ {
+ SVPDEBUG1("SVPAudioUtility::DisableMicSourceL aStream");
+
+ DisableMicSourceL( *source );
+ }
+
+ if ( aStream.BoundStream() )
+ {
+ source = aStream.BoundStreamL().Source();
+ if ( source )
+ {
+ SVPDEBUG1("SVPAudioUtility::DisableMicSourceL BoundStream");
+
+ DisableMicSourceL( *source );
+ }
+ }
+
+ SVPDEBUG1("SVPAudioUtility::DisableMicSourceL CMceMediaStream Out");
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::FindCodec
+// ---------------------------------------------------------------------------
+//
+CMceAudioCodec* SVPAudioUtility::FindCodec( CMceAudioStream& aAudiostream,
+ const TDesC8& aCodecname )
+ {
+ SVPDEBUG1("SVPAudioUtility::FindCodec In");
+
+ const RPointerArray<CMceAudioCodec>& codecs = aAudiostream.Codecs();
+ TInt codecCount = codecs.Count();
+ while ( codecCount )
+ {
+ codecCount--;
+ if ( !codecs[codecCount]->SdpName().CompareF( aCodecname ) )
+ {
+ SVPDEBUG1("SVPAudioUtility::SVPAudioUtility Codec found");
+
+ return codecs[codecCount];
+ }
+ }
+
+ SVPDEBUG1("SVPAudioUtility::FindCodec Out NULL");
+ return NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::RemoveCodecL
+// ---------------------------------------------------------------------------
+//
+void SVPAudioUtility::RemoveCodecL( CMceAudioStream& aAudiostream,
+ const TDesC8& aCodecname )
+ {
+ SVPDEBUG1("SVPAudioUtility::RemoveCodecL In");
+
+ CMceAudioCodec* codec = SVPAudioUtility::FindCodec( aAudiostream,
+ aCodecname );
+
+ while ( codec )
+ {
+ SVPDEBUG1("SVPAudioUtility::RemoveCodecL Removing");
+
+ aAudiostream.RemoveCodecL( *codec );
+ codec = SVPAudioUtility::FindCodec( aAudiostream, aCodecname );
+ }
+
+ SVPDEBUG1("SVPAudioUtility::RemoveCodecL Out");
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::MmfPriorityUpdateNeededL
+// ---------------------------------------------------------------------------
+//
+TBool SVPAudioUtility::MmfPriorityUpdateNeededL(
+ const RPointerArray<CMceMediaStream>& aStreams )
+ {
+ SVPDEBUG1( "SVPAudioUtility::MmfPriorityUpdateNeededL In" )
+
+ // We need to check if DTMF codec is found and then check uplink stream
+ // MMF priorities.
+ // 1) If DTMF codec is found and uplink stream codecs have preference
+ // KSVPAudioPrefAudioUplinkOobDtmf no update is needed.
+ // 2) If DTMF codec is not found and uplink stream codecs have preference
+ // KSVPAudioPrefAudioUplinkIbDtmf no update is needed.
+ // 3) In other cases we need to do MMF preference/priority update.
+
+ // In order to do this we need to find uplink audio streams, check whether
+ // the stream has DTMF codec and then check which MMF preference the codec
+ // codec has. We may have multiple streams, but for simplicity sake if
+ // we find just one stream needing priority/preference update, we return
+ // ETrue as update need.
+ TInt strmCount( aStreams.Count() );
+
+ SVPDEBUG2( "SVPAudioUtility::MmfPriorityUpdateNeededL strmCount: %d",
+ strmCount )
+
+ while ( strmCount )
+ {
+ SVPDEBUG2( "SVPAudioUtility::MmfPriorityUpdateNeededL tb checked",
+ strmCount )
+
+ strmCount--;
+
+ // Basic assertions. Streams have to be KMceAudio and 'main' stream
+ // must have a bound stream.
+ __ASSERT_ALWAYS( KMceAudio == aStreams[strmCount]->Type(),
+ User::Leave( KErrArgument ) );
+ __ASSERT_ALWAYS( aStreams[strmCount]->BoundStream(),
+ User::Leave( KErrArgument ) );
+ __ASSERT_ALWAYS( KMceAudio == aStreams[strmCount]->BoundStreamL().Type(),
+ User::Leave( KErrArgument ) );
+
+ // Now that we are clear from the asserts, we can safely do the casts
+ // and find the uplink stream for priority/preference checking.
+ CMceAudioStream* audioStream =
+ static_cast<CMceAudioStream*>( aStreams[strmCount] );
+ CMceAudioStream& boundStream =
+ static_cast<CMceAudioStream&>( audioStream->BoundStreamL() );
+
+ CMceAudioStream* uplinkStream = NULL;
+
+ if ( !IsDownlinkStream( *audioStream ) )
+ {
+ SVPDEBUG1( "SVPAudioUtility::MmfPriorityUpdateNeededL main is uplink" )
+
+ uplinkStream = audioStream;
+ }
+ else if ( !IsDownlinkStream( boundStream ) )
+ {
+ SVPDEBUG1( "SVPAudioUtility::MmfPriorityUpdateNeededL bound is uplink" )
+
+ uplinkStream = &boundStream;
+ }
+
+ // Next assert handles the missing else branch.
+ __ASSERT_ALWAYS( uplinkStream, User::Leave( KErrNotFound ) );
+
+ TBool res = MmfPriorityUpdateNeededL( *uplinkStream );
+ if ( res )
+ {
+ SVPDEBUG1( "SVPAudioUtility::MmfPriorityUpdateNeededL ETrue" )
+ return ETrue;
+ }
+ }
+
+ SVPDEBUG1( "SVPAudioUtility::MmfPriorityUpdateNeededL EFalse" )
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::MmfPriorityUpdateNeededL
+// ---------------------------------------------------------------------------
+//
+TBool SVPAudioUtility::MmfPriorityUpdateNeededL(
+ CMceAudioStream& aUplinkStream )
+ {
+ SVPDEBUG1( "SVPAudioUtility::MmfPriorityUpdateNeededL (stream) In" )
+
+ // Check which uplink preference we need to have based whether DTMF codec
+ // is part of the codec list.
+ TUint uplinkPreference = 0;
+ if ( FindCodec( aUplinkStream, KTELEVENT ) )
+ {
+ SVPDEBUG1( "SVPAudioUtility::MmfPriorityUpdateNeededL (stream) DTMF OB" )
+
+ uplinkPreference = KSVPAudioPrefUplinkOobDtmf;
+ }
+ else
+ {
+ SVPDEBUG1( "SVPAudioUtility::MmfPriorityUpdateNeededL (stream) DTMF IB" )
+
+ uplinkPreference = KSVPAudioPrefUplinkIbDtmf;
+ }
+
+ // Given stream must have at least one codec in order to do the priority /
+ // preference check. This function is private and called inside, thus this
+ // assertion just adds to the checks done in caller.
+ const RPointerArray<CMceAudioCodec>& codecs = aUplinkStream.Codecs();
+ TInt codecCount = codecs.Count();
+
+ SVPDEBUG2( "SVPAudioUtility::MmfPriorityUpdateNeededL (stream) codecCount: %d",
+ codecCount )
+
+ __ASSERT_ALWAYS( codecCount, User::Leave( KErrArgument ) );
+
+ while( codecCount )
+ {
+ SVPDEBUG2( "SVPAudioUtility::MmfPriorityUpdateNeededL (stream) tb checked: %d",
+ codecCount )
+
+ codecCount--;
+
+ SVPDEBUG2( "SVPAudioUtility::MmfPriorityUpdateNeededL curr.prio: %d",
+ codecs[codecCount]->MMFPriority() )
+ SVPDEBUG2( "SVPAudioUtility::MmfPriorityUpdateNeededL curr.pref: 0x%x",
+ codecs[codecCount]->MMFPriorityPreference() )
+
+ // Do not include DTMF codec into the preference check. Note CompareF
+ // return value also, 0 means match.
+ if ( codecs[codecCount]->SdpName().CompareF( KTELEVENT ) &&
+ uplinkPreference != codecs[codecCount]->MMFPriorityPreference() )
+ {
+ SVPDEBUG1( "SVPAudioUtility::MmfPriorityUpdateNeededL (stream) ETrue" )
+
+ return ETrue;
+ }
+
+ // else preferences match, ne-ext please!!!
+ }
+
+ SVPDEBUG1( "SVPAudioUtility::MmfPriorityUpdateNeededL (stream) EFalse" )
+ return EFalse;
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::DtmfActionCapableSession
+// ---------------------------------------------------------------------------
+//
+TBool SVPAudioUtility::DtmfActionCapableSession(
+ const CSVPSessionBase& aSession )
+ {
+ if ( aSession.HasHoldController() &&
+ ESVPConnected == aSession.HoldController().HoldState() )
+ {
+ SVPDEBUG1( "SVPAudioUtility::DtmfActionCapableSession ETrue 1" )
+
+ return ETrue;
+ }
+ else if ( !aSession.HasHoldController() )
+ {
+ SVPDEBUG1( "SVPAudioUtility::DtmfActionCapableSession ETrue 2" )
+
+ return ETrue;
+ }
+ else
+ {
+ SVPDEBUG1( "SVPAudioUtility::DtmfActionCapableSession EFalse" )
+
+ return EFalse;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Check DTMF capability of emergency session
+// ---------------------------------------------------------------------------
+//
+TBool SVPAudioUtility::DtmfActionCapableSession(
+ const CSVPEmergencySession& aSession )
+ {
+ if ( aSession.HasHoldController() &&
+ ESVPConnected == aSession.HoldController().HoldState() )
+ {
+ SVPDEBUG1( "SVPAudioUtility::DtmfActionCapableSession ETrue 1" )
+
+ return ETrue;
+ }
+ else if ( !aSession.HasHoldController() )
+ {
+ SVPDEBUG1( "SVPAudioUtility::DtmfActionCapableSession ETrue 2" )
+
+ return ETrue;
+ }
+ else
+ {
+ SVPDEBUG1( "SVPAudioUtility::DtmfActionCapableSession EFalse" )
+
+ return EFalse;
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// SVPAudioUtility::DtmfActionCapableStream
+// ---------------------------------------------------------------------------
+//
+TBool SVPAudioUtility::DtmfActionCapableStream(
+ const CMceMediaStream& aStream )
+ {
+ // We used to check for source's DtmfAvailable and DtmfActive attributes,
+ // but those are IPC calls which are not preferred for DTMF's real-time
+ // nature. Thus leaving those out and letting the server return us a
+ // error code if those attributes are not correct for DTMF sending
+ // actually does the same thing but improves performance.
+ // Thus what once was three IPC calls is now just one.
+ TBool ret = EFalse;
+ CMceMediaSource* source = aStream.Source();
+
+#ifdef _DEBUG
+ SVPDEBUG2( "SVPAudioUtility::DtmfActionCapableStream type: %d", aStream.Type() )
+ SVPDEBUG2( "SVPAudioUtility::DtmfActionCapableStream source: 0x%x", source )
+ if ( source )
+ {
+ SVPDEBUG2( "SVPAudioUtility::DtmfActionCapableStream enabled: %d", source->IsEnabled() )
+ }
+#endif
+
+ if ( KMceAudio == aStream.Type() && source && source->IsEnabled() )
+ {
+ ret = ETrue;
+ }
+
+ SVPDEBUG2( "SVPAudioUtility::DtmfActionCapableStream ret: %d", ret )
+
+ return ret;
+ }
+