|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Audio Stubs - Implementation of the DevSound utilities. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include <e32std.h> |
|
22 #include <barsc.h> |
|
23 #include <barsread.h> |
|
24 #include <mmfbase.h> |
|
25 #include <mmfplugininterfaceuids.hrh> |
|
26 #include <mmf/common/mmfcontroller.h> //needed for CleanupResetAndDestroyPushL() |
|
27 #include <fixedsequence.rsg> |
|
28 #include "DevSoundUtility.h" |
|
29 |
|
30 _LIT(KFixedSequenceResourceFile, "Z:\\Resource\\DevSound\\FixedSequence.rsc"); |
|
31 |
|
32 // CONSTANTS |
|
33 const TUint K4ByteSeq = 4; |
|
34 const TInt KFourCCStringLength = 9; |
|
35 |
|
36 inline TMMFRawPackage::TMMFRawPackage(TInt aDerivedSize) |
|
37 #pragma warning( disable : 4355 ) |
|
38 // 'this' : used in base member initializer list |
|
39 : iThis((TUint8*)this,aDerivedSize,aDerivedSize) |
|
40 #pragma warning( default : 4355 ) |
|
41 { |
|
42 } |
|
43 |
|
44 // ----------------------------------------------------------------------------- |
|
45 // TMMFRawPackage::Package |
|
46 // Returns a reference to descriptor pointer. |
|
47 // (other items were commented in a header). |
|
48 // ----------------------------------------------------------------------------- |
|
49 // |
|
50 inline TPtr8& TMMFRawPackage::Package() |
|
51 { |
|
52 ((TMMFRawPackage*)this)->iThis.Set((TUint8*)this, |
|
53 iThis.Length(), |
|
54 iThis.MaxLength()); |
|
55 return iThis; |
|
56 } |
|
57 |
|
58 // ----------------------------------------------------------------------------- |
|
59 // TMMFRawPackage::Package |
|
60 // Returns a reference to descriptor pointer. |
|
61 // (other items were commented in a header). |
|
62 // ----------------------------------------------------------------------------- |
|
63 // |
|
64 inline const TPtr8& TMMFRawPackage::Package() const |
|
65 { |
|
66 ((TMMFRawPackage*)this)->iThis.Set((TUint8*)this, |
|
67 iThis.Length(), |
|
68 iThis.MaxLength()); |
|
69 return iThis; |
|
70 } |
|
71 |
|
72 // ----------------------------------------------------------------------------- |
|
73 // TMMFRawPackage::SetSize |
|
74 // Sets the size of the raw package |
|
75 // (other items were commented in a header). |
|
76 // ----------------------------------------------------------------------------- |
|
77 // |
|
78 inline void TMMFRawPackage::SetSize(TInt aDerivedSize) |
|
79 { |
|
80 iThis.Set((TUint8*)this,aDerivedSize,aDerivedSize); |
|
81 } |
|
82 |
|
83 // ----------------------------------------------------------------------------- |
|
84 // TMMFToneFixedSequenceNames::TMMFToneFixedSequenceNames |
|
85 // Default constructor |
|
86 // (other items were commented in a header). |
|
87 // ----------------------------------------------------------------------------- |
|
88 // |
|
89 inline TMMFToneFixedSequenceNames::TMMFToneFixedSequenceNames() |
|
90 : TMMFRawPackage(sizeof(TMMFToneFixedSequenceNames)) |
|
91 { |
|
92 } |
|
93 |
|
94 // ----------------------------------------------------------------------------- |
|
95 // TNameBuf class definition |
|
96 // (other items were commented in a header). |
|
97 // ----------------------------------------------------------------------------- |
|
98 // |
|
99 #ifdef _UNICODE |
|
100 class TNameBuf : public TBufCBase16 |
|
101 #else |
|
102 class TNameBuf : public TBufCBase8 |
|
103 #endif |
|
104 { |
|
105 friend class HMMFToneFixedSequenceNames; |
|
106 }; |
|
107 |
|
108 // ----------------------------------------------------------------------------- |
|
109 // HMMFToneFixedSequenceNames::HMMFToneFixedSequenceNames |
|
110 // Default constructor |
|
111 // (other items were commented in a header). |
|
112 // ----------------------------------------------------------------------------- |
|
113 // |
|
114 HMMFToneFixedSequenceNames::HMMFToneFixedSequenceNames() |
|
115 { |
|
116 iCount = 0; |
|
117 } |
|
118 |
|
119 // ----------------------------------------------------------------------------- |
|
120 // HMMFToneFixedSequenceNames::AddNameL |
|
121 // Append a copy of the supplied descriptor to the end of the |
|
122 // current heap cell. This will involve a realloc that will normally |
|
123 // result in the object moving |
|
124 // ----------------------------------------------------------------------------- |
|
125 // |
|
126 HMMFToneFixedSequenceNames* |
|
127 HMMFToneFixedSequenceNames::AddNameL(const TDesC& aName) |
|
128 { |
|
129 TInt size = Package().Length(); |
|
130 TInt desSize = aName.Size() + sizeof(TInt); |
|
131 if (desSize&3) |
|
132 { |
|
133 // Must round up to word boundary to keep aligned |
|
134 desSize = ((desSize+4)&(~3)); |
|
135 } |
|
136 |
|
137 HMMFToneFixedSequenceNames* self = |
|
138 REINTERPRET_CAST(HMMFToneFixedSequenceNames*, |
|
139 User::ReAllocL(STATIC_CAST(TAny*,this), |
|
140 size + desSize)); |
|
141 TUint8* newDesPtr = REINTERPRET_CAST(TUint8*,self) + size; |
|
142 Mem::FillZ(newDesPtr,desSize); |
|
143 TNameBuf* newDes = REINTERPRET_CAST(TNameBuf*,newDesPtr); |
|
144 newDes->Copy(aName,aName.Length()); |
|
145 self->SetSize(size+desSize); |
|
146 self->iCount++; |
|
147 return self; |
|
148 } |
|
149 |
|
150 // ============================ MEMBER FUNCTIONS =============================== |
|
151 |
|
152 // ----------------------------------------------------------------------------- |
|
153 // CMMFDevSoundUtility::CMMFDevSoundUtility |
|
154 // C++ default constructor can NOT contain any code, that |
|
155 // might leave. |
|
156 // ----------------------------------------------------------------------------- |
|
157 // |
|
158 CMMFDevSoundUtility::CMMFDevSoundUtility() |
|
159 { |
|
160 // No default implementation |
|
161 } |
|
162 |
|
163 // ----------------------------------------------------------------------------- |
|
164 // CMMFDevSoundUtility::ConstructL |
|
165 // Symbian 2nd phase constructor can leave. |
|
166 // ----------------------------------------------------------------------------- |
|
167 // |
|
168 void CMMFDevSoundUtility::ConstructL() |
|
169 { |
|
170 iFixedSequenceNames = new (ELeave) HMMFToneFixedSequenceNames; |
|
171 } |
|
172 |
|
173 // ----------------------------------------------------------------------------- |
|
174 // CMMFDevSoundUtility::NewL |
|
175 // Two-phased constructor. |
|
176 // ----------------------------------------------------------------------------- |
|
177 // |
|
178 CMMFDevSoundUtility* CMMFDevSoundUtility::NewL() |
|
179 { |
|
180 CMMFDevSoundUtility* self = NewLC(); |
|
181 CleanupStack::Pop(self); |
|
182 return self; |
|
183 } |
|
184 |
|
185 // ----------------------------------------------------------------------------- |
|
186 // CMMFDevSoundUtility::NewLC |
|
187 // Two-phased constructor. |
|
188 // ----------------------------------------------------------------------------- |
|
189 // |
|
190 CMMFDevSoundUtility* CMMFDevSoundUtility::NewLC() |
|
191 { |
|
192 CMMFDevSoundUtility* self = new(ELeave) CMMFDevSoundUtility(); |
|
193 CleanupStack::PushL(self); |
|
194 self->ConstructL(); |
|
195 // Leave it on Cleanupstack |
|
196 return self; |
|
197 } |
|
198 |
|
199 // ----------------------------------------------------------------------------- |
|
200 // CMMFDevSoundUtility::~CMMFDevSoundUtility |
|
201 // Destructor |
|
202 // ----------------------------------------------------------------------------- |
|
203 // |
|
204 CMMFDevSoundUtility::~CMMFDevSoundUtility() |
|
205 { |
|
206 delete iInfo; |
|
207 delete iFixedSequenceNames; |
|
208 } |
|
209 |
|
210 // ----------------------------------------------------------------------------- |
|
211 // CMMFDevSoundUtility::SeekUsingFourCCLC |
|
212 // Finds the ECom plugins based on FourCC. |
|
213 // (other items were commented in a header). |
|
214 // ----------------------------------------------------------------------------- |
|
215 // |
|
216 void CMMFDevSoundUtility::SeekUsingFourCCLC( |
|
217 TUid aInterfaceUid, |
|
218 RImplInfoPtrArray& aPlugInArray, |
|
219 const TFourCC& aSrcDataType, |
|
220 const TFourCC& aDstDataType, |
|
221 const TDesC& aPreferredSupplier) |
|
222 { |
|
223 // Create a match string using the two FourCC codes. |
|
224 _LIT8(KEmptyFourCCString, " , "); |
|
225 TBufC8<9> fourCCString(KEmptyFourCCString); |
|
226 TPtr8 fourCCPtr = fourCCString.Des(); |
|
227 TPtr8 fourCCPtr1(&fourCCPtr[0], 4); |
|
228 TPtr8 fourCCPtr2(&fourCCPtr[5], 4 ); |
|
229 aSrcDataType.FourCC(&fourCCPtr1); |
|
230 aDstDataType.FourCC(&fourCCPtr2); |
|
231 |
|
232 // Create a TEcomResolverParams structure. |
|
233 TEComResolverParams resolverParams; |
|
234 resolverParams.SetDataType(fourCCPtr); |
|
235 resolverParams.SetWildcardMatch(EFalse); |
|
236 |
|
237 // ListImplementationsL leaves if it cannot find anything so trap the error |
|
238 // and ignore it. |
|
239 TRAPD(err, REComSession::ListImplementationsL(aInterfaceUid, |
|
240 resolverParams, |
|
241 aPlugInArray)); |
|
242 |
|
243 // The error above may not be KErrNotFound eg could be KErrNoMemory in which |
|
244 // case leave |
|
245 User::LeaveIfError(err); |
|
246 |
|
247 // If there are no plugins, indicate failure |
|
248 if (aPlugInArray.Count() == 0) |
|
249 { |
|
250 User::Leave(KErrNotFound) ; |
|
251 } |
|
252 |
|
253 // If more than one match, narrow the search by preferred supplier |
|
254 if ((aPlugInArray.Count() > 1) && aPreferredSupplier.Length()) |
|
255 { |
|
256 SelectByPreference( aPlugInArray, aPreferredSupplier ) ; |
|
257 } |
|
258 } |
|
259 |
|
260 |
|
261 // ----------------------------------------------------------------------------- |
|
262 // CMMFDevSoundUtility::SelectByPreference |
|
263 // local function to disable items which do not match the preferred supplier. |
|
264 // Note that at least one enabled item is returned (if there was an enabled item |
|
265 // to begin with) which may not match the preferred supplier. |
|
266 // ----------------------------------------------------------------------------- |
|
267 // |
|
268 void CMMFDevSoundUtility::SelectByPreference(RImplInfoPtrArray& aPlugInArray, |
|
269 const TDesC& aPreferredSupplier) |
|
270 { |
|
271 |
|
272 // Use the Disabled flag to eliminated all currently enabled matches that |
|
273 // do not match the preferred supplier. |
|
274 TInt firstEnabled = -1 ; // to ensure that we return something valid |
|
275 TInt matchCount = 0 ; |
|
276 |
|
277 for ( TInt ii = 0 ; ii < aPlugInArray.Count() ; ii++ ) |
|
278 { |
|
279 if (!(aPlugInArray[ii]->Disabled())) |
|
280 { |
|
281 if (firstEnabled == -1) |
|
282 { |
|
283 firstEnabled = ii; |
|
284 } |
|
285 |
|
286 if (aPlugInArray[ii]->DisplayName().FindF(aPreferredSupplier) == |
|
287 KErrNotFound) |
|
288 { |
|
289 aPlugInArray[ii]->SetDisabled(ETrue) ; |
|
290 } |
|
291 else |
|
292 { |
|
293 matchCount++ ; |
|
294 } |
|
295 } |
|
296 } |
|
297 |
|
298 // If there are no matches then re-enable the first enabled |
|
299 if (matchCount == 0 ) |
|
300 { |
|
301 aPlugInArray[firstEnabled]->SetDisabled(EFalse); |
|
302 } |
|
303 else if (matchCount > 1) |
|
304 { |
|
305 // find the latest version from more than one match |
|
306 TInt highestVersionIndex = -1; |
|
307 |
|
308 for (TInt ii = 0; ii < aPlugInArray.Count(); ii++) |
|
309 { |
|
310 // only interested in enabled elements |
|
311 if (!(aPlugInArray[ii]->Disabled())) |
|
312 { |
|
313 if (highestVersionIndex == -1) |
|
314 { |
|
315 // first match. Store this. Keep it enabled |
|
316 highestVersionIndex = ii; |
|
317 } |
|
318 else if (aPlugInArray[ii]->Version() > |
|
319 aPlugInArray[highestVersionIndex]->Version()) |
|
320 { |
|
321 // A new leader. Disable the previous leader. |
|
322 // Keep this one. |
|
323 aPlugInArray[highestVersionIndex]->SetDisabled(ETrue); |
|
324 highestVersionIndex = ii; |
|
325 } |
|
326 else // we already have a higher version. |
|
327 aPlugInArray[ii]->SetDisabled(ETrue); |
|
328 } |
|
329 } |
|
330 } |
|
331 } |
|
332 |
|
333 // ----------------------------------------------------------------------------- |
|
334 // CMMFDevSoundUtility::SeekHwDevicePluginsL |
|
335 // This method looks for hwDevicePlugins that support the state given in aState |
|
336 // which must be either EMMFStatePlaying or EMMFStateRecording. |
|
337 // For each HwDevice plugin found the datatype as indicated by its fourCC code |
|
338 // from the default_data field in the resource file is added to the array of |
|
339 // aSupportedDataTypes |
|
340 // ----------------------------------------------------------------------------- |
|
341 // |
|
342 void CMMFDevSoundUtility::SeekHwDevicePluginsL( |
|
343 RArray<TFourCC>& aSupportedDataTypes, |
|
344 TMMFState aState) |
|
345 { |
|
346 //check argument precondition for aState |
|
347 if ((aState != EMMFStatePlaying) && (aState != EMMFStateRecording)) |
|
348 { |
|
349 User::Leave(KErrArgument); |
|
350 } |
|
351 |
|
352 //clear any existing data in aSupportedDataTypes array |
|
353 aSupportedDataTypes.Reset(); |
|
354 |
|
355 // Array to return hw device plugin resource info(place on cleanupstack |
|
356 // _after_ ListImplementationsL() ) |
|
357 RImplInfoPtrArray plugInArray; |
|
358 TUid KUidMmfHWPluginInterfaceCodec = {KMmfUidPluginInterfaceHwDevice}; |
|
359 |
|
360 // ListImplementationsL leaves if it cannot find anything so trap the error |
|
361 TRAPD(err, REComSession::ListImplementationsL(KUidMmfHWPluginInterfaceCodec, |
|
362 plugInArray)); |
|
363 CleanupResetAndDestroyPushL(plugInArray); |
|
364 |
|
365 TUint numberOfHwDevicePlugins = plugInArray.Count(); |
|
366 |
|
367 // if no errors and have hwdevice plugin resource entries then scan entries |
|
368 // matching on a datatype of pcm16 as the destination datatype for play and |
|
369 // the source datatype for record. If a match is found and isn't already in |
|
370 // the list of supported data types, then add it to the list |
|
371 if ((err == KErrNone) && (numberOfHwDevicePlugins)) |
|
372 { |
|
373 CImplementationInformation* hwDeviceResourceEntry = NULL; |
|
374 _LIT8(KPCM16FourCCString, " P16"); |
|
375 TBufC8<KFOURCCLENGTH> fourCCStringPCM16(KPCM16FourCCString); |
|
376 TPtr8 fourCCPtrPCM16 = fourCCStringPCM16.Des(); |
|
377 TUint entryNumber = 0; |
|
378 |
|
379 // check each resource entry for dst 4CC = P16 for play and |
|
380 // src 4CC = P16 for record |
|
381 for (TUint hwDeviceEntry = 0; |
|
382 hwDeviceEntry < numberOfHwDevicePlugins; |
|
383 hwDeviceEntry++) |
|
384 { |
|
385 hwDeviceResourceEntry = plugInArray[hwDeviceEntry]; |
|
386 |
|
387 if (IsDataTypeMatch(hwDeviceResourceEntry, fourCCPtrPCM16, aState)) |
|
388 { |
|
389 // resource entry data field has dest/src datatype ' P16' |
|
390 // i.e. pcm16 for play/record |
|
391 TPtrC8 fourCCPtr(0,0); |
|
392 |
|
393 if (aState == EMMFStatePlaying) |
|
394 { |
|
395 // datatype supported 4CC is left 4 chars |
|
396 fourCCPtr.Set( |
|
397 hwDeviceResourceEntry->DataType().Left(KFOURCCLENGTH)); |
|
398 } |
|
399 else if (aState == EMMFStateRecording) |
|
400 { |
|
401 // datatype supported 4CC is right 4 chars |
|
402 fourCCPtr.Set( |
|
403 hwDeviceResourceEntry->DataType().Right(KFOURCCLENGTH)); |
|
404 } |
|
405 |
|
406 TFourCC fourCCEntry(fourCCPtr); |
|
407 //need to check if entry already exists to prevent |
|
408 // duplicate entries |
|
409 TBool alreadyExists = EFalse; |
|
410 |
|
411 for (TUint fourCCEntryNumber = 0; |
|
412 fourCCEntryNumber < entryNumber; |
|
413 fourCCEntryNumber++) |
|
414 { |
|
415 if (aSupportedDataTypes[fourCCEntryNumber]==fourCCEntry) |
|
416 { |
|
417 // we already have this 4CC in the supported data types |
|
418 alreadyExists = ETrue; |
|
419 break; |
|
420 } |
|
421 } |
|
422 if (!alreadyExists) |
|
423 { |
|
424 err = aSupportedDataTypes.Append(fourCCEntry); |
|
425 if (err) |
|
426 { |
|
427 // note: we don't destroy array because we don't own it |
|
428 // but we do reset it as it is incomplete |
|
429 aSupportedDataTypes.Reset(); |
|
430 User::Leave(err); |
|
431 } |
|
432 } |
|
433 } |
|
434 } |
|
435 } |
|
436 else |
|
437 { |
|
438 // if an error occured and not KErrNotFound then must be a 'real' error |
|
439 // e.g. KErrNoMemory |
|
440 if ((err != KErrNotFound) && (err != KErrNone)) |
|
441 { |
|
442 User::Leave(err); |
|
443 } |
|
444 } |
|
445 |
|
446 CleanupStack::PopAndDestroy(&plugInArray); |
|
447 } |
|
448 |
|
449 // ----------------------------------------------------------------------------- |
|
450 // CMMFDevSoundUtility::IsDataTypeMatch |
|
451 // This method takes a given resource entry from a hardware device and |
|
452 // determines whether the hwdevice plugin is a data type match for playing or |
|
453 // recording depending on the setting of aState |
|
454 // The method matchs the default_data field from the hw device resource entry |
|
455 // matching it with the aHwMatchFourCC code. |
|
456 // ----------------------------------------------------------------------------- |
|
457 // |
|
458 TBool CMMFDevSoundUtility::IsDataTypeMatch( |
|
459 CImplementationInformation* aHwDeviceResourceEntry, |
|
460 const TDesC8& aHwMatchFourCC, |
|
461 TMMFState aState) |
|
462 { |
|
463 TBool match = EFalse; |
|
464 // extra length safety check to remove adapter plugins and incorrect ones |
|
465 if (aHwDeviceResourceEntry->DataType().Length()>=KFourCCStringLength) |
|
466 { |
|
467 if (aState == EMMFStatePlaying) |
|
468 { |
|
469 //play need to match with the right four characters |
|
470 match = |
|
471 (!(aHwMatchFourCC.Match( |
|
472 aHwDeviceResourceEntry->DataType().Right(KFOURCCLENGTH)) == |
|
473 KErrNotFound)); |
|
474 } |
|
475 else if (aState == EMMFStateRecording) |
|
476 { |
|
477 //record need to match with the left four characters |
|
478 match = |
|
479 (!(aHwMatchFourCC.Match( |
|
480 aHwDeviceResourceEntry->DataType().Left(KFOURCCLENGTH)) == |
|
481 KErrNotFound)); |
|
482 } |
|
483 } |
|
484 return match; |
|
485 } |
|
486 |
|
487 // ----------------------------------------------------------------------------- |
|
488 // CMMFDevSoundUtility::InitializeFixedSequenceL |
|
489 // Populate fixed sequences |
|
490 // (other items were commented in a header). |
|
491 // ----------------------------------------------------------------------------- |
|
492 // |
|
493 void CMMFDevSoundUtility::InitializeFixedSequenceL( |
|
494 CPtrC8Array** aFixedSequences) |
|
495 { |
|
496 |
|
497 RFs fsSession; |
|
498 User::LeaveIfError(fsSession.Connect()); |
|
499 CleanupClosePushL(fsSession); |
|
500 |
|
501 // Open the resource file |
|
502 RResourceFile resourceFile; |
|
503 resourceFile.OpenL(fsSession, KFixedSequenceResourceFile); |
|
504 CleanupClosePushL(resourceFile); |
|
505 |
|
506 // Allocate buffer to hold resource data in binary format |
|
507 iInfo = resourceFile.AllocReadL(FIXED_TONE_SEQUENCE); |
|
508 |
|
509 TResourceReader reader; |
|
510 reader.SetBuffer(iInfo); |
|
511 |
|
512 // Create array to hold fixed sequences data |
|
513 CPtrC8Array* tempSequences = new(ELeave) CPtrC8Array(8); // granularity |
|
514 CleanupStack::PushL(tempSequences); |
|
515 |
|
516 // First word gives number of entries |
|
517 TInt numberOfEntries = reader.ReadUint16(); |
|
518 ASSERT(!(numberOfEntries&1)); // Should have atleast one entry |
|
519 |
|
520 // There must be an even number entries as each sequence structure is made |
|
521 // of a name string and a data string (SEQUENCE_NAME and SEQUENCE_DATA) |
|
522 |
|
523 HMMFToneFixedSequenceNames* names = new (ELeave) HMMFToneFixedSequenceNames; |
|
524 CleanupStack::PushL(names); |
|
525 |
|
526 for (TInt i = 0; i < numberOfEntries; i += 2) |
|
527 { |
|
528 // Copy name from resource array to returnable array |
|
529 HMMFToneFixedSequenceNames* newNames = |
|
530 names->AddNameL(reader.ReadTPtrC()); |
|
531 |
|
532 if (names != newNames) |
|
533 { |
|
534 // May have moved so fixup cleanupstack reference |
|
535 CleanupStack::Pop(names); |
|
536 names = newNames; |
|
537 CleanupStack::PushL(names); |
|
538 } |
|
539 |
|
540 TInt len = reader.ReadUint16(); |
|
541 TPtrC8 tempTPtrC8(REINTERPRET_CAST(const TUint8*,reader.Ptr()),len<<1); |
|
542 tempSequences->AppendL(tempTPtrC8); |
|
543 reader.Advance(len<<1); |
|
544 } |
|
545 |
|
546 CleanupStack::Pop(names); |
|
547 |
|
548 // Delete the old fixed sequence names |
|
549 delete iFixedSequenceNames; |
|
550 iFixedSequenceNames = NULL; |
|
551 iFixedSequenceNames = names; |
|
552 |
|
553 *aFixedSequences = tempSequences; |
|
554 CleanupStack::Pop(tempSequences); |
|
555 CleanupStack::PopAndDestroy(&resourceFile); |
|
556 CleanupStack::PopAndDestroy(&fsSession); |
|
557 } |
|
558 |
|
559 // ----------------------------------------------------------------------------- |
|
560 // CMMFDevSoundUtility::RecognizeSequence |
|
561 // Recognizes tone sequence. |
|
562 // (other items were commented in a header). |
|
563 // ----------------------------------------------------------------------------- |
|
564 // |
|
565 TBool CMMFDevSoundUtility::RecognizeSequence(const TDesC8& aData) |
|
566 { |
|
567 TBool ret = EFalse; |
|
568 if (aData.Length() > K4ByteSeq) |
|
569 { |
|
570 //Check for Smart Message (OTA) formats |
|
571 if ((aData[0x000] == 0x02) && |
|
572 (aData[0x001] == 0x4a) && |
|
573 (aData[0x002] == 0x3a)) |
|
574 { |
|
575 ret = ETrue; |
|
576 } |
|
577 else if ((aData[0x000] == 0x03) && |
|
578 (aData[0x001] == 0x4a) && |
|
579 (aData[0x002] == 0x44) && |
|
580 (aData[0x003] == 0x3a)) |
|
581 { |
|
582 ret = ETrue; |
|
583 } |
|
584 else if ((aData[0] == 0x00) && |
|
585 (aData[1] == 0x11)) // Check for Nokia Ring Tone format |
|
586 { |
|
587 ret = ETrue; |
|
588 } |
|
589 } |
|
590 return ret; |
|
591 } |
|
592 |
|
593 // ----------------------------------------------------------------------------- |
|
594 // CMMFDevSoundUtility::FixedSequenceName |
|
595 // Returns a descriptor reference containing name of the fixed sequence. |
|
596 // (other items were commented in a header). |
|
597 // ----------------------------------------------------------------------------- |
|
598 // |
|
599 const TDesC& CMMFDevSoundUtility::FixedSequenceName(TInt aSequenceNumber) |
|
600 { |
|
601 ASSERT(iFixedSequenceNames); // Defect if not true when previous was true |
|
602 ASSERT((aSequenceNumber>=0) && |
|
603 (aSequenceNumber<iFixedSequenceNames->iCount)); |
|
604 |
|
605 // Ptr to first descriptor |
|
606 TUint8* ptr = REINTERPRET_CAST(TUint8*, |
|
607 &(iFixedSequenceNames->iCount))+sizeof(TInt); |
|
608 TDesC* desPtr = REINTERPRET_CAST(TDesC*,ptr); // First des |
|
609 |
|
610 while (aSequenceNumber--) |
|
611 { |
|
612 TInt size = desPtr->Size(); |
|
613 if (size&3) |
|
614 { |
|
615 size = ((size+4)&(~3)); |
|
616 } |
|
617 |
|
618 ptr += sizeof(TInt) + size; |
|
619 desPtr = REINTERPRET_CAST(TDesC*,ptr); // Next des |
|
620 } |
|
621 |
|
622 return *desPtr; |
|
623 } |
|
624 |
|
625 // End of File |