alarmui/src/AlmAlarmPlayer.cpp
changeset 0 f979ecb2b13e
child 18 c198609911f9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/alarmui/src/AlmAlarmPlayer.cpp	Tue Feb 02 10:12:19 2010 +0200
@@ -0,0 +1,468 @@
+/*
+* Copyright (c) 2006-2007 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:  This class provides audio playback for Alarm UI.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "AlmAlarmPlayer.h"
+#include "alarmutils.h"
+#include "pim_trace.h"
+
+#include <AudioPreference.h>
+
+// CONSTANTS AND MACROS
+const TInt KSoundInterval( 1000000 );  // 1 second
+
+// set player volume
+#define SET_VOLUME( t, v )  t->SetVolume( v );
+
+// Copied from Phone's Toneplayer.
+_LIT8( KPhoneBeepSequence, "\x00\x11\x06\x0A\x08\x73\x0A\x40\x28\x0A\xF7\x05\xFC\x40\x64\x0A\x08\x40\x32\x0A\xF7\x06\x0B" );
+_LIT8( KPhoneNoSoundSequence, "\x00\x11\x06\x05\xFC\x0A\x08\x40\x32\x0A\xF7\x40\x64\x06\x0B" );
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+CAlmAlarmPlayer::CAlmAlarmPlayer(CAlarmUtils* aAlarmUtils)
+ : iAlarmUtils( aAlarmUtils )
+{
+    TRACE_ENTRY_POINT;
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Symbian 2nd phase constructor.
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::ConstructL(void)
+{
+    TRACE_ENTRY_POINT;
+    PlayAlarmL();
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CAlmAlarmPlayer* CAlmAlarmPlayer::NewL(CAlarmUtils* aAlarmUtils)
+{ // static
+    TRACE_ENTRY_POINT;
+    CAlmAlarmPlayer* self = new( ELeave )CAlmAlarmPlayer( aAlarmUtils );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    TRACE_EXIT_POINT;
+    return self;
+}
+
+// -----------------------------------------------------------------------------
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CAlmAlarmPlayer::~CAlmAlarmPlayer(void)
+{
+    TRACE_ENTRY_POINT;
+
+    if( iSequencePlayer )
+    {
+        if( iSequencePlayer->State() == EMdaAudioToneUtilityPlaying )
+        {
+            iSequencePlayer->CancelPlay();
+        }
+        else
+        {
+            iSequencePlayer->CancelPrepare();
+        }
+        delete iSequencePlayer;
+    }
+
+    if( iSamplePlayer )
+    {
+        iSamplePlayer->Stop();
+        iSamplePlayer->Close();
+        delete iSamplePlayer;
+    }
+
+    if( iBeepPlayer )
+    {
+        if( iBeepPlayer->State() == EMdaAudioToneUtilityPlaying )
+        {
+            iBeepPlayer->CancelPlay();
+        }
+        else
+        {
+            iBeepPlayer->CancelPrepare();
+        }
+        delete iBeepPlayer;
+    }
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Once tone initialization is complete play the tone.
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::MatoPrepareComplete(TInt aError)
+{
+    TRACE_ENTRY_POINT;
+    if( aError != KErrNone )
+    {
+        PIM_TRAPD_ASSERT( HandlePlayErrorL( aError ); )
+    }
+    else if( iBeepPlayer )
+    {
+        iBeepPlayer->Play();
+    }
+    else
+    {
+        iSequencePlayer->Play();
+    }
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Callback for completing tone player.
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::MatoPlayComplete(TInt aError)
+{
+    TRACE_ENTRY_POINT;
+    if( aError != KErrNone )
+    {
+        PIM_TRAPD_ASSERT( HandlePlayErrorL( aError ); )
+    }
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// When initialization is complete set the player settings and play the sound.
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::MapcInitComplete(TInt aError, const TTimeIntervalMicroSeconds& /*aDuration*/)
+{
+    TRACE_ENTRY_POINT;
+    if( aError == KErrNone )
+    {
+        iSamplePlayer->SetVolumeRamp( TTimeIntervalMicroSeconds( iAlarmUtils->AlarmData().iVolumeRampTime ) );
+
+        iSamplePlayer->SetRepeats( iAlarmUtils->AlarmData().iRepeatValue, 
+                                   TTimeIntervalMicroSeconds( KSoundInterval ) );
+
+        SET_VOLUME( iSamplePlayer, 
+                    PlayerVolume( iSamplePlayer->MaxVolume(),
+                                  iAlarmUtils->AlarmData().iVolume ) )
+
+        iSamplePlayer->Play();
+    }
+    else
+    {
+        PIM_TRAPD_ASSERT( HandlePlayErrorL( aError ); )
+    }
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Callback for completing audio player.
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::MapcPlayComplete(TInt aError)
+{
+    TRACE_ENTRY_POINT;
+    if( aError != KErrNone )
+    {
+        PIM_TRAPD_ASSERT( HandlePlayErrorL( aError ); )
+    }
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Play appropriate alarm type using profile ringing type setting.
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::PlayCalendarAlarmL(TBool aIsRngTone)
+{
+    TRACE_ENTRY_POINT;
+    if( iAlarmUtils->AlarmData().iRingType == EProfileRingingTypeBeepOnce )
+    {
+        PlayCalendarBeepL();
+    }
+    else if( iAlarmUtils->AlarmData().iRingType == EProfileRingingTypeSilent )
+    {
+        PlaySilentCalendarAlarmL();
+    }
+    else
+    {
+        if( aIsRngTone )
+        {
+            PlayCalendarAlarmToneL();
+        }
+        else // normal sound file
+        {
+            if( iSamplePlayer )
+            {
+                iSamplePlayer->Close();
+                delete iSamplePlayer;
+                iSamplePlayer = NULL;
+            }
+            iSamplePlayer = CMdaAudioPlayerUtility::NewFilePlayerL(
+                iAlarmUtils->AlarmData().iAlarmTone,
+                *this, 
+                KAudioPriorityAlarm, 
+                static_cast<TMdaPriorityPreference>( KAudioPrefCalendarAlarm ) );
+        }
+    }
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Play calendar alarm tone. (KRngMimeType files only)
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::PlayCalendarAlarmToneL(void)
+{
+    TRACE_ENTRY_POINT;
+    if( iSequencePlayer )
+    {
+        delete iSequencePlayer;
+        iSequencePlayer = NULL;
+    }
+    iSequencePlayer = CMdaAudioToneUtility::NewL( *this );
+
+    iSequencePlayer->SetPriority( KAudioPriorityAlarm, static_cast<TMdaPriorityPreference>( KAudioPrefCalendarAlarm ) );
+
+    iSequencePlayer->SetRepeats( iAlarmUtils->AlarmData().iRepeatValue, 
+                                 TTimeIntervalMicroSeconds( KSoundInterval ) );
+
+    SET_VOLUME( iSequencePlayer, 
+                PlayerVolume( iSequencePlayer->MaxVolume(),
+                              iAlarmUtils->AlarmData().iVolume ) )
+
+    iSequencePlayer->SetVolumeRamp( TTimeIntervalMicroSeconds( iAlarmUtils->AlarmData().iVolumeRampTime ) );
+
+    iSequencePlayer->PrepareToPlayFileSequence( iAlarmUtils->AlarmData().iAlarmTone );
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Play silent calendar alarm. (needed to for vibra)
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::PlaySilentCalendarAlarmL(void)
+{
+    TRACE_ENTRY_POINT;
+    iBeepPlayer = CMdaAudioToneUtility::NewL( *this );
+
+    SET_VOLUME( iBeepPlayer, 
+                PlayerVolume( iBeepPlayer->MaxVolume(),
+                              iAlarmUtils->AlarmData().iVolume ) )
+
+    iBeepPlayer->SetPriority( KAudioPriorityAlarm, static_cast<TMdaPriorityPreference>( KAudioPrefCalendarAlarm ) );
+
+    iBeepPlayer->PrepareToPlayDesSequence( KPhoneNoSoundSequence );
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Play beep alarm for calendar.
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::PlayCalendarBeepL(void)
+{
+    TRACE_ENTRY_POINT;
+    iBeepPlayer = CMdaAudioToneUtility::NewL( *this );
+
+    SET_VOLUME( iBeepPlayer, 
+                PlayerVolume( iBeepPlayer->MaxVolume(),
+                              iAlarmUtils->AlarmData().iVolume ) )
+
+    iBeepPlayer->SetPriority( KAudioPriorityAlarm, static_cast<TMdaPriorityPreference>( KAudioPrefCalendarAlarm ) );
+
+    iBeepPlayer->PrepareToPlayDesSequence( KPhoneBeepSequence );
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Play beep alarm for clock.
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::PlayClockBeepL(void)
+{
+    TRACE_ENTRY_POINT;
+    iBeepPlayer = CMdaAudioToneUtility::NewL( *this );
+
+    SET_VOLUME( iBeepPlayer, 
+                PlayerVolume( iBeepPlayer->MaxVolume(),
+                              iAlarmUtils->AlarmData().iVolume ) )
+
+    iBeepPlayer->SetPriority( KAudioPriorityAlarm, static_cast<TMdaPriorityPreference>( KAudioPrefAlarmClock ) );
+
+    iBeepPlayer->PrepareToPlayDesSequence( KPhoneBeepSequence );
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Play normal clock alarm.
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::PlayClockAlarmL(void)
+{
+    TRACE_ENTRY_POINT;
+    if( iSamplePlayer )
+    {
+        iSamplePlayer->Close();
+        delete iSamplePlayer;
+        iSamplePlayer = NULL;
+    }
+    iSamplePlayer = CMdaAudioPlayerUtility::NewFilePlayerL(
+        iAlarmUtils->AlarmData().iAlarmTone, 
+        *this, 
+        KAudioPriorityAlarm, 
+        static_cast<TMdaPriorityPreference>( KAudioPrefAlarmClock ) );
+    TRACE_EXIT_POINT;
+
+}
+
+// -----------------------------------------------------------------------------
+// Play calendar alarm tone. (KRngMimeType files only)
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::PlayClockAlarmToneL(void)
+{
+    TRACE_ENTRY_POINT;
+    if( iSequencePlayer )
+    {
+        delete iSequencePlayer;
+        iSequencePlayer = NULL;
+    }
+    iSequencePlayer = CMdaAudioToneUtility::NewL( *this );
+
+    iSequencePlayer->SetPriority( KAudioPriorityAlarm, static_cast<TMdaPriorityPreference>( KAudioPrefAlarmClock ) );
+
+    iSequencePlayer->SetRepeats( iAlarmUtils->AlarmData().iRepeatValue, 
+                                 TTimeIntervalMicroSeconds( KSoundInterval ) );
+
+    SET_VOLUME( iSequencePlayer, 
+                PlayerVolume( iSequencePlayer->MaxVolume(),
+                              iAlarmUtils->AlarmData().iVolume ) )
+
+    iSequencePlayer->SetVolumeRamp( TTimeIntervalMicroSeconds( iAlarmUtils->AlarmData().iVolumeRampTime ) );
+
+    iSequencePlayer->PrepareToPlayFileSequence( iAlarmUtils->AlarmData().iAlarmTone );
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Check the file and alarm type and try to play the alarm.
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::PlayAlarmL()
+{
+    TRACE_ENTRY_POINT;
+    if( iAlarmUtils->AlarmData().iAlarmTone.Length() )
+    {
+        const TBool isRngTone( iAlarmUtils->IsRngTone() );
+
+        if( iAlarmUtils->IsClockAlarm() )
+        {
+            if( !isRngTone )
+            {
+                PlayClockAlarmL();
+            }
+            else
+            {
+                PlayClockAlarmToneL();
+            }
+        }
+        else
+        {
+            PlayCalendarAlarmL( isRngTone );
+        }
+    }
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Common fallback functionality for prepare/play errors.
+// -----------------------------------------------------------------------------
+//
+void CAlmAlarmPlayer::HandlePlayErrorL(TInt aError)
+{
+    TRACE_ENTRY_POINT;
+    /**
+    * No fallback for KErrUnderflow - alarm got replaced with the default beep.
+    * Also, nothing to do if iBeepPlayer was already used.
+    **/
+    if( aError != KErrUnderflow && !iBeepPlayer )
+    {
+        // fallback to beep tone on OOM or if the default tone was already in use
+        if( aError == KErrNoMemory || 
+            iAlarmUtils->AlarmData().iAlarmTone == iAlarmUtils->AlarmData().iDefaultAlarmTone )
+        {
+            delete iSequencePlayer;
+            iSequencePlayer = NULL;
+
+            if( iSamplePlayer )
+            {
+                iSamplePlayer->Close();
+            }
+            delete iSamplePlayer;
+            iSamplePlayer = NULL;
+
+            // try playing the beep tone
+            if( iAlarmUtils->IsClockAlarm() )
+            {
+                PlayClockBeepL();
+            }
+            else
+            {
+                PlayCalendarBeepL();
+            }
+        }
+        else // retry using the default tone
+        {
+            iAlarmUtils->AlarmData().iAlarmTone = iAlarmUtils->AlarmData().iDefaultAlarmTone;
+            PlayAlarmL();
+        }
+    }
+    TRACE_EXIT_POINT;
+}
+
+// -----------------------------------------------------------------------------
+// Set volume between zero and player's maximum volume
+// -----------------------------------------------------------------------------
+//
+TInt CAlmAlarmPlayer::PlayerVolume(TInt aPlayerMaxVol, TInt aVol)
+{
+    TRACE_ENTRY_POINT;
+    const TInt profileMaxVol( iAlarmUtils->MaxProfileVolume() );
+    TInt vol( 0 ); // leave as 0 if using off tone
+    if( !iAlarmUtils->IsOffTone() )
+    {
+        // calculate value between 0 and aPlayerMaxVolume
+        vol = Max( 0, Min( aPlayerMaxVol / profileMaxVol * aVol, aPlayerMaxVol ) );
+    }
+    TRACE_EXIT_POINT;
+    return vol;
+}
+
+
+// End of File