os/mm/devsound/sounddevbt/src/A2dpBlueTooth/headsetaudioif/A2dpCodecUtilities.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2005-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 //
    15 
    16 #include "A2dpCodecUtilities.h"
    17 
    18 
    19 /**
    20 A2dp codec utilities Panics
    21 **/
    22 enum TA2dpCodecUtilitiesPanic
    23 	{
    24 	EA2dpCodecUtilNoRemoteCodecConfig, //0
    25 	EA2dpCodecUtilUnexpectedDataType, //1
    26 	EA2dpCodecUtilUnsupportedDataType, //2
    27 	EA2dpCodecUtilUnexpectedConfiguration, //3
    28 	EA2dpCodecUtilDataMemberNotSet //4
    29 	};
    30 
    31 
    32 static void Panic(TA2dpCodecUtilitiesPanic aPanic)
    33 // Panic client
    34 	{
    35 	_LIT(KA2dpCodecUtilitiesPanicName, "A2DP Codec Util Panic");
    36 	User::Panic(KA2dpCodecUtilitiesPanicName, aPanic);
    37 	}
    38 
    39 
    40 TInt TA2dpCodecCapabilityParser::GetSupportedSBCSampleRates(const TSBCCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedDiscreteRates)
    41 	{
    42 	TInt err = KErrNone;
    43 	TSBCSamplingFrequencyBitmask samplingRatesBitMask = aCodecCaps.SamplingFrequencies();
    44 	if (samplingRatesBitMask & E16kHz)
    45 		{
    46 		err = aSupportedDiscreteRates.Append(16000);
    47 		}
    48 	if (!err && (samplingRatesBitMask & E32kHz))
    49 		{
    50 		err = aSupportedDiscreteRates.Append(32000);
    51 		}
    52 	if (!err && (samplingRatesBitMask & E44100Hz))
    53 		{
    54 		err = aSupportedDiscreteRates.Append(44100);
    55 		}
    56 	if (!err && (samplingRatesBitMask & E48kHz))
    57 		{
    58 		err = aSupportedDiscreteRates.Append(48000);
    59 		}
    60 	return err;
    61 	}
    62 
    63 	
    64 TInt TA2dpCodecCapabilityParser::GetSupportedMPEG12SampleRates(const TNonSBCCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedDiscreteRates)
    65 	{
    66 	TInt err = KErrNone;
    67 	
    68 	TPtrC8 codecCapsData(aCodecCaps.CodecData());
    69 	
    70 	TMPEG12SamplingFrequencyBitmask samplingRatesBitMask = codecCapsData[1] & KA2dpMPEG12SamplingFrequencyMask;
    71 
    72 	if (samplingRatesBitMask & EMPEG12_16kHz)
    73 		{
    74 		err = aSupportedDiscreteRates.Append(16000);		
    75 		}
    76 	if (!err && samplingRatesBitMask & EMPEG12_22050Hz)
    77 		{
    78 		err = aSupportedDiscreteRates.Append(22050);	
    79 		}
    80 	if (!err && samplingRatesBitMask & EMPEG12_24kHz)
    81 		{
    82 		err = aSupportedDiscreteRates.Append(24000);	
    83 		}
    84 	if (!err && samplingRatesBitMask & EMPEG12_32kHz)
    85 		{
    86 		err = aSupportedDiscreteRates.Append(32000);		
    87 		}
    88 	if (!err && samplingRatesBitMask & EMPEG12_44100Hz)
    89 		{
    90 		err = aSupportedDiscreteRates.Append(44100);		
    91 		}
    92 	if (!err && samplingRatesBitMask & EMPEG12_48kHz)
    93 		{
    94 		err = aSupportedDiscreteRates.Append(48000);			
    95 		}
    96 				
    97 	return err;
    98 	}
    99 	
   100 	
   101 TInt TA2dpCodecCapabilityParser::GetSupportedSampleRates(const TAvdtpMediaCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedDiscreteRates)
   102 	{
   103 	TInt err = KErrNotSupported;
   104 	switch(aCodecCaps.MediaCodecType())
   105 		{
   106 		case EAudioCodecSBC:
   107 			err = GetSupportedSBCSampleRates(static_cast<const TSBCCodecCapabilities&>(aCodecCaps), aSupportedDiscreteRates);
   108 			break;
   109 		case EAudioCodecMPEG12Audio:
   110 			err = GetSupportedMPEG12SampleRates(static_cast<const TNonSBCCodecCapabilities&>(aCodecCaps), aSupportedDiscreteRates);
   111 			break;
   112 		case EAudioCodecMPEG24AAC:
   113 			break;
   114 		case EAudioCodecATRAC:
   115 			break;
   116 		default:
   117 			Panic(EA2dpCodecUtilUnexpectedDataType);
   118 			break;
   119 		}
   120 	return err;
   121 	}
   122 
   123 
   124 TInt TA2dpCodecCapabilityParser::GetSupportedSBCChannels(const TSBCCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedChannels, TMMFStereoSupport& aStereoSupport)
   125 	{
   126 	TInt err = KErrNotSupported;
   127 
   128 	TSBCChannelModeBitmask channelModesBitMask = aCodecCaps.ChannelModes();
   129 	
   130 	err = GetSupportedChannelsCommonCode(channelModesBitMask, aSupportedChannels, aStereoSupport);
   131 	
   132 	return err;
   133 	}
   134 
   135 	
   136 TInt TA2dpCodecCapabilityParser::GetSupportedMPEG12Channels(const TNonSBCCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedChannels, TMMFStereoSupport& aStereoSupport)
   137 	{
   138 	TInt err = KErrNotSupported;
   139 	
   140 	TPtrC8 codecCapsData(aCodecCaps.CodecData());
   141 	TSBCChannelModeBitmask channelModesBitMask = codecCapsData[0] & KA2dpMPEG12AudioChannelModeMask;
   142 		
   143 	err = GetSupportedChannelsCommonCode(channelModesBitMask, aSupportedChannels, aStereoSupport);
   144 		
   145 	return err;
   146 	}
   147 
   148 
   149 /**
   150 MPEG12 uses the same channel mode bit mask as SBC so we'll factor out the common code
   151 and reuse the TSBCChannelModeBitmask for mp3 as well
   152 */	
   153 TInt TA2dpCodecCapabilityParser::GetSupportedChannelsCommonCode(TSBCChannelModeBitmask aChannelModesBitMask, RArray<TUint>& aSupportedChannels, TMMFStereoSupport& aStereoSupport)
   154 	{
   155 	TInt err = KErrNotSupported;
   156 
   157 	if (aChannelModesBitMask & EMono)
   158 		{
   159 		err = aSupportedChannels.Append(EMMFMono);
   160 		}
   161 	if (!err)
   162 		{
   163 		if ((aChannelModesBitMask & EStereo) || (aChannelModesBitMask & EJointStereo))
   164 			{
   165 			err = aSupportedChannels.Append(EMMFStereo);
   166 			aStereoSupport = EMMFInterleavedOnly;
   167 			}
   168 		}
   169 	if (!err && (aChannelModesBitMask & EJointStereo))
   170 		{
   171 		//we have to cast as the TMMFStereoSupport is an enumeration
   172 		//but is really should be a bitmap
   173 		//but don't want to change it in order to preserve BC
   174 		TUint aStereoSupportInt = static_cast<TUint>(aStereoSupport);
   175 		aStereoSupportInt |= static_cast<TUint>(EMMFJoint);
   176 		aStereoSupport = static_cast<TMMFStereoSupport>(aStereoSupportInt);
   177 		}
   178 	return err;
   179 	}
   180 
   181 
   182 TInt TA2dpCodecCapabilityParser::GetSupportedChannels(const TAvdtpMediaCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedChannels, TMMFStereoSupport& aStereoSupport)
   183 	{
   184 	TInt err = KErrNotSupported;
   185 	switch(aCodecCaps.MediaCodecType())
   186 		{
   187 		case EAudioCodecSBC:
   188 			err = GetSupportedSBCChannels(static_cast<const TSBCCodecCapabilities&>(aCodecCaps), aSupportedChannels, aStereoSupport);
   189 			break;
   190 		case EAudioCodecMPEG12Audio:
   191 			err = GetSupportedMPEG12Channels(static_cast<const TNonSBCCodecCapabilities&>(aCodecCaps), aSupportedChannels, aStereoSupport);
   192 			break;
   193 		case EAudioCodecMPEG24AAC:
   194 			Panic(EA2dpCodecUtilUnsupportedDataType);
   195 			break;
   196 		case EAudioCodecATRAC:
   197 			Panic(EA2dpCodecUtilUnsupportedDataType);
   198 			break;
   199 		default:
   200 			Panic(EA2dpCodecUtilUnexpectedDataType);
   201 			break;
   202 		}
   203 	return err;
   204 	}
   205 
   206 	
   207 /**
   208 static
   209 */
   210 TUint8 TRTPa2dpCodecSpecificUtils::PayloadType(const TFourCC& aCodecDataType)
   211 	{
   212 	TUint8 payloadType = 0;
   213 	switch(const_cast<TFourCC&>(aCodecDataType).FourCC())
   214 		{
   215 		case KMMFFourCCCodeSBC:
   216 			payloadType = KSbcRTPPayloadType;
   217 			break;
   218 		case KMMFFourCCCodeMP3:
   219 			payloadType = KMPEG12RTPAudioPayloadType; 
   220 			break;
   221 		case KMMFFourCCCodeAAC:
   222 			Panic(EA2dpCodecUtilUnsupportedDataType);
   223 			break;
   224 		case KMMFFourCCCodeATRAC3:
   225 			Panic(EA2dpCodecUtilUnsupportedDataType);
   226 			break;
   227 		default:
   228 			Panic(EA2dpCodecUtilUnexpectedDataType);
   229 			break;
   230 		}
   231 	return payloadType;
   232 	}
   233 
   234 
   235 TUint TRTPa2dpCodecSpecificUtils::MediaPayloadHeaderLength(const TFourCC& aCodecDataType)
   236 	{
   237 	TUint mediaPayloadHeaderLength = 0;
   238 	switch(const_cast<TFourCC&>(aCodecDataType).FourCC())
   239 		{
   240 		case KMMFFourCCCodeSBC:
   241 			mediaPayloadHeaderLength = KSbcRTPMediaPayloadHeaderLength;
   242 			break;
   243 		case KMMFFourCCCodeMP3:
   244 			mediaPayloadHeaderLength = KMPEG12RTPMediaPayloadHeaderLength;
   245 			break;
   246 		case KMMFFourCCCodeAAC:
   247 			Panic(EA2dpCodecUtilUnsupportedDataType);
   248 			break;
   249 		case KMMFFourCCCodeATRAC3:
   250 			Panic(EA2dpCodecUtilUnsupportedDataType);
   251 			break;
   252 		default:
   253 			Panic(EA2dpCodecUtilUnexpectedDataType);
   254 			break;
   255 		}
   256 	return mediaPayloadHeaderLength;
   257 	}
   258 
   259 
   260 	
   261 TTimeIntervalMicroSeconds32 TFrameTimingUtils::FrameDuration(TUint aFrameLength, TUint aBitRate)
   262 	{
   263 	TUint frameDurationuS = (aFrameLength*8*1000000)/aBitRate;
   264 	return TTimeIntervalMicroSeconds32(frameDurationuS);
   265 	}
   266 	
   267 
   268 TUint TFrameTimingUtils::CalculateSBCTimeStampIncrementPerFrame(TUint aFrameLength, TUint aBitRate, TUint aSampleRate)
   269 	{
   270 	//SBC uses the sampleRate clock as the timestamp clock A2DP spec 4.3.3.1
   271 	TUint frameDurationuS = FrameDuration(aFrameLength, aBitRate).Int();
   272 	
   273 	return (frameDurationuS*aSampleRate)/1000000;
   274 	}
   275 	
   276 
   277 TUint TFrameTimingUtils::CalculateMPEG12TimeStampIncrementPerFrame(TUint aFrameLength, TUint aBitRate)
   278 	{
   279 	//MPEG12 uses a 90Khz clock as the timestamp clock RFC3551 section 4.5.13
   280 	TUint frameDurationuS = FrameDuration(aFrameLength, aBitRate).Int();
   281 
   282 	//div 1000000 as frame duration is in microseconds
   283 	return (frameDurationuS*KMPEG12RTPTimeStampClock)/1000000;
   284 	}
   285 	
   286 	
   287 TUint TFrameTimingUtils::TimeStampIncrementPerFrame(const TFourCC& aCodecDataType, TUint aFrameLength, TUint aBitRate, TUint aSampleRate)
   288 	{
   289 	TInt timeStampIncrement = 0;
   290 	switch (const_cast<TFourCC&>(aCodecDataType).FourCC())
   291 		{
   292 		case KMMFFourCCCodeSBC:
   293 			timeStampIncrement = CalculateSBCTimeStampIncrementPerFrame(aFrameLength, aBitRate, aSampleRate);
   294 			break;
   295 		case KMMFFourCCCodeMP3:
   296 			timeStampIncrement = CalculateMPEG12TimeStampIncrementPerFrame(aFrameLength, aBitRate);
   297 			break;
   298 		case KMMFFourCCCodeAAC:
   299 			Panic(EA2dpCodecUtilUnsupportedDataType);
   300 			break;
   301 		case KMMFFourCCCodeATRAC3:
   302 			Panic(EA2dpCodecUtilUnsupportedDataType);
   303 			break;
   304 		default:
   305 			//the datatype is a non A2DP datatype
   306 			//which is not supported so panic
   307 			Panic(EA2dpCodecUtilUnexpectedDataType);
   308 			break;
   309 		}
   310 	return timeStampIncrement;
   311 	}
   312 
   313 
   314 CA2dpLocalCodecCapabilities* CA2dpLocalCodecCapabilities::NewL()
   315 	{
   316 	return new(ELeave) CA2dpLocalCodecCapabilities();
   317 	}
   318 
   319 
   320 CA2dpLocalCodecCapabilities::CA2dpLocalCodecCapabilities()	
   321 	{
   322 	
   323 	}
   324 
   325 	
   326 CA2dpLocalCodecCapabilities::~CA2dpLocalCodecCapabilities()
   327 	{
   328 	delete iLocalCodecCapabilities;
   329 	}
   330 
   331 	
   332 TAvdtpMediaCodecCapabilities*  CA2dpLocalCodecCapabilities::LocalCodecCapabilities(const TFourCC& aCodecDataType)
   333 	{
   334 	switch(const_cast<TFourCC&>(aCodecDataType).FourCC())
   335 		{
   336 		case KMMFFourCCCodeSBC:
   337 			iLocalCodecCapabilities = LocalSBCCodecCapabilities();
   338 			break;
   339 		case KMMFFourCCCodeMP3:
   340 			iLocalCodecCapabilities = LocalMPEG12CodecCapabilities();
   341 			break;
   342 		case KMMFFourCCCodeAAC:
   343 			Panic(EA2dpCodecUtilUnsupportedDataType);
   344 			break;
   345 		case KMMFFourCCCodeATRAC3:
   346 			Panic(EA2dpCodecUtilUnsupportedDataType);
   347 			break;
   348 		default:
   349 			Panic(EA2dpCodecUtilUnexpectedDataType);
   350 			break;
   351 		}
   352 	return iLocalCodecCapabilities;
   353 	}
   354 	
   355 
   356 TSBCCodecCapabilities* CA2dpLocalCodecCapabilities::LocalSBCCodecCapabilities()
   357 	{
   358 	delete iLocalCodecCapabilities;
   359 	iLocalCodecCapabilities = NULL;
   360 	TSBCCodecCapabilities* localSbcCodecCapabilities = new TSBCCodecCapabilities();
   361 	if (localSbcCodecCapabilities)
   362 		{
   363 		localSbcCodecCapabilities->SetSamplingFrequencies(E16kHz|E32kHz|E44100Hz|E48kHz);
   364 		localSbcCodecCapabilities->SetChannelModes(EMono|EStereo|EJointStereo);
   365 		localSbcCodecCapabilities->SetBlockLengths(EBlockLenFour|EBlockLenEight|EBlockLenTwelve|EBlockLenSixteen);
   366 		localSbcCodecCapabilities->SetSubbands(EFourSubbands|EEightSubbands);
   367 		localSbcCodecCapabilities->SetAllocationMethods(ELoudness|ESNR);
   368 		localSbcCodecCapabilities->SetMinBitpoolValue(KMinBitPoolValue);
   369 		localSbcCodecCapabilities->SetMaxBitpoolValue(KMaxBitPoolValue);
   370 		}
   371 	return localSbcCodecCapabilities;
   372 	}
   373 
   374 
   375 TNonSBCCodecCapabilities* CA2dpLocalCodecCapabilities::LocalMPEG12CodecCapabilities()
   376 	{
   377 	delete iLocalCodecCapabilities;
   378 	iLocalCodecCapabilities = NULL;
   379 	TNonSBCCodecCapabilities* localSEPmpeg12CodecCapabilities = new TNonSBCCodecCapabilities(EAvdtpMediaTypeAudio, EAudioCodecMPEG12Audio);
   380 	if (localSEPmpeg12CodecCapabilities)
   381 		{
   382 		TBuf8<4>	mpeg12CodecCapabilitiesData;
   383 
   384 		//MPEG12 channel modes are the same as SBC so we'll use SBC structure
   385 		TSBCChannelModeBitmask channelModes = (EMono|EStereo);
   386 		mpeg12CodecCapabilitiesData.Append(KA2dpMPEG12LayerMP3Supported | channelModes);
   387 		
   388 		//no MPF-2 support, will support 16-44100khz sample
   389 		TInt8 samplingFrequencySupport = EMPEG12_16kHz|EMPEG12_22050Hz|EMPEG12_24kHz|EMPEG12_32kHz|EMPEG12_44100Hz;
   390 		mpeg12CodecCapabilitiesData.Append(samplingFrequencySupport);
   391 		
   392 		//no VBR all bitrates <= 96kbs-1 except free format
   393 		mpeg12CodecCapabilitiesData.Append(0);
   394 		mpeg12CodecCapabilitiesData.Append(KA2dpMPEG12SupportedBitRateIndex);//all bit rates <= 96kbs-1
   395 		localSEPmpeg12CodecCapabilities->SetCodecData(mpeg12CodecCapabilitiesData);
   396 		}
   397 	return localSEPmpeg12CodecCapabilities;
   398 	}
   399 
   400 
   401 	
   402 CA2dpAudioCodecConfiguration* CA2dpAudioCodecConfiguration::NewL()
   403 	{
   404 	return new(ELeave)CA2dpAudioCodecConfiguration();
   405 	}
   406 	
   407 
   408 CA2dpAudioCodecConfiguration::CA2dpAudioCodecConfiguration() : iHeadsetCodecDataType(KMMFFourCCCodeSBC), iSampleRate(KDefaultSampleRate), iChannels(KDefaultChannels), iStereoSupport(KDefaultStereoSupport)
   409 	{	
   410 	}
   411 	
   412 CA2dpAudioCodecConfiguration::~CA2dpAudioCodecConfiguration()
   413 	{
   414 	delete iRemoteCodecConfiguration;
   415 	}
   416 
   417 
   418 void CA2dpAudioCodecConfiguration::Reset()
   419 	{
   420 	delete iRemoteCodecConfiguration;
   421 	iRemoteCodecConfiguration = NULL;
   422 	iHeadsetCodecDataType = KMMFFourCCCodeSBC;
   423 	iSampleRate = KDefaultSampleRate;
   424 	iChannels = KDefaultChannels;
   425 	iStereoSupport = KDefaultStereoSupport;
   426 	iLocalSBCCodecConfiguration.Reset();
   427 	}
   428 
   429 /**
   430 Function used to return a TAvdtpMediaCodecCapabilities structure
   431 that can be used to configure the SEP at the remote end ie on the headset
   432 The capabilities are used to determine the configuration
   433 need to return by pointer rather than by ref as TAvdtpMediaCodecCapabilities is abstract
   434 Note that this parameter passed in treats the  TAvdtpMediaCodecCapabilities as 
   435 the capabilities of the code, whereas the returned TAvdtpMediaCodecCapabilities is a
   436 configuration ie a specific set of values that can be used to configure the remote codec
   437 
   438 @param aCodecCapabilities  This is the capabilities supported by the remote codec
   439 @return The configuration for the remote codec
   440 */
   441 //void CA2dpAudioCodecConfiguration::GetRemoteCodecConfiguration(const TAvdtpMediaCodecCapabilities& aRemoteCodecCapabilities, TAvdtpMediaCodecCapabilities& aRemoteCodecConfiguration)
   442 TAvdtpMediaCodecCapabilities* CA2dpAudioCodecConfiguration::UpdateRemoteCodecConfiguration(const TAvdtpMediaCodecCapabilities& aRemoteCodecCapabilities)
   443 	{
   444 	delete iRemoteCodecConfiguration;
   445 	iRemoteCodecConfiguration = NULL;
   446 		{
   447 		//this hasn't been set yet so set it
   448 		//first find out the capabilities of the codec
   449 		switch (aRemoteCodecCapabilities.MediaCodecType())
   450 			{
   451 			case EAudioCodecSBC:
   452 				iRemoteCodecConfiguration = GetRemoteSBCCodecConfiguration(static_cast<const TSBCCodecCapabilities&>(aRemoteCodecCapabilities));
   453 				iHeadsetCodecDataType = KMMFFourCCCodeSBC;
   454 				break;
   455 			case EAudioCodecMPEG12Audio:
   456 				iRemoteCodecConfiguration = GetRemoteMPEG12CodecConfiguration(static_cast<const TNonSBCCodecCapabilities&>(aRemoteCodecCapabilities));
   457 				iHeadsetCodecDataType = KMMFFourCCCodeMP3;
   458 				break;
   459 			case EAudioCodecMPEG24AAC:
   460 				Panic(EA2dpCodecUtilUnsupportedDataType);
   461 				break;
   462 			case EAudioCodecATRAC:
   463 				Panic(EA2dpCodecUtilUnsupportedDataType);
   464 				break;
   465 			default:
   466 				//the datatype is a non A2DP datatype
   467 				//which is not supported so panic
   468 				Panic(EA2dpCodecUtilUnexpectedDataType);
   469 				break;
   470 			}
   471 		}
   472 	return iRemoteCodecConfiguration;
   473 	}
   474 		
   475 
   476 /**
   477 
   478 */
   479 TSBCCodecCapabilities* CA2dpAudioCodecConfiguration::GetRemoteSBCCodecConfiguration(const TSBCCodecCapabilities& aCodecCaps)
   480 	{
   481 	TSBCCodecCapabilities* sbcCodecConfiguration = new TSBCCodecCapabilities();
   482 	
   483 	if (sbcCodecConfiguration)	
   484 		{
   485 		//--sampling frequency--
   486 		TSBCSamplingFrequencyBitmask freqs;
   487 		switch(iSampleRate)
   488 			{
   489 			case 16000:
   490 				freqs = E16kHz;
   491 				break;
   492 			case 32000:
   493 				freqs = E32kHz;
   494 				break;
   495 			case 44100:
   496 				freqs = E44100Hz;
   497 				break;
   498 			case 48000:
   499 				freqs = E48kHz;
   500 				break;
   501 			default:
   502 				freqs = E16kHz;
   503 				break;
   504 			}
   505 		//check we really can support this sampling frequency
   506 		//since we may be using the default which may not be supported
   507 		//by the headset (even if the A2DP spec says it is mandatory)
   508 		TSBCSamplingFrequencyBitmask samplingFreqsSupportedByHeadset = aCodecCaps.SamplingFrequencies();
   509 		if 	(iForcedRemoteSBCCodecConfiguration)
   510 			{
   511 			samplingFreqsSupportedByHeadset = iForcedRemoteSBCCodecConfiguration->SamplingFrequencies();
   512 			}
   513 		if (!(freqs & samplingFreqsSupportedByHeadset))
   514 			{//then the headset doesn't support the sampling frequency
   515 			//this could happen if iSampleRate is a default that the headset doesn't support
   516 			//note that evenif the default is a mandatory sample rate eg 44100
   517 			//we still do not make any assumptions about what is supported 
   518 			if (samplingFreqsSupportedByHeadset & E16kHz)
   519 				{
   520 				iSampleRate = 16000;
   521 				freqs = E16kHz;
   522 				}
   523 			else if (samplingFreqsSupportedByHeadset & E32kHz)
   524 				{
   525 				iSampleRate = 32000;
   526 				freqs = E32kHz;
   527 				}
   528 			else if (samplingFreqsSupportedByHeadset & E44100Hz)
   529 				{
   530 				iSampleRate = 44100;
   531 				freqs = E44100Hz;
   532 				}
   533 			else if (samplingFreqsSupportedByHeadset & E48kHz)
   534 				{
   535 				iSampleRate = 48000;
   536 				freqs = E48kHz;
   537 				}
   538 			//else just keep as is
   539 			}
   540 			sbcCodecConfiguration->SetSamplingFrequencies(freqs);
   541 			
   542 		//--channels--
   543 		TSBCChannelModeBitmask channelMode = EMono;
   544 		TSBCChannelModeBitmask channelModesSupportedByHeadset = EMono;
   545 		channelModesSupportedByHeadset = aCodecCaps.ChannelModes();
   546 		if (iChannels == EMMFMono)
   547 			{
   548 			channelMode = EMono;
   549 			}
   550 		else if ((iChannels == EMMFStereo) && (iStereoSupport == EMMFInterleavedOnly))
   551 			{
   552 			channelMode = EStereo;
   553 			}
   554 		else if ((iChannels == EMMFStereo) && (iStereoSupport == EMMFJoint))
   555 			{
   556 			channelMode = EJointStereo;
   557 			}
   558 		if (!(channelMode & channelModesSupportedByHeadset))
   559 			{
   560 			//then we don't support the selected channel mode
   561 			if (channelModesSupportedByHeadset & EMono)
   562 				{
   563 				iChannels = EMMFMono;
   564 				iStereoSupport = EMMFNone;
   565 				channelMode = EMono;
   566 				}
   567 			else if (channelModesSupportedByHeadset & EJointStereo)
   568 				{
   569 				iChannels = EMMFStereo;
   570 				iStereoSupport = EMMFJoint;
   571 				channelMode = EJointStereo;
   572 				}
   573 			else if (channelModesSupportedByHeadset & EStereo)
   574 				{
   575 				iChannels = EMMFStereo;
   576 				iStereoSupport = EMMFInterleavedOnly;
   577 				channelMode = EStereo;
   578 				}
   579 			}
   580 		sbcCodecConfiguration->SetChannelModes(channelMode);	
   581 	
   582 		//--block mode--
   583 		//we'll choose a preference order of 16,12, 8,4
   584 		//although there may be a more intelligent way of doing this
   585 		//based on the other parameters.
   586 		TSBCBlockLengthBitmask blockLength = EBlockLenSixteen;
   587 		TSBCBlockLengthBitmask blockLengthsSupportedByHeadset = aCodecCaps.BlockLengths();
   588 		if 	(iForcedRemoteSBCCodecConfiguration)
   589 			{
   590 			blockLengthsSupportedByHeadset = iForcedRemoteSBCCodecConfiguration->BlockLengths();
   591 			}
   592 		if (blockLengthsSupportedByHeadset & EBlockLenSixteen)
   593 			{
   594 			blockLength = EBlockLenSixteen;
   595 			}
   596 		else if (blockLengthsSupportedByHeadset & EBlockLenTwelve)
   597 			{
   598 			blockLength = EBlockLenTwelve;
   599 			}
   600 		else if (blockLengthsSupportedByHeadset & EBlockLenEight)
   601 			{
   602 			blockLength = EBlockLenEight;
   603 			}
   604 		else if (blockLengthsSupportedByHeadset & EBlockLenFour)
   605 			{
   606 			blockLength = EBlockLenFour;
   607 			}
   608 		sbcCodecConfiguration->SetBlockLengths(blockLength);
   609 	
   610 		//--subbands--
   611 		//Subbands currently have a preference of 8 over 4
   612 		TUint numberOfSubbands = 8; //used later for max bit pool value calculation
   613 		TSBCSubbandsBitmask subbands = EEightSubbands;
   614 		TSBCSubbandsBitmask subbandsSupportedByHeadset = aCodecCaps.Subbands();
   615 		if 	(iForcedRemoteSBCCodecConfiguration)
   616 			{
   617 			subbandsSupportedByHeadset = iForcedRemoteSBCCodecConfiguration->Subbands();
   618 			}
   619 		if (subbandsSupportedByHeadset & EEightSubbands)
   620 			{
   621 			subbands = EEightSubbands;
   622 			}
   623 		else if (subbandsSupportedByHeadset & EFourSubbands)
   624 			{
   625 			subbands = EFourSubbands;
   626 			numberOfSubbands = 4;
   627 			} 
   628 		sbcCodecConfiguration->SetSubbands(subbands);
   629 	
   630 		//--Allocation--
   631 		//although allocation support of SNR and loudness are mandatory the headset
   632 		//may have reconfigured to use a particular allocation method
   633 		//If both allocation methods are available we have to choose which one
   634 		//so we'll choose a preference order of loudness over SNR
   635 		TSBCAllocationMethodBitmask allocationMethod = ELoudness;
   636 		TSBCAllocationMethodBitmask allocationMethodsSupportedByHeadset = aCodecCaps.AllocationMethods(); 
   637 		if (iForcedRemoteSBCCodecConfiguration)
   638 			{
   639 			allocationMethodsSupportedByHeadset = iForcedRemoteSBCCodecConfiguration->AllocationMethods();
   640 			}
   641 		if (allocationMethodsSupportedByHeadset & ELoudness)
   642 			{
   643 			allocationMethod = ELoudness;
   644 			}
   645 		else if (allocationMethodsSupportedByHeadset & ESNR)
   646 			{
   647 			allocationMethod = ESNR;
   648 			}
   649 		sbcCodecConfiguration->SetAllocationMethods(allocationMethod);
   650 
   651 		//--bitpool
   652 		// The bitpool value must be in the range of 2-250 and must not exceed
   653 		// 16*numberOfSubbands*channels
   654 		// note that we don't normally play SBC directly, except for test purposes
   655 		// in order to arbitary play any SBC file extra code would be required
   656 		// to parse the SBC frame header to get the bitpool value
   657 		// since for unit testing the the SBC test file is known to have a
   658 		// bit pool value of 20, this shall be the default value
   659 		// This code could be made more more intelligent and base the 
   660 		// bitpool value around table 4.7 in the A2DP specification
   661 		TUint minBitPoolValue = KMinBitPoolValue;
   662 		TUint maxBitPoolValue = KMaxBitPoolValue; 
   663 		if (KMinBitPoolValue < aCodecCaps.MinBitpoolValue())
   664 			{
   665 			minBitPoolValue = aCodecCaps.MinBitpoolValue();
   666 			}
   667 		if (KMaxBitPoolValue > aCodecCaps.MaxBitpoolValue())
   668 			{
   669 			TUint maxAllowableBitPoolValueForCurrentConfiguration = 16*iChannels*numberOfSubbands;
   670 			maxBitPoolValue = aCodecCaps.MaxBitpoolValue();
   671 			if (maxBitPoolValue > maxAllowableBitPoolValueForCurrentConfiguration)
   672 				{
   673 				maxBitPoolValue = maxAllowableBitPoolValueForCurrentConfiguration;
   674 				}
   675 			}
   676 		sbcCodecConfiguration->SetMinBitpoolValue(minBitPoolValue);
   677 		sbcCodecConfiguration->SetMaxBitpoolValue(maxBitPoolValue);
   678 		}//if (sbcCodecConfiguration)
   679 
   680 	return sbcCodecConfiguration;
   681 	}
   682 	
   683 
   684 /**
   685 internal function to get a remote codec configuration from the capabilities
   686 Note technically speaking MPEG12 refers to MPEG 1 & MPEG 2 audio layers 1,2 and 3
   687 however since mp1 & mp2 is rarely used in practice this 
   688 will be MPEG 1 layer 3 ie mp3 in most case
   689 */
   690 TNonSBCCodecCapabilities* CA2dpAudioCodecConfiguration::GetRemoteMPEG12CodecConfiguration(const TNonSBCCodecCapabilities& aCodecCaps)
   691 	{
   692 	TNonSBCCodecCapabilities* mpeg12CodecConfiguration = new TNonSBCCodecCapabilities(EAvdtpMediaTypeAudio, EAudioCodecMPEG12Audio);
   693 	TBuf8<4>	mpeg12CodecConfigurationData;//should be 4 make 6 for bug??
   694 	if (mpeg12CodecConfiguration)
   695 		{//codecData should contain data conformant to A2DP profile
   696 		// codec specific information elements section A2DP 4.4.2
   697 		TPtrC8 codecCapsData(aCodecCaps.CodecData());
   698 		TInt8 mpegLayerSupport = codecCapsData[0] & KA2dpMPEG12LayerMask;
   699 		if (!(mpegLayerSupport & KA2dpMPEG12LayerMP3Supported))
   700 			{
   701 			//then mp3 is not supported must be mp1 or mp2 which we don't support
   702 			delete mpeg12CodecConfiguration;
   703 			mpeg12CodecConfiguration = NULL;
   704 			return mpeg12CodecConfiguration;
   705 			}
   706 		mpegLayerSupport = KA2dpMPEG12LayerMP3Supported; //mp3
   707 		//we don't bother with CRC protection so don't check
   708 		
   709 		//the MPEG12 channel support structure is identical to 
   710 		//SBC so we'll use the SBC structure
   711 		//--channels--
   712 		TSBCChannelModeBitmask channelMode = EMono;
   713 		TSBCChannelModeBitmask channelModesSupportedByHeadset = EMono;
   714 		channelModesSupportedByHeadset = codecCapsData[0] & KA2dpMPEG12AudioChannelModeMask;
   715 		if (iChannels == EMMFMono)
   716 			{
   717 			channelMode = EMono;
   718 			}
   719 		else if ((iChannels == EMMFStereo) && (iStereoSupport == EMMFInterleavedOnly))
   720 			{
   721 			channelMode = EStereo;
   722 			}
   723 		else if ((iChannels == EMMFStereo) && (iStereoSupport == EMMFJoint))
   724 			{
   725 			channelMode = EJointStereo;
   726 			}
   727 		if (!(channelMode & channelModesSupportedByHeadset))
   728 			{
   729 			//then we don't support the selected channel mode
   730 			if (channelModesSupportedByHeadset & EMono)
   731 				{
   732 				iChannels = EMMFMono;
   733 				iStereoSupport = EMMFNone;
   734 				channelMode = EMono;
   735 				}
   736 			else if (channelModesSupportedByHeadset & EJointStereo)
   737 				{
   738 				iChannels = EMMFStereo;
   739 				iStereoSupport = EMMFJoint;
   740 				channelMode = EJointStereo;
   741 				}
   742 			else if (channelModesSupportedByHeadset & EStereo)
   743 				{
   744 				iChannels = EMMFStereo;
   745 				iStereoSupport = EMMFInterleavedOnly;
   746 				channelMode = EStereo;
   747 				}
   748 			}
   749 		mpeg12CodecConfigurationData.Append(mpegLayerSupport | channelMode);
   750 	
   751 		//Media Payload Format 
   752 		//this ref implementation shall only support the media payload format
   753 		//defined in RFC2250, RFC3119 is not supported
   754 		//therefore there is no need to check this since MPF-1/RFC2250 is mandatory
   755 		
   756 		//--sampling frequency--
   757 		//the mp3 sampling frequency mask is not the same as SBC so can't use TSBCSamplingFrequencyBitmask
   758 		TMPEG12SamplingFrequencyBitmask freqs;
   759 		switch(iSampleRate)
   760 			{
   761 			case 16000:
   762 				freqs = EMPEG12_16kHz;
   763 				break;
   764 			case 22050:
   765 				freqs = EMPEG12_22050Hz;
   766 				break;
   767 			case 24000:
   768 				freqs = EMPEG12_24kHz;
   769 				break;
   770 			case 32000:
   771 				freqs = EMPEG12_32kHz;
   772 				break;
   773 			case 44100:
   774 				freqs = EMPEG12_44100Hz;
   775 				break;
   776 			case 48000:
   777 				freqs = EMPEG12_48kHz;
   778 				break;
   779 			default:
   780 				freqs = EMPEG12_16kHz;
   781 				break;
   782 			}
   783 		//check we really can support this sampling frequency
   784 		//since we may be using the default which may not be supported
   785 		//by the headset (even if the A2DP spec says it is mandatory)
   786 		TMPEG12SamplingFrequencyBitmask samplingFreqsSupportedByHeadset = codecCapsData[1] & KA2dpMPEG12SamplingFrequencyMask;
   787 		if (!(freqs & samplingFreqsSupportedByHeadset))
   788 			{//then the headset doesn't support the sampling frequency
   789 			//this could happen if iSampleRate is a default that the headset doesn't support
   790 			//note that evenif the default is a mandatory sample rate eg 44100
   791 			//we still do not make any assumptions about what is supported 
   792 			if (samplingFreqsSupportedByHeadset & EMPEG12_16kHz)
   793 				{
   794 				iSampleRate = 16000;
   795 				freqs = EMPEG12_16kHz;
   796 				}
   797 			else if (samplingFreqsSupportedByHeadset & EMPEG12_22050Hz)
   798 				{
   799 				iSampleRate = 22050;
   800 				freqs = EMPEG12_22050Hz;
   801 				}
   802 			else if (samplingFreqsSupportedByHeadset & EMPEG12_24kHz)
   803 				{
   804 				iSampleRate = 24000;
   805 				freqs = EMPEG12_24kHz;
   806 				}
   807 			else if (samplingFreqsSupportedByHeadset & EMPEG12_32kHz)
   808 				{
   809 				iSampleRate = 32000;
   810 				freqs = EMPEG12_32kHz;
   811 				}
   812 			else if (samplingFreqsSupportedByHeadset & EMPEG12_44100Hz)
   813 				{
   814 				iSampleRate = 44100;
   815 				freqs = EMPEG12_44100Hz;
   816 				}
   817 			else if (samplingFreqsSupportedByHeadset & EMPEG12_48kHz)
   818 				{
   819 				iSampleRate = 48000;
   820 				freqs = EMPEG12_48kHz;
   821 				}
   822 			//else just keep as is
   823 			}
   824 		//set frequency, MPF-1
   825 		mpeg12CodecConfigurationData.Append(freqs);
   826 		
   827 		
   828 		//The casira pod only supports bit rates up to 96kbs-1
   829 		//so check the headset supports these as well
   830 		//we'll just mask with all the lower bit rates
   831 		//all the lower bit rate support up to 96kbs-1are in octet 3
   832 		//so just make out octet 2 bit rate support
   833 		//also VBR = 0 as no VBR support
   834 		mpeg12CodecConfigurationData.Append(0);
   835 		
   836 		//all bitrates <= 96kbs-1 except free format
   837 		mpeg12CodecConfigurationData.Append(KA2dpMPEG12SupportedBitRateIndex & codecCapsData[3]);
   838 		mpeg12CodecConfiguration->SetCodecData(mpeg12CodecConfigurationData);
   839 		}
   840 	return mpeg12CodecConfiguration;
   841 	}
   842 
   843 
   844 /**
   845 Utility function get the codec capabilities used by Gavdp into the SBC codec paramerers
   846 used by the SBC codec
   847 The function uses the TSBCCodecCapabilities to generate a set of TSBCFrameParameters
   848 which can be used to configure the codec
   849 the remote codec configuration must have already been updated before calling
   850 this function
   851 
   852 @param aSBCFrameParameters  These are set to the current configuration settings
   853 */
   854 TSBCFrameParameters& CA2dpAudioCodecConfiguration::UpdateLocalSBCCodecConfiguration()
   855 	{
   856 	__ASSERT_DEBUG(iRemoteCodecConfiguration, Panic(EA2dpCodecUtilNoRemoteCodecConfig));
   857 	__ASSERT_DEBUG((iHeadsetCodecDataType == KMMFFourCCCodeSBC) && (iRemoteCodecConfiguration->MediaCodecType() == EAudioCodecSBC), Panic(EA2dpCodecUtilUnexpectedDataType));
   858 	TSBCCodecCapabilities* remoteSBCCodecConfiguration =  static_cast<TSBCCodecCapabilities*>(iRemoteCodecConfiguration);
   859 		
   860 	//note that for sampling frequency and channels the capabilites
   861 	//have already been checked in SetSampleRate and SetChannels
   862 	//and once set we don't allow these to be reconfigured
   863 	//so no need to check these again with the codecCaps
   864 	//if set the iSampleRate should always be in agreement with 
   865 	//the settings on the remote codec
   866 	TSBCFrameParameters::TSamplingFrequency SBCSamplingFrequency;
   867 	switch(iSampleRate)
   868 		{
   869 		case 32000:
   870 			SBCSamplingFrequency = TSBCFrameParameters::E32000Hz;
   871 			break;
   872 		case 44100:
   873 			SBCSamplingFrequency = TSBCFrameParameters::E44100Hz;
   874 			break;
   875 		case 48000:
   876 			SBCSamplingFrequency = TSBCFrameParameters::E48000Hz;
   877 			break;
   878 		default://[TODO] change default to 44100 when hardware 
   879 		//(ie BT support H2 or higher bandwidth support on Casira) supports it
   880 			SBCSamplingFrequency = TSBCFrameParameters::E16000Hz;
   881 			break;
   882 		}
   883 
   884 	iLocalSBCCodecConfiguration.SetSamplingFrequency(SBCSamplingFrequency);
   885 	
   886 	//although a block length of 4,8,12,16 are mandatory the headset
   887 	//may have reconfigured to use a particular block length
   888 	//If all block lengths are available we have to choose which one
   889 	//For now we'll choose a preference order of 12,16,8,4
   890 	//although there may be a more intelligent way of doing this
   891 	//based on the other parameters.
   892 	switch(remoteSBCCodecConfiguration->BlockLengths())
   893 		{
   894 		case EBlockLenTwelve:
   895 			iLocalSBCCodecConfiguration.SetBlockLength(TSBCFrameParameters::E12Blocks);
   896 			break;
   897 		case EBlockLenSixteen:
   898 			iLocalSBCCodecConfiguration.SetBlockLength(TSBCFrameParameters::E16Blocks);
   899 			break;
   900 		case EBlockLenEight:
   901 			iLocalSBCCodecConfiguration.SetBlockLength(TSBCFrameParameters::E8Blocks);
   902 			break;
   903 		case EBlockLenFour:
   904 			iLocalSBCCodecConfiguration.SetBlockLength(TSBCFrameParameters::E4Blocks);
   905 			break;
   906 		default:
   907 			Panic(EA2dpCodecUtilUnexpectedConfiguration);
   908 			break;
   909 		}
   910 	
   911 	
   912 	//channel mode
   913 	//although the number of channels can't be changed on the fly
   914 	//switching between stereo and joint stereo is supported
   915 	//note different namespaces for EStereo & EJointStereo !
   916 	TSBCFrameParameters::TChannelMode channelMode = TSBCFrameParameters::EMono;//default
   917 	if (iChannels == EMMFStereo)
   918 		{
   919 		if (iStereoSupport & EMMFJoint)
   920 			{
   921 			channelMode = TSBCFrameParameters::EJointStereo;
   922 			}
   923 		else if (iStereoSupport & EMMFInterleavedOnly)
   924 			{
   925 			channelMode = TSBCFrameParameters::EStereo;
   926 			}
   927 		else
   928 			{
   929 			Panic(EA2dpCodecUtilUnexpectedConfiguration);
   930 			}
   931 		}
   932 
   933 	iLocalSBCCodecConfiguration.SetChannelMode(channelMode);
   934 	
   935 	//Allocation
   936 	//although allocation support of SNR and loudness are mandatory the headset
   937 	//may have reconfigured to use a particular allocation method
   938 	//If both allocation methods are available we have to choose which one
   939 	//For now we'll choose a preference order of loudness followed by SNR
   940 
   941 	switch(remoteSBCCodecConfiguration->AllocationMethods())
   942 		{
   943 		case ELoudness:
   944 			iLocalSBCCodecConfiguration.SetAllocationMethod(TSBCFrameParameters::ELoudness);
   945 			break;
   946 		case ESNR:
   947 			iLocalSBCCodecConfiguration.SetAllocationMethod(TSBCFrameParameters::ESNR);
   948 			break;
   949 		default:
   950 			Panic(EA2dpCodecUtilUnexpectedConfiguration);
   951 			break;
   952 		}
   953 	
   954 	
   955 	//Subbands currently have a preference of four over 8, but change to 8 later
   956 	//when hardware is available to support higher bandwidth
   957 	switch(remoteSBCCodecConfiguration->Subbands())
   958 		{
   959 		case EFourSubbands:
   960 			iLocalSBCCodecConfiguration.SetSubbands(TSBCFrameParameters::E4Subbands);
   961 			break;
   962 		case EEightSubbands:
   963 			iLocalSBCCodecConfiguration.SetSubbands(TSBCFrameParameters::E8Subbands);
   964 			break;
   965 		default:
   966 			Panic(EA2dpCodecUtilUnexpectedConfiguration);
   967 			break;
   968 		}
   969 
   970 	// note that we don't normally play SBC directly, except for test purposes
   971 	// in order to arbitary play any SBC file extra code would be required
   972 	// to parse the SBC frame header to get the bitpool value
   973 	// since for unit testing the the SBC test file is known to have a
   974 	// bit pool value of 20, this shall be the default value
   975 	// This code could be made more more intelligent and base the 
   976 	// bitpool value around table 4.7 in the A2DP specification
   977 	TUint bitPoolValue = KDefaultBitPoolValue; //default is 20
   978 	if (KDefaultBitPoolValue < remoteSBCCodecConfiguration->MinBitpoolValue())
   979 		{
   980 		bitPoolValue = remoteSBCCodecConfiguration->MinBitpoolValue();
   981 		}
   982 	else if (KDefaultBitPoolValue > remoteSBCCodecConfiguration->MaxBitpoolValue())
   983 		{
   984 		bitPoolValue = remoteSBCCodecConfiguration->MaxBitpoolValue();
   985 		}
   986 	iLocalSBCCodecConfiguration.SetBitpool(bitPoolValue); 
   987 	
   988 	return iLocalSBCCodecConfiguration;
   989 	}	
   990 
   991 	
   992 /**
   993 Internal function to calculate the SBC buffer length required from the SBC frame parameters
   994 using the given pcm16 buffer length
   995 */
   996 TUint CA2dpAudioCodecConfiguration::CalculateSBCBufferLength(TUint aPCM16BufferLength) const
   997 	{
   998 	//ASSERT data type = SBC
   999 	
  1000 	//first calculate the number of PCM16 samples in one SBC frame
  1001 	TUint numberOfSamplesPerSBCFrame = iLocalSBCCodecConfiguration.BlockLength()*iLocalSBCCodecConfiguration.Subbands();
  1002 	
  1003 	//calculate the number of bytes in one sample
  1004 	TUint numberOfPCM16BytesPerSample = 2*iLocalSBCCodecConfiguration.Channels();
  1005 	
  1006 	TUint numberOfPCM16BytesPerSBCFrame = numberOfSamplesPerSBCFrame*numberOfPCM16BytesPerSample;
  1007 	
  1008 	TUint numberOfFrames = aPCM16BufferLength/numberOfPCM16BytesPerSBCFrame;
  1009 	
  1010 	TUint lengthOfSBCFrame = iLocalSBCCodecConfiguration.CalcFrameLength();
  1011 	
  1012 	return numberOfFrames*lengthOfSBCFrame;
  1013 	}
  1014 	
  1015 
  1016 /**
  1017 Test function to force the remote SBC codec configuration to that set in aRemoteCodecConfiguration
  1018 This function is just used for test purposes to set the SBC settings for
  1019 playing SBC data direct to the a2dpBTHeadsetAudioIf ie when the Data type is 
  1020 set to SBC
  1021 It is up to the user to ensure that the headset supports the configuration
  1022 since this will bypass the normal capability check
  1023 */	
  1024 void CA2dpAudioCodecConfiguration::TEST_ForceRemoteSBCCodecConfiguration(const TSBCCodecCapabilities& aRemoteCodecConfiguration)
  1025 	{
  1026 	iForcedRemoteSBCCodecConfiguration = const_cast<TSBCCodecCapabilities*>(&aRemoteCodecConfiguration);
  1027 	}
  1028 
  1029 	
  1030 
  1031 
  1032 CA2dpCodecFrameHeaderParser* CA2dpCodecFrameHeaderParser::NewL(const TFourCC& aCodecDataType, const TDesC8& aHeader)
  1033 	{
  1034 	CA2dpCodecFrameHeaderParser* self = new (ELeave) CA2dpCodecFrameHeaderParser();
  1035 	CleanupStack::PushL(self);
  1036 	self->ConstructL(aCodecDataType, aHeader);
  1037 	CleanupStack::Pop(self);
  1038 	return self;
  1039 	}
  1040 
  1041 
  1042 CA2dpCodecFrameHeaderParser::CA2dpCodecFrameHeaderParser()
  1043 	{
  1044 	
  1045 	}
  1046 
  1047 
  1048 CA2dpCodecFrameHeaderParser::~CA2dpCodecFrameHeaderParser()
  1049 	{
  1050 	
  1051 	}	
  1052 
  1053 
  1054 /**
  1055 Only used for playing SBC test files
  1056 */
  1057 void CA2dpCodecFrameHeaderParser::ParseSBCHeaderL(const TDesC8& aHeader)
  1058 	{
  1059 	if (aHeader[0] != KSbcFrameHeaderSyncWord)
  1060 		{
  1061 		User::Leave(KErrCorrupt); //not a valid sbc frame
  1062 		}
  1063 	
  1064 	TUint samplingFrequency = (aHeader[1] & KSbcFrameHeaderSamplingFrequencyMask)>>6;
  1065 	switch(samplingFrequency)
  1066 		{
  1067 		case TSBCFrameParameters::E16000Hz:
  1068 			iSampleRate = 16000;
  1069 			break;
  1070 		case TSBCFrameParameters::E32000Hz:
  1071 			iSampleRate = 32000;
  1072 			break;
  1073 		case TSBCFrameParameters::E44100Hz:
  1074 			iSampleRate = 44100;
  1075 			break;
  1076 		case TSBCFrameParameters::E48000Hz:
  1077 			iSampleRate = 48000;
  1078 			break;
  1079 		default:
  1080 			User::Leave(KErrCorrupt);//not a valid header
  1081 			break;
  1082 		}
  1083 		
  1084 	TUint8 blocks = (aHeader[1] & KSbcFrameHeaderBlocksMask)>>4;
  1085 	switch(blocks)
  1086 		{
  1087 		case TSBCFrameParameters::E4Blocks:
  1088 			blocks = 4;
  1089 			break;
  1090 		case TSBCFrameParameters::E8Blocks:
  1091 			blocks = 8;
  1092 			break;
  1093 		case TSBCFrameParameters::E12Blocks:
  1094 			blocks = 12;
  1095 			break;
  1096 		case TSBCFrameParameters::E16Blocks:
  1097 			blocks = 16;
  1098 			break;
  1099 		default:
  1100 			User::Leave(KErrCorrupt);//not a valid header
  1101 			break;
  1102 		}
  1103 	TUint8 channelMode = (aHeader[1] & KSbcFrameHeaderChannelModeMask)>>2;
  1104 	TUint8 channels = 1;
  1105 	
  1106 	if (channelMode != TSBCFrameParameters::EMono)
  1107 		{
  1108 		channels = 2;
  1109 		}
  1110 	
  1111 	TUint8 subbands = 4;
  1112 	if (aHeader[1] & KSbcFrameHeaderSubbandsMask)
  1113 		{
  1114 		subbands = 8;
  1115 		}
  1116 		
  1117 	TUint8 bitpool = aHeader[2];
  1118 	
  1119 	TUint temp = 0;
  1120 	switch (channelMode)
  1121 		{
  1122 		case TSBCFrameParameters::EMono:
  1123 			temp = blocks * bitpool; // blocks * bitpool
  1124 			break;	
  1125 		case TSBCFrameParameters::EDualChannel:
  1126 			temp = (blocks * bitpool) << 1; // blocks * bitpool * 2
  1127 			break;	
  1128 		case TSBCFrameParameters::EStereo:
  1129 			temp = blocks * bitpool; // blocks * bitpool
  1130 			break;	
  1131 		case TSBCFrameParameters::EJointStereo:
  1132 			temp = subbands + blocks * bitpool; // subbands + blocks * bitpool
  1133 			break;
  1134 		}
  1135 		
  1136 	iFrameLength = 4 + ( (subbands * channels) >> 1) + (temp >> 3);
  1137 	if (temp & 0x7)
  1138 		{
  1139 		iFrameLength++;
  1140 		}
  1141 		
  1142 	iBitRate = (8*iFrameLength*iSampleRate)/(subbands*blocks);
  1143 	}
  1144 
  1145 
  1146 void CA2dpCodecFrameHeaderParser::ParseMPEG12HeaderL(const TDesC8& aHeader)
  1147 	{
  1148 	if (aHeader[0] != KMPEGAudioFrameHeaderSyncWord )
  1149 		{
  1150 		User::Leave(KErrCorrupt); //not a valid MPEG audio frame
  1151 		}
  1152 	
  1153 	//check it's really mp3 as opposed to mp1 or mp2
  1154 	if ((aHeader[1] & KMp3AudioFrameHeaderIdMask) != KMp3AudioFrameHeaderId)
  1155 		{
  1156 		User::Leave(KErrNotSupported); //either corrupt or mp1/mp2
  1157 		}
  1158 	
  1159 	TUint8 sampleRateIndex = (aHeader[2] & KMp3FrameHeaderSamplingFrequencyMask)>>2;
  1160 	switch(sampleRateIndex)
  1161 		{
  1162 		case 0x00:
  1163 			iSampleRate = 44100;
  1164 			break;
  1165 		case 0x01:
  1166 			iSampleRate = 48000;
  1167 			break;
  1168 		case 0x02:
  1169 			iSampleRate = 32000;
  1170 			break;
  1171 		default:
  1172 			User::Leave(KErrCorrupt); //invalid mp3 header?
  1173 			break;
  1174 		}
  1175 	TUint8 bitRateIndex = (aHeader[2] & KMp3FrameHeaderBitRateIndexMask)>>4;
  1176 	switch(bitRateIndex)
  1177 		{
  1178 		case EMp3BitRateIndex32000:
  1179 			iBitRate = 32000;
  1180 			break;
  1181 		case EMp3BitRateIndex40000:
  1182 			iBitRate = 40000;
  1183 			break;
  1184 		case EMp3BitRateIndex48000:
  1185 			iBitRate = 48000;
  1186 			break;
  1187 		case EMp3BitRateIndex56000:
  1188 			iBitRate = 56000;
  1189 			break;
  1190 		case EMp3BitRateIndex64000:
  1191 			iBitRate = 64000;
  1192 			break;
  1193 		case EMp3BitRateIndex80000:
  1194 			iBitRate = 80000;
  1195 			break;
  1196 		case EMp3BitRateIndex96000:
  1197 			iBitRate = 96000;
  1198 			break;
  1199 		default:
  1200 			User::Leave(KErrNotSupported);//don't support more than 96kbs-1
  1201 			break;
  1202 		}
  1203 	
  1204 	//this code should really be made more clever to take allowance for any padding
  1205 	//and use a frame length such that if padding is used then take the lowest
  1206 	//common multiple of frames tht gives a common frame length eg if the frames
  1207 	//alternate between 100 and 101 bytes due to an extra padding byte everyother
  1208 	//frame then set the frame length to 201;	
  1209 	TUint bitRateX144 = iBitRate*144;
  1210 	iFrameLength = bitRateX144/iSampleRate;
  1211 	}
  1212 
  1213 	
  1214 /**
  1215 static
  1216 */	
  1217 void CA2dpCodecFrameHeaderParser::ConstructL(const TFourCC& aCodecDataType, const TDesC8& aHeader)
  1218 	{
  1219 	switch(const_cast<TFourCC&>(aCodecDataType).FourCC())
  1220 		{
  1221 		case KMMFFourCCCodeSBC:
  1222 			ParseSBCHeaderL(aHeader);
  1223 			break;
  1224 		case KMMFFourCCCodeMP3:
  1225 			ParseMPEG12HeaderL(aHeader);
  1226 			break;
  1227 		case KMMFFourCCCodeAAC:
  1228 			User::Leave(KErrNotSupported);
  1229 			break;
  1230 		case KMMFFourCCCodeATRAC3:
  1231 			User::Leave(KErrNotSupported);
  1232 			break;
  1233 		default:
  1234 			User::Leave(KErrNotSupported);
  1235 			break;
  1236 		}
  1237 	}	
  1238