convergedcallengine/csplugin/src/cspaudiostreams.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:15:03 +0100
branchRCL_3
changeset 20 987c9837762f
parent 0 ff3b6d0fd310
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2006 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:  Starts and stops audio streams.
*
*/


#include "cspaudiostreams.h"
#include "cspmicrophone.h"
#include "cspspeaker.h"
#include "csplogger.h"
#include "mcspaudiostreamobserver.h"
#include "csptimer.h"

#include <TelephonyAudioRouting.h>

/**
* Timeout initial value.
*/
const TInt KTimeoutInitial = 200000; // 0.2s

/**
* Double the timeout for every retry.
*/
const TInt KTimeoutMultiplier = 2;

// ======== MEMBER FUNCTIONS ========
   
// ---------------------------------------------------------------------------
// Static constructor
// ---------------------------------------------------------------------------
//
CSPAudioStreams* CSPAudioStreams::NewL( )
    {
    CSPAudioStreams* self = 
        CSPAudioStreams::NewLC();
    CleanupStack::Pop( self );
    return self;
    }

// ---------------------------------------------------------------------------
// Static constructor
// ---------------------------------------------------------------------------
//
CSPAudioStreams* CSPAudioStreams::NewLC(  )
    {
    CSPAudioStreams* self = new( ELeave ) CSPAudioStreams( );
    CleanupStack::PushL( self );
    self->ConstructL( );
    return self;
    }

// ---------------------------------------------------------------------------
// Destructor
// ---------------------------------------------------------------------------
//
CSPAudioStreams::~CSPAudioStreams()
    {
    if (iTimer)
        {
        iTimer->CancelNotify();    
        delete iTimer;
        }
    
    delete iSpeaker;
    delete iMic;
    delete iAudioRouting;
    }

// ---------------------------------------------------------------------------
// Sets observer for audio stream.
// ---------------------------------------------------------------------------
//
void CSPAudioStreams::SetAudioStreamObserver( 
    MCSPAudioStreamObserver& aObserver )
    {
    iStreamObserver = &aObserver;
    }
    
// ---------------------------------------------------------------------------
// Gives access to mic
// ---------------------------------------------------------------------------
//
CSPMicrophone& CSPAudioStreams::Mic() const
    {
    return *iMic;
    }

// ---------------------------------------------------------------------------
// Gives access to speaker
// ---------------------------------------------------------------------------
//
CSPSpeaker& CSPAudioStreams::Speaker() const
    {
    return *iSpeaker;
    }
    
// ---------------------------------------------------------------------------
// From class MCSPAudioStream
// Activates mic and speaker.
// ---------------------------------------------------------------------------
//
void CSPAudioStreams::StartStreams() 
    {
    CSPLOGSTRING(CSPINT, "CSPAudioStreams::StartStreams");
    
    if( !IsMicAndSpeakerStarted() )    
        {
        StartMicAndSpeaker(); 
        
        if( iStreamObserver )
            {
            iStreamObserver->AudioStreamsStarted();
            }
        }
    }

// ---------------------------------------------------------------------------
// From class MCSPAudioStream
// Deactivates mic and speaker if the streams are active or they are 
// activating. 
// ---------------------------------------------------------------------------
//
void CSPAudioStreams::StopStreams() 
    {
    CSPLOGSTRING(CSPINT, "CSPAudioStreams::StopStreams");
    
    if( IsMicAndSpeakerStarted() )
        {
            CSPLOGSTRING(CSPINT, "CSPAudioStreams::StopStreams Stopping");
        iTimer->CancelNotify(); 
        iTimeout = KTimeoutInitial;
        if( iStreamObserver ) 
            {
            iStreamObserver->AudioStreamsGoingToStop();
            }
        iMic->Deactivate();
        iSpeaker->Deactivate();
        }
    }

// ---------------------------------------------------------------------------
// CSPAudioStreams::VolumeChangedEar
// ---------------------------------------------------------------------------
//
void CSPAudioStreams::VolumeChangedEar(TInt aVolume)
    {
    CSPLOGSTRING2(CSPINT, "CSPAudioStreams::SetVolume %d", aVolume);
    iVolumeEar = aVolume;
    iSpeaker->SetVolume( aVolume );
    }

