--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/voicerecorder/RecViewSrc/CVRMemo.cpp Thu Dec 17 08:46:57 2009 +0200
@@ -0,0 +1,667 @@
+/*
+* Copyright (c) 2002 - 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:
+* This class represents a voice memo. It is able to create new files,
+* rename and delete existing files, and to save them to permanent storage.
+*
+*/
+
+
+// INCLUDE FILES
+
+#include <eikapp.h>
+#include <eikappui.h>
+#include <eikenv.h>
+#include <AknWaitDialog.h>
+#include <AknQueryDialog.h>
+#include <StringLoader.h>
+#include <bautils.h>
+#include <AknGlobalNote.h>
+#include <sysutil.h>
+#include <pathinfo.h>
+#include <systemwarninglevels.hrh>
+#include <AknNotifyStd.h>
+#include <coeutils.h>
+
+#include <voicerecorder.rsg>
+#include <VoiceRecorderUID.h>
+#include "CVRMemo.h"
+#include "VRConsts.h"
+#include "TVRRename.h"
+#include "VRUtils.h"
+
+// CONSTANTS
+// Max length is 300 millisecs over one minute so possible cropping
+// of the file after stop doesn't drop the length under one minute
+const TInt KVRMMSMemoMaxRecordLength( 60300000 );
+const TInt KVREstimateDelayDuration( 10000000 );
+
+
+// ================= MEMBER FUNCTIONS ========================================
+
+// ---------------------------------------------------------------------------
+// CVRMemo::CVRMemo
+//
+// ---------------------------------------------------------------------------
+//
+CVRMemo::CVRMemo()
+ : iDuration( 0 ), iPosition( 0 ), iMaxDuration( KVRDefaultMaxLength ),
+ iQuality( EQualityMMSOptimized ),iIsRecorded( EFalse )
+ {
+#ifndef RD_MULTIPLE_DRIVE
+ iStoragePlace = EMemoStorePhoneMemory;
+#else
+ TRAP_IGNORE(iStorageDrive = VRUtils::DefaultMemoDriveL());
+#endif
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::~CVRMemo
+//
+// ---------------------------------------------------------------------------
+//
+CVRMemo::~CVRMemo()
+ {
+ DeleteEmptyFile();
+
+ // Close the file handle and file server session
+ iFile.Close();
+ iFs.Close();
+
+ delete iFileMan;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::ConstructL
+//
+// ---------------------------------------------------------------------------
+//
+void CVRMemo::ConstructL(TInt aDefaultAudioFormat)
+ {
+ User::LeaveIfError( iFs.Connect() );
+ iFs.ShareProtected();
+
+ iFileMan = CFileMan::NewL( iFs );
+
+ iVRAudioFormat = aDefaultAudioFormat;
+
+ iQuality = VRUtils::QualityL();
+ if ( !VRUtils::FeatureEnabled( EVRFeatureShowQualitySetting )
+ || iEmbedded )
+ {
+ iMaxDuration = KVRMMSMemoMaxRecordLength;
+ iQuality = EQualityMMSOptimized;
+ }
+ else
+ {
+ TInt64 max( VRUtils::MaxLengthL() );
+ max = max * KVRMinuteAsMicroSeconds;
+ iMaxDuration = max;
+ }
+
+ // Current storage place
+#ifndef RD_MULTIPLE_DRIVE
+ iStoragePlace = VRUtils::MemoStoreL();
+#else
+ iStorageDrive = VRUtils::MemoDriveL();
+#endif
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::SetName
+//
+// ---------------------------------------------------------------------------
+//
+void CVRMemo::SetName( const TDesC& aFilename )
+ {
+ iFilename.Copy( aFilename );
+ TParsePtrC parse( iFilename );
+ iNamePtr.Set( parse.Name().Left( VRMEMONAMEMAXLENGTH ) );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::SetTemporaryNameL
+//
+// ---------------------------------------------------------------------------
+//
+void CVRMemo::SetTemporaryNameL( TBool aEmbedded )
+ {
+ iEmbedded = aEmbedded;
+
+ // We can use the same handle, no need to create new name
+ // Empty the file so it can be overwritten with new memo
+ if ( iEmbedded && !iExternalFileHandle )
+ {
+ if ( iFile.SubSessionHandle() )
+ {
+ iFile.SetSize( 0 );
+ return;
+ }
+ }
+
+ // Checks if the file handle can be found i.e if file is created
+ if ( iFile.SubSessionHandle() )
+ {
+ // Retrieving new settings
+ TVRQuality newQuality( VRUtils::QualityL() );
+
+#ifndef RD_MULTIPLE_DRIVE
+ TVRMemoStore newStoragePlace ( VRUtils::MemoStoreL() );
+
+ // If the current file is empty, we can reuse it if quality or
+ // the storage place hasn't changed
+ if ( iQuality == newQuality && iStoragePlace == newStoragePlace )
+ {
+ TInt size( 0 );
+ iFile.Size( size );
+
+ // If current file has already been recorded to, a new file has
+ // to be generated
+ if ( !IsRecorded() )
+ {
+ iFile.SetSize( 0 );
+ return;
+ }
+ }
+ // The file has been created but the settings have been changed
+ // before using the file -> delete file and create a new one
+ else
+ {
+ DeleteEmptyFile();
+ }
+
+#else
+ // for Multiple drives
+ TInt newStorageDrive ( VRUtils::MemoDriveL() );
+
+ // If the current file is empty, we can reuse it if quality or
+ // the storage place hasn't changed
+ if ( iQuality == newQuality && iStorageDrive == newStorageDrive )
+ {
+ TInt size( 0 );
+ iFile.Size( size );
+
+ // If current file has already been recorded to, a new file has
+ // to be generated
+ if ( !IsRecorded() )
+ {
+ iFile.SetSize( 0 );
+ return;
+ }
+ }
+ // The file has been created but the settings have been changed
+ // before using the file -> delete file and create a new one
+ else
+ {
+ DeleteEmptyFile();
+ }
+
+
+#endif
+ }
+
+ TFileName memoName;
+ // Retrieve storage path
+ if ( iSavingLocation.Length() > 0 )
+ {
+ memoName = iSavingLocation;
+ }
+ else
+ {
+ VRUtils::MemoStoreDirectoryL( memoName );
+ }
+
+ // Recheck the quality before naming memo
+ if ( !VRUtils::FeatureEnabled( EVRFeatureShowQualitySetting )
+ || iEmbedded )
+ {
+ iQuality = EQualityMMSOptimized;
+ }
+ else
+ {
+ iQuality = VRUtils::QualityL();
+ }
+
+ // Current storage place
+#ifndef RD_MULTIPLE_DRIVE
+ iStoragePlace = VRUtils::MemoStoreL();
+#else
+ iStorageDrive = VRUtils::MemoDriveL();
+#endif
+
+ // Choose the file type
+ // Use amr if quality is MMS Optimized or we are recording
+ // in embedded mode, wav otherwise
+ TVRFiletype type( EVRFileAmr );
+ if( iEmbedded || iQuality == EQualityMMSOptimized )
+ {
+ type = EVRFileAmr;
+ }
+
+// **** updated for new CR, if it QualitySetting is Normal, save as WAV
+
+#ifdef __AAC_ENCODER_PLUGIN
+ else if (iQuality == EQualityNormal)
+ {
+ type = EVRFileWav;
+ }
+
+// **** the following are updated for new CR, if it QualitySetting is High, save as mp4
+ else if (iQuality == EQualityHigh)
+ {
+ type = EVRFileAAC_LC;
+ }
+#else
+
+ else
+ {
+ type = EVRFileWav;
+ }
+
+#endif
+
+ // Generate unique final file name
+ VRUtils::GenerateUniqueFilenameL( iFs, memoName, type );
+
+ // Make sure that file handles are not leaked
+ if ( iFile.SubSessionHandle() )
+ {
+ iFile.Close();
+ }
+
+ // Ensure that path exists
+ BaflUtils::EnsurePathExistsL( iFs, memoName );
+
+// Open the memo file
+
+#ifdef __AAC_ENCODER_PLUGIN
+ if((iQuality == EQualityHigh)) //for mp4 format , 3gplib does not support EFileShareExclusive so EFileShareAny is used here
+ {
+ User::LeaveIfError( iFile.Create( iFs, memoName, EFileWrite|EFileShareAny) );
+ }
+ else // for other formats
+ {
+ User::LeaveIfError( iFile.Create( iFs, memoName, EFileShareExclusive|EFileWrite ) );
+
+ }
+#else // it is not mp4, so still use the old flag
+ User::LeaveIfError( iFile.Create( iFs, memoName, EFileShareExclusive|EFileWrite ) );
+
+#endif
+
+ TInt error = iFile.SetAtt(KEntryAttHidden, KEntryAttNormal );
+ SetName( memoName );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::QueryAndDeleteL
+//
+// ---------------------------------------------------------------------------
+//
+TBool CVRMemo::QueryAndDeleteL()
+ {
+ //Delete?\n%U" �qtn.query.common.conf.delete�
+ TParsePtrC parse( iFilename );
+ HBufC* text = StringLoader::LoadLC( R_QTN_QUERY_COMMON_CONF_DELETE,
+ parse.Name() );
+
+ // Show confirm note
+ CAknQueryDialog* dlg = CAknQueryDialog::NewL();
+ TInt result( dlg->ExecuteLD( R_VR_CONFIRMATION_QUERY, *text ) );
+ CleanupStack::PopAndDestroy( text );
+
+ if ( result )
+ {
+ DeleteL();
+ return ETrue;
+ }
+
+ return EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::DeleteL
+//
+// ---------------------------------------------------------------------------
+//
+void CVRMemo::DeleteL()
+ {
+ if ( iFile.SubSessionHandle() )
+ {
+ if ( iExternalFileHandle )
+ {
+ // We shouldn't delete the file handle, so let's
+ // just empty the file
+ iFile.SetSize( 0 );
+ }
+ else
+ {
+ TFileName fileName( KNullDesC );
+ iFile.FullName( fileName );
+ iFile.Close();
+
+ TInt err( iFileMan->Delete( fileName ) );
+ if ( err != KErrNone && err != KErrNotFound )
+ {
+ // Try to open the file again so we wont end up
+ // in goofy state without open file
+ User::LeaveIfError( iFile.Open( iFs, fileName,
+ EFileShareReadersOnly ) );
+ User::LeaveIfError( err );
+ }
+ }
+ }
+ SetName( KNullDesC );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::QueryAndRenameL
+//
+// ---------------------------------------------------------------------------
+//
+TBool CVRMemo::QueryAndRenameL()
+ {
+ TVRRename renamer( iFs );
+ if ( renamer.RenameL( iFile, R_QTN_FLDR_ITEM_NAME_PRMPT ) )
+ {
+ TFileName name( KNullDesC );
+ iFile.FullName( name );
+ SetName( name );
+
+ return ETrue;
+ }
+ return EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::SavePermanentlyL
+//
+// ---------------------------------------------------------------------------
+//
+void CVRMemo::SavePermanentlyL( CAknGlobalNote* /*aWaitNote*/,
+ TInt& /*aNoteId*/,
+ const TDesC& /*aLabel*/,
+ TBool /*aProduceCopy*/ )
+
+ {
+ // Don't do anything if recording to external file handle
+ if ( iExternalFileHandle )
+ {
+ return;
+ }
+
+ // Change file open mode to read
+ TFileName name( KNullDesC );
+ iFile.FullName( name );
+ iFile.Close();
+ User::LeaveIfError( iFile.Open( iFs,
+ name,
+ EFileRead|EFileShareReadersOnly) );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::IsValid
+//
+// ---------------------------------------------------------------------------
+//
+TBool CVRMemo::IsValid() const
+ {
+ return iFile.SubSessionHandle() == 0 ? EFalse : ETrue;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::UpdateModifiedDate
+//
+// ---------------------------------------------------------------------------
+//
+void CVRMemo::UpdateModifiedDate()
+ {
+ if ( IsValid() )
+ {
+ TLocale locale;
+ iFile.Modified( iDateCreated );
+ iDateCreated += locale.UniversalTimeOffset();
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::SetSavingLocationL
+//
+// ---------------------------------------------------------------------------
+//
+void CVRMemo::SetSavingLocationL( const TDesC& aPath )
+ {
+ iSavingLocation = aPath;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::DeleteEmptyFile
+// Deletes an empty file that hasn't been recorded into. After deleting
+// also decreases central repository's memo count value
+// ---------------------------------------------------------------------------
+//
+TBool CVRMemo::DeleteEmptyFile()
+ {
+ if ( iFile.SubSessionHandle() != 0 )
+ {
+ TInt size( 0 );
+
+ // Error code ignored
+ iFile.Size( size );
+
+ if ( !iIsRecorded )
+ {
+ TFileName name( KNullDesC );
+ iFile.FullName( name );
+
+ iFile.Close();
+ iFileMan->Delete( name );
+
+ // Central repository value has to be decreased by one because it
+ // was increased earlier, when current filename was generated
+ VRUtils::SetMemoCount( VRUtils::MemoCount() - 1 );
+
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::SetFileHandle
+//
+// ---------------------------------------------------------------------------
+//
+void CVRMemo::SetFileHandle( RFile& aFile, const TBool aEmbedded )
+ {
+ iEmbedded = aEmbedded;
+ iExternalFileHandle = ETrue;
+
+ iFile = aFile;
+
+ // Set the correct name for UI
+ TFileName name( KNullDesC );
+ iFile.FullName( name );
+ SetName( name );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::MaxDuration
+// Returns in microseconds the maximum time that can be still recorded with
+// current settings (codecs and mem storage place)
+// ---------------------------------------------------------------------------
+//
+const TTimeIntervalMicroSeconds& CVRMemo::MaxDuration()
+ {
+ if ( iEmbedded ||
+ !VRUtils::FeatureEnabled( EVRFeatureShowQualitySetting ) ||
+ iQuality == EQualityMMSOptimized )
+ {
+ //Voice Recorder change to remove 1 Min. limit for AMR for Stand alone recording
+ //if embedded allow 1 min recording for EQualityMMSOptimized(AMR)
+ //else allow 1 hour recording
+ if(iEmbedded)
+ {
+ iMaxDuration = KVRMMSMemoMaxRecordLength;
+ return iMaxDuration;
+ }
+ }
+
+ // Make the first estimate after KVRFirstEstimateTime seconds recording
+ if ( Duration() < KVRFirstEstimateTime )
+ {
+ // Fetch the setting for high quality max length
+ TInt64 max( 0 );
+ TRAPD( err, max = VRUtils::MaxLengthL() );
+ if ( err != KErrNone )
+ {
+ max = KVRMMSMemoMaxRecordLength;
+ }
+
+ max = max * KVRMinuteAsMicroSeconds;
+ iMaxDuration = max;
+
+ // Reset the time of last estimate
+ TDateTime date;
+ date.SetYear( -1 );
+ iLastEstimate = date; // invalid
+
+ return iMaxDuration;
+ }
+
+ // Make new estimate if there's no last estimate or if 10 secs have passed
+ // from the previous estimate
+ TTime currentTime;
+ currentTime.HomeTime();
+ if ( iLastEstimate.DateTime().Year() == -1 ||
+ currentTime.MicroSecondsFrom( iLastEstimate ) >=
+ TTimeIntervalMicroSeconds( KVREstimateDelayDuration ) )
+ {
+ iLastEstimate = currentTime;
+
+ TEntry fileEntry;
+ TFileName name( KNullDesC );
+ iFile.FullName( name );
+
+ TInt err = iFs.Entry( name, fileEntry );
+ if( err != KErrNone )
+ {
+ return iMaxDuration;
+ }
+
+ // Retrieve free space
+ TVolumeInfo volInfo;
+
+// old storage
+#ifndef RD_MULTIPLE_DRIVE
+ TVRMemoStore memoStore( EMemoStorePhoneMemory );
+ TRAP( err, memoStore = VRUtils::MemoStoreL() );
+ if ( err != KErrNone )
+ {
+ memoStore = EMemoStorePhoneMemory;
+ }
+
+ if ( memoStore == EMemoStorePhoneMemory )
+ {
+ err = iFs.Volume( volInfo, EDriveC );
+ }
+ else // memostore is MMC
+ {
+ err = iFs.Volume( volInfo, EDriveE );
+ }
+
+// multiple drive
+#else
+
+ TInt drive = 0;
+ TRAP_IGNORE(drive = VRUtils::DefaultMemoDriveL());
+ TRAP( err, drive = VRUtils::MemoDriveL() );
+ if ( err != KErrNone )
+ {
+ TRAP_IGNORE(drive = VRUtils::DefaultMemoDriveL());
+ }
+ err = iFs.Volume( volInfo, drive );
+
+#endif
+
+ if( err != KErrNone )
+ {
+
+ return iMaxDuration;
+ }
+
+ // Calculate the current disk consumption "speed" of the memo
+ TReal speed( fileEntry.iSize / ( Duration().Int64() /
+ KVRSecondAsMicroSeconds ) );
+
+ // The total free memory
+ TInt64 freeSpace(volInfo.iFree);
+ // Free memory if Critical Memory isn't taken into account
+ TInt64 freeSpaceMinusCrlevel( freeSpace - KDRIVECCRITICALTHRESHOLD);
+
+ // Estimate the time left
+ TInt64 value( freeSpaceMinusCrlevel / speed );
+ TTimeIntervalMicroSeconds estimate( value * KVRSecondAsMicroSeconds );
+
+ // Estimate should include also the length of clip
+ estimate = TTimeIntervalMicroSeconds( estimate.Int64()
+ + Duration().Int64() );
+ if ( estimate < iMaxDuration)
+ {
+ iMaxDuration = estimate;
+ }
+ }
+
+ return iMaxDuration;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::IsRecorded
+// Returns the attribute iIsRecorded value that indicates if the recording of
+// the clip currently open is started or not
+// ---------------------------------------------------------------------------
+//
+TBool CVRMemo::IsRecorded() const
+ {
+ return iIsRecorded;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CVRMemo::SetRecorded
+// Sets the value of iIsRecorded attribute
+// ---------------------------------------------------------------------------
+//
+void CVRMemo::SetRecorded( TBool aRecorded )
+ {
+ iIsRecorded = aRecorded;
+ }
+
+// End of file