diff -r 000000000000 -r bde4ae8d615e os/mm/mmlibs/mmfw/src/Client/Audio/mmfclientaudioconverter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/mm/mmlibs/mmfw/src/Client/Audio/mmfclientaudioconverter.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,1782 @@ +// Copyright (c) 2002-2009 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: +// + +#include +#include +#include +#include + +#include "mmfclientaudioconverter.h" + +// declared in the recorder module +void Panic(TInt aPanicCode); + +//CMdaAudioConvertUtility + + +/** +Returns the current utility state. + +@return The state of the audio sample data. See CMdaAudioClipUtility::TState. + +@since 5.0 +*/ +CMdaAudioClipUtility::TState CMdaAudioConvertUtility::State() + { + ASSERT(iProperties); + return iProperties->State(); + } + +/** +Closes the current audio clip. + +@since 5.0 +*/ +void CMdaAudioConvertUtility::Close() + { + ASSERT(iProperties); + iProperties->Close(); + } + +/** +This function is mapped to ConvertL(). ConvertL() should be used instead. + +@see ConvertL() + +@since 5.0 +*/ +void CMdaAudioConvertUtility::PlayL() + { + ASSERT(iProperties); + iProperties->PlayL(); + } + +/** +This function is mapped to ConvertL. ConvertL() should be used instead. + +@since 5.0 +*/ +void CMdaAudioConvertUtility::RecordL() + { + ASSERT(iProperties); + iProperties->RecordL(); + } + +/** +Stops the current operation (playback/recording/conversion). + +When conversion has been stopped, successfully or otherwise, the client is notified by +MMdaObjectStateChangeObserver::MoscoStateChangeEvent(). The callback is initiated by this function +providing it with state change information and error codes. + +@since 5.0 +*/ +void CMdaAudioConvertUtility::Stop() + { + ASSERT(iProperties); + iProperties->Stop(); + } + +/** +Crops the current clip from the current position. The remainder of the clip is discarded. + +The effects of the function cannot be undone. The function is synchronous and can leave if there is +a problem. The leave code depends on the configuration. + +@since 5.0 +*/ +void CMdaAudioConvertUtility::CropL() + { + ASSERT(iProperties); + iProperties->CropL(ETrue); + } + +/** +Sets the current position in the audio clip. + +A subsequent call to ConvertL() starts conversion from this new position. + +@param aPosition + The position in the audio clip, in microseconds. + +@since 5.0 +*/ +void CMdaAudioConvertUtility::SetPosition(const TTimeIntervalMicroSeconds& aPosition) + { + ASSERT(iProperties); + iProperties->SetPosition(aPosition); + } + +/** +Returns the current position in the audio clip. The position is defined in terms of a time interval +measured from the beginning of the audio sample data. + +@return The current position in the audio clip, in microseconds. + +@since 5.0 +*/ +const TTimeIntervalMicroSeconds& CMdaAudioConvertUtility::Position() + { + ASSERT(iProperties); + return iProperties->Position(); + } + +/** +Returns the amount of recording time available to the current clip. + +@return The recording time available measured in microseconds. + +@since 5.0 +*/ +const TTimeIntervalMicroSeconds& CMdaAudioConvertUtility::RecordTimeAvailable() + { + ASSERT(iProperties); + return iProperties->RecordTimeAvailable(); + } + +/** +Returns the duration of the audio clip. + +@return The duration in microseconds. + +@since 5.0 +*/ +const TTimeIntervalMicroSeconds& CMdaAudioConvertUtility::Duration() + { + ASSERT(iProperties); + return iProperties->Duration(); + } + +/** +Sets a window for playback. + +The window is defined in terms of a start and end time. A subsequent call to ConvertL() results +in just the data within the window being converted. + +@param aStart + The position in the clip to start playback, in microseconds. This must be any value from zero + to aEnd. If this value is less than zero or greater than aEnd, this function raises + EMMFMediaClientPanicServerCommunicationProblem panic in debug version. +@param aEnd + The position in the clip to end playback, in microseconds. This must be any value from aStart + to the value returned by Duration(). If this value is greater than the value returned by + Duration() or less than aStart, this function raises EMMFMediaClientPanicServerCommunicationProblem panic in debug version. + +@since 5.0 +*/ +void CMdaAudioConvertUtility::SetPlayWindow(const TTimeIntervalMicroSeconds& aStart, const TTimeIntervalMicroSeconds& aEnd) + { + ASSERT(iProperties); + iProperties->SetPlayWindow(aStart, aEnd); + } + +/** +Clears the playback window. + +Playback returns to playing the entire clip. A subsequent call to ConvertL() results in the entire +source audio being converted. + +@since 5.0 +*/ +void CMdaAudioConvertUtility::ClearPlayWindow() + { + ASSERT(iProperties); + iProperties->ClearPlayWindow(); + } + +/** +Sets the number of repetitions for playback. This is unsupported for CMdaConvertUtility as there is +no playback facility. It is provided only for binary compatibility. + +@param aRepeatNumberOfTimes + The number of times to repeat the audio clip, after the first playback. If this is set to + KMdaRepeatForever, then the audio sample, together with the trailing silence, is repeated + indefinitely. If this is set to zero, then the audio sample is not repeated. +@param aTrailingSilence + A delay to wait before each repetition. + +@since 5.0 +*/ +void CMdaAudioConvertUtility::SetRepeats(TInt aRepeatNumberOfTimes, const TTimeIntervalMicroSeconds& aTrailingSilence) + { + ASSERT(iProperties); + iProperties->SetRepeats(aRepeatNumberOfTimes, aTrailingSilence); + } + +/** +Sets the maximum size of an audio clip. + +This function is provided so that applications such as recorders and converters can limit the amount +of file storage/memory that should be allocated. + +@param aMaxWriteLength + The maximum size of the audio clip, in bytes. If the default value is used, there is no + maximum file size. + +@since 7.0 +*/ +void CMdaAudioConvertUtility::SetMaxWriteLength(TInt aMaxWriteLength /* = KMdaClipLocationMaxWriteLengthNone*/) + { + ASSERT(iProperties); + iProperties->SetMaxWriteLength(aMaxWriteLength); + } + +/** +Crops the audio clip from the start of the file to the current position. The audio data +prior to the current position is discarded. + +The effects of the function cannot be undone. + +The function is synchronous and can leave if there is a problem. The leave code depends on the +configuration. + +@since 7.0s +*/ +void CMdaAudioConvertUtility::CropFromBeginningL() + { + ASSERT(iProperties); + iProperties->CropL(EFalse); + } + +/** +Constructs and initialises a new instance of the audio converter for converting audio sample data +from one format to another. + +The function leaves if the audio converter object cannot be created. + +@param aObserver + The class to receive state change events from converter. +@param aServer + No longer used, should be NULL. +@param aPriority + The Priority Value - this client's relative priority. This is a value between EMdaPriorityMin and + EMdaPriorityMax and represents a relative priority. A higher value indicates a more important request. +@param aPref + The Priority Preference - an additional audio policy parameter. The suggested default is + EMdaPriorityPreferenceNone. Further values are given by TMdaPriorityPreference, and additional + values may be supported by given phones and/or platforms, but should not be depended upon by + portable code. + +@return A pointer to a new instance of CMdaAudioConvertUtility. + +@since 5.0 + +Note: The Priority Value and Priority Preference are used primarily when deciding what to do when +several audio clients attempt to play or record simultaneously. In addition to the Priority Value and Preference, +the adaptation may consider other parameters such as the SecureId and Capabilities of the client process. +Whatever, the decision as to what to do in such situations is up to the audio adaptation, and may +vary between different phones. Portable applications are advised not to assume any specific behaviour. +*/ +EXPORT_C CMdaAudioConvertUtility* CMdaAudioConvertUtility::NewL(MMdaObjectStateChangeObserver& aObserver, + CMdaServer* /*aServer*/, + TInt aPriority, + TInt aPref) + { + CMdaAudioConvertUtility* self = new(ELeave) CMdaAudioConvertUtility(); + CleanupStack::PushL(self); + self->iProperties = new(ELeave) CMMFMdaAudioConvertUtility(self, aObserver); + self->iProperties->ConstructL(aPriority, aPref); + CleanupStack::Pop(self); + return self; + } + +/** +Destructor. + +Closes the audio clip and frees resources. + +@since 5.0 +*/ +CMdaAudioConvertUtility::~CMdaAudioConvertUtility() + { + delete iProperties; + } + +/** +Ensures that any subsequent calls to OpenXYZ() will create controllers that +share a heap. + +The default behaviour is that for each converter utility a controller with its own heap +is created. Each heap uses a chunk, so using this function avoids situations where +the number of chunks per process is limited. +The default behaviour is generally to be preferred, and should give lower overall +memory usage. However, if many controllers are to be created for a particular thread, +then this function should be used to prevent running out of heaps or chunks. + +@since 9.2 +*/ +EXPORT_C void CMdaAudioConvertUtility::UseSharedHeap() + { + ASSERT(iProperties); + iProperties->UseSharedHeap(); + } + +/** +Opens source and target files (both of which must already exist) so that audio sample data can be +extracted from the source file, converted and appended to the target file. + +When opening is complete, successfully or otherwise, the client is notified by +MMdaObjectStateChangeObserver::MoscoStateChangeEvent(). The callback is initiated by this function +providing it with state change information and error codes. + +@param aPrimaryFile + The full path and filename of a file containing audio sample data to be converted. +@param aSecondaryFile + The full path and filename of a file to which converted data is appended. + +@since 5.0 +*/ +void CMdaAudioConvertUtility::OpenL(const TDesC& aPrimaryFile, const TDesC& aSecondaryFile) + { + ASSERT(iProperties); + iProperties->OpenL(aPrimaryFile, aSecondaryFile); + } + +/** +Opens an existing audio file so that audio sample data can be extracted from it, converted and +placed into the target audio object. + +When opening is complete, successfully or otherwise, the client is notified by +MMdaObjectStateChangeObserver::MoscoStateChangeEvent(). The callback is initiated by this function +providing it with state change information and error codes. + +@param aPrimaryFile + The full path and filename of a file containing audio sample data to be converted. +@param aLocation + The target location for the audio data. This is normally a file (TMdaFileClipLocation) or a + descriptor (TMdaDesClipLocation). +@param aFormat + The audio format for the target audio object. +@param aArg1 + The codec to use for the target audio object. +@param aArg2 + The audio settings for the target audio object. + +@since 5.0 +*/ +void CMdaAudioConvertUtility::OpenL(const TDesC& aPrimaryFile, TMdaClipLocation* aLocation, TMdaClipFormat* aFormat, + TMdaPackage* aArg1 /*= NULL*/, TMdaPackage* aArg2 /*= NULL*/) + { + ASSERT(iProperties); + iProperties->OpenL(aPrimaryFile, aLocation, aFormat, aArg1, aArg2); + } + +/** +Opens an audio clip for conversion. + +@param aPriLocation + The source location for audio data. This is normally a file (TMdaFileClipLocation) or a + descriptor (TMdaDesClipLocation). +@param aSecLocation + The target location for audio data. This is normally a file (TMdaFileClipLocation) or a + descriptor (TMdaDesClipLocation). +@param aPriFormat + The audio format of the source audio object. +@param aSecFormat + The audio format for the target audio object. +@param aPriArg1 + The codec used by the source audio object. +@param aPriArg2 + The audio settings of the source audio object. +@param aSecArg1 + The codec to be used for the target audio object. +@param aSecArg2 + The audio settings for the target audio object. + +@since 5.0 +*/ +void CMdaAudioConvertUtility::OpenL(TMdaClipLocation* aPriLocation, TMdaClipLocation* aSecLocation, + TMdaClipFormat* aPriFormat, TMdaClipFormat* aSecFormat, + TMdaPackage* aPriArg1 /*= NULL*/, TMdaPackage* aPriArg2 /*= NULL*/, + TMdaPackage* aSecArg1 /*= NULL*/, TMdaPackage* aSecArg2 /*= NULL*/) + { + ASSERT(iProperties); + iProperties->OpenL(aPriLocation, aSecLocation, aPriFormat, aSecFormat, aPriArg1, aPriArg2, aSecArg1, aSecArg2); + } + +// New functions for 7.0s +/** +Opens source and target audio objects and specifies controller and audio format and codec +information. + +When opening is complete, successfully or otherwise, the client is notified by +MMdaObjectStateChangeObserver::MoscoStateChangeEvent(). The callback is initiated by this function +providing it with state change information and error codes. + +@param aPriLocation + The source location for audio data. This is normally a file (TMdaFileClipLocation) or a + descriptor (TMdaDesClipLocation). +@param aSecLocation + The destination location for the converted audio data. This is normally a file + (TMdaFileClipLocation) or a descriptor (TMdaDesClipLocation). +@param aControllerUid + The UID of the controller to used for conversion. +@param aDestFormatUid + The UID of the destination format. +@param aDestDataType + The audio codec to use for the destination data sink. + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::OpenL(TMdaClipLocation* aPriLocation, TMdaClipLocation* aSecLocation, TUid aControllerUid, + TUid aDestFormatUid, TFourCC aDestDataType) + { + ASSERT(iProperties); + iProperties->OpenL(aPriLocation, aSecLocation, aControllerUid, aDestFormatUid, aDestDataType); + } + +/** +Returns a list of the supported data types for the conversion destination. + +@param aSupportedDestinationDataTypes + A list of four character codes, representing the supported data + encodings for the conversion destination. + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::GetSupportedDestinationDataTypesL(RArray& aSupportedDestinationDataTypes) + { + ASSERT(iProperties); + iProperties->GetSupportedDestinationDataTypesL(aSupportedDestinationDataTypes); + } + +/** +Sets the data type of the destination audio clip. + +@param aCodec + The four character code, representing the encoding of the destination audio clip + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::SetDestinationDataTypeL(TFourCC aCodec) + { + ASSERT(iProperties); + iProperties->SetDestinationDataTypeL(aCodec); + } + +/** +Returns the data type of the destination audio clip. + +@return The four character code, representing the encoding of the destination audio clip. + +@since 7.0s +*/ +EXPORT_C TFourCC CMdaAudioConvertUtility::DestinationDataTypeL() + { + ASSERT(iProperties); + return iProperties->DestinationDataTypeL(); + } + +/** +Returns the data type of the source audio clip. + +@return The four character code, representing the encoding of the source audio clip. + +@since 7.0s +*/ +EXPORT_C TFourCC CMdaAudioConvertUtility::SourceDataTypeL() + { + ASSERT(iProperties); + return iProperties->SourceDataTypeL(); + } + +/** +Sets the bit rate of the destination audio clip. + +The bit rate must be one of the supported bit rates of the audio target. Use +GetSupportedConversionBitRatesL() to retrieve a list of supported bit rates. + +@param aBitRate + The destination bit rate in bits/second. + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::SetDestinationBitRateL(TUint aBitRate) + { + ASSERT(iProperties); + iProperties->SetDestinationBitRateL(aBitRate); + } + +/** +Returns the bit rate of the destination audio clip. + +@return The destination bit rate in bits/second. + +@since 7.0s +*/ +EXPORT_C TUint CMdaAudioConvertUtility::DestinationBitRateL() + { + ASSERT(iProperties); + return iProperties->DestinationBitRateL(); + } + +/** +Gets a list of the supported bit rates for the conversion destination. + +@param aSupportedBitRates + The list of bit rates supported for the conversion destination. + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::GetSupportedConversionBitRatesL(RArray& aSupportedBitRates) + { + ASSERT(iProperties); + iProperties->GetSupportedConversionBitRatesL(aSupportedBitRates); + } + +/** +Returns the bit rate of the source audio clip. + +@return The source bit rate in bits/second. + +@since 7.0s +*/ +EXPORT_C TInt CMdaAudioConvertUtility::SourceBitRateL() + { + ASSERT(iProperties); + return iProperties->SourceBitRateL(); + } + +/** +Sets the sample rate for the conversion destination. + +The sample rate must be one of the supported sample rates of the audio target. Use +GetSupportedConversionSampleRatesL() to retrieve a list of supported sample rates. +This function should not be used if the audio clip already exists; that is, in the +"Open and Append" scenario, when the function's behaviour is undefined. + +@param aSampleRate + The sample rate of the conversion destination in samples per second. + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::SetDestinationSampleRateL(TUint aSampleRate) + { + ASSERT(iProperties); + iProperties->SetDestinationSampleRateL(aSampleRate); + } + +/** +Returns the sample rate of the conversion destination. + +@return The sample rate of the conversion destination in samples per second. + +@since 7.0s +*/ +EXPORT_C TUint CMdaAudioConvertUtility::DestinationSampleRateL() + { + ASSERT(iProperties); + return iProperties->DestinationSampleRateL(); + } + +/** +Gets a list of supported conversion sample rates. This is a list of the sample rates that +the conversion destination can take. + +@param aSupportedSampleRates + A list of the sample rates that are supported for the conversion. + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::GetSupportedConversionSampleRatesL(RArray& aSupportedSampleRates) + { + ASSERT(iProperties); + iProperties->GetSupportedConversionSampleRatesL(aSupportedSampleRates); + } + +/** +Returns the sample rate of the source audio clip. + +@return The source sample rate in samples/second. + +@since 7.0s +*/ +EXPORT_C TUint CMdaAudioConvertUtility::SourceSampleRateL() + { + ASSERT(iProperties); + return iProperties->SourceSampleRateL(); + } + +/** +Sets the format of the destination audio clip. + +The UID (aFormatUid) corresponds to the UID of the destination format to use. + +@param aFormatUid + The UID of the destination format. + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::SetDestinationFormatL(TUid aFormatUid) + { + ASSERT(iProperties); + iProperties->SetDestinationFormatL(aFormatUid); + } + +/** +Returns the format of the destination audio clip. + +@return The UID of the destination format. + +@since 7.0s +*/ +EXPORT_C TUid CMdaAudioConvertUtility::DestinationFormatL() + { + ASSERT(iProperties); + return iProperties->DestinationFormatL(); + } + +/** +Returns the format of the source audio clip. + +@return The UID of the source format. + +@since 7.0s +*/ +EXPORT_C TUid CMdaAudioConvertUtility::SourceFormatL() + { + ASSERT(iProperties); + return iProperties->SourceFormatL(); + } + +/** +Sets the number of channels the destination audio clip contains. + +The number of channels must be one of the values returned by +GetSupportedConversionNumberOfChannelsL(). + +@param aNumberOfChannels + The number of channels. + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::SetDestinationNumberOfChannelsL(TUint aNumberOfChannels) + { + ASSERT(iProperties); + iProperties->SetDestinationNumberOfChannelsL(aNumberOfChannels); + } + +/** +Returns the number of channels the destination audio clip contains. + +@return The number of channels. + +@since 7.0s +*/ +EXPORT_C TUint CMdaAudioConvertUtility::DestinationNumberOfChannelsL() + { + ASSERT(iProperties); + return iProperties->DestinationNumberOfChannelsL(); + } + +/** +Returns a list of the supported number of channels for conversion. + +For example, 1 for mono, 2 for stereo and so on. + +@param aSupportedNumChannels + A list of the number of channels supported for the conversion destination. + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::GetSupportedConversionNumberOfChannelsL(RArray& aSupportedNumChannels) + { + ASSERT(iProperties); + iProperties->GetSupportedConversionNumberOfChannelsL(aSupportedNumChannels); + } + +/** +Returns the number of channels used by the conversion source. + +@return The number of channels. + +@since 7.0s +*/ +EXPORT_C TUint CMdaAudioConvertUtility::SourceNumberOfChannelsL() + { + ASSERT(iProperties); + return iProperties->SourceNumberOfChannelsL(); + } +/** +Performs the conversion from the source audio format to the destination. + +When conversion is complete, successfully or otherwise, the client is notified by +MMdaObjectStateChangeObserver::MoscoStateChangeEvent(). The callback is initiated by this function +providing it with state change information and error codes. + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::ConvertL() + { + ASSERT(iProperties); + iProperties->ConvertL(); + } + +/** +Returns the controller implementation information associated with the current controller. + +@return The controller implementation structure associated with the controller + +@since 7.0s +*/ +EXPORT_C const CMMFControllerImplementationInformation& CMdaAudioConvertUtility::ControllerImplementationInformationL() + { + ASSERT(iProperties); + return iProperties->ControllerImplementationInformationL(); + } + +/** +Sends a synchronous custom command to the controller. + +@param aDestination + The destination of the message, consisting of the UID of the interface of this message. +@param aFunction + The function number to indicate which function is to be called + on the interface defined in the aDestination parameter. +@param aDataTo1 + A reference to the first chunk of data to be copied to the controller + framework. The exact contents of the data are dependent on the + interface being called. Can be KNullDesC8. +@param aDataTo2 + A reference to the second chunk of data to be copied to the controller + framework. The exact contents of the data are dependent on the + interface being called. Can be KNullDesC8. +@param aDataFrom + A reference to an area of memory to which the controller framework will + write any data to be passed back to the client. Can't be KNullDesC8. + +@return The result of the request. Exact range of values is dependent on the interface. + +@since 7.0s +*/ +EXPORT_C TInt CMdaAudioConvertUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom) + { + ASSERT(iProperties); + return iProperties->CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom); + } + +/** +Sends a synchronous custom command to the controller. + +@param aDestination + The destination of the message, consisting of the UID of the interface of this message. +@param aFunction + The function number to indicate which function is to be called on the interface defined in + the aDestination parameter. +@param aDataTo1 + A reference to the first chunk of data to be copied to the controllert framework. The exact + contents of the data are dependent on the interface being called. Can be KNullDesC8. +@param aDataTo2 + A reference to the second chunk of data to be copied to the controller framework. The exact + contents of the data are dependent on the interface being called. Can be KNullDesC8. + +@return The result of the request. The exact range of values is dependent on the interface. + +@since 7.0s +*/ +EXPORT_C TInt CMdaAudioConvertUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2) + { + ASSERT(iProperties); + return iProperties->CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2); + } + +/** +Send a asynchronous custom command to the controller. + +Note: This method will return immediately. The RunL of the active object owning the +aStatus parameter will be called when the command is completed by the controller framework. + +@param aDestination + The destination of the message, consisting of the UID of the interface of this message. +@param aFunction + The function number to indicate which function is to be called on the interface defined in + the aDestination parameter. +@param aDataTo1 + A reference to the first chunk of data to be copied to the controller framework. The exact + contents of the data are dependent on the interface being called. Can be KNullDesC8. +@param aDataTo2 + A reference to the second chunk of data to be copied to the controller framework. The exact + contents of the data are dependent on the interface being called. Can be KNullDesC8. +@param aDataFrom + A reference to an area of memory to which the controller framework will write any data to be + passed back to the client. Can't be KNullDesC8. +@param aStatus + The TRequestStatus of an active object. This will contain the result of the request on + completion. The exact range of result values is dependent on the interface. +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus) + { + ASSERT(iProperties); + iProperties->CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus); + } + +/** +Send a asynchronous custom command to the controller. + +Note: This method will return immediately. The RunL of the active object owning the +aStatus parameter will be called when the command is completed by the controller framework. + +@param aDestination + The destination of the message, consisting of the UID of the interface of this message. +@param aFunction + The function number to indicate which function is to be called on the interface defined in + the aDestination parameter. +@param aDataTo1 + A reference to the first chunk of data to be copied to the controller framework. The exact + contents of the data are dependent on the interface being called. Can be KNullDesC8. +@param aDataTo2 + A reference to the second chunk of data to be copied to the controller framework. The exact + contents of the data are dependent on the interface being called. Can be KNullDesC8. +@param aStatus + The TRequestStatus of an active object. This will contain the result of the request on + completion. The exact range of result values is dependent on the interface. + +@since 7.0s +*/ +EXPORT_C void CMdaAudioConvertUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus) + { + ASSERT(iProperties); + iProperties->CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus); + } + +/** +Set the priority of the controller's sub thread. + +This can be used to increase the responsiveness of the audio plugin to minimise +any lag in processing. This function should be used with care as it may have knock-on +effects elsewhere in the system. + +@param aPriority + The TThreadPriority that the thread should run under. The default is EPriorityNormal. +@return TInt + A standard error code: KErrNone if successful, KErrNotReady if the thread does not have a + valid handle. +*/ +EXPORT_C TInt CMdaAudioConvertUtility::SetThreadPriority(const TThreadPriority& aThreadPriority) const + { + ASSERT(iProperties); + return iProperties->SetThreadPriority(aThreadPriority); + } + + +/******************************************************************************/ + + +CMMFMdaAudioConvertUtility::CMMFMdaAudioConvertUtility(CMdaAudioConvertUtility* aParent, + MMdaObjectStateChangeObserver& aCallback) : + iCallback(aCallback), + iAudioControllerCustomCommands(iController), + iAudioPlayControllerCustomCommands(iController), + iAudioRecordControllerCustomCommands(iController), + iParent(aParent), + iHasCropped(EFalse), + iCroppedDuration(0) + { + iConvertStart = TTimeIntervalMicroSeconds(0); + iConvertEnd = TTimeIntervalMicroSeconds(0); + iConvertWindowSet = EFalse; + } + +void CMMFMdaAudioConvertUtility::ConstructL(TInt /*aPriority*/, TInt /*aPref*/) + { + iControllerEventMonitor = CMMFControllerEventMonitor::NewL(*this, iController); + iAsyncCallback = CMMFMdaObjectStateChangeObserverCallback::NewL(iCallback); + User::LeaveIfError(iMediaIds.Append(KUidMediaTypeAudio)); + iFindAndOpenController = CMMFFindAndOpenController::NewL(*this); + iFindAndOpenController->Configure(iMediaIds[0], iPrioritySettings); + iFindAndOpenController->ConfigureController(iController, *iControllerEventMonitor, CMMFFindAndOpenController::EConvert); + } + +CMMFMdaAudioConvertUtility::~CMMFMdaAudioConvertUtility() + { + delete iControllerImplementationInformation; + delete iAsyncCallback; + delete iFindAndOpenController; + delete iControllerEventMonitor; + iMediaIds.Close(); + iController.Close(); + } + +void CMMFMdaAudioConvertUtility::UseSharedHeap() + { + iFindAndOpenController->UseSharedHeap(); + } + +void CMMFMdaAudioConvertUtility::MfaocComplete( + TInt& aError, + RMMFController* /*aController*/, + TUid aControllerUid, + TMMFMessageDestination* /*aSourceHandle*/, + TMMFMessageDestination* /*aSinkHandle*/) + { + TInt oldState = iState; + + if (aError == KErrNone) + { + iControllerUid = aControllerUid; + aError = ControllerOpen(); + if (iFindAndOpenController) + { + iFindAndOpenController->Close(); + } + } + + iAsyncCallback->CallBack(iParent, oldState, iState, aError); + } + +void CMMFMdaAudioConvertUtility::OpenL(TMdaClipLocation* aPriLocation, + TMdaClipLocation* aSecLocation, + TMdaClipFormat* aPriFormat, + TMdaClipFormat* aSecFormat, + TMdaPackage* aPriArg1 /*= NULL*/, + TMdaPackage* aPriArg2 /*= NULL*/, + TMdaPackage* aSecArg1 /*= NULL*/, + TMdaPackage* aSecArg2 /*= NULL*/) + { + __ASSERT_ALWAYS((aPriLocation && aSecLocation && aPriFormat && aSecFormat), User::Leave(KErrArgument)); + + __ASSERT_ALWAYS((((aPriLocation->Uid() == KUidMdaFileResLoc) || (aPriLocation->Uid() == KUidMdaDesResLoc) || (aPriLocation->Uid() == KUidMdaUrlResLoc)) && + ((aSecLocation->Uid() == KUidMdaFileResLoc) || (aSecLocation->Uid() == KUidMdaDesResLoc) || (aSecLocation->Uid() == KUidMdaUrlResLoc))), + User::Leave(KErrNotSupported)); + + __ASSERT_ALWAYS(((aPriFormat->Uid() != KNullUid) && (aSecFormat->Uid() != KNullUid)), User::Leave(KErrNotSupported)); + + Reset(); + + //Do aPriArg2 & aSecArg2 contain the correct package type + if(aPriArg2) + { + TMdaPackage* pckg = aPriArg2; + if(pckg->Uid() != KUidMdaMediaTypeAudio) + User::Leave(KErrNotSupported); + + TMdaAudioDataSettings audioSettings = *(TMdaAudioDataSettings*)aPriArg2; + iSourceSampleRate = audioSettings.iSampleRate; + iSourceChannels = audioSettings.iChannels; + } + + if(aSecArg2) + { + TMdaPackage* pckg = aSecArg2; + if(pckg->Uid() != KUidMdaMediaTypeAudio) + User::Leave(KErrNotSupported); + TMdaAudioDataSettings audioSettings = *(TMdaAudioDataSettings*)aSecArg2; + iSinkSampleRate = audioSettings.iSampleRate; + iSinkChannels = audioSettings.iChannels; + } + + + //Do aPriArg1 & aSecArg1 contain supported FourCC types + iSourceDataType = KMMFFourCCCodeNULL; + if (aPriArg1) + { + iSourceDataType = CMMFClientUtility::ConvertMdaCodecToFourCC(*aPriArg1); + if(iSourceDataType == KMMFFourCCCodeNULL) + User::Leave(KErrNotSupported); + } + + iSinkDataType = KMMFFourCCCodeNULL; + if (aSecArg1) + { + iSinkDataType = CMMFClientUtility::ConvertMdaCodecToFourCC(*aSecArg1); + if(iSinkDataType == KMMFFourCCCodeNULL) + User::Leave(KErrNotSupported); + } + + + + TInt err = KErrNone; + + iSourceFormatUid = CMMFClientUtility::ConvertMdaFormatUidToECOMRead(aPriFormat->Uid()); + //If a new formatter plugin has been added, use the supplied read format implementation ID + if (iSourceFormatUid == KNullUid) + iSourceFormatUid = aPriFormat->Uid(); + + iSinkFormatUid = CMMFClientUtility::ConvertMdaFormatUidToECOMWrite(aSecFormat->Uid()); + //If a new formatter plugin has been added, use the supplied write format implementation ID + if (iSinkFormatUid == KNullUid) + iSinkFormatUid = aSecFormat->Uid(); + + TRAP(err, ConfigureSourceSinkL(aPriLocation, aSecLocation)); + + if (!err) + iFindAndOpenController->OpenByFormatUid(iSourceFormatUid, iSinkFormatUid); + + if (err) + { + TInt oldState = State(); + iAsyncCallback->CallBack(iParent, oldState, oldState, err); + return; + } + } + + + + +void CMMFMdaAudioConvertUtility::OpenL(const TDesC& aPrimaryFile, const TDesC& aSecondaryFile) + { + Reset(); + + iFindAndOpenController->ConfigureSourceSink( + CMMFFindAndOpenController::TSourceSink(KUidMmfFileSource, CMMFFindAndOpenController::GetConfigFile(aPrimaryFile)), + CMMFFindAndOpenController::TSourceSink(KUidMmfFileSink, CMMFFindAndOpenController::GetConfigFile(aSecondaryFile))); + + TMMFileSource tfs(aPrimaryFile); + iFindAndOpenController->OpenByFileSource(tfs, aSecondaryFile); + } + +void CMMFMdaAudioConvertUtility::OpenL(const TDesC& aPrimaryFile, + TMdaClipLocation* aLocation, // Normally file or descriptor + TMdaClipFormat* aFormat, // Data format + TMdaPackage* aArg1, // Normally codec to use + TMdaPackage* aArg2) // Normally audio settings + { + __ASSERT_ALWAYS(aLocation && aFormat, User::Leave(KErrArgument)); + + Reset(); + + // convert from the old parameters + if (aFormat) + { + iSinkFormatUid = CMMFClientUtility::ConvertMdaFormatUidToECOMWrite(aFormat->Uid()); + + //If a new formatter plugin has been added, use the supplied format ID + if (iSinkFormatUid == KNullUid) + iSinkFormatUid = aFormat->Uid(); + } + + if (aArg1) + iSinkDataType = CMMFClientUtility::ConvertMdaCodecToFourCC(*aArg1); + + if (aArg2) + {//have audio settings + TMdaAudioDataSettings audioSettings = *(TMdaAudioDataSettings*)aArg2; //shoud check arg2 are data settings + iSinkSampleRate = audioSettings.iSampleRate; + iSinkChannels = audioSettings.iChannels; + } + + + + TMMFFileConfig sourceCfg; + sourceCfg().iPath = aPrimaryFile; + + TMMFDescriptorConfig dstDesCfg; + TMMFFileConfig dstFileCfg; + CBufFlat* dstCfgBuffer = NULL; + CMMFUrlParams* dstURLCfg = NULL; + TUid dstUid = KNullUid; + TPtrC8 dstCfg(NULL, 0); + + TInt err = KErrNone; + + if (aLocation->Uid() == KUidMdaFileResLoc) + {//sink clip location is a file + TDesC& fileName = ((TMdaFileClipLocation*)aLocation)->iName; + dstFileCfg().iPath = fileName; + dstCfg.Set(dstFileCfg); + dstUid = KUidMmfFileSink; + } + else if (aLocation->Uid() == KUidMdaDesResLoc) + {//sink clip is a descriptor - pass down descriptor & thread id + TMdaDesClipLocation* desLoc = (TMdaDesClipLocation*)aLocation; + dstDesCfg().iDes = desLoc->iDes; + dstDesCfg().iDesThreadId = desLoc->iThreadId; + dstCfg.Set(dstDesCfg); + dstUid = KUidMmfDescriptorSink; + } + else if (aLocation->Uid() == KUidMdaUrlResLoc) + { + TMdaUrlClipLocation* desLoc = (TMdaUrlClipLocation*)aLocation; + dstURLCfg = CMMFUrlParams::NewLC(desLoc->iUrl, desLoc->iIapId); + dstCfgBuffer = dstURLCfg->ExternalizeToCBufFlatLC(); + dstCfg.Set(dstCfgBuffer->Ptr(0)); + dstUid = KUidMmfUrlSink; + } + else + err = KErrNotSupported; + + if (!err) + { + iFindAndOpenController->ConfigureSourceSink( + CMMFFindAndOpenController::TSourceSink(KUidMmfFileSource, sourceCfg), + CMMFFindAndOpenController::TSourceSink(dstUid, dstCfg)); + + TMMFileSource tfs(aPrimaryFile); + iFindAndOpenController->OpenByFileSource(tfs); + } + + + + if (dstCfgBuffer) + CleanupStack::PopAndDestroy(dstCfgBuffer); + if (dstURLCfg) + CleanupStack::PopAndDestroy(dstURLCfg); + + + if (err) + { + TInt oldState = State(); + iAsyncCallback->CallBack(iParent, oldState, oldState, err); + return; + } + } + +void CMMFMdaAudioConvertUtility::OpenL(TMdaClipLocation* aPriLocation, + TMdaClipLocation* aSecLocation, + TUid aControllerUid, // the controller to use + TUid aDestFormatUid, + TFourCC aDestDataType) + { + __ASSERT_ALWAYS(aPriLocation && aSecLocation, User::Leave(KErrArgument)); + + Reset(); + + + // Configure the destination format and data type + if (aDestFormatUid != KNullUid) + iSinkFormatUid = aDestFormatUid; + + if (aDestDataType != KMMFFourCCCodeNULL) + iSinkDataType = aDestDataType; + + TRAPD(err, ConfigureSourceSinkL(aPriLocation, aSecLocation)); + if (!err) + iFindAndOpenController->OpenByControllerUid(aControllerUid); + + + if (err) + { + TInt oldState = State(); + iAsyncCallback->CallBack(iParent, oldState, oldState, err); + return; + } + } + + +void CMMFMdaAudioConvertUtility::HandleEvent(const TMMFEvent& aEvent) + { + //When converting, state is EPlaying, ERecording is never used + if (aEvent.iEventType==KMMFEventCategoryPlaybackComplete || aEvent.iEventType==KMMFErrorCategoryControllerGeneralError) + { + TInt oldState = iState; + iState = CMdaAudioClipUtility::EOpen; + + //if we weren't converting, don't advise Client. + if(oldState == CMdaAudioClipUtility::EPlaying) + iCallback.MoscoStateChangeEvent(iParent, CMdaAudioClipUtility::EPlaying, iState, aEvent.iErrorCode); + } + } + +void CMMFMdaAudioConvertUtility::PlayL() + { + // N.B. ConvertL should be used in preference to PlayL + ConvertL(); + } + +void CMMFMdaAudioConvertUtility::RecordL() + { + // N.B. ConvertL should be used in preference to RecordL + ConvertL(); + } + +void CMMFMdaAudioConvertUtility::ConvertL() + { + if (iState == CMdaAudioClipUtility::EOpen) + { + TInt err; + err = iController.Prime(); + if (err==KErrNone) + { + err=iController.SetPosition(iPosition); + if (!err && iConvertWindowSet) + err = iAudioPlayControllerCustomCommands.SetPlaybackWindow(iConvertStart, iConvertEnd); + if (err==KErrNone) + err = iController.Play(); + } + + TInt oldState = iState; + if (!err) + iState = CMdaAudioClipUtility::EPlaying; + + iAsyncCallback->CallBack(iParent, oldState, iState, err); + } + else + iAsyncCallback->CallBack(iParent, iState, iState, KErrNotReady); + } + +void CMMFMdaAudioConvertUtility::Stop() + { + TInt err = iController.Pause(); + TInt oldState = iState; + if (!err) + iState = CMdaAudioClipUtility::EOpen; + iAsyncCallback->CallBack(iParent, oldState, iState, err); + } + +void CMMFMdaAudioConvertUtility::CropL(TBool aCropToEnd) + { + // if we are busy converting, or we have not opened the file, return KErrNotReady + if (iState!=CMdaAudioClipUtility::EOpen) + User::Leave(KErrNotReady); + + // check that cropping position is valid if clip has been cropped before + if (iHasCropped && iPosition > iCroppedDuration) + { + User::Leave(KErrArgument); + } + + TInt err = iController.Prime(); + if (!err) + { + + if (!err) + err = iController.SetPosition(iPosition); + + err = iAudioRecordControllerCustomCommands.Crop(aCropToEnd); + // try to stop controller regardless of whether any of the above commands failed + iController.Stop(); + // save the duration of the cropped clip because + // Duration() returns length of the original clip only + // this is used to prevent a subsequent crop, beyond the end of the + // already cropped clip. + if (err == KErrNone) + { + iHasCropped = ETrue; + if (aCropToEnd) + iCroppedDuration = iPosition; + else + iCroppedDuration = TTimeIntervalMicroSeconds(iDuration.Int64() - iPosition.Int64()); + } + } + User::LeaveIfError(err); + } + +void CMMFMdaAudioConvertUtility::SetPosition(const TTimeIntervalMicroSeconds& aPosition) + { + iPosition = aPosition; + + // Clip the position if aPosition is greater than the duration, or less then 0 + const TTimeIntervalMicroSeconds duration = Duration(); + if (iPosition > duration) + iPosition = duration; + else if (iPosition < TTimeIntervalMicroSeconds(0)) + iPosition = 0; + + if (iState==CMdaAudioClipUtility::EPlaying) + iController.SetPosition(iPosition); + } + +const TTimeIntervalMicroSeconds& CMMFMdaAudioConvertUtility::Position() + { + if (iState==CMdaAudioClipUtility::EPlaying) + { + TInt err = iController.GetPosition(iPositionTemp); + if (err==KErrNone) + return iPositionTemp; + } + return iPosition; + } + +const TTimeIntervalMicroSeconds& CMMFMdaAudioConvertUtility::RecordTimeAvailable() + { +#ifdef _DEBUG + TInt error = +#endif + iAudioRecordControllerCustomCommands.GetRecordTimeAvailable(iRecordTimeAvailable); + __ASSERT_DEBUG(error==KErrNone, Panic(EMMFMediaClientPanicServerCommunicationProblem)); + return iRecordTimeAvailable; + } + +const TTimeIntervalMicroSeconds& CMMFMdaAudioConvertUtility::Duration() + { + TInt err = iController.GetDuration(iDuration); + if (err) + iDuration = 0; + return iDuration; + } + +void CMMFMdaAudioConvertUtility::SetMaxWriteLength(TInt aMaxWriteLength) + { + iAudioRecordControllerCustomCommands.SetMaxFileSize(aMaxWriteLength); + } + + +void CMMFMdaAudioConvertUtility::SetPlayWindow(const TTimeIntervalMicroSeconds& aStart, const TTimeIntervalMicroSeconds& aEnd) + { + if (aStart >= TTimeIntervalMicroSeconds(0) && + aStart < iDuration && + aStart <= aEnd && + aEnd <= iDuration ) + { + iConvertStart = aStart; + iConvertEnd = aEnd; + iConvertWindowSet = ETrue; + + if (iState==CMdaAudioClipUtility::EPlaying) + { +#ifdef _DEBUG + TInt error = +#endif + iAudioPlayControllerCustomCommands.SetPlaybackWindow(aStart, aEnd); + __ASSERT_DEBUG(error==KErrNone, Panic(EMMFMediaClientPanicServerCommunicationProblem)); + } + } + else + { + __ASSERT_DEBUG(EFalse, Panic(EMMFMediaClientPanicServerCommunicationProblem)); + } + } + +void CMMFMdaAudioConvertUtility::ClearPlayWindow() + { + iConvertWindowSet = EFalse; +#ifdef _DEBUG + TInt err = +#endif //_DEBUG + iAudioPlayControllerCustomCommands.DeletePlaybackWindow(); + __ASSERT_DEBUG(err==KErrNone, Panic(EMMFMediaClientPanicServerCommunicationProblem)); + } + +void CMMFMdaAudioConvertUtility::SetRepeats(TInt /*aRepeatNumberOfTimes*/, const TTimeIntervalMicroSeconds& /*aTrailingSilence*/) + { + // This doesn't really make sense for the converter. + } + +void CMMFMdaAudioConvertUtility::SetPriority(TInt aPriority, TInt aPref) + { + iPrioritySettings.iPref = aPref; + iPrioritySettings.iPriority = aPriority; + iFindAndOpenController->Configure(iMediaIds[0], iPrioritySettings); + iController.SetPrioritySettings(iPrioritySettings); + } + + +void CMMFMdaAudioConvertUtility::Close() + { + iControllerEventMonitor->Cancel(); + iController.Close(); + + if (iFindAndOpenController) + iFindAndOpenController->Close(); + + iHasCropped = EFalse; + iCroppedDuration = 0; + iState = CMdaAudioClipUtility::ENotReady; + if(iControllerImplementationInformation) + { + delete iControllerImplementationInformation; + iControllerImplementationInformation = NULL; + } + iControllerUid = KNullUid; + } + +void CMMFMdaAudioConvertUtility::CropL(const TTimeIntervalMicroSeconds &aCropBegin, + const TTimeIntervalMicroSeconds &aCropEnd) + { + // if we are busy converting, or we have not opened the file, return KErrNotReady + if (iState!=CMdaAudioClipUtility::EOpen) + User::Leave(KErrNotReady); + + // check that cropping positions are valid if clip has been cropped before + if (iHasCropped && aCropEnd > iCroppedDuration) + { + User::Leave(KErrArgument); + } + + TInt err = iController.Prime(); + if (!err) + { + err =iController.SetPosition(aCropEnd); + if (!err) + err = iAudioRecordControllerCustomCommands.Crop(ETrue); + if (!err) + { + //remember the cropping, store the cropped length + iHasCropped = ETrue; + iCroppedDuration = aCropEnd; + err = iController.SetPosition(aCropBegin); + } + if (!err) + err = iAudioRecordControllerCustomCommands.Crop(EFalse); + if (!err) // store the new cropped length + iCroppedDuration = TTimeIntervalMicroSeconds(aCropEnd.Int64() - aCropBegin.Int64()); + + // try to stop controller regardless of whether any of the above commands failed + iController.Stop(); + } + User::LeaveIfError(err); + } + +CMdaAudioClipUtility::TState CMMFMdaAudioConvertUtility::State() + { + return iState; + } + +void CMMFMdaAudioConvertUtility::GetSupportedDestinationDataTypesL(RArray& aSupportedDataTypes) + { + iAudioControllerCustomCommands.GetSupportedSinkDataTypesL(aSupportedDataTypes); + } + +void CMMFMdaAudioConvertUtility::SetSourceDataTypeL(TFourCC aDataType) + { + User::LeaveIfError(iAudioControllerCustomCommands.SetSourceDataType(aDataType)); + } + +void CMMFMdaAudioConvertUtility::SetDestinationDataTypeL(TFourCC aDataType) + { + User::LeaveIfError(iAudioControllerCustomCommands.SetSinkDataType(aDataType)); + } + +TFourCC CMMFMdaAudioConvertUtility::DestinationDataTypeL() + { + TFourCC dataType; + User::LeaveIfError(iAudioControllerCustomCommands.GetSinkDataType(dataType)); + return dataType; + } + +TFourCC CMMFMdaAudioConvertUtility::SourceDataTypeL() + { + TFourCC dataType; + User::LeaveIfError(iAudioControllerCustomCommands.GetSourceDataType(dataType)); + return dataType; + } + + +void CMMFMdaAudioConvertUtility::SetDestinationBitRateL(TUint aBitRate) + { + User::LeaveIfError(iAudioControllerCustomCommands.SetSinkBitRate(aBitRate)); + } + +void CMMFMdaAudioConvertUtility::SetSourceSampleRateL(TUint aSampleRate) + { + User::LeaveIfError(iController.Stop()); + User::LeaveIfError(iAudioControllerCustomCommands.SetSourceSampleRate(aSampleRate)); + } + +void CMMFMdaAudioConvertUtility::SetDestinationSampleRateL(TUint aSampleRate) + { + User::LeaveIfError(iController.Stop()); + User::LeaveIfError(iAudioControllerCustomCommands.SetSinkSampleRate(aSampleRate)); + } + +void CMMFMdaAudioConvertUtility::SetSourceFormatL(TUid aRecordFormat) + { + User::LeaveIfError(iAudioControllerCustomCommands.SetSourceFormat(aRecordFormat)); + } + +void CMMFMdaAudioConvertUtility::SetDestinationFormatL(TUid aRecordFormat) + { + User::LeaveIfError(iAudioControllerCustomCommands.SetSinkFormat(aRecordFormat)); + } + +void CMMFMdaAudioConvertUtility::SetSourceNumberOfChannelsL(TUint aNumberOfChannels) + { + User::LeaveIfError(iAudioControllerCustomCommands.SetSourceNumChannels(aNumberOfChannels)); + } + +void CMMFMdaAudioConvertUtility::SetDestinationNumberOfChannelsL(TUint aNumberOfChannels) + { + User::LeaveIfError(iAudioControllerCustomCommands.SetSinkNumChannels(aNumberOfChannels)); + } + +TUint CMMFMdaAudioConvertUtility::DestinationBitRateL() + { + TUint bitRate; + User::LeaveIfError(iAudioControllerCustomCommands.GetSinkBitRate(bitRate)); + return bitRate; + } + +TUint CMMFMdaAudioConvertUtility::DestinationSampleRateL() + { + TUint sampleRate; + User::LeaveIfError(iAudioControllerCustomCommands.GetSinkSampleRate(sampleRate)); + return sampleRate; + } + +TUid CMMFMdaAudioConvertUtility::DestinationFormatL() + { + TUid format; + User::LeaveIfError(iAudioControllerCustomCommands.GetSinkFormat(format)); + return format; + } + +TUint CMMFMdaAudioConvertUtility::DestinationNumberOfChannelsL() + { + TUint numChannels; + User::LeaveIfError(iAudioControllerCustomCommands.GetSinkNumChannels(numChannels)); + return numChannels; + } + +TUint CMMFMdaAudioConvertUtility::SourceBitRateL() + { + TUint bitRate; + User::LeaveIfError(iAudioControllerCustomCommands.GetSourceBitRate(bitRate)); + return bitRate; + } + +TUint CMMFMdaAudioConvertUtility::SourceSampleRateL() + { + TUint sampleRate; + User::LeaveIfError(iAudioControllerCustomCommands.GetSourceSampleRate(sampleRate)); + return sampleRate; + } + +TUid CMMFMdaAudioConvertUtility::SourceFormatL() + { + TUid format; + User::LeaveIfError(iAudioControllerCustomCommands.GetSourceFormat(format)); + return format; + } + +TUint CMMFMdaAudioConvertUtility::SourceNumberOfChannelsL() + { + TUint numChannels; + User::LeaveIfError(iAudioControllerCustomCommands.GetSourceNumChannels(numChannels)); + return numChannels; + } + + +void CMMFMdaAudioConvertUtility::GetSupportedConversionBitRatesL(RArray& aSupportedBitRates) + { + iAudioControllerCustomCommands.GetSupportedSinkBitRatesL(aSupportedBitRates); + } + +void CMMFMdaAudioConvertUtility::GetSupportedConversionSampleRatesL(RArray& aSupportedSampleRates) + { + User::LeaveIfError(iController.Prime()); + iAudioControllerCustomCommands.GetSupportedSinkSampleRatesL(aSupportedSampleRates); + User::LeaveIfError(iController.Stop()); + } + +void CMMFMdaAudioConvertUtility::GetSupportedConversionNumberOfChannelsL(RArray& aSupportedNumChannels) + { + iAudioControllerCustomCommands.GetSupportedSinkNumChannelsL(aSupportedNumChannels); + } + +CMdaAudioConvertUtility* CMMFMdaAudioConvertUtility::Parent() const + { + ASSERT(iParent); + return static_cast(iParent); + } + +TInt CMMFMdaAudioConvertUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom) + { + return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom); + } + +TInt CMMFMdaAudioConvertUtility::CustomCommandSync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2) + { + return iController.CustomCommandSync(aDestination, aFunction, aDataTo1, aDataTo2); + } + +void CMMFMdaAudioConvertUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TDes8& aDataFrom, TRequestStatus& aStatus) + { + iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aDataFrom, aStatus); + } + +void CMMFMdaAudioConvertUtility::CustomCommandAsync(const TMMFMessageDestinationPckg& aDestination, TInt aFunction, const TDesC8& aDataTo1, const TDesC8& aDataTo2, TRequestStatus& aStatus) + { + iController.CustomCommandAsync(aDestination, aFunction, aDataTo1, aDataTo2, aStatus); + } + +const CMMFControllerImplementationInformation& CMMFMdaAudioConvertUtility::ControllerImplementationInformationL() + { + if (!iControllerImplementationInformation) + { + if (iControllerUid==KNullUid) + User::Leave(KErrNotReady); + iControllerImplementationInformation = CMMFControllerImplementationInformation::NewL(iControllerUid); + } + return *iControllerImplementationInformation; + } + + +void CMMFMdaAudioConvertUtility::Reset() + { + // Make sure any existing controller is closed. + Close(); + + iSourceFormatUid = KNullUid; + iSinkFormatUid = KNullUid; + iSourceDataType = KMMFFourCCCodeNULL; + iSinkDataType = KMMFFourCCCodeNULL; + iSourceSampleRate = 0; + iSinkSampleRate = 0; + iSourceChannels = 0; + iSinkChannels = 0; + } + + +TInt CMMFMdaAudioConvertUtility::ControllerOpen() + { + TInt err = KErrNone; + + if(iSourceFormatUid != KNullUid) + TRAP(err, SetSourceFormatL(iSourceFormatUid)); + + if(!err && iSinkFormatUid != KNullUid) + TRAP(err, SetDestinationFormatL(iSinkFormatUid)); + + if(!err && iSourceDataType != KMMFFourCCCodeNULL) + { + TRAP(err, SetSourceDataTypeL(iSourceDataType)); + } + + if(!err && iSinkDataType != KMMFFourCCCodeNULL) + { + TRAP(err, SetDestinationDataTypeL(iSinkDataType)); + } + + // set the audio data settings ie sample rate & channels + if (!err && iSourceSampleRate != 0) + { + TRAP(err, SetSourceSampleRateL(iSourceSampleRate)); + } + + if (!err && iSourceChannels != 0) + { + TRAP(err, SetSourceNumberOfChannelsL(iSourceChannels)); + } + + if (!err && iSinkSampleRate != 0) + { + TRAP(err, SetDestinationSampleRateL(iSinkSampleRate)); + } + + if (!err && iSinkChannels != 0) + { + TRAP(err, SetDestinationNumberOfChannelsL(iSinkChannels)); + } + + //get the clip duration + if (!err) + { + iDuration = TTimeIntervalMicroSeconds(0); + err = iController.GetDuration(iDuration); + } + + if (err) + Close(); + else + iState = CMdaAudioClipUtility::EOpen; + + return err; + } + + +void CMMFMdaAudioConvertUtility::ConfigureSourceSinkL(TMdaClipLocation* aPriLocation, TMdaClipLocation* aSecLocation) + { + TMMFDescriptorConfig srcDesCfg; + TMMFFileConfig srcFileCfg; + CBufFlat* srcCfgBuffer = NULL; + CMMFUrlParams* srcURLCfg = NULL; + TPtrC8 sourceCfg; + TUid sourceUid = KNullUid; + + TMMFDescriptorConfig dstDesCfg; + TMMFFileConfig dstFileCfg; + CBufFlat* dstCfgBuffer = NULL; + CMMFUrlParams* dstURLCfg = NULL; + TPtrC8 dstCfg; + TUid dstUid = KNullUid; + + TInt err = KErrNone; + + // setup the source config info + if (aPriLocation->Uid() == KUidMdaFileResLoc) + {//sink clip location is a file + TDesC& fileName = ((TMdaFileClipLocation*)aPriLocation)->iName; + srcFileCfg().iPath = fileName; + sourceCfg.Set(srcFileCfg); + sourceUid = KUidMmfFileSource; + } + else if (aPriLocation->Uid() == KUidMdaDesResLoc) + {//sink clip is a descriptor - pass down descriptor & thread id + TMdaDesClipLocation* srcLoc = (TMdaDesClipLocation*)aPriLocation; + srcDesCfg().iDes = srcLoc->iDes; + srcDesCfg().iDesThreadId = srcLoc->iThreadId; + sourceCfg.Set(srcDesCfg); + sourceUid = KUidMmfDescriptorSource; + } + else if (aPriLocation->Uid() == KUidMdaUrlResLoc) + { + TMdaUrlClipLocation* srcLoc = (TMdaUrlClipLocation*)aPriLocation; + srcURLCfg = CMMFUrlParams::NewLC(srcLoc->iUrl, srcLoc->iIapId); + srcCfgBuffer = srcURLCfg->ExternalizeToCBufFlatLC(); + sourceCfg.Set(srcCfgBuffer->Ptr(0)); + sourceUid = KUidMmfUrlSource; + } + else + { + err = KErrNotSupported; + } + + if (!err) + { + if (aSecLocation->Uid() == KUidMdaFileResLoc) + {//sink clip location is a file + TDesC& fileName = ((TMdaFileClipLocation*)aSecLocation)->iName; + dstFileCfg().iPath = fileName; + dstCfg.Set(dstFileCfg); + dstUid = KUidMmfFileSink; + } + else if (aSecLocation->Uid() == KUidMdaDesResLoc) + {//sink clip is a descriptor - pass down descriptor & thread id + TMdaDesClipLocation* desLoc = (TMdaDesClipLocation*)aSecLocation; + dstDesCfg().iDes = desLoc->iDes; + dstDesCfg().iDesThreadId = desLoc->iThreadId; + dstCfg.Set(dstDesCfg); + dstUid = KUidMmfDescriptorSink; + } + else if (aSecLocation->Uid() == KUidMdaUrlResLoc) + { + TMdaUrlClipLocation* desLoc = (TMdaUrlClipLocation*)aSecLocation; + dstURLCfg = CMMFUrlParams::NewLC(desLoc->iUrl, desLoc->iIapId); + dstCfgBuffer = dstURLCfg->ExternalizeToCBufFlatLC(); + dstCfg.Set(dstCfgBuffer->Ptr(0)); + dstUid = KUidMmfUrlSink; + } + else + { + err = KErrNotSupported; + } + } + + if (!err) + { + iFindAndOpenController->ConfigureSourceSink( + CMMFFindAndOpenController::TSourceSink(sourceUid, sourceCfg), + CMMFFindAndOpenController::TSourceSink(dstUid, dstCfg)); + } + + if (dstCfgBuffer) + CleanupStack::PopAndDestroy(2); //dstCfgBuffer, dstURLCfg + if (srcCfgBuffer) + CleanupStack::PopAndDestroy(2); //srcCfgBuffer, srcURLCfg + + User::LeaveIfError(err); + } + + +TInt CMMFMdaAudioConvertUtility::SetThreadPriority(const TThreadPriority& aThreadPriority) const + { + return iController.SetThreadPriority(aThreadPriority); + } + + + + +