devsound/sounddevbt/src/A2dpBlueTooth/headsetaudioif/A2dpCodecUtilities.cpp
changeset 0 40261b775718
equal deleted inserted replaced
-1:000000000000 0:40261b775718
       
     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