messagingapp/smartmessaging/ringbc/src/ringbctoneconverter.cpp
changeset 23 238255e8b033
child 34 84197e66a4bd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingapp/smartmessaging/ringbc/src/ringbctoneconverter.cpp	Fri Apr 16 14:56:15 2010 +0300
@@ -0,0 +1,520 @@
+/*
+* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*       For checking the validity of Smart messaging ringing tone and for 
+*       ripping the ringing tone title from binary data. 
+*
+*/
+
+
+
+// SYSTEM INCLUDES
+#include <e32svr.h>
+
+// USER INCLUDES
+#include "ringbctoneconverter.h"
+#include "NsmRingTone.h"
+#include "debugtraces.h"
+
+
+// LOCAL CONSTANTS AND MACROS
+const TInt KCompMaxSongLength = 240; // maximum number of notes
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// NewL()
+//
+// ---------------------------------------------------------
+RingBCNSMConverter* RingBCNSMConverter::NewL()
+    {
+	RingBCNSMConverter* self = new (ELeave) RingBCNSMConverter();
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	CleanupStack::Pop();	// self
+	return self;
+    }
+
+// ---------------------------------------------------------
+// RingBCNSMConverter()
+//
+// ---------------------------------------------------------
+RingBCNSMConverter::RingBCNSMConverter()
+    {
+	iScale = EScale2;
+	iStyle = EStyleNatural;
+    }
+
+// ---------------------------------------------------------
+// RingBCNSMConverter()
+//
+// ---------------------------------------------------------
+void RingBCNSMConverter::ConstructL()
+    {
+   
+    
+   
+    }
+
+// ---------------------------------------------------------
+// ~RingBCNSMConverter()
+//
+// ---------------------------------------------------------
+RingBCNSMConverter::~RingBCNSMConverter()
+    {
+	delete iCompData.iSongData; 	
+    }
+
+
+// ---------------------------------------------------------
+// ConvertNsmToCompDataL()
+//
+// ---------------------------------------------------------
+TCompData* RingBCNSMConverter::ConvertNsmToCompDataL( const TDesC8& aFileData )
+    {
+    QDEBUG_WRITE( "***BEGIN" );
+    
+    iReceivedNsmRTData.Set( aFileData );
+
+    iReadOnly = EFalse;
+	ResetForCompData();
+	delete iCompData.iSongData;
+	iCompData.iSongData = NULL;
+	iCompData.iSongData = new(ELeave) CArrayFixFlat<TInstruction>( KCompMaxSongLength );
+
+    QDEBUG_WRITE_FORMAT( "***NSM DATA LENGTH:", iReceivedNsmRTData.Length() );
+
+    if( iReceivedNsmRTData.Length() == 0 )
+        {
+        QDEBUG_WRITE( "!!!ZERO LENGTH" );
+        User::Leave( KErrCorrupt );
+        }
+
+	TInt commandlength( 1 );
+	while( commandlength != KrtCommandEnd && 
+        iNsmPosition < iReceivedNsmRTData.Length() )
+        {
+		commandlength = GetBits(KrtCommandLengthBits);
+		
+
+        QDEBUG_WRITE_FORMAT( "***NEXT CMD LENGTH :", commandlength );
+
+		if (commandlength > 3)
+            {
+            QDEBUG_WRITE( "!!!CMD TOO LONG" );
+            User::Leave( KErrCorrupt );
+            }
+
+		for (TInt i=0; i<commandlength; i++)
+            {		
+
+            QDEBUG_WRITE_FORMAT( "***CMD NUMBER ", i );
+
+			ProcessNsmRingToneCommandPartL();
+            }
+        }
+
+	return &iCompData;
+    }
+
+// ---------------------------------------------------------
+// ProcessNsmRingToneCommandPartL()
+//
+// ---------------------------------------------------------
+void RingBCNSMConverter::ProcessNsmRingToneCommandPartL()
+    {
+	TInt commandpart( GetBits(KrtCommandPartBits) );
+
+    QDEBUG_WRITE_FORMAT( "***CMD PART: ", commandpart );
+
+	switch (commandpart)
+	    {
+	    case KrtCommandRTProgramming:
+			{
+			iNsmRTFlags |= KrtFlagRTProgramming;
+		    break;
+			}
+	    case KrtCommandUnicode:
+			{
+			iNsmRTFlags |= KrtFlagUnicode;
+		    break;
+			}
+	    case KrtCommandCancelCommand:
+			{
+		    if (GetBits(KrtCommandPartBits) == KrtCommandUnicode)
+                {
+			    iNsmRTFlags &= ~KrtFlagUnicode;
+                }
+		    break;
+			}
+	    case KrtCommandSound:
+			{
+			if ((iNsmRTFlags & KrtFlagRTProgramming) == 0)
+                {
+                QDEBUG_WRITE( "!!!CMD SOUND WITH NO RT PROGRAMMING" );
+                User::Leave( KErrCorrupt );
+                }
+		    ProcessNsmRingToneSoundSpecL();
+		    break;
+			}
+	    default:
+			{
+            // Ignore unknown commands
+            QDEBUG_WRITE( "???CMD UNKNOWN" );
+            iReadOnly = ETrue;
+		    break;
+			}
+	    }
+
+	GetBits(KrtFiller); // skip the filler bits
+    }
+
+// ---------------------------------------------------------
+// ProcessNsmRingToneSoundSpecL()
+//
+// ---------------------------------------------------------
+void RingBCNSMConverter::ProcessNsmRingToneSoundSpecL()
+    {
+	TInt soundspec( GetBits(KrtSongTypeBits) );
+
+    QDEBUG_WRITE_FORMAT( "***SONG TYPE :", soundspec );
+
+	switch (soundspec)
+	    {
+	    case KrtSongTypeBasic:
+			{
+		    ProcessNsmRingToneSongTitleL();
+		    ProcessNsmRingToneSongL();
+		    break;
+			}
+	    case KrtSongTypeTemporary:
+            {
+		    ProcessNsmRingToneSongL();
+		    break;
+			}
+	    default:
+            {
+		    iReadOnly = ETrue;
+		    break;
+			}
+	    }
+
+	iCompData.iSongLength = iCompDataPosition;
+    }
+
+// ---------------------------------------------------------
+// ProcessNsmRingToneSongTitleL()
+//
+// ---------------------------------------------------------
+void RingBCNSMConverter::ProcessNsmRingToneSongTitleL()
+{
+	TInt titlelength( GetBits(KrtSongTitleTextLengthBits) );
+    QDEBUG_WRITE_FORMAT( "***TITLE LENGTH ", titlelength );
+
+    TInt charWidth( KrtDefaultCharBits );
+	if( iNsmRTFlags & KrtFlagUnicode )
+    	{
+        charWidth = KrtUnicodeCharBits;
+        }
+    QDEBUG_WRITE_FORMAT( "***TITLE CHAR WIDTH: ", charWidth );
+
+    TBuf<KrtSongTitleMaxLength> title;
+	for( TInt i( 0 ); i < titlelength; i++ )
+        {
+        title.Append( GetBits(charWidth) );
+        }
+    QDEBUG_WRITE_FORMAT( "***TITLE: ", &title );
+
+    SetTitle( title );
+    }
+
+// ---------------------------------------------------------
+// ProcessNsmRingToneSong()
+//
+// ---------------------------------------------------------
+void RingBCNSMConverter::ProcessNsmRingToneSongL()
+    {
+	TInt songsequencelength( GetBits(KrtSongsequenceLengthBits) );
+    QDEBUG_WRITE_FORMAT( "***SEQUENCE LENGTH ", songsequencelength );
+
+	/*if( songsequencelength == 0 )
+		{
+		iReadOnly = ETrue;
+		}*/
+
+	for (TInt i( 0 ); i<songsequencelength; i++)
+	    {
+		TInt patternheaderid( GetBits(KrtInstructionIdLengthBit) );
+        QDEBUG_WRITE_FORMAT( "***PATTERN HEADER ID:", patternheaderid );
+		if (patternheaderid != EPatternHeaderId)
+            {
+            QDEBUG_WRITE( "!!!PATTERN HEADER ID INVALID" );
+			User::Leave(KErrCorrupt);
+            }
+
+		TInt patternid( GetBits(KrtPatternIdLengthBit) );
+        QDEBUG_WRITE_FORMAT( "***PATTERN ID:", patternid );
+		TInt loopvalue( GetBits(KrtPatternLoopValueBits) );
+        QDEBUG_WRITE_FORMAT( "***PATTERN LOOP VALUE:", loopvalue );
+		TInt patternspec( GetBits(KrtPatternSpecBits) );
+        QDEBUG_WRITE_FORMAT( "***PATTERN SPEC:", patternspec );
+		
+		if( patternspec != KrtPatternDefined )
+		    {
+            QDEBUG_WRITE( "***PATTERN NOT DEFINED" );
+			iNsmRTPatterns[patternid].iStart = iCompData.iSongData->Count();
+			
+            for (TInt l( 0 ); l < patternspec && iCompDataPosition < KCompMaxSongLength; l++)
+                {
+				ProcessNsmRingTonePatternInstructionL();
+                }
+			iNsmRTPatterns[patternid].iEnd = iCompDataPosition - 1;
+		    }
+		// check if the pattern is really already defined before copying
+		TInt start( iNsmRTPatterns[patternid].iStart );
+		TInt end( iNsmRTPatterns[patternid].iEnd );
+		if( start < end )
+		    {
+			if( loopvalue < KrtPatternRepeatInfinite )
+			    {
+				for( TInt loopNum( 0 ); loopNum < loopvalue; loopNum++ ) // handle repeat
+				    {
+					for (TInt k=start; (k<=end)&&(iCompDataPosition<KCompMaxSongLength); 
+						k++, iCompDataPosition++)
+                        {
+						iCompData.iSongData->AppendL( iCompData.iSongData->At( k ) );
+                        }
+				    }
+			    }
+			else // handle infinite repeat
+			    {
+				while( iCompDataPosition<KCompMaxSongLength )
+				    {
+					for (TInt k=start; (k<=end)&&(iCompDataPosition<KCompMaxSongLength); 
+						k++, iCompDataPosition++)
+                        {
+						iCompData.iSongData->AppendL( iCompData.iSongData->At( k ) );
+                        }
+				    }
+			}
+		}
+	}
+}
+
+// ---------------------------------------------------------
+// ProcessNsmRingTonePatternInstruction()
+//
+// ---------------------------------------------------------
+void RingBCNSMConverter::ProcessNsmRingTonePatternInstructionL()
+    {
+	TInt instructionid( GetBits(KrtInstructionIdLengthBit) );
+    QDEBUG_WRITE_FORMAT( "***INSTRUCTION ID:", instructionid );
+	switch (instructionid)
+	    {
+	    case ENoteInstructionId:
+			{
+            QDEBUG_WRITE_FORMAT( "***INSTRUCTION ID: NOTE", instructionid );
+		    ProcessNsmRingToneNoteInstructionL(iScale, iStyle);
+		    break;
+			}
+	    case EScaleInstructionId:
+			{
+			iScale = GetBits(KrtNoteScaleBits);
+            QDEBUG_WRITE_FORMAT( "***INSTRUCTION SCALE:", iScale );
+		    break;
+			}
+	    case EStyleInstructionId:
+			{
+			iStyle = GetBits(KrtNoteStyleBits);
+            QDEBUG_WRITE_FORMAT( "***INSTRUCTION STYLE:", iStyle );
+            if( iStyle == EStyleReserved )
+                {
+                QDEBUG_WRITE( "???INSTRUCTION STYLE NOT SUPPORTED" );
+                iReadOnly = ETrue;
+                }
+		    break;
+			}
+	    case ETempoInstructionId:
+			{
+			iCompData.iTempo = GetBits(KrtTempoBits);
+            QDEBUG_WRITE_FORMAT( "***INSTRUCTION TEMPO:", iCompData.iTempo );
+            if( iCompData.iTempo > ETempo250 )
+                {
+                QDEBUG_WRITE( "???TEMPO TOO HIGH" );
+                iReadOnly = ETrue;
+                }
+		    break;
+			}
+	    case EVolumeInstructionId:
+            {
+			QDEBUG_WRITE( "***INSTRUCTION VOLUME" );
+		    GetBits(KrtVolumebits);
+		    break;
+			}
+	    default:
+            {
+			QDEBUG_WRITE( "???INSTRUCTION NOT SUPPORTED" );
+            iReadOnly = ETrue;
+		    break;
+			}
+	    }
+    }
+
+// ---------------------------------------------------------
+// ProcessNsmRingToneNoteInstruction()
+//
+// ---------------------------------------------------------
+void RingBCNSMConverter::ProcessNsmRingToneNoteInstructionL(TInt aScale, TInt aStyle)
+    {
+	TInt notevalue( GetBits(KrtNoteValueBits) );
+    QDEBUG_WRITE_FORMAT( "***NOTE VALUE:", notevalue );
+    if( notevalue != ENotePause && (notevalue > ENoteB 
+        || iScale == EScale4 && notevalue > ENoteGis
+        || iScale == EScale1 && notevalue < ENoteG ) )
+        {
+        QDEBUG_WRITE( "???NOTE VALUE OUT OF RANGE" );
+        iReadOnly = ETrue;
+        }
+
+	TInt noteduration( GetBits(KrtNoteDurationBits) );
+    QDEBUG_WRITE_FORMAT( "***NOTE DURATION:", noteduration );
+    if( noteduration > EDurationThirtysecond )
+        {
+        QDEBUG_WRITE( "???NOTE DURATION OUT OF RANGE" );
+        iReadOnly = ETrue;
+        }
+
+	TInt notedurspecifier( GetBits(KrtNoteDurSpecifierBits) );
+    QDEBUG_WRITE_FORMAT( "***NOTE DURATION SPECIFIER:", notedurspecifier);
+    if( notedurspecifier == EDurSpecifireDoubleDotted
+        || notedurspecifier > EDurSpecifierTriplet )
+        {
+        QDEBUG_WRITE( "???NOTE DURATION SPECIFIER OUT OF RANGE" );
+        iReadOnly = ETrue;
+        }
+
+	TInstruction symbol;
+	symbol.iValue = notevalue;
+	symbol.iDuration = noteduration;
+	symbol.iDurspecifier = notedurspecifier;
+	symbol.iScale = aScale;
+	symbol.iStyle = aStyle;
+
+	iCompData.iSongData->AppendL( symbol );
+	iCompDataPosition ++;
+    }
+
+// ---------------------------------------------------------
+// GetBits()
+//
+// ---------------------------------------------------------
+TInt RingBCNSMConverter::GetBits(TInt aNumBits)
+    {
+	TUint32 buf( 0 );   
+	if( aNumBits == 0 ) // handle byte alignment
+	    {
+		if (iNsmPositionBit != 0)
+		    {
+			iNsmPositionBit = 0;	// skip filler bits
+			iNsmPosition ++;			
+		    }
+		return buf;
+	    }
+
+	for (TInt n=0; n<4; n++)
+	    {
+		buf <<= 8;
+		if ( iNsmPosition+n < iReceivedNsmRTData.Length() )
+            {
+			buf |= iReceivedNsmRTData[iNsmPosition+n];
+            }
+	    }
+
+	TUint32 filter = 0;
+	buf = (buf >> (32 - iNsmPositionBit - aNumBits)) & ~(~filter << aNumBits);
+
+	iNsmPositionBit += aNumBits;
+	while (iNsmPositionBit > 7)
+	    {
+		iNsmPositionBit -= 8;
+		iNsmPosition ++;
+	    }
+	return buf;
+    }
+
+// ---------------------------------------------------------
+// ResetForCompData()
+//
+// ---------------------------------------------------------
+void RingBCNSMConverter::ResetForCompData()
+    {
+	iNsmRTPatterns[EPatternIdA].iStart = 0;
+	iNsmRTPatterns[EPatternIdA].iEnd = 0;
+	iNsmRTPatterns[EPatternIdB].iStart = 0;
+	iNsmRTPatterns[EPatternIdB].iEnd = 0;
+	iNsmRTPatterns[EPatternIdC].iStart = 0;
+	iNsmRTPatterns[EPatternIdC].iEnd = 0;
+	iNsmRTPatterns[EPatternIdD].iStart = 0;
+	iNsmRTPatterns[EPatternIdD].iEnd = 0;
+	iNsmRTFlags = 0;
+    iNsmPosition = 0;
+	iNsmPositionBit = 0;
+	iCompDataPosition = 0;
+
+	iCompData.iTempo = KrtBpmDefault;
+	iCompData.iSongLength = 0;
+    }
+
+// ---------------------------------------------------------
+// SetTitle()
+//
+// ---------------------------------------------------------
+void RingBCNSMConverter::SetTitle( const TDesC& aFileName )
+    {
+    iCompData.iSongTitle = aFileName.Left( KrtSongTitleTextLength );
+    }
+
+
+// ---------------------------------------------------------
+// TitleLC()
+//
+// ---------------------------------------------------------
+HBufC* RingBCNSMConverter::TitleLC(TPtr8& aFileData)
+{
+	iReceivedCompData = ConvertNsmToCompDataL(aFileData);
+
+	HBufC* titlePtr = iReceivedCompData->iSongTitle.AllocLC();
+	return titlePtr;
+}
+
+
+// ---------------------------------------------------------
+// IsRingToneMimeTypeL()
+//
+// ---------------------------------------------------------
+TBool  RingBCNSMConverter::IsRingToneMimeTypeL(TPtr8& aFileData)
+    {
+	TRAPD( returnError, 
+        iReceivedCompData = ConvertNsmToCompDataL(aFileData) );
+    if( returnError != KErrCorrupt 
+        && returnError != KErrNotSupported )
+        {
+        User::LeaveIfError( returnError );
+        }
+
+    return returnError != KErrCorrupt;
+    }
+
+// end of file