diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/mmfrawformat_8cpp_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/mmfrawformat_8cpp_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,792 @@ + + + + +TB9.2 Example Applications: examples/Multimedia/MmfExFormatPlugin/mmfrawformat.cpp Source File + + + + + +

examples/Multimedia/MmfExFormatPlugin/mmfrawformat.cpp

00001 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+00002 // All rights reserved.
+00003 // This component and the accompanying materials are made available
+00004 // under the terms of "Eclipse Public License v1.0"
+00005 // which accompanies this distribution, and is available
+00006 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
+00007 //
+00008 // Initial Contributors:
+00009 // Nokia Corporation - initial contribution.
+00010 //
+00011 // Contributors:
+00012 //
+00013 // Description:
+00014 //
+00015 
+00016 // MMF framework headers
+00017 #include <mmffile.h>
+00018 #include <ecom.h>
+00019 #include <mmfformatimplementationuids.hrh>
+00020 #include <mmffourcc.h>
+00021 
+00022 #include "mmfrawformat.h"
+00023 #include "UIDs.hrh"
+00024 
+00025 const TUint KFormatDefaultFrameSize(0x1000); //Set default frame size to 4 K
+00026 const TUint KDefineIOBufferSize(0x0200); //easy to read clip buffer size
+00027 const TUint KOneSecondInMicroSeconds(1000000); //1 Second
+00028 const TUint KMono(1);
+00029 const TUint KStereo(2);
+00030 //this defines the valid sample rates for RAW
+00031 const TUint KRawSampleRates[] = { 8000, 11025, 22050, 44100 };
+00032 
+00033 
+00034 //
+00035 // CMMFRawFormatRead
+00036 //
+00037 
+00038 // Factory function
+00039 CMMFFormatDecode* CMMFRawFormatRead::NewL(MDataSource* aSource)
+00040         {
+00041         if ((aSource->DataSourceType()==KUidMmfDescriptorSource)||
+00042                         (aSource->DataSourceType()==KUidMmfFileSource))
+00043                 {//currently only files and descriptor MDataSources are supported
+00044                 CMMFRawFormatRead* self = new(ELeave)CMMFRawFormatRead;
+00045                 CleanupStack::PushL(self);
+00046                 self->ConstructL(aSource);
+00047                 CleanupStack::Pop();
+00048                 return self;
+00049                 }
+00050         else return NULL;
+00051         }
+00052 
+00053 // Destructor
+00054 CMMFRawFormatRead::~CMMFRawFormatRead()
+00055         {
+00056         delete iBuffer;
+00057         }
+00058         
+00059 // Second-phase constructor
+00060 void CMMFRawFormatRead::ConstructL(MDataSource* aSource)
+00061         {
+00062         // tell clip we're using it
+00063         iClip = aSource;
+00064         User::LeaveIfError(iClip->SourceThreadLogon(*this));
+00065         iClip->SourcePrimeL();
+00066         iFrameSize = KFormatDefaultFrameSize;
+00067         iClipLength = (static_cast<CMMFClip*>(iClip))->Size();
+00068         }
+00069 
+00070 // Implementing MDataSource
+00071 
+00072 // Handle request to fill buffer with data from clip
+00073 void CMMFRawFormatRead::FillBufferL(CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId aMediaId )
+00074         {       
+00075         // check media id & pass onto the clip
+00076         if (aMediaId.iMediaType != KUidMediaTypeAudio) User::Leave(KErrNotSupported); 
+00077         iDataPath = aConsumer;
+00078         //assumes first frame is frame 1
+00079         TUint position = ((aBuffer->FrameNumber()-1)*iFrameSize)+iStartPosition;
+00080         (static_cast<CMMFClip*>(iClip))->ReadBufferL(aBuffer, position, this);
+00081         // notified of when buffer is full by BufferFilledL
+00082         }
+00083 
+00084 // creates the buffer for the source
+00085 // This overload supplies the sink buffer, as optimal source buffer size creation may depend on this
+00086 CMMFBuffer* CMMFRawFormatRead::CreateSourceBufferL(TMediaId aMediaId, CMMFBuffer& aSinkBuffer, TBool &aReference)
+00087         {
+00088         if (aMediaId.iMediaType == KUidMediaTypeAudio) 
+00089                 {
+00090                 NegotiateSourceBufferL(aSinkBuffer); //sets frame size to match sink buffer
+00091                 return CreateSourceBufferL(aMediaId, aReference);
+00092                 }
+00093         else User::Leave(KErrNotSupported);
+00094         return NULL;
+00095         }
+00096 
+00097 // creates the buffer for the source
+00098 CMMFBuffer* CMMFRawFormatRead::CreateSourceBufferL(TMediaId aMediaId, TBool &aReference)
+00099         {
+00100         if (aMediaId.iMediaType == KUidMediaTypeAudio) 
+00101                 {
+00102                 // assume default frame size if haven't determined a better one
+00103                 if (!iFrameSize) iFrameSize = KFormatDefaultFrameSize;
+00104                 // sets aReference to false if a new CMMFBuffer is returned
+00105                 aReference = EFalse;
+00106                 return CreateSourceBufferOfSizeL(iFrameSize);
+00107                 }
+00108         else User::Leave(KErrNotSupported);
+00109         return NULL;
+00110         }
+00111 
+00112 // Helper function to create and zero fill a buffer of specified size
+00113 CMMFDataBuffer* CMMFRawFormatRead::CreateSourceBufferOfSizeL(TUint aSize)
+00114         {
+00115         //needs to create source buffer
+00116         CMMFDataBuffer* buffer = CMMFDataBuffer::NewL(aSize);
+00117         buffer->Data().FillZ(aSize);
+00118         return buffer;
+00119         }
+00120 
+00121 // Helper function to determine best source buffer size
+00122 void CMMFRawFormatRead::NegotiateSourceBufferL(CMMFBuffer& aSinkBuffer)
+00123         {
+00124         // if sink buffer has a fixed size use this to determine source buffer size
+00125         if (aSinkBuffer.Type() == KUidMmfDataBuffer)
+00126                 {
+00127                 // RAW is linear data, so can set target buffer to sink buffer size
+00128                 TUint sinkBufferLength = (static_cast<CMMFDataBuffer&>(aSinkBuffer)).Data().MaxLength();
+00129                 if (sinkBufferLength == 0) sinkBufferLength = KFormatDefaultFrameSize;
+00130                 iFrameSize = sinkBufferLength; 
+00131                 CalculateFrameTimeInterval();
+00132                 }
+00133         else 
+00134                 User::Leave(KErrNotSupported);
+00135         }
+00136 
+00137 // returns the codec FourCC code for the mediaId
+00138 TFourCC CMMFRawFormatRead::SourceDataTypeCode(TMediaId aMediaId)
+00139         {
+00140         if (aMediaId.iMediaType == KUidMediaTypeAudio) return iFourCC;
+00141         else return TFourCC(); //defaults to 'NULL' fourCC
+00142         }
+00143 
+00144 // sets the codec FourCC code for the mediaId
+00145 TInt CMMFRawFormatRead::SetSourceDataTypeCode(TFourCC aSinkFourCC, TMediaId aMediaId)
+00146         {
+00147         if (aMediaId.iMediaType != KUidMediaTypeAudio) return KErrNotSupported;
+00148         else iFourCC = aSinkFourCC;
+00149         
+00150         if ((iFourCC == KMMFFourCCCodePCM16) || 
+00151                 (iFourCC == KMMFFourCCCodePCM16B) || 
+00152                 (iFourCC == KMMFFourCCCodePCMU16)) 
+00153                         iBitsPerSample = 16;
+00154         else if ((iFourCC == KMMFFourCCCodeIMAD) || 
+00155                 (iFourCC == KMMFFourCCCodeIMAS)) 
+00156                         iBitsPerSample = 4;
+00157         else 
+00158                         iBitsPerSample = 8; //default to 8
+00159         return KErrNone;
+00160         }
+00161 
+00162 // Initiate use of the interface 
+00163 TInt CMMFRawFormatRead::SourceThreadLogon(MAsyncEventHandler& aEventHandler)
+00164         {//pass through to source clip
+00165         return(iClip->SourceThreadLogon(aEventHandler));
+00166         }
+00167 
+00168 // Prepare clip
+00169 void CMMFRawFormatRead::SourcePrimeL()
+00170         {
+00171         iClip->SourcePrimeL();
+00172         CalculateFrameTimeInterval();
+00173         }
+00174 
+00175 // Play clip
+00176 void CMMFRawFormatRead::SourcePlayL()
+00177         {
+00178         iClip->SourcePlayL();
+00179         }
+00180 
+00181 // Pause clip
+00182 void CMMFRawFormatRead::SourcePauseL()
+00183         {
+00184         iClip->SourcePauseL(); //propagate state change down to clip
+00185         }
+00186 
+00187 // Stop clip
+00188 void CMMFRawFormatRead::SourceStopL()
+00189         {
+00190         iClip->SourceStopL();
+00191         }
+00192 
+00193 // End use of the interface
+00194 void CMMFRawFormatRead::SourceThreadLogoff()
+00195         {
+00196         iClip->SourceThreadLogoff();
+00197         }
+00198 
+00199 // from MDataSink
+00200 
+00201 // called by MDataSource to pass back full buffer to the sink
+00202 void CMMFRawFormatRead::BufferFilledL(CMMFBuffer* aBuffer)
+00203         {
+00204         //set position
+00205         TTimeIntervalMicroSeconds position = //assumes frame numbers begin at frame 1
+00206                 TTimeIntervalMicroSeconds(TInt64(aBuffer->FrameNumber()-1)*iFrameTimeInterval.Int64());
+00207         aBuffer->SetTimeToPlay(position);
+00208         iDataPath->BufferFilledL(aBuffer);      
+00209         }
+00210 
+00211 
+00212 // from CMMFFormatDecode
+00213 
+00214 // returns number of streams
+00215 TUint CMMFRawFormatRead::Streams(TUid aMediaType) const
+00216         {
+00217         //need to check aMediaType for audio
+00218         if (aMediaType == KUidMediaTypeAudio) return 1; //raw files can only have 1 audio stream
+00219         else return 0;
+00220         }
+00221 
+00222 // returns the time interval for one frame
+00223 TTimeIntervalMicroSeconds CMMFRawFormatRead::FrameTimeInterval(TMediaId aMediaId) const
+00224         {
+00225         if (aMediaId.iMediaType == KUidMediaTypeAudio) return iFrameTimeInterval;
+00226         else return TTimeIntervalMicroSeconds(0);
+00227         }
+00228 
+00229 // returns the duration of the source clip
+00230 TTimeIntervalMicroSeconds CMMFRawFormatRead::Duration(TMediaId aMediaId) const
+00231         {
+00232         if ((aMediaId.iMediaType == KUidMediaTypeAudio) && 
+00233                 (iClipLength) && (iSampleRate) && (iBitsPerSample) && (iChannels))
+00234                 {//we have enough values to calculate the duration
+00235                 TInt64 clipLength(iClipLength);
+00236                 clipLength*=KOneSecondInMicroSeconds;
+00237                 TTimeIntervalMicroSeconds duration = TTimeIntervalMicroSeconds(clipLength/iSampleRate);
+00238                 duration = TTimeIntervalMicroSeconds(duration.Int64()/(iBitsPerSample*iChannels));
+00239                 duration = TTimeIntervalMicroSeconds(duration.Int64()*8);
+00240                 return duration;
+00241                 }
+00242         else return TTimeIntervalMicroSeconds(0);
+00243         }
+00244 
+00245 // helper function: calculates time between frames
+00246 void CMMFRawFormatRead::CalculateFrameTimeInterval()
+00247         {
+00248         if ((iFrameSize) && (iSampleRate) && (iBitsPerSample) && (iChannels))
+00249                 {
+00250                 iFrameTimeInterval = TTimeIntervalMicroSeconds((iFrameSize*KOneSecondInMicroSeconds)/iSampleRate);
+00251                 iFrameTimeInterval = 
+00252                         TTimeIntervalMicroSeconds(iFrameTimeInterval.Int64()/(iBitsPerSample*iChannels));
+00253                 iFrameTimeInterval = TTimeIntervalMicroSeconds(iFrameTimeInterval.Int64()*8);
+00254                 }
+00255         }
+00256 
+00257 // called by sink to suggest a source buffer size
+00258 void CMMFRawFormatRead::SuggestSourceBufferSize(TUint aSuggestedBufferSize)
+00259         {
+00260         iFrameSize = aSuggestedBufferSize; //set source format frame size to buffer size suggested by sink
+00261         CalculateFrameTimeInterval();
+00262         }
+00263 
+00264 // set the number of channels
+00265 TInt CMMFRawFormatRead::SetNumChannels(TUint aChannels)
+00266         {
+00267         TInt error = KErrNone;
+00268         if ((aChannels ==  KMono)||(aChannels == KStereo)) iChannels = aChannels;
+00269         else error = KErrNotSupported; //only alow one or two channels
+00270         return error;
+00271         }
+00272 
+00273 // set the sample rate
+00274 TInt CMMFRawFormatRead::SetSampleRate(TUint aSampleRate)
+00275         {
+00276         TInt status = KErrNotSupported;
+00277         //we'll iterate through the valid sample table
+00278         TInt i = sizeof(KRawSampleRates) / sizeof(TUint);
+00279                 
+00280         while ((i--) && (status != KErrNone))
+00281                 {
+00282                 if (aSampleRate == KRawSampleRates[i])
+00283                         {
+00284                         iSampleRate = aSampleRate;
+00285                         status = KErrNone;
+00286                         }
+00287                 }
+00288         return status;
+00289         }
+00290 
+00291 // helper function to read from clip
+00292 void CMMFRawFormatRead::DoReadL(TInt aReadPosition)
+00293         {
+00294         STATIC_CAST(CMMFClip*,iClip)->ReadBufferL(iBuffer,aReadPosition);
+00295         }
+00296 
+00297 // get the supported sample rates
+00298 void CMMFRawFormatRead::GetSupportedSampleRatesL(RArray<TUint>& aSampleRates)
+00299         {
+00300         aSampleRates.Reset();
+00301 
+00302         // Iterate through the valid sample table and append each value to aSampleRates
+00303         TInt i = sizeof(KRawSampleRates) / sizeof(TUint);
+00304         
+00305         while (i--)
+00306                 {
+00307                 User::LeaveIfError(aSampleRates.Append(KRawSampleRates[i]));
+00308                 }
+00309         }
+00310 
+00311 // get the supported channel number options
+00312 void CMMFRawFormatRead::GetSupportedNumChannelsL(RArray<TUint>& aNumChannels)
+00313         {
+00314         aNumChannels.Reset();
+00315         User::LeaveIfError(aNumChannels.Append(KMono));
+00316         User::LeaveIfError(aNumChannels.Append(KStereo));
+00317         }
+00318 
+00319 // get the supported codecs
+00320 void CMMFRawFormatRead::GetSupportedDataTypesL(TMediaId aMediaId, RArray<TFourCC>& aDataTypes)
+00321         {
+00322         if (aMediaId.iMediaType != KUidMediaTypeAudio)
+00323                 User::Leave(KErrNotSupported);
+00324         aDataTypes.Reset();
+00325         User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodePCM16));
+00326         User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodePCM16B));
+00327         User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodePCMU16));
+00328         User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodeIMAD));
+00329         User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodeIMAS));
+00330         }
+00331 
+00332 
+00333 //
+00334 // CMMFRawFormatWrite
+00335 //
+00336 
+00337 // Factory function
+00338 CMMFFormatEncode* CMMFRawFormatWrite::NewL(MDataSink* aSink)
+00339         {
+00340         if ((aSink->DataSinkType()==KUidMmfDescriptorSink)||
+00341                         (aSink->DataSinkType()==KUidMmfFileSink))
+00342                 {//currently only files and descriptor MDataSources are supported
+00343                 CMMFRawFormatWrite* self = new(ELeave)CMMFRawFormatWrite;
+00344                 CleanupStack::PushL(self);
+00345                 self->ConstructL(aSink);
+00346                 CleanupStack::Pop();
+00347                 return STATIC_CAST(CMMFFormatEncode*, self);
+00348                 }
+00349         else return NULL;
+00350         }
+00351 
+00352 // destructor
+00353 CMMFRawFormatWrite::~CMMFRawFormatWrite()
+00354         {
+00355         delete iBuffer;
+00356         delete iConvertBuffer;
+00357         delete iChannelAndSampleRateConverterFactory;
+00358         }
+00359         
+00360 // second-phase construction    
+00361 void CMMFRawFormatWrite::ConstructL(MDataSink* aSink)
+00362         {
+00363         iClip = aSink;
+00364         //first need to check if sink clip already exists to get settings.
+00365         User::LeaveIfError(iClip->SinkThreadLogon(*this));
+00366         iClip->SinkPrimeL();
+00367         iBuffer = CreateSinkBufferOfSizeL(KDefineIOBufferSize); //512 easiest file size to read
+00368         DoReadL(0);//read from beginning of clip
+00369         if (iBuffer->Data().Size()> 0)
+00370                 {
+00371                 iClipAlreadyExists = ETrue;
+00372                 //There is no header, so data size is the same as the clip size in this case.
+00373                 iDataSize = iClipLength = STATIC_CAST(CMMFClip*,iClip)->Size();
+00374                 }
+00375         iFrameSize = KFormatDefaultFrameSize;
+00376         }
+00377 
+00378 // from MDataSink
+00379 
+00380 // sink thread attaches
+00381 TInt CMMFRawFormatWrite::SinkThreadLogon(MAsyncEventHandler& aEventHandler)
+00382         {//pass through to sink clip
+00383         return(iClip->SinkThreadLogon(aEventHandler));
+00384         }
+00385 
+00386 // helper function: calculates time between frames
+00387 void CMMFRawFormatWrite::CalculateFrameTimeInterval()
+00388         {
+00389         if ((iFrameSize) && (iSampleRate) && (iBitsPerSample) && (iChannels))
+00390                 {
+00391                 iFrameTimeInterval = TTimeIntervalMicroSeconds((iFrameSize*KOneSecondInMicroSeconds)/iSampleRate);
+00392                 iFrameTimeInterval = 
+00393                         TTimeIntervalMicroSeconds((iFrameTimeInterval.Int64())/(iBitsPerSample*iChannels));
+00394                 iFrameTimeInterval = TTimeIntervalMicroSeconds(iFrameTimeInterval.Int64()*8);
+00395                 }
+00396         }
+00397 
+00398 // called if sink setup depends on source
+00399 void CMMFRawFormatWrite::Negotiate(MDataSource& aSource)
+00400         {
+00401         if (aSource.DataSourceType() == KUidMmfAudioInput)
+00402                 {
+00403                 // could query the audio capabilities from DevSound for the settings below
+00404                 iSourceSampleRate = 8000; // assume 8KHz for now
+00405                 iSourceChannels = 1; //assume mono
+00406                 iSourceFourCC.Set(KMMFFourCCCodePCM16); //16 bit PCM
+00407                 }
+00408         else if (aSource.DataSourceType() == KUidMmfFormatDecode)
+00409                 {//source is a clip so for now set sink settings to match source
+00410                 iSourceSampleRate = ((CMMFFormatDecode&)aSource).SampleRate();
+00411                 iSourceChannels = ((CMMFFormatDecode&)aSource).NumChannels();
+00412                 iSourceFourCC.Set(aSource.SourceDataTypeCode(TMediaId(KUidMediaTypeAudio)));
+00413                 iSourceWillSampleConvert = STATIC_CAST(CMMFFormatDecode&, aSource).SourceSampleConvert();
+00414                 ((CMMFFormatDecode&)aSource).SuggestSourceBufferSize(iFrameSize); //for now suggest format src takes same buf size as sink??
+00415                 //make the start position the end of the clip
+00416                 }
+00417         else return;
+00418         //set default sink parameters to be the same as the source
+00419         if (iClipAlreadyExists) iStartPosition = iClipLength;
+00420         if (!iSampleRate) iSampleRate = iSourceSampleRate; //might have already been set by custom command
+00421         if (!iChannels) iChannels = iSourceChannels;
+00422         if (!iBitsPerSample)
+00423                 {
+00424                 iFourCC.Set(iSourceFourCC);
+00425                 if ((iFourCC == KMMFFourCCCodePCM16) ||
+00426                         (iFourCC == KMMFFourCCCodePCM16B) ||
+00427                         (iFourCC == KMMFFourCCCodePCMU16))
+00428                                 iBitsPerSample = 16;            
+00429                 else if ((iFourCC == KMMFFourCCCodeIMAD) || 
+00430                         (iFourCC == KMMFFourCCCodeIMAS))
+00431                                 iBitsPerSample = 4;     
+00432                 else 
+00433                                 iBitsPerSample = 8; //default to 8
+00434                 }
+00435         CalculateFrameTimeInterval();
+00436         }
+00437 
+00438 // Prime the sink to be accessed
+00439 void CMMFRawFormatWrite::SinkPrimeL()
+00440         {
+00441         iClip->SinkPrimeL(); //propagate state change down to clip
+00442         CalculateFrameTimeInterval();
+00443         }
+00444 
+00445 // Play the sink
+00446 void CMMFRawFormatWrite::SinkPlayL()
+00447         {
+00448         iClip->SinkPlayL(); //propagate state change down to clip
+00449         if ((iChannels != iSourceChannels) || (iSampleRate != iSourceSampleRate) && (!iSourceWillSampleConvert))
+00450                 {//the source channels & sample rate don't match the formats - therefore need to do a conversion 
+00451                 //currently only pcm16 is supported so return with an error if format not pcm16
+00452                 if (iFourCC != KMMFFourCCCodePCM16) User::Leave(KErrNotSupported);
+00453                 iChannelAndSampleRateConverterFactory 
+00454                         = new(ELeave)CMMFChannelAndSampleRateConverterFactory;
+00455                 iChannelAndSampleRateConverter = 
+00456                         iChannelAndSampleRateConverterFactory->CreateConverterL( iSourceSampleRate, iSourceChannels, 
+00457                                                                                                                                         iSampleRate, iChannels);
+00458                 //need to create an intermediate buffer in which to place the converted data
+00459                 TUint convertedBufferFrameSize = (iFrameSize*iChannels)/iSourceChannels;
+00460                 iConvertBuffer = CreateSinkBufferOfSizeL(convertedBufferFrameSize);
+00461                 }
+00462         iFileHasChanged = ETrue; //file will change if we start playing to it
+00463         }
+00464 
+00465 // Pause the sink
+00466 void CMMFRawFormatWrite::SinkPauseL()
+00467         {
+00468         iClip->SinkPauseL(); //propagate state change down to clip
+00469         }
+00470 
+00471 // Stop the sink
+00472 void CMMFRawFormatWrite::SinkStopL()
+00473         {
+00474         iClip->SinkStopL(); //propagate state change down to clip
+00475         }
+00476 
+00477 // Detach from the sink
+00478 void CMMFRawFormatWrite::SinkThreadLogoff()
+00479         {
+00480         iClip->SinkThreadLogoff(); //propagate down to clip
+00481         }
+00482 
+00483 // Called by the CMMFDataPath to add a buffer to a clip
+00484 void CMMFRawFormatWrite::EmptyBufferL(CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId aMediaId)
+00485         {
+00486         //since raw always contains linear audio the sink buffer size can set the source buffer size
+00487 
+00488         //check media id &pass onto clip
+00489         if (aMediaId.iMediaType!=KUidMediaTypeAudio) User::Leave(KErrNotSupported); 
+00490         iDataPath = aSupplier;
+00491 
+00492         // Check we haven't exceeded any set maximum on our clip length
+00493         if (iMaximumClipSize > 0)
+00494                 {
+00495                 // Find the current clip size
+00496                 TInt currentClipLength = STATIC_CAST(CMMFClip*, iClip)->Size();
+00497                 TInt bufferSize = aBuffer->BufferSize();
+00498                 if ((currentClipLength + bufferSize) >= iMaximumClipSize)
+00499                         User::Leave(KErrEof);
+00500                 }
+00501 
+00502         //assumes first frame is frame 1
+00503         iBufferToEmpty = aBuffer; //save this so it can be returned to datapath
+00504         TInt position = ((aBuffer->FrameNumber()-1)*iFrameSize)+iStartPosition;
+00505         if (position < (TInt)iStartPosition) position = iStartPosition; //can't write before start of header
+00506         if ((iChannelAndSampleRateConverter) && (!iSourceWillSampleConvert))
+00507                 {//need to perform channel & sample rate conversion before writing to clip
+00508                 iFrameSize = iChannelAndSampleRateConverter->Convert(*(CMMFDataBuffer*)aBuffer,*iConvertBuffer);
+00509                 STATIC_CAST(CMMFClip*,iClip)->WriteBufferL(iConvertBuffer, position, this);
+00510                 }
+00511         else
+00512                 {//no need to convert the data
+00513                 STATIC_CAST(CMMFClip*,iClip)->WriteBufferL(aBuffer, position, this);
+00514                 }
+00515         iPos = position; //save current write position
+00516         }
+00517 
+00518 // helper function to create buffer of specficed size
+00519 CMMFDataBuffer* CMMFRawFormatWrite::CreateSinkBufferOfSizeL(TUint aSize)
+00520         {
+00521         //needs to create source buffer
+00522         CMMFDataBuffer* buffer = CMMFDataBuffer::NewL(aSize);
+00523         buffer->Data().FillZ(aSize);
+00524         iBufferCreated = ETrue;
+00525         return buffer;
+00526         }
+00527 
+00528 // create buffer to receive data
+00529 CMMFBuffer* CMMFRawFormatWrite::CreateSinkBufferL(TMediaId aMediaId, TBool &aReference)
+00530         {
+00531         if (aMediaId.iMediaType == KUidMediaTypeAudio) 
+00532                 {
+00533                 if (!iFrameSize) iFrameSize = KFormatDefaultFrameSize;
+00534                 aReference = EFalse;
+00535                 return CreateSinkBufferOfSizeL(iFrameSize);
+00536                 }
+00537         else User::Leave(KErrNotSupported);
+00538         return NULL;
+00539         }
+00540 
+00541 // gets the codec type
+00542 TFourCC CMMFRawFormatWrite::SinkDataTypeCode(TMediaId aMediaId)
+00543         {
+00544         if (aMediaId.iMediaType == KUidMediaTypeAudio) return iFourCC;
+00545         else return TFourCC(); //defaults to 'NULL' fourCC
+00546         }
+00547 
+00548 // sets the codec type
+00549 TInt CMMFRawFormatWrite::SetSinkDataTypeCode(TFourCC aSinkFourCC, TMediaId aMediaId)
+00550         {
+00551         if (aMediaId.iMediaType != KUidMediaTypeAudio) return KErrNotSupported;
+00552         else iFourCC = aSinkFourCC;
+00553         
+00554         if ((iFourCC == KMMFFourCCCodePCM16) || 
+00555                 (iFourCC == KMMFFourCCCodePCM16B) ||
+00556                 (iFourCC == KMMFFourCCCodePCMU16)) 
+00557                         iBitsPerSample = 16;
+00558         else if ((iFourCC == KMMFFourCCCodeIMAD) ||
+00559                 (iFourCC == KMMFFourCCCodeIMAS)) 
+00560                         iBitsPerSample = 4;
+00561         else 
+00562                         iBitsPerSample = 8; //default to 8
+00563 
+00564         return KErrNone;
+00565         }
+00566 
+00567 // helper function to read data from clip
+00568 void CMMFRawFormatWrite::DoReadL(TInt aReadPosition)
+00569         {
+00570         STATIC_CAST(CMMFClip*,iClip)->ReadBufferL(iBuffer,aReadPosition);
+00571         }
+00572 
+00573 // helper function to write data to clip
+00574 void CMMFRawFormatWrite::DoWriteL(TInt aWritePosition)
+00575         {
+00576         STATIC_CAST(CMMFClip*,iClip)->WriteBufferL(iBuffer,aWritePosition);
+00577         }
+00578 
+00579 
+00580 // from MDataSource
+00581 
+00582 // called by MDataSink to pass back emptied buffer to the source
+00583 void CMMFRawFormatWrite::BufferEmptiedL(CMMFBuffer* aBuffer)
+00584         {
+00585         iDataSize+=aBuffer->BufferSize(); //total bytes written
+00586         iPos += aBuffer->BufferSize(); //total bytes written so far - iPos is not always = iDataSize due to repositions
+00587         if (iMaxPos < iPos) iMaxPos = iPos; //need iMaxPos incase we write data then repos to an earlier pos in the clip
+00588         if (iBufferToEmpty != aBuffer) iDataPath->BufferEmptiedL(iBufferToEmpty); //need to return same buffer
+00589         else iDataPath->BufferEmptiedL(aBuffer);
+00590         }
+00591 
+00592 
+00593 // from CMMFFormatEncode
+00594 
+00595 // set the number of channels 
+00596 TInt CMMFRawFormatWrite::SetNumChannels(TUint aChannels)
+00597         {
+00598         TInt error = KErrNone;
+00599         if ((aChannels ==  KMono)||(aChannels == KStereo)) iChannels = aChannels;
+00600         else error = KErrNotSupported; //only alow one or two channels
+00601         return error;
+00602         }
+00603 
+00604 // set the sample rate
+00605 TInt CMMFRawFormatWrite::SetSampleRate(TUint aSampleRate)
+00606         {
+00607         TInt status = KErrNotSupported;
+00608         //we'll iterate through the valid sample table
+00609         TInt i = sizeof(KRawSampleRates) / sizeof(TUint);
+00610                 
+00611         while ((i--) && (status != KErrNone))
+00612                 {
+00613                 if (aSampleRate == KRawSampleRates[i])
+00614                         {
+00615                         iSampleRate = aSampleRate;
+00616                         status = KErrNone;
+00617                         }
+00618                 }
+00619         return status;
+00620         }
+00621 
+00622 // get the frame interval
+00623 TTimeIntervalMicroSeconds CMMFRawFormatWrite::FrameTimeInterval(TMediaId aMediaId) const
+00624         {
+00625         if (aMediaId.iMediaType == KUidMediaTypeAudio) return iFrameTimeInterval;
+00626         else return TTimeIntervalMicroSeconds(0);
+00627         }
+00628 
+00629 // returns the duration of the source clip
+00630 TTimeIntervalMicroSeconds CMMFRawFormatWrite::Duration(TMediaId aMediaId) const
+00631         {
+00632         if ((aMediaId.iMediaType == KUidMediaTypeAudio) 
+00633                 && (iDataSize) && (iSampleRate) && (iBitsPerSample) && (iChannels))
+00634                 {
+00635                 TInt64 clipLength(iDataSize);
+00636                 clipLength*=KOneSecondInMicroSeconds;
+00637                 TTimeIntervalMicroSeconds duration = TTimeIntervalMicroSeconds(clipLength/iSampleRate);
+00638                 duration = 
+00639                         TTimeIntervalMicroSeconds(duration.Int64()/(iBitsPerSample*iChannels));
+00640                 duration = TTimeIntervalMicroSeconds(duration.Int64()*8);
+00641                 return duration;
+00642                 }
+00643         else return TTimeIntervalMicroSeconds(0);
+00644         }
+00645 
+00646 // Calculate and return the number of bytes used for on second of audio.
+00647 TInt64 CMMFRawFormatWrite::BytesPerSecond() 
+00648         {
+00649         TInt64 bitsPerSecond = iSampleRate * iBitsPerSample * iChannels ;
+00650         TInt64 bytesPerSecond = bitsPerSecond/8;
+00651         return bytesPerSecond ;
+00652         }
+00653 
+00654 // Shortens the clip from the position specified to the end specified.
+00655 void CMMFRawFormatWrite::CropL(TTimeIntervalMicroSeconds aPosition, TBool aToEnd )
+00656         {
+00657         // Does clip have any size to crop
+00658         if (!(STATIC_CAST(CMMFClip*,iClip)->Size())) User::Leave(KErrNotFound); //no clip to crop or clip is 0 bytes.
+00659 
+00660 
+00661         // Is aPosition between the start and the end?
+00662         if ( ( aPosition < TTimeIntervalMicroSeconds(0) ) || ( aPosition >= Duration( KUidMediaTypeAudio) ) ) 
+00663                 User::Leave( KErrArgument ) ;
+00664 
+00665         // Convert aPostion to cropPosition in bytes
+00666 
+00667         TInt64 cropPosition64 = 
+00668                 TInt64( ( aPosition.Int64() * iSampleRate * (iBitsPerSample/8) * iChannels ) /KOneSecondInMicroSeconds);
+00669         TUint cropPosition = I64INT(cropPosition64);
+00670 
+00671         // Does cropPosition need adjustment to retain integrity?  (assume not)
+00672 
+00673         TUint dataSize ;  // This will be the size of the data left after cropping.
+00674 
+00675         if ( !aToEnd )
+00676                 {
+00677                 // Shift the data physically
+00678                 // move the data in blocks
+00679                 // Create a CMMFDataBuffer and use CMMFClip to shift the data
+00680                 dataSize = iMaxPos - cropPosition ;
+00681                 if (( dataSize > 0 ) && (aPosition != TTimeIntervalMicroSeconds(0)))
+00682                         {
+00683                         TUint bufSize = ( dataSize < KDefineIOBufferSize ? dataSize : KDefineIOBufferSize ) ; //max bufSize 512
+00684                         CMMFDataBuffer* buffer = CMMFDataBuffer::NewL(bufSize) ;
+00685                         CleanupStack::PushL( buffer ) ;
+00686 
+00687                         TUint rPos = cropPosition ; // read position
+00688                         TUint wPos = 0;
+00689                         TInt dataToShift = ETrue ;
+00690                         while ( dataToShift )
+00691                                 {
+00692                                 STATIC_CAST( CMMFClip*, iClip )->ReadBufferL( buffer, rPos ) ;  // synchronous calls
+00693                                 STATIC_CAST( CMMFClip*, iClip )->WriteBufferL( buffer, wPos ) ;
+00694                                 if ( rPos > iMaxPos ) 
+00695                                         dataToShift = EFalse ;  // past the end:  Done
+00696                                 else
+00697                                         { // shift the pointers
+00698                                         rPos += bufSize ;
+00699                                         wPos += bufSize ;
+00700                                         }
+00701                                 }// while data to shift
+00702                         CleanupStack::PopAndDestroy( ) ; // buffer
+00703                         }// if data to shift
+00704                 }// crop to start
+00705         else // crop to end
+00706                 dataSize = cropPosition ;
+00707 
+00708         iDataSize = dataSize ;
+00709         iMaxPos = dataSize ;
+00710 
+00711         // Do the physical chop
+00712         if ( iClip->DataSinkType() == KUidMmfFileSink )
+00713                 {
+00714                 STATIC_CAST( CMMFFile*, iClip )->FileL().SetSize( iMaxPos ) ;
+00715                 iClipLength = iMaxPos; 
+00716                 }
+00717         }
+00718 
+00719 // get the supported sample rates
+00720 void CMMFRawFormatWrite::GetSupportedSampleRatesL(RArray<TUint>& aSampleRates)
+00721         {
+00722         aSampleRates.Reset();
+00723 
+00724         // Iterate through the valid sample table and append each value to aSampleRates
+00725         TInt i = sizeof(KRawSampleRates) / sizeof(TUint);
+00726         
+00727         while (i--)
+00728                 {
+00729                 User::LeaveIfError(aSampleRates.Append(KRawSampleRates[i]));
+00730                 }
+00731         }
+00732 
+00733 // get the supported channel number options
+00734 void CMMFRawFormatWrite::GetSupportedNumChannelsL(RArray<TUint>& aNumChannels)
+00735         {
+00736         aNumChannels.Reset();
+00737         User::LeaveIfError(aNumChannels.Append(KMono));
+00738         User::LeaveIfError(aNumChannels.Append(KStereo));
+00739         }
+00740 
+00741 // set maximum clip size
+00742 void CMMFRawFormatWrite::SetMaximumClipSize(TInt aBytes)
+00743         {
+00744         iMaximumClipSize = aBytes;
+00745         }
+00746 
+00747 // get the supported codecs
+00748 void CMMFRawFormatWrite::GetSupportedDataTypesL(TMediaId aMediaId, RArray<TFourCC>& aDataTypes)
+00749         {
+00750         if (aMediaId.iMediaType != KUidMediaTypeAudio)
+00751                 User::Leave(KErrNotSupported);
+00752         aDataTypes.Reset();
+00753         User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodePCM16));
+00754         User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodePCM16B));
+00755         User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodePCMU16));
+00756         User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodeIMAD));
+00757         User::LeaveIfError(aDataTypes.Append(KMMFFourCCCodeIMAS));
+00758         }
+00759 
+00760 
+00761 // __________________________________________________________________________
+00762 // Exported proxy for instantiation method resolution
+00763 // Define the interface UIDs
+00764 
+00765 const TImplementationProxy ImplementationTable[] = 
+00766         {
+00767                 IMPLEMENTATION_PROXY_ENTRY(KRawDecoder, CMMFRawFormatRead::NewL),
+00768                 IMPLEMENTATION_PROXY_ENTRY(KRawEncoder, CMMFRawFormatWrite::NewL)
+00769         };
+00770 
+00771 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+00772         {
+00773         aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+00774 
+00775         return ImplementationTable;
+00776         }
+
+
Generated by  + +doxygen 1.6.2
+ +