// ---------------------------------------------------------------------------
// CSPAudioStreams::VolumeChangedLoudspeaker
// ---------------------------------------------------------------------------
//
void CSPAudioStreams::VolumeChangedLoudspeaker(TInt aVolume)
    {
    CSPLOGSTRING2(CSPINT, "CSPAudioStreams::SetVolume %d", aVolume);
    iVolumeLoudspeaker = aVolume;
    iSpeaker->SetVolume( aVolume );
    }

// ---------------------------------------------------------------------------
// CSPAudioStreams::StoreVolumes
// ---------------------------------------------------------------------------
//
void CSPAudioStreams::StoreVolumes(TInt aVolumeEar, TInt aVolumeLoudspeaker )
    {
    iVolumeEar = aVolumeEar;
    iVolumeLoudspeaker = aVolumeLoudspeaker;
    }
    
// ---------------------------------------------------------------------------
// CSPAudioStreams::ApplyVolume
// ---------------------------------------------------------------------------
//
void CSPAudioStreams::ApplyVolume(TInt aVolumeEar, TInt aVolumeLoudspeaker )
    {
    CTelephonyAudioRouting::TAudioOutput current = iAudioRouting->Output();
    if ( current == CTelephonyAudioRouting::ELoudspeaker )
        {
        CSPLOGSTRING( CSPINT, "CSPAudioStreams::ApplyVolume Loudspeaker Active: SetVolume" );
        iSpeaker->SetVolume( aVolumeLoudspeaker );
        }
        // else: ear volume should be used
     else if ( current == CTelephonyAudioRouting::EHandset )
        {
        CSPLOGSTRING( CSPINT, "CSPAudioStreams::ApplyVolume Ear Active: SetVolume" );
        iSpeaker->SetVolume( aVolumeEar );
        }
    else
        {
        CSPLOGSTRING2( CSPINT, "CSPAudioStreams::ApplyVolume UNKNOWN AUDIO OUTPUT MODE %d", current );
        // No volume setting
        iSpeaker->SetVolume( aVolumeEar );
        }
    }

// ---------------------------------------------------------------------------
// CSPAudioStreams::SetMuted
// ---------------------------------------------------------------------------
//  
void CSPAudioStreams::SetMuted() 
    {
    iMic->SetMuted();
    }

// ---------------------------------------------------------------------------
// CSPAudioStreams::SetUnmuted
// ---------------------------------------------------------------------------
//  
void CSPAudioStreams::SetUnmuted() 
    {
    iMic->SetUnmuted();
    }

// ---------------------------------------------------------------------------
// From class MCSPAudioStreamObserver
// If speaker is already active then the streams are active.
// If speker is not active and it is not activating then speaker then
// activation has failed and start retry timer.
// ---------------------------------------------------------------------------
//   
void CSPAudioStreams::MicActivatedSuccessfully()
    {
    CSPLOGSTRING(CSPINT, "CSPAudioStreams::MicActivatedSuccessfully" );
    if( iSpeaker->IsActive() )
        {
        // Mic and speaker are active.
        AudioStreamsStarted();
        }
    else if( !iSpeaker->IsActivationOngoing() ) 
        {
        // Start retry timer for activating speaker again
        StartTimer();
        }
    }
    
// ---------------------------------------------------------------------------
// From class MCSPAudioStreamObserver
// If mic is already active then streams are active.
// If mic is not active and it is not activating then mic activation has
// failed and start retry timer.
// ---------------------------------------------------------------------------
//   
void CSPAudioStreams::SpeakerActivatedSuccessfully()
    {
    CSPLOGSTRING(CSPINT, "CSPAudioStreams::SpeakerActivatedSuccessfully" );
    if( iMic->IsActive() ) 
        {
        // Mic and speaker are active.
        AudioStreamsStarted();
        }
    else if( !iMic->IsActivationOngoing() ) 
        {
        // Start retry timer for activating mic again.
        StartTimer();
        }
    }

// ---------------------------------------------------------------------------
// From class MCSPAudioStreamObserver
// Starts timer for trying activation again.
// ---------------------------------------------------------------------------
//    
void CSPAudioStreams::MicActivationFailed()
    {
    CSPLOGSTRING(CSPINT, "CSPAudioStreams::MicActivationFailed" );
   
    // Dont start timer until speaker has stopped activation.
    if( !iSpeaker->IsActivationOngoing() ) 
        {
        StartTimer();
        }
    }
    
