multimediacommscontroller/mmccdtmfpayloadformat/src/dtmfpayloadencoder.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2006-2007 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:    DTMF RTP payload encoder for named telephone events
       
    15 *                and tones.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDES
       
    23 #include <mmf/server/mmfdatabuffer.h>
       
    24 #include "dtmfpayloadformatdefs.h"
       
    25 #include "dtmfpayloadencoder.h"
       
    26 #include "dtmfeventpayloadinfo.h"
       
    27 #include "dtmftonepayloadinfo.h"
       
    28 #include "streamformatter.h"
       
    29 
       
    30 // CONSTANTS
       
    31 const TInt KEventLengthInBytes = 8;
       
    32 const TInt KByteIndex = 2;
       
    33 const TInt KReservedBits = 4;
       
    34 
       
    35 #ifdef VOIP_TRACE_ENABLED
       
    36 #include <voip_trace.h>
       
    37 #endif
       
    38 
       
    39 // ======== MEMBER FUNCTIONS ========
       
    40 
       
    41 
       
    42 // ---------------------------------------------------------------------------
       
    43 // CDTMFPayloadEncoder::CDTMFPayloadEncoder
       
    44 // C++ default constructor can NOT contain any code, that
       
    45 // might leave.
       
    46 // ---------------------------------------------------------------------------
       
    47 //
       
    48 CDTMFPayloadEncoder::CDTMFPayloadEncoder()
       
    49     {
       
    50     }
       
    51 
       
    52 // ---------------------------------------------------------------------------
       
    53 // CDTMFPayloadEncoder::NewL
       
    54 // Two-phased constructor.
       
    55 // ---------------------------------------------------------------------------
       
    56 //
       
    57 CDTMFPayloadEncoder* CDTMFPayloadEncoder::NewL()
       
    58     {
       
    59     #ifdef VOIP_TRACE_ENABLED
       
    60         VoipTrace( "%x %x", MCC_TRACE, MCC_DTMF_PLF_ENC_NEWL );
       
    61     #endif
       
    62 
       
    63     CDTMFPayloadEncoder* self = new( ELeave ) CDTMFPayloadEncoder;
       
    64     return self;
       
    65     }
       
    66 
       
    67 // ---------------------------------------------------------------------------
       
    68 // CDTMFPayloadEncoder::~CDTMFPayloadEncoder
       
    69 // Destructor.
       
    70 // ---------------------------------------------------------------------------
       
    71 //
       
    72 CDTMFPayloadEncoder::~CDTMFPayloadEncoder()
       
    73     {
       
    74     #ifdef VOIP_TRACE_ENABLED
       
    75         VoipTrace( "%x %x", MCC_TRACE, MCC_DTMF_PLF_ENC_DESTRUCTOR );
       
    76     #endif
       
    77     iEventArray.Reset();
       
    78     }
       
    79 
       
    80 // ---------------------------------------------------------------------------
       
    81 // CDTMFPayloadEncoder::EncodeEvent
       
    82 // Forms payload for named events.
       
    83 // ---------------------------------------------------------------------------
       
    84 //
       
    85 /*
       
    86     0                   1                   2                   3 
       
    87     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       
    88    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
    89    |     event     |E|R| volume    |          duration             | 
       
    90    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
    91 */  
       
    92 TInt CDTMFPayloadEncoder::EncodeEvent( 
       
    93     const TDTMFEventPayloadInfo& aEventInfo,
       
    94     CMMFBuffer* aOutputBuffer )
       
    95     {
       
    96     #ifdef VOIP_TRACE_ENABLED
       
    97         VoipTrace( "%x %x", MCC_TRACE, MCC_DTMF_PLF_ENC_ENCEV );
       
    98     #endif
       
    99     if ( EDTMFPayloadFormatRedEvents == iPayloadFormat )
       
   100         {
       
   101         return EncodeRedundantEventPayload( aEventInfo, aOutputBuffer );
       
   102         }
       
   103 
       
   104     if ( aOutputBuffer )
       
   105         {
       
   106         // Possible events are: 0-9, * (10), # (11), A-D (12-15)
       
   107         TInt eventAsInteger = EventAsInteger( aEventInfo.Event() );
       
   108 
       
   109         TStreamEncoder streamEncoder;
       
   110         TDes8& dataDes = 
       
   111             static_cast<CMMFDataBuffer*>( aOutputBuffer )->Data();
       
   112         const TUint8* seekPtr = dataDes.Ptr();
       
   113          // 32 bits
       
   114         dataDes.SetLength( KEventBlockLengthInBytes );
       
   115         
       
   116         streamEncoder.Initialize( const_cast<TUint8*>( seekPtr ), 0, 0 );
       
   117         
       
   118         // Encode Event Field
       
   119         streamEncoder.Encode( eventAsInteger, KEventFieldBits );
       
   120         
       
   121         // Encode end bit for final packet.
       
   122         streamEncoder.Encode( aEventInfo.EndBit(), 1 );
       
   123         
       
   124         // Encode reserved bit
       
   125         streamEncoder.Encode( 0, 1 );
       
   126         
       
   127         // Encode volume field. Volume must be encoded only if it is relevant
       
   128         // to the event. Otherwise it must be set to zero.
       
   129         streamEncoder.Encode( aEventInfo.Volume(), KVolFieldBits );
       
   130         
       
   131         // Encode duration field
       
   132         streamEncoder.Encode( aEventInfo.Duration(), KDurationFieldBits );
       
   133         
       
   134         // Update event array for redundant events encoding
       
   135         iEventArray.Append( aEventInfo );
       
   136         if ( KDTMFDefaultRedundancyCount < iEventArray.Count() )
       
   137             {
       
   138             iEventArray.Remove( 0 );
       
   139             }
       
   140         
       
   141         return KErrNone;
       
   142         }
       
   143     else
       
   144         {
       
   145         return KErrArgument;
       
   146         }
       
   147     }
       
   148 
       
   149 // ---------------------------------------------------------------------------
       
   150 // CDTMFPayloadEncoder::EncodeRedundantEventPayload
       
   151 // Encodes events to Event Payload Format using Multi-Event Redundancy.
       
   152 // ---------------------------------------------------------------------------
       
   153 //
       
   154 /*
       
   155    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   156    |F|   block PT  |     timestamp offset      |   block length    | 
       
   157    |1|     97      |            11200          |         4         | 
       
   158    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   159    |F|   block PT  |     timestamp offset      |   block length    | 
       
   160    |1|     97      |   11200 - 6400 = 4800     |         4         | 
       
   161    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   162    |F|   Block PT  | 
       
   163    |0|     97      | 
       
   164    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   165    |     digit     |E R| volume    |          duration             | 
       
   166    |       9       |1 0|     7     |             1600              |  
       
   167    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   168    |     digit     |E R| volume    |          duration             | 
       
   169    |       1       |1 0|    10     |             2000              |  
       
   170    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   171    |     digit     |E R| volume    |          duration             | 
       
   172    |       1       |0 0|    20     |              400              |  
       
   173    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   174    */
       
   175 TInt CDTMFPayloadEncoder::EncodeRedundantEventPayload(
       
   176     const TDTMFEventPayloadInfo& aEventInfo, CMMFBuffer* aOutputBuffer )
       
   177     {
       
   178     #ifdef VOIP_TRACE_ENABLED
       
   179         VoipTrace( "%x %x", MCC_TRACE, MCC_DTMF_PLF_ENC_ENCREDEVPL );
       
   180     #endif
       
   181     if ( aOutputBuffer )
       
   182         {
       
   183         TStreamEncoder streamEncoder;
       
   184         TDes8& dataDes = 
       
   185             static_cast<CMMFDataBuffer*>( aOutputBuffer )->Data();
       
   186         const TUint8* seekPtr = dataDes.Ptr();
       
   187         
       
   188         // Count length of packet. Event consists of 4 byte header and 4 byte
       
   189         // payload. Length of the redundancy header of last event is one byte.
       
   190         TInt length( iEventArray.Count() * KEventLengthInBytes - 3 );
       
   191         if ( length > 0 && length < dataDes.MaxSize() )
       
   192             {
       
   193             dataDes.SetLength( length );    
       
   194             }
       
   195 
       
   196         streamEncoder.Initialize( const_cast<TUint8*>( seekPtr ), 0, 0 );
       
   197         
       
   198         // Update event array
       
   199         iEventArray.Append( aEventInfo );
       
   200         if ( KDTMFDefaultRedundancyCount < iEventArray.Count() )
       
   201             {
       
   202             iEventArray.Remove( 0 );
       
   203             }
       
   204             
       
   205         // Encode redundancy headers
       
   206         TInt eventCount( iEventArray.Count() );
       
   207         for ( TInt i = 0; i < eventCount; i++ )
       
   208             {
       
   209             if ( i != eventCount - 1 )
       
   210                 {
       
   211                 // F-bit
       
   212                 streamEncoder.Encode( 1, 1 );
       
   213                 streamEncoder.Encode( iPayloadType, KBlockPTBits );
       
   214                 
       
   215                 // Encode Timestamp offset
       
   216                 TUint offset( iEventArray[eventCount - 1].TimeStamp().Int()
       
   217                                          - iEventArray[i].TimeStamp().Int() );
       
   218                 streamEncoder.Encode( offset, KTimeStampOffsetBits );
       
   219                 
       
   220                 streamEncoder.Encode( KEventBlockLengthInBytes, 
       
   221                                                         KBlockLengthBits );
       
   222                 }
       
   223             else
       
   224                 {
       
   225                 // Last redundancy header
       
   226                 // F-bit
       
   227                 streamEncoder.Encode( 0, 1 );
       
   228                 streamEncoder.Encode( iPayloadType, KBlockPTBits );
       
   229                 }
       
   230             }
       
   231 
       
   232         // Encode payload blocks
       
   233         for ( TInt index = 0; index < eventCount; index++ )
       
   234             {
       
   235             // Possible events are: 0-9, * (10), # (11), A-D (12-15)
       
   236             TInt eventAsInteger = 
       
   237                                 EventAsInteger( iEventArray[index].Event() );
       
   238 
       
   239             // Encode digit field
       
   240             streamEncoder.Encode( eventAsInteger, KEventFieldBits );
       
   241 
       
   242             // Encode E-bit
       
   243             if ( index != eventCount - 1 )
       
   244                 {
       
   245                 streamEncoder.Encode( 1, 1 );
       
   246                 }
       
   247             else
       
   248                 {
       
   249                 // Last event
       
   250                 streamEncoder.Encode( 0, 1 );
       
   251                 }
       
   252 
       
   253             // Encode Reserved bit
       
   254             streamEncoder.Encode( 0, 1 );
       
   255 
       
   256             // Encode Volume Field
       
   257             streamEncoder.Encode( iEventArray[index].Volume(), 
       
   258                                                             KVolFieldBits );
       
   259             
       
   260             // Encode Duration Field
       
   261             streamEncoder.Encode( iEventArray[index].Duration(), 
       
   262                                                         KDurationFieldBits );
       
   263             }
       
   264 
       
   265         return KErrNone;
       
   266         }
       
   267     else
       
   268         {
       
   269         return KErrArgument;
       
   270         }
       
   271     }
       
   272 
       
   273 // ---------------------------------------------------------------------------
       
   274 // CDTMFPayloadEncoder::EncodeTone
       
   275 // Forms tone payload for DTMF digit.
       
   276 // ---------------------------------------------------------------------------
       
   277 //
       
   278 /*
       
   279      0                   1                   2                   3 
       
   280      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
       
   281     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   282     |    modulation   |T|  volume   |          duration             | 
       
   283     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   284     |R R R R|       frequency       |R R R R|       frequency       | 
       
   285     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   286     |R R R R|       frequency       |R R R R|       frequency       | 
       
   287     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   288         ...... 
       
   289     
       
   290     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   291     |R R R R|       frequency       |R R R R|      frequency        | 
       
   292     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
       
   293 */
       
   294 TInt CDTMFPayloadEncoder::EncodeTone( const TDTMFTonePayloadInfo& aToneInfo,
       
   295     CMMFDataBuffer* aOutputBuffer ) const
       
   296     {
       
   297     #ifdef VOIP_TRACE_ENABLED
       
   298         VoipTrace( "%x %x", MCC_TRACE, MCC_DTMF_PLF_ENC_ENCTONE );
       
   299     #endif
       
   300     if ( aOutputBuffer )
       
   301         {
       
   302         TInt toneAsInteger = EventAsInteger( aToneInfo.Tone() );
       
   303         if ( toneAsInteger < 0 || toneAsInteger >= KDtmfGroupFrequencyCount )
       
   304             {
       
   305             return KErrArgument;
       
   306             }
       
   307         TUint lowGroupFrequency( KDTMFLowGroupFrequencies[ toneAsInteger ] );
       
   308         TUint highGroupFrequency( 
       
   309                                 KDTMFHighGroupFrequencies[ toneAsInteger ] );
       
   310         
       
   311         TStreamEncoder streamEncoder;
       
   312         TDes8& dataDes = 
       
   313             STATIC_CAST( CMMFDataBuffer*, aOutputBuffer )->Data();
       
   314         const TUint8* seekPtr = dataDes.Ptr();
       
   315         // 2 * 32 bits
       
   316         dataDes.SetLength( KEventLengthInBytes );
       
   317         
       
   318         streamEncoder.Initialize( const_cast<TUint8*>( seekPtr ), 0, 0 );
       
   319         
       
   320         // Encode modulation field
       
   321         streamEncoder.Encode( aToneInfo.Modulation(), KModulationBits );
       
   322         
       
   323         // Encode T bit
       
   324         streamEncoder.Encode( 0, 1 );
       
   325         
       
   326         // Encode Volume Field
       
   327         streamEncoder.Encode( aToneInfo.Volume(), KVolFieldBits );
       
   328         
       
   329         // Encode Duration Field
       
   330         streamEncoder.Encode( aToneInfo.Duration(), KDurationFieldBits );
       
   331         
       
   332         // Encode four R(eserved) bits
       
   333         streamEncoder.Encode( 0, KReservedBits );
       
   334         
       
   335         // Encode first Frequency Field
       
   336         streamEncoder.Encode( lowGroupFrequency, KFrequencyBits );
       
   337         
       
   338         // Encode four R(eserved) bits
       
   339         streamEncoder.Encode( 0, KReservedBits );
       
   340         
       
   341         // Encode second Frequency Field
       
   342         streamEncoder.Encode( highGroupFrequency, KFrequencyBits );
       
   343         
       
   344         return KErrNone;
       
   345         }
       
   346     else
       
   347         {
       
   348         return KErrArgument;
       
   349         }
       
   350     }
       
   351 
       
   352 // ---------------------------------------------------------------------------
       
   353 // CDTMFPayloadEncoder::UpdateEventPayload
       
   354 // Updates previously created event payload according to parameters.
       
   355 // ---------------------------------------------------------------------------
       
   356 //
       
   357 TInt CDTMFPayloadEncoder::UpdateEventPayload( const TBool aFinalPacket,
       
   358     const TUint aDuration,
       
   359     CMMFDataBuffer* aOutputBuffer ) const
       
   360     {
       
   361     #ifdef VOIP_TRACE_ENABLED
       
   362         VoipTrace( "%x %x", MCC_TRACE, MCC_DTMF_PLF_ENC_UPDEVPL );
       
   363     #endif
       
   364     if ( aOutputBuffer )
       
   365         {
       
   366         TStreamEncoder streamEncoder;
       
   367         TDes8& dataDes = STATIC_CAST( CMMFDataBuffer*, 
       
   368                                                     aOutputBuffer )->Data();
       
   369         const TUint8* seekPtr = dataDes.Ptr();
       
   370         
       
   371         // End bit starts from the beginning of second byte
       
   372         streamEncoder.Initialize( const_cast<TUint8*>( seekPtr ), 1, 0 );
       
   373         
       
   374         // Encode End Bit
       
   375         if ( aFinalPacket )
       
   376             {
       
   377             streamEncoder.Encode( 1, 1 );    
       
   378             }
       
   379             
       
   380         // Duration Field starts from third byte
       
   381         streamEncoder.SetBitIndex( 0 );
       
   382         streamEncoder.SetByteIndex( KByteIndex );
       
   383         
       
   384         // Encode Duration Field with new value
       
   385         streamEncoder.Encode( aDuration, KDurationFieldBits );
       
   386         
       
   387         return KErrNone;
       
   388         }
       
   389     else
       
   390         {
       
   391         return KErrArgument;
       
   392         }
       
   393     }
       
   394 
       
   395 
       
   396 // ---------------------------------------------------------------------------
       
   397 // CDTMFPayloadEncoder::UpdateTonePayload
       
   398 // Updates previously created tone payload according to parameters.
       
   399 // ---------------------------------------------------------------------------
       
   400 //     
       
   401 TInt CDTMFPayloadEncoder::UpdateTonePayload( const TUint aToneDuration,
       
   402     CMMFDataBuffer* aOutputBuffer ) const
       
   403     {
       
   404     #ifdef VOIP_TRACE_ENABLED
       
   405         VoipTrace( "%x %x", MCC_TRACE, MCC_DTMF_PLF_ENC_UPDTONEPL );
       
   406     #endif
       
   407 
       
   408     if ( aOutputBuffer )
       
   409         {
       
   410         TStreamEncoder streamEncoder;
       
   411         TDes8& dataDes = STATIC_CAST( CMMFDataBuffer*, 
       
   412                                       aOutputBuffer )->Data();
       
   413         const TUint8* seekPtr = dataDes.Ptr();
       
   414 
       
   415         // Duration Field starts from third byte
       
   416         streamEncoder.Initialize( const_cast<TUint8*>( seekPtr ), 3, 0 );
       
   417         
       
   418         // Encode Duration Field with a new value
       
   419         streamEncoder.Encode( aToneDuration, KDurationFieldBits );
       
   420 
       
   421         return KErrNone;
       
   422         }
       
   423     else
       
   424         {
       
   425         return KErrArgument;
       
   426         }
       
   427     }
       
   428 
       
   429 // ---------------------------------------------------------------------------
       
   430 // CDTMFPayloadEncoder::PayloadFormat
       
   431 // Returns payload format in use.
       
   432 // ---------------------------------------------------------------------------
       
   433 //
       
   434 TDTMFPayloadFormat CDTMFPayloadEncoder::PayloadFormat( ) const
       
   435     {
       
   436     return iPayloadFormat;
       
   437     }
       
   438 
       
   439 // ---------------------------------------------------------------------------
       
   440 // CDTMFPayloadEncoder::SetPayloadFormat
       
   441 // Sets payload format in use.
       
   442 // ---------------------------------------------------------------------------
       
   443 //
       
   444 TInt CDTMFPayloadEncoder::SetPayloadFormat( 
       
   445     TDTMFPayloadFormat aPayloadFormat )
       
   446     {
       
   447     #ifdef VOIP_TRACE_ENABLED
       
   448         VoipTrace( "%x %x %d", MCC_TRACE, MCC_DTMF_PLF_ENC_SETPLF, aPayloadFormat );
       
   449     #endif
       
   450 
       
   451     if ( EDTMFPayloadFormatEvent != aPayloadFormat
       
   452          && EDTMFPayloadFormatTone != aPayloadFormat
       
   453          && EDTMFPayloadFormatRedEvents != aPayloadFormat )
       
   454         {
       
   455         return KErrNotSupported;
       
   456         }
       
   457     else
       
   458         {
       
   459         iPayloadFormat = aPayloadFormat;
       
   460         }
       
   461 
       
   462     return KErrNone;
       
   463     }
       
   464 
       
   465 // ---------------------------------------------------------------------------
       
   466 // CDTMFPayloadEncoder::PayloadType
       
   467 // Returns payload type in use.
       
   468 // ---------------------------------------------------------------------------
       
   469 //
       
   470 TUint8 CDTMFPayloadEncoder::PayloadType( ) const
       
   471     {
       
   472     return iPayloadType;
       
   473     }
       
   474 
       
   475 // ---------------------------------------------------------------------------
       
   476 // CDTMFPayloadEncoder::SetPayloadType
       
   477 // Sets payload type in use.
       
   478 // ---------------------------------------------------------------------------
       
   479 //    
       
   480 void CDTMFPayloadEncoder::SetPayloadType( TUint8 aPayloadType )
       
   481     {
       
   482     iPayloadType = aPayloadType;
       
   483     }
       
   484      
       
   485 // ---------------------------------------------------------------------------
       
   486 // CDTMFPayloadEncoder::EventAsInteger
       
   487 // Converts DTMF digit / Tone represented as TChar to the integer encoding
       
   488 // used in payload.
       
   489 // ---------------------------------------------------------------------------
       
   490 //
       
   491 TInt CDTMFPayloadEncoder::EventAsInteger( const TChar& aEvent ) const
       
   492     {
       
   493     TInt returnValue( KErrNotFound );
       
   494 
       
   495     // Conversion because of PC_LINT warning #1561
       
   496     TChar argument( aEvent );
       
   497     // For PC_LINT error   #1023
       
   498     TUint nullChar( '0' );
       
   499 
       
   500     if ( '0' <= aEvent && '9' >= aEvent )
       
   501         {
       
   502         returnValue = argument - nullChar;
       
   503         }
       
   504     else
       
   505         {
       
   506         switch ( aEvent )
       
   507             {
       
   508             case '*':
       
   509                 returnValue = KEventCodeForAsterisk;
       
   510                 break;
       
   511             case '#':
       
   512                 returnValue = KEventCodeForHashMark;
       
   513                 break;
       
   514             case 'a':
       
   515             case 'A':
       
   516                 returnValue = KEventCodeForA;
       
   517                 break;
       
   518             case 'b':
       
   519             case 'B':
       
   520                 returnValue = KEventCodeForB;
       
   521                 break;
       
   522             case 'c':                
       
   523             case 'C':
       
   524                 returnValue = KEventCodeForC;
       
   525                 break;
       
   526             case 'd':
       
   527             case 'D':
       
   528                 returnValue = KEventCodeForD;
       
   529                 break;
       
   530             default:
       
   531                 break;
       
   532             }
       
   533         }
       
   534 
       
   535     return returnValue;
       
   536     }
       
   537 
       
   538 //  End of File