diff -r 000000000000 -r 845549f293a7 voicerecorder/RecViewSrc/CVRMemo.cpp --- /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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#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