// ---------------------------------------------------------------------------
// From class MCSPAudioStreamObserver
// Starts timer for trying activation again.
// ---------------------------------------------------------------------------
// 
void CSPAudioStreams::SpeakerActivationFailed()
    {
    CSPLOGSTRING(CSPINT, "PE.AudioStreams::SpeakerActivationFailed" );
    
    // Dont start timer until mic has stopped activation.
    if( !iMic->IsActivationOngoing() )
        {
        StartTimer();
        }
    }
    
// ---------------------------------------------------------------------------
// From class MCSPTimerObserver
// Notify from CSPTimer that timeout passed. Try to start mic and
// speaker again.
// ---------------------------------------------------------------------------
// 
void CSPAudioStreams::TimerEvent()
    {
    CSPLOGSTRING(CSPINT, "CSPAudioStreams.TimerEvent" );
    iTimeout *= KTimeoutMultiplier;
    StartMicAndSpeaker();
    }

// -----------------------------------------------------------------------------
// CTSEAudioRouteObserver::AvailableOutputsChanged
// -----------------------------------------------------------------------------
//
void CSPAudioStreams::AvailableOutputsChanged( 
        CTelephonyAudioRouting& /*aTelephonyAudioRouting*/ )
    {
    CSPLOGSTRING(CSPINT, "CSPAudioStreams::AvailableOutputsChanged" );
    }
    
// -----------------------------------------------------------------------------
// CTSEAudioRouteObserver::OutputChanged
// -----------------------------------------------------------------------------
//
void CSPAudioStreams::OutputChanged( 
        CTelephonyAudioRouting& /*aTelephonyAudioRouting*/ )
    {
    CSPLOGSTRING(CSPINT, "CSPAudioStreams::OutputChanged" );
    ApplyVolume(iVolumeEar, iVolumeLoudspeaker);
    }

// -----------------------------------------------------------------------------
// CSPAudioStreams::SetOutputComplete
// -----------------------------------------------------------------------------
//
void CSPAudioStreams::SetOutputComplete( CTelephonyAudioRouting& /*aTelephonyAudioRouting*/,
                                         TInt /*aError*/ )
   {
   }  

// ---------------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------------
//
CSPAudioStreams::CSPAudioStreams( ): iTimeout(KTimeoutInitial)
    {
    }

// ---------------------------------------------------------------------------
// Second phase constructor
// ---------------------------------------------------------------------------
//
void CSPAudioStreams::ConstructL( )
    {
    CSPLOGSTRING(CSPINT, "CSPAudioStreams::ConstructL");

    iTimer = CSPTimer::NewL();
    iMic = CSPMicrophone::NewL( *this );
    iSpeaker = CSPSpeaker::NewL( *this );
    
    #if !defined(__WINSCW__)
    iAudioRouting = CTelephonyAudioRouting::NewL( *this );
    #endif //__WINSCW__        
    }
    
// ---------------------------------------------------------------------------
// Resets timer
// ---------------------------------------------------------------------------
//
void CSPAudioStreams::AudioStreamsStarted()
    {
    CSPLOGSTRING(CSPINT, "CSPAudioStreams::AudioStreamsStarted" );
    iTimeout = KTimeoutInitial; 
    iTimer->CancelNotify();
    }

// ---------------------------------------------------------------------------
// Starts timer
// ---------------------------------------------------------------------------
//
void CSPAudioStreams::StartTimer() 
    {
    CSPLOGSTRING(CSPINT, "CSPAudioStreams::StartTimer" );
    iTimer->NotifyAfter( iTimeout, *this );
    }
    
// ---------------------------------------------------------------------------
// Starts mic and speaker
// ---------------------------------------------------------------------------
//
void CSPAudioStreams::StartMicAndSpeaker()
    {
    // if speaker and mic is active then activation does not
    // cause any actions.
    iSpeaker->Activate();
    iMic->Activate();   
    }

// ---------------------------------------------------------------------------
// Indicated if mic and speaker are started or starting up.
// ---------------------------------------------------------------------------
//    
TBool CSPAudioStreams::IsMicAndSpeakerStarted()
    {
    TBool areStreamsActive( iSpeaker->IsActive() && iMic->IsActive() );
    TBool areStreamsActivating( iMic->IsActivationOngoing() ||  
        iSpeaker->IsActivationOngoing() || iTimer->IsNotifyOngoing() );
        
    return areStreamsActive || areStreamsActivating;
    }

//  End of File