|
1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // MMF\SoundDev\src\SoundDevice\DevSoundUtility.cpp |
|
15 // File: DevSoundUtility.cpp |
|
16 // Author: Vasudevan Ramachandraiah |
|
17 // Date: July 16, 2002 |
|
18 // Class that provides API to list ECOM plugin implementation IDs |
|
19 // (c) Nokia Inc. |
|
20 // Revisions: |
|
21 // Date: Author Description |
|
22 // |
|
23 // |
|
24 |
|
25 #include <e32std.h> |
|
26 #include <barsc.h> |
|
27 #include <barsread.h> |
|
28 #include <mmfbase.h> |
|
29 #include <mmfplugininterfaceuids.hrh> |
|
30 #include <fixedsequence.rsg> |
|
31 #include "DevSoundUtility.h" |
|
32 #include <mmf/common/mmfcontroller.h> //needed for CleanupResetAndDestroyPushL() |
|
33 #include <mm/mmpluginutils.h> |
|
34 #ifdef SYMBIAN_MULTIMEDIA_CODEC_API |
|
35 #include <mdf/codecapiresolverutils.h> |
|
36 #include <mdf/codecapiresolverdata.h> |
|
37 #include <mdf/codecapiuids.hrh> |
|
38 #include <mdf/codecapiresolver.hrh> |
|
39 #endif // SYMBIAN_MULTIMEDIA_CODEC_API |
|
40 |
|
41 _LIT(KFixedSequenceResourceFile, "Z:\\Resource\\DevSound\\FixedSequence.rsc"); |
|
42 const TInt KFourCCStringLength = 9; |
|
43 |
|
44 inline TMMFRawPackage::TMMFRawPackage(TInt aDerivedSize) |
|
45 #pragma warning( disable : 4355 ) // 'this' : used in base member initializer list |
|
46 : iThis((TUint8*)this,aDerivedSize,aDerivedSize) |
|
47 #pragma warning( default : 4355 ) |
|
48 { |
|
49 } |
|
50 |
|
51 inline TPtr8& TMMFRawPackage::Package() |
|
52 { |
|
53 ((TMMFRawPackage*)this)->iThis.Set((TUint8*)this,iThis.Length(),iThis.MaxLength()); |
|
54 return iThis; |
|
55 } |
|
56 |
|
57 inline const TPtr8& TMMFRawPackage::Package() const |
|
58 { |
|
59 ((TMMFRawPackage*)this)->iThis.Set((TUint8*)this,iThis.Length(),iThis.MaxLength()); |
|
60 return iThis; |
|
61 } |
|
62 |
|
63 inline void TMMFRawPackage::SetSize(TInt aDerivedSize) |
|
64 { |
|
65 iThis.Set((TUint8*)this,aDerivedSize,aDerivedSize); |
|
66 } |
|
67 |
|
68 inline TMMFToneFixedSequenceNames::TMMFToneFixedSequenceNames() : |
|
69 TMMFRawPackage(sizeof(TMMFToneFixedSequenceNames)) {} |
|
70 |
|
71 #ifdef _UNICODE |
|
72 class TNameBuf : public TBufCBase16 |
|
73 #else |
|
74 class TNameBuf : public TBufCBase8 |
|
75 #endif |
|
76 { |
|
77 friend class HMMFToneFixedSequenceNames; |
|
78 }; |
|
79 |
|
80 HMMFToneFixedSequenceNames::HMMFToneFixedSequenceNames() |
|
81 { |
|
82 iCount = 0; |
|
83 } |
|
84 |
|
85 HMMFToneFixedSequenceNames* HMMFToneFixedSequenceNames::AddNameL(const TDesC& aName) |
|
86 // Append a copy of the supplied descriptor to the end of the |
|
87 // current heap cell. This will involve a realloc that will normally |
|
88 // result in the object moving |
|
89 { |
|
90 TInt size = Package().Length(); |
|
91 TInt desSize = aName.Size() + sizeof(TInt); |
|
92 if (desSize&3) |
|
93 desSize = ((desSize+4)&(~3)); // Must round up to word boundary to keep aligned |
|
94 HMMFToneFixedSequenceNames* self = REINTERPRET_CAST(HMMFToneFixedSequenceNames*,User::ReAllocL(STATIC_CAST(TAny*,this),size + desSize)); |
|
95 TUint8* newDesPtr = REINTERPRET_CAST(TUint8*,self) + size; |
|
96 Mem::FillZ(newDesPtr,desSize); |
|
97 TNameBuf* newDes = REINTERPRET_CAST(TNameBuf*,newDesPtr); |
|
98 newDes->Copy(aName,aName.Length()); |
|
99 self->SetSize(size+desSize); |
|
100 self->iCount++; |
|
101 return self; |
|
102 } |
|
103 |
|
104 |
|
105 /****************************************************************** |
|
106 * CMMFDevSoundUtility |
|
107 ******************************************************************/ |
|
108 CMMFDevSoundUtility::CMMFDevSoundUtility() |
|
109 { |
|
110 // No default implementation |
|
111 } |
|
112 |
|
113 |
|
114 CMMFDevSoundUtility::~CMMFDevSoundUtility() |
|
115 { |
|
116 delete iInfo; |
|
117 delete iFixedSequenceNames; |
|
118 } |
|
119 |
|
120 CMMFDevSoundUtility* CMMFDevSoundUtility::NewL() |
|
121 { |
|
122 CMMFDevSoundUtility* self = NewLC(); |
|
123 CleanupStack::Pop(); |
|
124 return self; |
|
125 } |
|
126 |
|
127 CMMFDevSoundUtility* CMMFDevSoundUtility::NewLC() |
|
128 { |
|
129 CMMFDevSoundUtility* self = new(ELeave) CMMFDevSoundUtility(); |
|
130 CleanupStack::PushL(self); |
|
131 self->ConstructL(); |
|
132 // Leave it on Cleanupstack |
|
133 return self; |
|
134 } |
|
135 |
|
136 void CMMFDevSoundUtility::ConstructL() |
|
137 { |
|
138 iFixedSequenceNames = new (ELeave) HMMFToneFixedSequenceNames; |
|
139 } |
|
140 |
|
141 void CMMFDevSoundUtility::SeekUsingFourCCL(TUid aInterfaceUid, RImplInfoPtrArray& aPlugInArray, const TFourCC& aSrcDataType, const TFourCC& aDstDataType, const TDesC& aPreferredSupplier) |
|
142 { |
|
143 |
|
144 // Create a match string using the two FourCC codes. |
|
145 _LIT8(KEmptyFourCCString, " , "); |
|
146 TBufC8<KFourCCStringLength> fourCCString(KEmptyFourCCString); |
|
147 TPtr8 fourCCPtr = fourCCString.Des(); |
|
148 TPtr8 fourCCPtr1(&fourCCPtr[0], 4); |
|
149 TPtr8 fourCCPtr2(&fourCCPtr[5], 4 ); |
|
150 aSrcDataType.FourCC(&fourCCPtr1); |
|
151 aDstDataType.FourCC(&fourCCPtr2); |
|
152 |
|
153 MmPluginUtils::FindImplementationsL(aInterfaceUid, aPlugInArray, fourCCPtr); |
|
154 |
|
155 // If more than one match. Narrow the search by preferred supplier |
|
156 if((aPlugInArray.Count() > 1) && aPreferredSupplier.Length()) |
|
157 { |
|
158 SelectByPreference( aPlugInArray, aPreferredSupplier ); |
|
159 } |
|
160 |
|
161 // If there are no plugins, return failure |
|
162 if(aPlugInArray.Count() == 0) |
|
163 { |
|
164 User::Leave( KErrNotFound ); |
|
165 } |
|
166 } |
|
167 |
|
168 |
|
169 #ifdef SYMBIAN_MULTIMEDIA_CODEC_API |
|
170 void CMMFDevSoundUtility::FindHwDeviceAdapterL(TUid aInterfaceUid, RImplInfoPtrArray& aPlugInArray) |
|
171 { |
|
172 // Create a match string using the two FourCC codes. |
|
173 _LIT8(KAdapterMatch, "*"); |
|
174 |
|
175 MmPluginUtils::FindImplementationsL(aInterfaceUid, aPlugInArray, KAdapterMatch); |
|
176 |
|
177 // If there are no plugins, return failure |
|
178 |
|
179 if(aPlugInArray.Count() == 0) |
|
180 { |
|
181 User::Leave( KErrNotFound ); |
|
182 } |
|
183 } |
|
184 |
|
185 void CMMFDevSoundUtility::SeekCodecPluginsL(RArray<TFourCC>& aSupportedDataTypes, TMMFState aState, TBool aAppend) |
|
186 { |
|
187 _LIT8(KPCM16FourCCString, " P16"); |
|
188 //check argument precondition for aState |
|
189 if ((aState != EMMFStatePlaying) && (aState != EMMFStateRecording)) |
|
190 { |
|
191 User::Leave(KErrArgument); |
|
192 } |
|
193 |
|
194 if (!aAppend) |
|
195 { |
|
196 aSupportedDataTypes.Reset(); //clear any existing data in aSupportedDataTypes array if not appending |
|
197 } |
|
198 |
|
199 CCodecApiResolverData* customMatchData = CCodecApiResolverData::NewLC(); |
|
200 if (aState == EMMFStatePlaying) |
|
201 { |
|
202 customMatchData->SetMatchType(EMatchOutputDataFormat); |
|
203 customMatchData->SetOutputDataL(KPCM16FourCCString); |
|
204 } |
|
205 else |
|
206 { |
|
207 customMatchData->SetMatchType(EMatchInputDataFormat); |
|
208 customMatchData->SetInputDataL(KPCM16FourCCString); |
|
209 } |
|
210 |
|
211 customMatchData->SetImplementationType(TUid::Uid(KUidAudioCodec)); |
|
212 |
|
213 HBufC8* package = customMatchData->NewPackLC(); |
|
214 |
|
215 RImplInfoPtrArray ecomArray; |
|
216 CleanupResetAndDestroyPushL(ecomArray); |
|
217 |
|
218 TInt err = KErrNone; |
|
219 MmPluginUtils::FindImplementationsL(TUid::Uid(KUidMdfProcessingUnit), ecomArray, *package, TUid::Uid(KUidCodecApiResolverImplementation)); |
|
220 |
|
221 for (TInt i=0 ; i < ecomArray.Count() ; i++) |
|
222 { |
|
223 CCodecApiOpaqueData* data = NULL; |
|
224 TRAP(err, data = CCodecApiOpaqueData::NewL(ecomArray[i]->OpaqueData())); |
|
225 // simply ignore plugins that we can't parse the opaque data. They should not cause other plugins |
|
226 // to fall over |
|
227 if (err == KErrNone) |
|
228 { |
|
229 const TDesC8* dataType; |
|
230 if (aState == EMMFStatePlaying) |
|
231 { |
|
232 dataType = &data->InputDataType(); |
|
233 } |
|
234 else |
|
235 { |
|
236 dataType = &data->OutputDataType(); |
|
237 } |
|
238 TFourCC fourCC(*dataType); |
|
239 delete data; |
|
240 aSupportedDataTypes.AppendL(fourCC); |
|
241 } |
|
242 } |
|
243 CleanupStack::PopAndDestroy(3, customMatchData); |
|
244 } |
|
245 #endif // SYMBIAN_MULTIMEDIA_CODEC_API |
|
246 |
|
247 /* |
|
248 * local function to disable items which do not match the preferred supplier. |
|
249 * Note that at least one enabled item is returned (if there was an enabled item to begin with) which |
|
250 * may not match the preferred supplier. |
|
251 * |
|
252 */ |
|
253 void CMMFDevSoundUtility::SelectByPreference( RImplInfoPtrArray& aPlugInArray, const TDesC& aPreferredSupplier ) |
|
254 { |
|
255 |
|
256 // Use the Disabled flag to eliminated all currently enabled matches that |
|
257 // do not match the preferred supplier. |
|
258 TInt firstEnabled = -1 ; // to ensure that we return something valid |
|
259 TInt matchCount = 0 ; |
|
260 for ( TInt ii = 0 ; ii < aPlugInArray.Count() ; ii++ ) |
|
261 { |
|
262 if ( !( aPlugInArray[ii]->Disabled() ) ) |
|
263 { |
|
264 if ( firstEnabled == -1 ) |
|
265 firstEnabled = ii ; |
|
266 if ( aPlugInArray[ii]->DisplayName().FindF( aPreferredSupplier ) == KErrNotFound ) |
|
267 aPlugInArray[ii]->SetDisabled( ETrue ) ; |
|
268 else |
|
269 matchCount++ ; |
|
270 } |
|
271 } |
|
272 |
|
273 // If there are no matches then re-enable the first enabled |
|
274 if ( matchCount == 0 ) |
|
275 aPlugInArray[firstEnabled]->SetDisabled( EFalse ) ; |
|
276 else if ( matchCount > 1 ) |
|
277 { |
|
278 // find the latest version from more than one match |
|
279 TInt highestVersionIndex = -1 ; |
|
280 for ( TInt ii = 0 ; ii < aPlugInArray.Count() ; ii++ ) |
|
281 { |
|
282 if ( !( aPlugInArray[ii]->Disabled() ) ) // only interested in enabled elements |
|
283 { |
|
284 if ( highestVersionIndex == -1 ) |
|
285 { // first match. Store this. Keep it enabled |
|
286 highestVersionIndex = ii ; |
|
287 } |
|
288 else if ( aPlugInArray[ii]->Version() > aPlugInArray[highestVersionIndex]->Version() ) |
|
289 { // a new leader. Disable the previous leader. Keep this one. |
|
290 aPlugInArray[highestVersionIndex]->SetDisabled( ETrue ) ; |
|
291 highestVersionIndex = ii ; |
|
292 } |
|
293 else // we already have a higher version. |
|
294 aPlugInArray[ii]->SetDisabled( ETrue ) ; |
|
295 } |
|
296 } |
|
297 } |
|
298 } |
|
299 |
|
300 |
|
301 /* |
|
302 * SeekHwDevicePluginsL |
|
303 * This method looks for hwDevicePlugins that support the state given in aState which |
|
304 * must be either EMMFStatePlaying or EMMFStateRecording |
|
305 * For each HwDevice plugin found the datatype as indicated by its fourCC code |
|
306 * from the default_data field in the resource file is added to the array of aSupportedDataTypes |
|
307 * |
|
308 * @internalComponent |
|
309 * |
|
310 * @param "RArray<TFourCC>& aSupportedDataTypes" |
|
311 * an array of fourCC codes that has a fourCC code added to for each hardware device found |
|
312 * |
|
313 * @param "TMMFState aState" |
|
314 * must be set to EMMFStatePlaying if seeking HwDevice plugins that support play and |
|
315 * EMMFStateRecording if seeking HwDevice plugins that support record |
|
316 * |
|
317 * @leave KErrArgument if aState is not EMMFStatePlaying or EMMFStateRecording else leaves |
|
318 * with standard symbian OS error code |
|
319 */ |
|
320 void CMMFDevSoundUtility::SeekHwDevicePluginsL(RArray<TFourCC>& aSupportedDataTypes, TMMFState aState) |
|
321 { |
|
322 //check argument precondition for aState |
|
323 if ((aState != EMMFStatePlaying) && (aState != EMMFStateRecording)) |
|
324 { |
|
325 User::Leave(KErrArgument); |
|
326 } |
|
327 |
|
328 aSupportedDataTypes.Reset(); //clear any existing data in aSupportedDataTypes array |
|
329 |
|
330 RImplInfoPtrArray plugInArray ; // Array to return hw device plugin resource info |
|
331 CleanupResetAndDestroyPushL(plugInArray); |
|
332 |
|
333 TUid KUidMmfHWPluginInterfaceCodec = {KMmfUidPluginInterfaceHwDevice}; |
|
334 |
|
335 MmPluginUtils::FindImplementationsL(KUidMmfHWPluginInterfaceCodec, plugInArray); |
|
336 |
|
337 TUint numberOfHwDevicePlugins = plugInArray.Count(); |
|
338 |
|
339 //if have hwdevice plugin resource entries then scan entries |
|
340 //matching on a datatype of pcm16 as the destination datatype for play and the |
|
341 //source datatype for record |
|
342 //if a match is found and isn't already in list of supported data types |
|
343 //then add it to the list |
|
344 if (numberOfHwDevicePlugins) |
|
345 { |
|
346 CImplementationInformation* hwDeviceResourceEntry = NULL; |
|
347 _LIT8(KPCM16FourCCString, " P16"); |
|
348 TBufC8<KFourCCLength> fourCCStringPCM16(KPCM16FourCCString); |
|
349 TPtr8 fourCCPtrPCM16 = fourCCStringPCM16.Des(); |
|
350 TUint entryNumber = 0; |
|
351 |
|
352 //check each resource entry for dst 4CC = P16 for play and src 4CC = P16 for record |
|
353 for (TUint hwDeviceEntry = 0; hwDeviceEntry < numberOfHwDevicePlugins; hwDeviceEntry++) |
|
354 { |
|
355 hwDeviceResourceEntry = plugInArray[hwDeviceEntry]; |
|
356 if (IsDataTypeMatch(hwDeviceResourceEntry, fourCCPtrPCM16, aState)) |
|
357 {//resource entry data field has dest/src datatype ' P16' ie pcm16 for play/record |
|
358 TPtrC8 fourCCPtr(0,0); |
|
359 if (aState == EMMFStatePlaying)//then datatype supported 4CC is left 4 chars |
|
360 { |
|
361 fourCCPtr.Set(hwDeviceResourceEntry->DataType().Left(KFourCCLength)); |
|
362 } |
|
363 else if (aState == EMMFStateRecording) //then datatype supported 4CC is right 4 chars |
|
364 { |
|
365 fourCCPtr.Set(hwDeviceResourceEntry->DataType().Right(KFourCCLength)); |
|
366 } |
|
367 TFourCC fourCCEntry(fourCCPtr); |
|
368 //need to check if entry already exists to prevent duplicate entries |
|
369 entryNumber = aSupportedDataTypes.Count(); |
|
370 TBool alreadyExists = EFalse; |
|
371 for (TUint fourCCEntryNumber = 0; fourCCEntryNumber < entryNumber; fourCCEntryNumber++) |
|
372 { |
|
373 if (aSupportedDataTypes[fourCCEntryNumber]==fourCCEntry) |
|
374 { |
|
375 alreadyExists = ETrue;//we already have this 4CC in the supported data types |
|
376 break; |
|
377 } |
|
378 } |
|
379 if (!alreadyExists) |
|
380 { |
|
381 TInt err = aSupportedDataTypes.Append(fourCCEntry); |
|
382 if (err) |
|
383 {//note we don't destroy array because we don't own it |
|
384 //but we do reset it as it is incomplete |
|
385 aSupportedDataTypes.Reset(); |
|
386 User::Leave(err); |
|
387 } |
|
388 } |
|
389 }//if (IsDataTypeMatch(hwDeviceResourceEntry, fourCCPtrPCM16, aState)) |
|
390 }//for (TUint hwDeviceEntry = 0; hwDeviceEntry < numberOfHwDevicePlugins; hwDeviceEntry++) |
|
391 }//if (numberOfHwDevicePlugins) |
|
392 |
|
393 CleanupStack::PopAndDestroy(&plugInArray); |
|
394 } |
|
395 |
|
396 |
|
397 /* |
|
398 * IsDataTypeMatch |
|
399 * This method takes a given resource entry from a hardware device and determines |
|
400 * whether the hwdevice plugin is a data type match for playing or recording |
|
401 * depending on the setting of aState |
|
402 * The method matchs the default_data field from the hw device resource entry matching |
|
403 * it with the aHwMatchFourCC code. |
|
404 * |
|
405 * @internalComponent |
|
406 * |
|
407 * @param "CImplementationInformation aHwDeviceResourceEntry" |
|
408 * the hw device resource entry that is to be checked |
|
409 * whether it can be used to play or record |
|
410 * |
|
411 * @param "TDesC8& aHwMatchFourCC |
|
412 * the data type fourCC code to match to that the hardware device that must convert to for |
|
413 * playing and convert from for recording - for the reference DevSound this is always ' P16' ie pcm16 |
|
414 * |
|
415 * @param "TMMFState aState" |
|
416 * this determines whether the match is for playing or recording and should take |
|
417 * either the values EMMFStatePlaying or EMMFStateRecording |
|
418 * |
|
419 * @return ETrue if a match for play or record else EFalse |
|
420 */ |
|
421 TBool CMMFDevSoundUtility::IsDataTypeMatch(CImplementationInformation* aHwDeviceResourceEntry,const TDesC8& aHwMatchFourCC, TMMFState aState) |
|
422 { |
|
423 TBool match = EFalse; |
|
424 // extra length safety check to remove adapter plugins and incorrect ones |
|
425 if (aHwDeviceResourceEntry->DataType().Length()>=KFourCCStringLength) |
|
426 { |
|
427 if (aState == EMMFStatePlaying) |
|
428 {//play need to match with the right four characters |
|
429 match = (!(aHwMatchFourCC.Match(aHwDeviceResourceEntry->DataType().Right(KFourCCLength))==KErrNotFound)); |
|
430 } |
|
431 else if (aState == EMMFStateRecording) |
|
432 {//record need to match with the left four characters |
|
433 match = (!(aHwMatchFourCC.Match(aHwDeviceResourceEntry->DataType().Left(KFourCCLength))==KErrNotFound)); |
|
434 } |
|
435 } |
|
436 return match; |
|
437 } |
|
438 |
|
439 |
|
440 /** |
|
441 * Populate fixed sequences |
|
442 * |
|
443 */ |
|
444 void CMMFDevSoundUtility::InitializeFixedSequenceL(CPtrC8Array** aFixedSequences) |
|
445 { |
|
446 |
|
447 RFs fsSession; |
|
448 User::LeaveIfError(fsSession.Connect()); |
|
449 CleanupClosePushL(fsSession); |
|
450 |
|
451 // Open the resource file |
|
452 RResourceFile resourceFile; |
|
453 resourceFile.OpenL(fsSession, KFixedSequenceResourceFile); |
|
454 CleanupClosePushL(resourceFile); |
|
455 |
|
456 // Allocate buffer to hold resource data in binary format |
|
457 iInfo = resourceFile.AllocReadL(FIXED_TONE_SEQUENCE); |
|
458 |
|
459 TResourceReader reader; |
|
460 reader.SetBuffer(iInfo); |
|
461 |
|
462 // Create array to hold fixed sequences data |
|
463 CPtrC8Array* tempSequences = new(ELeave) CPtrC8Array(8); // granularity |
|
464 CleanupStack::PushL(tempSequences); |
|
465 |
|
466 // First word gives number of entries |
|
467 TInt numberOfEntries = reader.ReadUint16(); |
|
468 ASSERT(!(numberOfEntries&1)); // Should have atleast one entry |
|
469 |
|
470 // There must be an even number entries as each sequence structure |
|
471 // is made of a name string and a data string (SEQUENCE_NAME and SEQUENCE_DATA) |
|
472 |
|
473 HMMFToneFixedSequenceNames* names = new (ELeave) HMMFToneFixedSequenceNames; |
|
474 CleanupStack::PushL(names); |
|
475 for (TInt i=0;i<numberOfEntries;i+=2) |
|
476 { |
|
477 // Copy name from resource array to returnable array |
|
478 HMMFToneFixedSequenceNames* newNames = names->AddNameL(reader.ReadTPtrC()); |
|
479 if (names != newNames) |
|
480 { // May have moved so fixup cleanupstack reference |
|
481 CleanupStack::Pop(); |
|
482 names = newNames; |
|
483 CleanupStack::PushL(names); |
|
484 } |
|
485 TInt len = reader.ReadUint16(); |
|
486 TPtrC8 tempTPtrC8(REINTERPRET_CAST(const TUint8*,reader.Ptr()),len<<1); |
|
487 tempSequences->AppendL(tempTPtrC8); |
|
488 reader.Advance(len<<1); |
|
489 } |
|
490 CleanupStack::Pop(); // names |
|
491 |
|
492 // Delete the old fixed sequence names |
|
493 delete iFixedSequenceNames; |
|
494 iFixedSequenceNames = NULL; |
|
495 iFixedSequenceNames = names; |
|
496 |
|
497 *aFixedSequences = tempSequences; |
|
498 CleanupStack::Pop(tempSequences); |
|
499 CleanupStack::PopAndDestroy(2); // resourceFile, fsSession |
|
500 } |
|
501 |
|
502 TBool CMMFDevSoundUtility::RecognizeSequence(const TDesC8& aData) |
|
503 { |
|
504 // Reference plug-in only supports its own sequence format |
|
505 _LIT8(KSequenceSignature,"SQNC"); |
|
506 if (aData.Length() > 4) |
|
507 { |
|
508 if (aData.Left(4) == KSequenceSignature) |
|
509 return ETrue; |
|
510 } |
|
511 // Didn't recognise |
|
512 return EFalse; |
|
513 } |
|
514 |
|
515 const TDesC& CMMFDevSoundUtility::FixedSequenceName(TInt aSequenceNumber) |
|
516 { |
|
517 ASSERT(iFixedSequenceNames); // Defect if this not true when previous was true |
|
518 ASSERT((aSequenceNumber>=0)&&(aSequenceNumber<iFixedSequenceNames->iCount)); |
|
519 |
|
520 // Ptr to first descriptor |
|
521 TUint8* ptr = REINTERPRET_CAST(TUint8*,&(iFixedSequenceNames->iCount))+sizeof(TInt); |
|
522 TDesC* desPtr = REINTERPRET_CAST(TDesC*,ptr); // First des |
|
523 while (aSequenceNumber--) |
|
524 { |
|
525 TInt size = desPtr->Size(); |
|
526 if (size&3) |
|
527 size = ((size+4)&(~3)); |
|
528 ptr += sizeof(TInt) + size; |
|
529 desPtr = REINTERPRET_CAST(TDesC*,ptr); // Next des |
|
530 } |
|
531 return *desPtr; |
|
532 } |