messagingapp/smartmessaging/ringbc/src/ringbctoneconverter.cpp
changeset 31 ebfee66fde93
parent 23 238255e8b033
child 34 84197e66a4bd
equal deleted inserted replaced
30:6a20128ce557 31:ebfee66fde93
       
     1 /*
       
     2 * Copyright (c) 2002 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:  
       
    15 *       For checking the validity of Smart messaging ringing tone and for 
       
    16 *       ripping the ringing tone title from binary data. 
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 // SYSTEM INCLUDES
       
    23 #include <e32svr.h>
       
    24 
       
    25 // USER INCLUDES
       
    26 #include "ringbctoneconverter.h"
       
    27 #include "NsmRingTone.h"
       
    28 #include "debugtraces.h"
       
    29 
       
    30 
       
    31 // LOCAL CONSTANTS AND MACROS
       
    32 const TInt KCompMaxSongLength = 240; // maximum number of notes
       
    33 
       
    34 
       
    35 // ================= MEMBER FUNCTIONS =======================
       
    36 
       
    37 // ---------------------------------------------------------
       
    38 // NewL()
       
    39 //
       
    40 // ---------------------------------------------------------
       
    41 RingBCNSMConverter* RingBCNSMConverter::NewL()
       
    42     {
       
    43 	RingBCNSMConverter* self = new (ELeave) RingBCNSMConverter();
       
    44 	CleanupStack::PushL(self);
       
    45 	self->ConstructL();
       
    46 	CleanupStack::Pop();	// self
       
    47 	return self;
       
    48     }
       
    49 
       
    50 // ---------------------------------------------------------
       
    51 // RingBCNSMConverter()
       
    52 //
       
    53 // ---------------------------------------------------------
       
    54 RingBCNSMConverter::RingBCNSMConverter()
       
    55     {
       
    56 	iScale = EScale2;
       
    57 	iStyle = EStyleNatural;
       
    58     }
       
    59 
       
    60 // ---------------------------------------------------------
       
    61 // RingBCNSMConverter()
       
    62 //
       
    63 // ---------------------------------------------------------
       
    64 void RingBCNSMConverter::ConstructL()
       
    65     {
       
    66    
       
    67     
       
    68    
       
    69     }
       
    70 
       
    71 // ---------------------------------------------------------
       
    72 // ~RingBCNSMConverter()
       
    73 //
       
    74 // ---------------------------------------------------------
       
    75 RingBCNSMConverter::~RingBCNSMConverter()
       
    76     {
       
    77 	delete iCompData.iSongData; 	
       
    78     }
       
    79 
       
    80 
       
    81 // ---------------------------------------------------------
       
    82 // ConvertNsmToCompDataL()
       
    83 //
       
    84 // ---------------------------------------------------------
       
    85 TCompData* RingBCNSMConverter::ConvertNsmToCompDataL( const TDesC8& aFileData )
       
    86     {
       
    87     QDEBUG_WRITE( "***BEGIN" );
       
    88     
       
    89     iReceivedNsmRTData.Set( aFileData );
       
    90 
       
    91     iReadOnly = EFalse;
       
    92 	ResetForCompData();
       
    93 	delete iCompData.iSongData;
       
    94 	iCompData.iSongData = NULL;
       
    95 	iCompData.iSongData = new(ELeave) CArrayFixFlat<TInstruction>( KCompMaxSongLength );
       
    96 
       
    97     QDEBUG_WRITE_FORMAT( "***NSM DATA LENGTH:", iReceivedNsmRTData.Length() );
       
    98 
       
    99     if( iReceivedNsmRTData.Length() == 0 )
       
   100         {
       
   101         QDEBUG_WRITE( "!!!ZERO LENGTH" );
       
   102         User::Leave( KErrCorrupt );
       
   103         }
       
   104 
       
   105 	TInt commandlength( 1 );
       
   106 	while( commandlength != KrtCommandEnd && 
       
   107         iNsmPosition < iReceivedNsmRTData.Length() )
       
   108         {
       
   109 		commandlength = GetBits(KrtCommandLengthBits);
       
   110 		
       
   111 
       
   112         QDEBUG_WRITE_FORMAT( "***NEXT CMD LENGTH :", commandlength );
       
   113 
       
   114 		if (commandlength > 3)
       
   115             {
       
   116             QDEBUG_WRITE( "!!!CMD TOO LONG" );
       
   117             User::Leave( KErrCorrupt );
       
   118             }
       
   119 
       
   120 		for (TInt i=0; i<commandlength; i++)
       
   121             {		
       
   122 
       
   123             QDEBUG_WRITE_FORMAT( "***CMD NUMBER ", i );
       
   124 
       
   125 			ProcessNsmRingToneCommandPartL();
       
   126             }
       
   127         }
       
   128 
       
   129 	return &iCompData;
       
   130     }
       
   131 
       
   132 // ---------------------------------------------------------
       
   133 // ProcessNsmRingToneCommandPartL()
       
   134 //
       
   135 // ---------------------------------------------------------
       
   136 void RingBCNSMConverter::ProcessNsmRingToneCommandPartL()
       
   137     {
       
   138 	TInt commandpart( GetBits(KrtCommandPartBits) );
       
   139 
       
   140     QDEBUG_WRITE_FORMAT( "***CMD PART: ", commandpart );
       
   141 
       
   142 	switch (commandpart)
       
   143 	    {
       
   144 	    case KrtCommandRTProgramming:
       
   145 			{
       
   146 			iNsmRTFlags |= KrtFlagRTProgramming;
       
   147 		    break;
       
   148 			}
       
   149 	    case KrtCommandUnicode:
       
   150 			{
       
   151 			iNsmRTFlags |= KrtFlagUnicode;
       
   152 		    break;
       
   153 			}
       
   154 	    case KrtCommandCancelCommand:
       
   155 			{
       
   156 		    if (GetBits(KrtCommandPartBits) == KrtCommandUnicode)
       
   157                 {
       
   158 			    iNsmRTFlags &= ~KrtFlagUnicode;
       
   159                 }
       
   160 		    break;
       
   161 			}
       
   162 	    case KrtCommandSound:
       
   163 			{
       
   164 			if ((iNsmRTFlags & KrtFlagRTProgramming) == 0)
       
   165                 {
       
   166                 QDEBUG_WRITE( "!!!CMD SOUND WITH NO RT PROGRAMMING" );
       
   167                 User::Leave( KErrCorrupt );
       
   168                 }
       
   169 		    ProcessNsmRingToneSoundSpecL();
       
   170 		    break;
       
   171 			}
       
   172 	    default:
       
   173 			{
       
   174             // Ignore unknown commands
       
   175             QDEBUG_WRITE( "???CMD UNKNOWN" );
       
   176             iReadOnly = ETrue;
       
   177 		    break;
       
   178 			}
       
   179 	    }
       
   180 
       
   181 	GetBits(KrtFiller); // skip the filler bits
       
   182     }
       
   183 
       
   184 // ---------------------------------------------------------
       
   185 // ProcessNsmRingToneSoundSpecL()
       
   186 //
       
   187 // ---------------------------------------------------------
       
   188 void RingBCNSMConverter::ProcessNsmRingToneSoundSpecL()
       
   189     {
       
   190 	TInt soundspec( GetBits(KrtSongTypeBits) );
       
   191 
       
   192     QDEBUG_WRITE_FORMAT( "***SONG TYPE :", soundspec );
       
   193 
       
   194 	switch (soundspec)
       
   195 	    {
       
   196 	    case KrtSongTypeBasic:
       
   197 			{
       
   198 		    ProcessNsmRingToneSongTitleL();
       
   199 		    ProcessNsmRingToneSongL();
       
   200 		    break;
       
   201 			}
       
   202 	    case KrtSongTypeTemporary:
       
   203             {
       
   204 		    ProcessNsmRingToneSongL();
       
   205 		    break;
       
   206 			}
       
   207 	    default:
       
   208             {
       
   209 		    iReadOnly = ETrue;
       
   210 		    break;
       
   211 			}
       
   212 	    }
       
   213 
       
   214 	iCompData.iSongLength = iCompDataPosition;
       
   215     }
       
   216 
       
   217 // ---------------------------------------------------------
       
   218 // ProcessNsmRingToneSongTitleL()
       
   219 //
       
   220 // ---------------------------------------------------------
       
   221 void RingBCNSMConverter::ProcessNsmRingToneSongTitleL()
       
   222 {
       
   223 	TInt titlelength( GetBits(KrtSongTitleTextLengthBits) );
       
   224     QDEBUG_WRITE_FORMAT( "***TITLE LENGTH ", titlelength );
       
   225 
       
   226     TInt charWidth( KrtDefaultCharBits );
       
   227 	if( iNsmRTFlags & KrtFlagUnicode )
       
   228     	{
       
   229         charWidth = KrtUnicodeCharBits;
       
   230         }
       
   231     QDEBUG_WRITE_FORMAT( "***TITLE CHAR WIDTH: ", charWidth );
       
   232 
       
   233     TBuf<KrtSongTitleMaxLength> title;
       
   234 	for( TInt i( 0 ); i < titlelength; i++ )
       
   235         {
       
   236         title.Append( GetBits(charWidth) );
       
   237         }
       
   238     QDEBUG_WRITE_FORMAT( "***TITLE: ", &title );
       
   239 
       
   240     SetTitle( title );
       
   241     }
       
   242 
       
   243 // ---------------------------------------------------------
       
   244 // ProcessNsmRingToneSong()
       
   245 //
       
   246 // ---------------------------------------------------------
       
   247 void RingBCNSMConverter::ProcessNsmRingToneSongL()
       
   248     {
       
   249 	TInt songsequencelength( GetBits(KrtSongsequenceLengthBits) );
       
   250     QDEBUG_WRITE_FORMAT( "***SEQUENCE LENGTH ", songsequencelength );
       
   251 
       
   252 	/*if( songsequencelength == 0 )
       
   253 		{
       
   254 		iReadOnly = ETrue;
       
   255 		}*/
       
   256 
       
   257 	for (TInt i( 0 ); i<songsequencelength; i++)
       
   258 	    {
       
   259 		TInt patternheaderid( GetBits(KrtInstructionIdLengthBit) );
       
   260         QDEBUG_WRITE_FORMAT( "***PATTERN HEADER ID:", patternheaderid );
       
   261 		if (patternheaderid != EPatternHeaderId)
       
   262             {
       
   263             QDEBUG_WRITE( "!!!PATTERN HEADER ID INVALID" );
       
   264 			User::Leave(KErrCorrupt);
       
   265             }
       
   266 
       
   267 		TInt patternid( GetBits(KrtPatternIdLengthBit) );
       
   268         QDEBUG_WRITE_FORMAT( "***PATTERN ID:", patternid );
       
   269 		TInt loopvalue( GetBits(KrtPatternLoopValueBits) );
       
   270         QDEBUG_WRITE_FORMAT( "***PATTERN LOOP VALUE:", loopvalue );
       
   271 		TInt patternspec( GetBits(KrtPatternSpecBits) );
       
   272         QDEBUG_WRITE_FORMAT( "***PATTERN SPEC:", patternspec );
       
   273 		
       
   274 		if( patternspec != KrtPatternDefined )
       
   275 		    {
       
   276             QDEBUG_WRITE( "***PATTERN NOT DEFINED" );
       
   277 			iNsmRTPatterns[patternid].iStart = iCompData.iSongData->Count();
       
   278 			
       
   279             for (TInt l( 0 ); l < patternspec && iCompDataPosition < KCompMaxSongLength; l++)
       
   280                 {
       
   281 				ProcessNsmRingTonePatternInstructionL();
       
   282                 }
       
   283 			iNsmRTPatterns[patternid].iEnd = iCompDataPosition - 1;
       
   284 		    }
       
   285 		// check if the pattern is really already defined before copying
       
   286 		TInt start( iNsmRTPatterns[patternid].iStart );
       
   287 		TInt end( iNsmRTPatterns[patternid].iEnd );
       
   288 		if( start < end )
       
   289 		    {
       
   290 			if( loopvalue < KrtPatternRepeatInfinite )
       
   291 			    {
       
   292 				for( TInt loopNum( 0 ); loopNum < loopvalue; loopNum++ ) // handle repeat
       
   293 				    {
       
   294 					for (TInt k=start; (k<=end)&&(iCompDataPosition<KCompMaxSongLength); 
       
   295 						k++, iCompDataPosition++)
       
   296                         {
       
   297 						iCompData.iSongData->AppendL( iCompData.iSongData->At( k ) );
       
   298                         }
       
   299 				    }
       
   300 			    }
       
   301 			else // handle infinite repeat
       
   302 			    {
       
   303 				while( iCompDataPosition<KCompMaxSongLength )
       
   304 				    {
       
   305 					for (TInt k=start; (k<=end)&&(iCompDataPosition<KCompMaxSongLength); 
       
   306 						k++, iCompDataPosition++)
       
   307                         {
       
   308 						iCompData.iSongData->AppendL( iCompData.iSongData->At( k ) );
       
   309                         }
       
   310 				    }
       
   311 			}
       
   312 		}
       
   313 	}
       
   314 }
       
   315 
       
   316 // ---------------------------------------------------------
       
   317 // ProcessNsmRingTonePatternInstruction()
       
   318 //
       
   319 // ---------------------------------------------------------
       
   320 void RingBCNSMConverter::ProcessNsmRingTonePatternInstructionL()
       
   321     {
       
   322 	TInt instructionid( GetBits(KrtInstructionIdLengthBit) );
       
   323     QDEBUG_WRITE_FORMAT( "***INSTRUCTION ID:", instructionid );
       
   324 	switch (instructionid)
       
   325 	    {
       
   326 	    case ENoteInstructionId:
       
   327 			{
       
   328             QDEBUG_WRITE_FORMAT( "***INSTRUCTION ID: NOTE", instructionid );
       
   329 		    ProcessNsmRingToneNoteInstructionL(iScale, iStyle);
       
   330 		    break;
       
   331 			}
       
   332 	    case EScaleInstructionId:
       
   333 			{
       
   334 			iScale = GetBits(KrtNoteScaleBits);
       
   335             QDEBUG_WRITE_FORMAT( "***INSTRUCTION SCALE:", iScale );
       
   336 		    break;
       
   337 			}
       
   338 	    case EStyleInstructionId:
       
   339 			{
       
   340 			iStyle = GetBits(KrtNoteStyleBits);
       
   341             QDEBUG_WRITE_FORMAT( "***INSTRUCTION STYLE:", iStyle );
       
   342             if( iStyle == EStyleReserved )
       
   343                 {
       
   344                 QDEBUG_WRITE( "???INSTRUCTION STYLE NOT SUPPORTED" );
       
   345                 iReadOnly = ETrue;
       
   346                 }
       
   347 		    break;
       
   348 			}
       
   349 	    case ETempoInstructionId:
       
   350 			{
       
   351 			iCompData.iTempo = GetBits(KrtTempoBits);
       
   352             QDEBUG_WRITE_FORMAT( "***INSTRUCTION TEMPO:", iCompData.iTempo );
       
   353             if( iCompData.iTempo > ETempo250 )
       
   354                 {
       
   355                 QDEBUG_WRITE( "???TEMPO TOO HIGH" );
       
   356                 iReadOnly = ETrue;
       
   357                 }
       
   358 		    break;
       
   359 			}
       
   360 	    case EVolumeInstructionId:
       
   361             {
       
   362 			QDEBUG_WRITE( "***INSTRUCTION VOLUME" );
       
   363 		    GetBits(KrtVolumebits);
       
   364 		    break;
       
   365 			}
       
   366 	    default:
       
   367             {
       
   368 			QDEBUG_WRITE( "???INSTRUCTION NOT SUPPORTED" );
       
   369             iReadOnly = ETrue;
       
   370 		    break;
       
   371 			}
       
   372 	    }
       
   373     }
       
   374 
       
   375 // ---------------------------------------------------------
       
   376 // ProcessNsmRingToneNoteInstruction()
       
   377 //
       
   378 // ---------------------------------------------------------
       
   379 void RingBCNSMConverter::ProcessNsmRingToneNoteInstructionL(TInt aScale, TInt aStyle)
       
   380     {
       
   381 	TInt notevalue( GetBits(KrtNoteValueBits) );
       
   382     QDEBUG_WRITE_FORMAT( "***NOTE VALUE:", notevalue );
       
   383     if( notevalue != ENotePause && (notevalue > ENoteB 
       
   384         || iScale == EScale4 && notevalue > ENoteGis
       
   385         || iScale == EScale1 && notevalue < ENoteG ) )
       
   386         {
       
   387         QDEBUG_WRITE( "???NOTE VALUE OUT OF RANGE" );
       
   388         iReadOnly = ETrue;
       
   389         }
       
   390 
       
   391 	TInt noteduration( GetBits(KrtNoteDurationBits) );
       
   392     QDEBUG_WRITE_FORMAT( "***NOTE DURATION:", noteduration );
       
   393     if( noteduration > EDurationThirtysecond )
       
   394         {
       
   395         QDEBUG_WRITE( "???NOTE DURATION OUT OF RANGE" );
       
   396         iReadOnly = ETrue;
       
   397         }
       
   398 
       
   399 	TInt notedurspecifier( GetBits(KrtNoteDurSpecifierBits) );
       
   400     QDEBUG_WRITE_FORMAT( "***NOTE DURATION SPECIFIER:", notedurspecifier);
       
   401     if( notedurspecifier == EDurSpecifireDoubleDotted
       
   402         || notedurspecifier > EDurSpecifierTriplet )
       
   403         {
       
   404         QDEBUG_WRITE( "???NOTE DURATION SPECIFIER OUT OF RANGE" );
       
   405         iReadOnly = ETrue;
       
   406         }
       
   407 
       
   408 	TInstruction symbol;
       
   409 	symbol.iValue = notevalue;
       
   410 	symbol.iDuration = noteduration;
       
   411 	symbol.iDurspecifier = notedurspecifier;
       
   412 	symbol.iScale = aScale;
       
   413 	symbol.iStyle = aStyle;
       
   414 
       
   415 	iCompData.iSongData->AppendL( symbol );
       
   416 	iCompDataPosition ++;
       
   417     }
       
   418 
       
   419 // ---------------------------------------------------------
       
   420 // GetBits()
       
   421 //
       
   422 // ---------------------------------------------------------
       
   423 TInt RingBCNSMConverter::GetBits(TInt aNumBits)
       
   424     {
       
   425 	TUint32 buf( 0 );   
       
   426 	if( aNumBits == 0 ) // handle byte alignment
       
   427 	    {
       
   428 		if (iNsmPositionBit != 0)
       
   429 		    {
       
   430 			iNsmPositionBit = 0;	// skip filler bits
       
   431 			iNsmPosition ++;			
       
   432 		    }
       
   433 		return buf;
       
   434 	    }
       
   435 
       
   436 	for (TInt n=0; n<4; n++)
       
   437 	    {
       
   438 		buf <<= 8;
       
   439 		if ( iNsmPosition+n < iReceivedNsmRTData.Length() )
       
   440             {
       
   441 			buf |= iReceivedNsmRTData[iNsmPosition+n];
       
   442             }
       
   443 	    }
       
   444 
       
   445 	TUint32 filter = 0;
       
   446 	buf = (buf >> (32 - iNsmPositionBit - aNumBits)) & ~(~filter << aNumBits);
       
   447 
       
   448 	iNsmPositionBit += aNumBits;
       
   449 	while (iNsmPositionBit > 7)
       
   450 	    {
       
   451 		iNsmPositionBit -= 8;
       
   452 		iNsmPosition ++;
       
   453 	    }
       
   454 	return buf;
       
   455     }
       
   456 
       
   457 // ---------------------------------------------------------
       
   458 // ResetForCompData()
       
   459 //
       
   460 // ---------------------------------------------------------
       
   461 void RingBCNSMConverter::ResetForCompData()
       
   462     {
       
   463 	iNsmRTPatterns[EPatternIdA].iStart = 0;
       
   464 	iNsmRTPatterns[EPatternIdA].iEnd = 0;
       
   465 	iNsmRTPatterns[EPatternIdB].iStart = 0;
       
   466 	iNsmRTPatterns[EPatternIdB].iEnd = 0;
       
   467 	iNsmRTPatterns[EPatternIdC].iStart = 0;
       
   468 	iNsmRTPatterns[EPatternIdC].iEnd = 0;
       
   469 	iNsmRTPatterns[EPatternIdD].iStart = 0;
       
   470 	iNsmRTPatterns[EPatternIdD].iEnd = 0;
       
   471 	iNsmRTFlags = 0;
       
   472     iNsmPosition = 0;
       
   473 	iNsmPositionBit = 0;
       
   474 	iCompDataPosition = 0;
       
   475 
       
   476 	iCompData.iTempo = KrtBpmDefault;
       
   477 	iCompData.iSongLength = 0;
       
   478     }
       
   479 
       
   480 // ---------------------------------------------------------
       
   481 // SetTitle()
       
   482 //
       
   483 // ---------------------------------------------------------
       
   484 void RingBCNSMConverter::SetTitle( const TDesC& aFileName )
       
   485     {
       
   486     iCompData.iSongTitle = aFileName.Left( KrtSongTitleTextLength );
       
   487     }
       
   488 
       
   489 
       
   490 // ---------------------------------------------------------
       
   491 // TitleLC()
       
   492 //
       
   493 // ---------------------------------------------------------
       
   494 HBufC* RingBCNSMConverter::TitleLC(TPtr8& aFileData)
       
   495 {
       
   496 	iReceivedCompData = ConvertNsmToCompDataL(aFileData);
       
   497 
       
   498 	HBufC* titlePtr = iReceivedCompData->iSongTitle.AllocLC();
       
   499 	return titlePtr;
       
   500 }
       
   501 
       
   502 
       
   503 // ---------------------------------------------------------
       
   504 // IsRingToneMimeTypeL()
       
   505 //
       
   506 // ---------------------------------------------------------
       
   507 TBool  RingBCNSMConverter::IsRingToneMimeTypeL(TPtr8& aFileData)
       
   508     {
       
   509 	TRAPD( returnError, 
       
   510         iReceivedCompData = ConvertNsmToCompDataL(aFileData) );
       
   511     if( returnError != KErrCorrupt 
       
   512         && returnError != KErrNotSupported )
       
   513         {
       
   514         User::LeaveIfError( returnError );
       
   515         }
       
   516 
       
   517     return returnError != KErrCorrupt;
       
   518     }
       
   519 
       
   520 // end of file