os/mm/devsound/sounddevbt/src/Plugin/Codec/SBCEncoder/BtSBCEncoder.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 "mmfSBCCodecImplementationUIDs.hrh" // KMmfUidSBCConfigure
    17 
    18 #include "BtSBCEncoder.h"
    19 #include "BtSBCConst.h"
    20 #include "BtSBCFrameParameters.h"
    21 #include "../../MmfBtFileDependencyUtil.h"
    22 
    23 /**
    24 The sbc configuration UID, used to identify configuration type, 
    25 have to use this to configure any sbc codec.
    26 */
    27 const TUid   KSBCConfigTypeUid = { KMmfUidSBCConfigure };
    28 
    29 /**
    30 SBC CRC shift register initial value for SBC CRC calculation
    31 */
    32 const TUint8 KSbcCRCShiftRegisterInit 	 = 0x0f;
    33 /**
    34 SBC CRC XOR mask, derived from polynomial G(X) = X^8 + X^4 + X^3 + X^2 + 1
    35 */
    36 const TUint8 KSbcCRCShiftRegisterXorMask = 0x1d;
    37 
    38 #ifdef _DEBUG
    39 
    40 enum 
    41 	{
    42 	ESbcBitstreamPosErr,
    43 	ESbcSampleOverflow
    44 	};
    45 	
    46 _LIT(KSBCEncoderPanicCategory, "CSBCEncoder");
    47 
    48 static inline void Panic(TInt aError)
    49 	{
    50 	User::Panic(KSBCEncoderPanicCategory, aError);
    51 	}
    52 	
    53 #endif
    54 	
    55 /* ========================= class CBitStreamParser ========================= */
    56 
    57 /**
    58 class CBitStreamParser constructor
    59 @internalComponent
    60 @param aBitStream
    61 The bit stream buffer to be parsed
    62 */
    63 CBitStreamParser::CBitStreamParser(TDes8& aBitStream) : iBitStream(aBitStream),	
    64 	iByteOffset(0), iBitOffset(0)
    65 	{
    66 	iPtr = const_cast<TUint8*>(aBitStream.Ptr() );
    67 	}
    68 	
    69 /**
    70 class CBitStreamParser destructor
    71 @internalComponent
    72 */
    73 CBitStreamParser::~CBitStreamParser()
    74 	{
    75 	}
    76 	
    77 /**
    78 class CBitStreamParser second phase constructor
    79 @internalComponent
    80 */
    81 void CBitStreamParser::ConstructL()
    82 	{
    83 	}
    84 
    85 /**
    86 This function creates a new CBitStreamParser object and push it into CleanupStack.
    87 @internalComponent
    88 @param aBitStream
    89 The bit stream buffer to be parsed
    90 @return pointer to the new CBitStreamParser object
    91 @leave if out of memory
    92 */
    93 CBitStreamParser* CBitStreamParser::NewLC(TDes8& aBitStream)
    94 	{
    95 	CBitStreamParser* self = new(ELeave) CBitStreamParser(aBitStream);
    96 	CleanupStack::PushL(self);
    97 	self->ConstructL();
    98 	return self;
    99 	}
   100 	
   101 /**
   102 This function reset the internal bit position of CBitStreamParser
   103 @internalComponent
   104 */
   105 void CBitStreamParser::Reset()
   106 	{
   107 	iPtr = const_cast<TUint8*>(iBitStream.Ptr() );
   108 	iByteOffset = 0;
   109 	iBitOffset = 0;
   110 	}
   111 	
   112 /**
   113 This function reads a number of bits from bit stream buffer at current bit position
   114 and change the bit position to then end of the last bit read.
   115 @internalComponent
   116 @param aBitsToRead
   117 Number of bits to read, at most 8 bits
   118 @return the bits value in byte
   119 @panic if bit position is outside of the stream buffer
   120 */
   121 TUint8 CBitStreamParser::ReadBits(TInt aBitsToRead)
   122 	{
   123 	TUint8 result = 0;
   124 	if (aBitsToRead >= 8 - iBitOffset)
   125 		{
   126 		__ASSERT_DEBUG(iByteOffset < static_cast<TUint>(iBitStream.MaxLength() ), Panic(ESbcBitstreamPosErr) );
   127 		// extra code to handle exception for URel version
   128 		if (iByteOffset >= static_cast<TUint>(iBitStream.MaxLength() ) )
   129 			{
   130 			return 0;
   131 			}
   132 			
   133 		aBitsToRead -= (8 - iBitOffset);
   134 		result = static_cast<TUint8>( (*iPtr & (0xff >> iBitOffset) ) << aBitsToRead);
   135 		
   136 		iPtr++;
   137 		iByteOffset++;
   138 		iBitOffset = 0;
   139 		}
   140 	if (aBitsToRead > 0)
   141 		{
   142 		__ASSERT_DEBUG(iByteOffset < static_cast<TUint>(iBitStream.MaxLength() ), Panic(ESbcBitstreamPosErr) );
   143 		// extra code to handle exception for URel version
   144 		if (iByteOffset >= static_cast<TUint>(iBitStream.MaxLength() ) )
   145 			{
   146 			return 0;
   147 			}
   148 			
   149 		result |= static_cast<TUint8>( (*iPtr & (0xff >> iBitOffset) ) >> (8 - iBitOffset - aBitsToRead) );
   150 		iBitOffset = static_cast<TUint8>(iBitOffset + aBitsToRead);
   151 		}
   152 	return result;
   153 	}
   154 	
   155 /**
   156 This function writes a number of bits to the bit stream buffer at current bit position
   157 and change the bit position to then end of the last bit written.
   158 @internalComponent
   159 @param aBitsToWrite
   160 Number of bits to write, at most 8 bits
   161 @param aBitsValue
   162 The bits value to write in byte
   163 @panic if bit position is outside of the stream buffer
   164 */
   165 void CBitStreamParser::WriteBits(TInt aBitsToWrite, TUint8 aBitsValue)
   166 	{
   167 	if (aBitsToWrite >= 8 - iBitOffset)
   168 		{
   169 		__ASSERT_DEBUG(iByteOffset < static_cast<TUint>(iBitStream.MaxLength() ), Panic(ESbcBitstreamPosErr) );
   170 		// extra code to handle exception for URel version
   171 		if (iByteOffset >= static_cast<TUint>(iBitStream.MaxLength() ) )
   172 			{
   173 			return;
   174 			}
   175 			
   176 		aBitsToWrite -= (8 - iBitOffset);
   177 		*iPtr &= ~(0xff >> iBitOffset); // clear bits
   178 		*iPtr |= (aBitsValue >> aBitsToWrite) & (0xff >> iBitOffset); // set bits
   179 		
   180 		iPtr++;
   181 		iByteOffset++;
   182 		iBitOffset = 0;
   183 		}
   184 	if (aBitsToWrite > 0)
   185 		{
   186 		__ASSERT_DEBUG(iByteOffset < static_cast<TUint>(iBitStream.MaxLength() ), Panic(ESbcBitstreamPosErr) );
   187 		// extra code to handle exception for URel version
   188 		if (iByteOffset >= static_cast<TUint>(iBitStream.MaxLength() ) )
   189 			{
   190 			return;
   191 			}
   192 			
   193 		*iPtr &= (0xff << (8 - iBitOffset) ) | (0xff >> (iBitOffset + aBitsToWrite) ); // clear bits
   194 		*iPtr |= (aBitsValue << (8 - iBitOffset - aBitsToWrite) ) & (0xff >> iBitOffset); // set bits
   195 		iBitOffset = static_cast<TUint8>(iBitOffset + aBitsToWrite);
   196 		}
   197 	}
   198 	
   199 /**
   200 This function reads 8 bits from bit stream buffer at current bit position
   201 and change the bit position to then end of the last bit read.
   202 @internalComponent
   203 @return the bits value in byte
   204 */
   205 TUint8 CBitStreamParser::ReadByte()
   206 	{
   207 	return ReadBits(8);
   208 	}
   209 	
   210 /**
   211 This function writes 8 bits to the bit stream buffer at current bit position
   212 and change the bit position to then end of the last bit written.
   213 @internalComponent
   214 @param aByteValue
   215 The byte value to write
   216 */
   217 void CBitStreamParser::WriteByte(TUint8 aByteValue)
   218 	{
   219 	WriteBits(8, aByteValue);
   220 	}
   221 	
   222 /**
   223 This function sets the bit position to a specific position.
   224 @internalComponent
   225 @param aByteOffset
   226 New byte position to set
   227 @param aBitOffset
   228 New bit position to set
   229 @panic if bit position is outside of the stream buffer
   230 */
   231 void CBitStreamParser::SetPosition(TUint aByteOffset, TUint8 aBitOffset)
   232 	{
   233 	while (aBitOffset >= 8)
   234 		{
   235 		aBitOffset -= 8;
   236 		iByteOffset++;
   237 		}
   238 	
   239 	__ASSERT_DEBUG(iByteOffset < static_cast<TUint>(iBitStream.MaxLength() ), Panic(ESbcBitstreamPosErr) );
   240 	// extra code to handle exception for URel version
   241 	if (iByteOffset >= static_cast<TUint>(iBitStream.MaxLength() ) )
   242 		{
   243 		aBitOffset = 0;
   244 		iByteOffset = iBitStream.MaxLength();
   245 		}
   246 		
   247 	iPtr = const_cast<TUint8*>(iBitStream.Ptr() ) + aByteOffset;
   248 	iByteOffset = aByteOffset;
   249 	iBitOffset = aBitOffset;
   250 	}
   251 	
   252 /**
   253 This function gets the bit position.
   254 @internalComponent
   255 @param aByteOffset
   256 Read byte position
   257 @param aBitOffset
   258 Read bit position
   259 */
   260 void CBitStreamParser::Position(TUint& aByteOffset, TUint8& aBitOffset) const
   261 	{
   262 	aByteOffset = iByteOffset;
   263 	aBitOffset = iBitOffset;
   264 	}
   265 	
   266 /* ========================= class CSbcCRCCalculator ========================= */
   267 
   268 /**
   269 Constructor
   270 @internalComponent
   271 */
   272 CSbcCRCCalculator::CSbcCRCCalculator() : iShiftRegister(KSbcCRCShiftRegisterInit)
   273 	{
   274 	}
   275 	
   276 /**
   277 This function resets the shift register value to intial SBC CRC value
   278 @internalComponent
   279 */
   280 void CSbcCRCCalculator::Reset()
   281 	{
   282 	iShiftRegister = KSbcCRCShiftRegisterInit;
   283 	}
   284 	
   285 /**
   286 This function inputs one bit into the shift register
   287 @internalComponent
   288 @param aBit
   289 The lowest bit contains the bit to input. 
   290 */
   291 void CSbcCRCCalculator::InputBit(TUint8 aBit)
   292 	{
   293 	TUint8 inputBit = static_cast<TUint8>( (iShiftRegister >> 7) ^ (aBit & 0x1) );
   294 	iShiftRegister <<= 1;
   295 	
   296 	if (inputBit)
   297 		{
   298 		iShiftRegister ^= KSbcCRCShiftRegisterXorMask;
   299 		}
   300 	}
   301 	
   302 /**
   303 This function inputs a number of bits into the shift register
   304 @internalComponent
   305 @param aBits
   306 The number of bits to input, at most 8 bits.
   307 @param aValue
   308 The input bits value. 
   309 */
   310 void CSbcCRCCalculator::InputBits(TUint8 aBits, TUint8 aValue)
   311 	{
   312 	for (TInt bit = aBits - 1; bit >= 0; bit--)
   313 		{
   314 		InputBit(static_cast<TUint8>(aValue >> bit) );
   315 		}
   316 	}
   317 	
   318 /**
   319 This function inputs 8 bits into the shift register.
   320 @internalComponent
   321 @param aValue
   322 The input byte value. 
   323 */
   324 void CSbcCRCCalculator::InputByte(TUint8 aByte)
   325 	{
   326 	InputBit(static_cast<TUint8>(aByte >> 7) );
   327 	InputBit(static_cast<TUint8>(aByte >> 6) );
   328 	InputBit(static_cast<TUint8>(aByte >> 5) );
   329 	InputBit(static_cast<TUint8>(aByte >> 4) );
   330 	InputBit(static_cast<TUint8>(aByte >> 3) );
   331 	InputBit(static_cast<TUint8>(aByte >> 2) );
   332 	InputBit(static_cast<TUint8>(aByte >> 1) );
   333 	InputBit(aByte);
   334 	}
   335 	
   336 /**
   337 This function gets the shift register value.
   338 @internalComponent
   339 @return the shift register value. 
   340 */
   341 TUint8 CSbcCRCCalculator::ShiftRegister()
   342 	{
   343 	return iShiftRegister;
   344 	}
   345 
   346 /* ============================ class CSBCEncoder ============================ */
   347 
   348 /**
   349 Constructor.
   350 @internalComponent
   351 */
   352 CSBCEncoder::CSBCEncoder()
   353 	{
   354 	}
   355 	
   356 /**
   357 Destructor.
   358 @internalComponent
   359 */
   360 CSBCEncoder::~CSBCEncoder()
   361 	{
   362 	delete iSbcFrameEncoder;
   363 	delete iPcmSampleCach; // this is used to cache any remaining samples less than on frame
   364 	}
   365 	
   366 /**
   367 Second phase constructor.
   368 @internalComponent
   369 @param aInitParams
   370 Initial parameters for creating this object, not in use for the moment
   371 @leave never
   372 */
   373 void CSBCEncoder::ConstructL(TAny* /*aInitParams*/)
   374 	{
   375 	}
   376 
   377 /**
   378 This function resets any existing audio samples from the cach.
   379 @internalComponent
   380 @leave never
   381 */
   382 void CSBCEncoder::ResetL()
   383 	{
   384 	if (iPcmSampleCach)
   385 		{
   386 		iPcmSampleCach->Des().Zero();
   387 		}
   388 	}
   389 
   390 /**
   391 This function creates a new CSBCEncoder object.
   392 @internalComponent
   393 @param aInitParams
   394 Initial parameters for creating this object, not in use for the moment
   395 @leave if out of memory
   396 */
   397 CMMFCodec* CSBCEncoder::NewL(TAny* aInitParams)
   398 	{
   399 	CSBCEncoder* self = new(ELeave) CSBCEncoder();
   400 	CleanupStack::PushL(self);
   401 	self->ConstructL(aInitParams);
   402 	CleanupStack::Pop();
   403 	return self;
   404 	}
   405 	
   406 /**
   407 This function is used for configuring the CSBCEncoder object. Should be called before encode
   408 @internalComponent
   409 @param aConfigType
   410 Configuration UID, has to be set to KSBCConfigTypeUid
   411 @param aConfigData
   412 A package buffer which contains all the settings
   413 @leave KErrNotSupported if configuration UID does't match or parameters setting is invalid.
   414 */
   415 void CSBCEncoder::ConfigureL(TUid aConfigType, const TDesC8& aConfigData)
   416 	{
   417 	if (aConfigType != KSBCConfigTypeUid)
   418 		{
   419 		User::Leave(KErrNotSupported);
   420 		}
   421 		
   422 	const TSBCFrameParameters& param = 
   423 		static_cast<const TPckgBuf<TSBCFrameParameters>&>(aConfigData)();
   424 	
   425 	if (param.Validate() != 0)
   426 		{
   427 		User::Leave(KErrArgument);
   428 		}
   429 	
   430 	iParameters = param;
   431 	
   432 	if (iPcmSampleCach)
   433 		{
   434 		delete iPcmSampleCach;
   435 		iPcmSampleCach = NULL;
   436 		}
   437 
   438 	if (iSbcFrameEncoder)
   439 		{
   440 		// must call this whenever ConfigureL() is called to make sure CSBCFrameEncoder
   441 		// uses the new configuration, as we can change the configuration without creating 
   442 		// a new CSBCFrameEncoder object
   443 		iSbcFrameEncoder->Configure(iParameters); 
   444 		}
   445 
   446 	iSbcFrameLength = iParameters.CalcFrameLength();
   447 	iPcmFrameSize = sizeof(TInt16) * param.BlockLength() * param.Subbands() * param.Channels();
   448 	}
   449 
   450 /**
   451 This function encodes sbc audio stream with PCM16 audio source samples, and write processed 
   452 result to destination buffer. It also caches any less than one frame remaining audio samples.
   453 @internalComponent
   454 @param aSrc
   455 Source buffer contains the PCM16 audio source samples
   456 @param aDst
   457 Destination buffer to contain the encoded sbc audio stream
   458 @return processed result
   459 @leave 
   460 	KErrAbort if configuration is invalid, 
   461 	KErrArgument if destination buffer size is smaller than one frame length,
   462 	KErrCorrupt if output bytes is not the same as frame length or 
   463 				if we still have enough src and dst but the process stoped, 
   464 	Or other errors e.g. out of memory error.
   465 */
   466 TCodecProcessResult CSBCEncoder::ProcessL(const CMMFBuffer& aSrc, CMMFBuffer& aDst)
   467 	{
   468 	// check if ConfigureL gets called already
   469 	if (iParameters.Validate() != 0)
   470 		{
   471 		User::Leave(KErrAbort);
   472 		}
   473 	
   474 	// check if dst big enough to hold at least one frame
   475 	CMMFDataBuffer* dst = static_cast<CMMFDataBuffer*>(&aDst);
   476 	const TUint dstMaxLen = dst->Data().MaxLength();
   477 	
   478 	if (dstMaxLen < iSbcFrameLength)
   479 		{
   480 		User::Leave(KErrArgument);
   481 		}
   482 
   483 	// process data
   484 	const CMMFDataBuffer* src = static_cast<const CMMFDataBuffer*>(&aSrc);
   485 	const TUint srcLen = src->Data().Length();
   486 	TUint srcPos = src->Position();
   487 	TUint dstPos = dst->Position();
   488 	
   489 	const TUint8* srcPtr = src->Data().Ptr();
   490 	TUint8* dstPtr = const_cast<TUint8*>(dst->Data().Ptr() );
   491 	TUint cachedSize = CachedSampleSize();
   492 	
   493 	while (cachedSize + srcLen - srcPos >= iPcmFrameSize && dstMaxLen - dstPos >= iSbcFrameLength)
   494 		{
   495 		TPtrC8 srcDes(srcPtr + srcPos, iPcmFrameSize);
   496 		TPtr8  dstDes(dstPtr + dstPos, iSbcFrameLength);
   497 		
   498 		srcPos += EncodeFrameL(srcDes, dstDes);
   499 		dstPos += iSbcFrameLength;
   500 		cachedSize = 0;
   501 		}
   502 	
   503 	// check result
   504 	TCodecProcessResult result;
   505 	result.iStatus = TCodecProcessResult::EProcessComplete;
   506 	
   507 	if (dstMaxLen - dstPos >= iSbcFrameLength) // still enough dst buffer
   508 		{
   509 		result.iStatus = TCodecProcessResult::EDstNotFilled;
   510 		}
   511 	
   512 	// cach remaining src
   513 	if (CachedSampleSize() + srcLen - srcPos >= iPcmFrameSize) // still enough src
   514 		{
   515 		if (result.iStatus == TCodecProcessResult::EDstNotFilled)
   516 			{
   517 			User::Leave(KErrCorrupt);
   518 			}
   519 		else
   520 			{
   521 			result.iStatus = TCodecProcessResult::EProcessIncomplete;
   522 			}
   523 		}
   524 	else if (srcLen - srcPos > 1) // remaining src less than one frame, cach it
   525 		{
   526 		srcPos += CachePcmSamplesL(*src, srcPos);
   527 		}
   528 	
   529 	// set new position for dst
   530 	dst->Data().SetLength(dstPos);
   531 	
   532 	// return result
   533 	result.iSrcBytesProcessed = srcPos - src->Position();
   534 	result.iDstBytesAdded = dstPos - dst->Position();
   535 	return result;
   536 	}
   537 
   538 /**
   539 This function encodes one SBC frame with PCM16 audio source samples, and write processed 
   540 result to destination buffer.
   541 @internalComponent
   542 @param aSrc
   543 Source buffer contains the PCM16 audio source samples
   544 @param aDst
   545 Destination buffer to contain the encoded sbc audio stream
   546 @return the number of bytes the source has been processed
   547 @leave if out of memory.
   548 */
   549 TUint CSBCEncoder::EncodeFrameL(const TDesC8& aSrc, TDes8& aDst)
   550 	{
   551 	if (!iSbcFrameEncoder)
   552 		{
   553 		iSbcFrameEncoder = CSBCFrameEncoder::NewL();
   554 		iSbcFrameEncoder->Configure(iParameters);
   555 		}
   556 	
   557 	if (CachedSampleSize() > 0)
   558 		{ // encode one frame with cached samples and src
   559 		TUint appendBytes = iPcmFrameSize - CachedSampleSize();
   560 		// append src to cach to make up one frame
   561 		iPcmSampleCach->Des().Append(aSrc.Ptr(), appendBytes);
   562 		// encode cach
   563 		iSbcFrameEncoder->EncodeFrameL(*iPcmSampleCach, aDst);
   564 		// empty cach
   565 		iPcmSampleCach->Des().Zero();
   566 		// return bytes src processed
   567 		return appendBytes;
   568 		}
   569 	else
   570 		{
   571 		// encode one frame with src only
   572 		iSbcFrameEncoder->EncodeFrameL(aSrc, aDst);
   573 		// return bytes src processed
   574 		return iPcmFrameSize;
   575 		}
   576 	}
   577 
   578 /**
   579 This function caches any less than one frame remaining audio samples. 
   580 @internalComponent
   581 @param aSrc
   582 Source buffer contains the PCM16 audio source samples.
   583 @param aSrcPos
   584 Position from where the samples are cached.
   585 @return the number of bytes the source has been cached
   586 @leave if out of memory.
   587 */
   588 TUint CSBCEncoder::CachePcmSamplesL(const CMMFDataBuffer& aSrc, TUint aSrcPos)
   589 	{
   590 	if (!iPcmSampleCach)
   591 		{
   592 		iPcmSampleCach = HBufC8::NewL(iPcmFrameSize);
   593 		}
   594 	
   595 	const TUint8* pSrc = aSrc.Data().Ptr() + aSrcPos;
   596 	const TUint cachSize = (aSrc.Data().Length() - aSrcPos) & 0xfffe; // take even number
   597 	
   598 	iPcmSampleCach->Des().Append(pSrc, cachSize);
   599 	
   600 	return cachSize;
   601 	}
   602 
   603 /**
   604 This function gets the size of the cach.
   605 @internalComponent
   606 @return the cached samples size
   607 */
   608 TUint CSBCEncoder::CachedSampleSize()
   609 	{
   610 	if (!iPcmSampleCach)
   611 		{
   612 		return 0;
   613 		}
   614 	return iPcmSampleCach->Des().Size();
   615 	}
   616 	
   617 /* ========================== class CSBCFrameEncoder ========================== */
   618 
   619 /**
   620 Constructor.
   621 @internalComponent
   622 */
   623 CSBCFrameEncoder::CSBCFrameEncoder()
   624 	{
   625 	}
   626 
   627 /**
   628 Destructor.
   629 @internalComponent
   630 */
   631 CSBCFrameEncoder::~CSBCFrameEncoder()
   632 	{
   633 	}
   634 	
   635 /**
   636 Second phase constructor.
   637 @internalComponent
   638 */
   639 void CSBCFrameEncoder::ConstructL()
   640 	{
   641 	}
   642 	
   643 /**
   644 This function creates a CSBCFrameEncoder object.
   645 @internalComponent
   646 @return pointer of the CSBCFrameEncoder object.
   647 */
   648 CSBCFrameEncoder* CSBCFrameEncoder::NewL()
   649 	{
   650 	CSBCFrameEncoder* self = new(ELeave) CSBCFrameEncoder();
   651 	CleanupStack::PushL(self);
   652 	self->ConstructL();
   653 	CleanupStack::Pop();
   654 	return self;
   655 	}
   656 
   657 /**
   658 This function resets the analysis filter bank, this should be called everytime 
   659 when encoding a new sbc audio stream.
   660 @internalComponent
   661 */
   662 void CSBCFrameEncoder::Reset()
   663 	{
   664 	const TUint8 numChannels = iParameters.Channels();
   665 	const TUint8 numSubbands = iParameters.Subbands();
   666 	
   667 	for (TUint8 channel = 0; channel < numChannels; channel++)
   668 		{
   669 		TInt16* analysisSamples = iAnalysisSamples[channel];
   670 		for (TUint8 subband = 0; subband < numSubbands; subband++)
   671 			{
   672 			*analysisSamples++ = 0;
   673 			}
   674 		}
   675 	}
   676 	
   677 /**
   678 This function sets the configuration for SBC Frame Encoder and resets the analysis filter bank.
   679 @internalComponent
   680 @param aParameters
   681 This contains all the parameters to set
   682 */
   683 void CSBCFrameEncoder::Configure(const TSBCFrameParameters& aParameters)
   684 	{
   685 	iParameters = aParameters;
   686 	// has to call this whenever the configuration changed, this resets the Analyse Filter Bank
   687 	Reset();
   688 	}
   689 	
   690 /**
   691 This function encodes one SBC frame with PCM16 source samples and output it to destination buffer.
   692 @internalComponent
   693 @param aSrc
   694 Source buffer contains the source samples
   695 @param aFrame
   696 Destination buffer to contain the processed sbc audio stream
   697 @leave if out of memory
   698 */
   699 void CSBCFrameEncoder::EncodeFrameL(const TDesC8& aSrc, TDes8& aFrame)
   700 	{
   701 	// encode frame
   702 	Analyse(aSrc);
   703 	CalcScaleFactors();
   704 	JoinSubbands();
   705 	CalcBitAllocation();
   706 	Quantize();
   707 	
   708 	// output frame
   709 	WriteFrameL(aFrame);
   710 	}
   711 
   712 /**
   713 This function does the analysis filtering, the analysed samples are used to encode sbc subbands.
   714 @internalComponent
   715 @param aSrc
   716 Source buffer contains the source samples
   717 */
   718 void CSBCFrameEncoder::Analyse(const TDesC8& aSrc)
   719 	{
   720 	const TUint8 channelMode = iParameters.ChannelMode();
   721 	const TInt16* inputSamples = reinterpret_cast<const TInt16*>(aSrc.Ptr() );
   722 	
   723 	if (channelMode == TSBCFrameParameters::EMono)
   724 		{
   725 		AnalyseMono(inputSamples);
   726 		}
   727 	else // two-channel modes
   728 		{
   729 		// two channel samples are interleavedly stored in the following order
   730 		// one left sample, one right sample, ...
   731 		AnalyseOneChannel(inputSamples, 0);
   732 		AnalyseOneChannel(inputSamples + 1, 1);
   733 		}
   734 	}
   735 
   736 /**
   737 This function analyses audio samples for Mono and Dual Channel modes.
   738 @internalComponent
   739 @param aInputSamples
   740 Array of source samples
   741 */
   742 void CSBCFrameEncoder::AnalyseMono(const TInt16 aInputSamples[])
   743 	{
   744 	const TUint8 numSubbands = iParameters.Subbands();
   745 	const TUint8 numBlocks = iParameters.BlockLength();
   746 	
   747 	for (TUint8 block = 0; block < numBlocks; block++)
   748 		{
   749 		if (numSubbands == 4)
   750 			{
   751 			Analyse4Subbands(aInputSamples, block, 0);
   752 			}
   753 		else
   754 			{
   755 			Analyse8Subbands(aInputSamples, block, 0);
   756 			}
   757 		aInputSamples += numSubbands;
   758 		}
   759 	}
   760 	
   761 /**
   762 This function analyses audio samples for Stereo and Joint Stereo modes.
   763 @internalComponent
   764 @param aInputSamples
   765 Array of source samples
   766 @param aChannel
   767 The channel number to be analysed
   768 */
   769 void CSBCFrameEncoder::AnalyseOneChannel(const TInt16 aInputSamples[], TUint8 aChannel)
   770 	{
   771 	const TUint8 numSubbands = iParameters.Subbands();
   772 	const TUint8 numBlocks = iParameters.BlockLength();
   773 	
   774 	TInt16 inputSamples[KSbcMaxSubbands];
   775 	for (TUint8 block = 0; block < numBlocks; block++)
   776 		{
   777 		for (TUint8 subband = 0; subband < numSubbands; subband++)
   778 			{
   779 			inputSamples[subband] = *aInputSamples;
   780 			aInputSamples += 2; // 1 left sample, 1 right sample, ... 
   781 			}
   782 			
   783 		if (numSubbands == 4)
   784 			{
   785 			Analyse4Subbands(inputSamples, block, aChannel);
   786 			}
   787 		else
   788 			{
   789 			Analyse8Subbands(inputSamples, block, aChannel);
   790 			}
   791 		}
   792 	}
   793 	
   794 
   795 /**
   796 This function analyses 4 subbands for sbc frame with 4 subbands.
   797 @internalComponent
   798 @param aInputSamples
   799 Array of source samples
   800 @param aBlock
   801 The block number to be analysed
   802 @param aChannel
   803 The channel number to be analysed
   804 */
   805 void CSBCFrameEncoder::Analyse4Subbands(const TInt16 aInputSamples[], TUint8 aBlock, TUint8 aChannel)
   806 	{
   807 	// for easier understanding, this code is a copy from the A2DP spec, 
   808 	// all the naming are kept.
   809 	TInt i = 0;
   810 	TInt k = 0;
   811 	TInt16* X = iAnalysisSamples[aChannel]; // 40 analyse samples
   812 	
   813 	for (i = 39; i >= 4; i--)
   814 		{
   815 		X[i] = X[i - 4];
   816 		}
   817 	for (i = 3; i >= 0; i--)
   818 		{
   819 		X[i] = *aInputSamples++;
   820 		}
   821 	
   822 	TInt64 Y[8]; // partial calculation, see Figure 12.5 in A2DP spec for detail
   823 	for (i = 0; i < 8; i++)
   824 		{
   825 		TInt64 sum = 0;
   826 		for (k = 0; k <= 4; k++)
   827 			{
   828 			// for some strange reason, RVCT is not happy about converting 
   829 			// TInt16 to TInt64 in the equation directly.
   830 			const TInt64 sample = X[i + (k << 3)];
   831 			sum += KSBCProto4[i + (k << 3)] * sample;
   832 			}
   833 		Y[i] = sum >> (KSBCProtoBitsShift - 10);
   834 		}
   835 
   836 	TInt32* outputSamples = iOutputSamples[aBlock][aChannel];
   837 	for (i = 0; i < 4; i++)
   838 		{
   839 		const TInt32* M = KSBCAnalysisMatrix4[i];
   840 		TInt64 sum = 0;
   841 		for (k = 0; k < 8; k++)
   842 			{
   843 			sum += M[k] * Y[k];
   844 			}
   845 		sum >>= (KSBCAnalysisMatrixBitsShift + 9);
   846 		sum = (sum >> 1) + (sum & 0x1);
   847 		outputSamples[i] = static_cast<TInt32>(sum);
   848 		}
   849 	}
   850 
   851 /**
   852 This function analyses 8 subbands for sbc frame with 8 subbands.
   853 @internalComponent
   854 @param aInputSamples
   855 Array of source samples
   856 @param aBlock
   857 The block number to be analysed
   858 @param aChannel
   859 The channel number to be analysed
   860 */
   861 void CSBCFrameEncoder::Analyse8Subbands(const TInt16 aInputSamples[], TUint8 aBlock, TUint8 aChannel)
   862 	{
   863 	// for easier understanding, this code is a copy from the A2DP spec, 
   864 	// all the naming are kept.
   865 	TInt i = 0;
   866 	TInt k = 0;
   867 	TInt16* X = iAnalysisSamples[aChannel]; // 80 analysis samples
   868 	
   869 	for (i = 79; i >= 8; i--)
   870 		{
   871 		X[i] = X[i - 8];
   872 		}
   873 	for (i = 7; i >= 0; i--)
   874 		{
   875 		X[i] = *aInputSamples++;
   876 		}
   877 	
   878 	TInt64 Y[16]; // partial calculation, see Figure 12.5 in A2DP spec for detail
   879 	for (i = 0; i < 16; i++)
   880 		{
   881 		TInt64 sum = 0;
   882 		for (k = 0; k <= 4; k++)
   883 			{
   884 			// for some strange reason, RVCT is not happy about converting 
   885 			// TInt16 to TInt64 in the equation directly.
   886 			const TInt64 sample = X[i + (k << 4)];
   887 			sum += KSBCProto8[i + (k << 4)] * sample;
   888 			}
   889 		Y[i] = sum >> (KSBCProtoBitsShift - 10);
   890 		}
   891 	
   892 	TInt32* outputSamples = iOutputSamples[aBlock][aChannel];
   893 	for (i = 0; i < 8; i++)
   894 		{
   895 		const TInt32* M = KSBCAnalysisMatrix8[i];
   896 		TInt64 sum = 0;
   897 		for (k = 0; k < 16; k++)
   898 			{
   899 			sum += M[k] * Y[k];
   900 			}
   901 		sum >>= (KSBCAnalysisMatrixBitsShift + 9);
   902 		sum = (sum >> 1) + (sum & 0x1);
   903 		outputSamples[i] = static_cast<TInt32>(sum);
   904 		}
   905 	}
   906 	
   907 /**
   908 This function calculates the scale factor for one sample.
   909 @internalComponent
   910 @param aSample
   911 A sample 
   912 @return scale factor of thie sample
   913 */
   914 static inline TUint8 ScaleFactor(TInt32 aSample)
   915 	{
   916 	if (aSample < 0)
   917 		aSample = -aSample;
   918 	
   919 	// top bit of the sample is sign bit, ignore it
   920 	// start from the second high bit	
   921 	TUint32 mask = 0x40000000; 
   922 	for (TInt8 bit = 30; bit > 0; bit--)
   923 		{
   924 		if (aSample & mask)
   925 			{
   926 			return bit;
   927 			}
   928 		mask >>= 1;
   929 		}
   930 	return 0;
   931 	}
   932 	
   933 /**
   934 This function calculates the scale factors for all samples in one sbc frame.
   935 @internalComponent
   936 */
   937 void CSBCFrameEncoder::CalcScaleFactors()
   938 	{
   939 	const TUint8 numBlocks = iParameters.BlockLength();
   940 	const TUint8 numChannels = iParameters.Channels();
   941 	const TUint8 numSubbands = iParameters.Subbands();
   942 	
   943 	TInt32 maxSubbandValues[KSbcMaxChannels][KSbcMaxSubbands];
   944 	
   945 	// find all maximum values of each subband
   946 	for (TUint8 block = 0; block < numBlocks; block++)
   947 		{
   948 		for (TUint8 channel = 0; channel < numChannels; channel++)
   949 			{
   950 			const TInt32* samples = iOutputSamples[block][channel];
   951 			TInt32* maxValues = maxSubbandValues[channel];
   952 			
   953 			for (TUint8 subband = 0; subband < numSubbands; subband++)
   954 				{
   955 				if (block == 0 || Abs(*samples) > *maxValues)
   956 					{
   957 					*maxValues = Abs(*samples);
   958 					}
   959 				samples++;
   960 				maxValues++;
   961 				}
   962 			}
   963 		}
   964 	
   965 	// calculate scale factors for all subband
   966 	for (TUint8 channel = 0; channel < numChannels; channel++)
   967 		{
   968 		const TInt32* maxValues = maxSubbandValues[channel];
   969 		TUint8* scale = iScaleFactors[channel];
   970 		
   971 		for (TUint8 subband = 0; subband < numSubbands; subband++)
   972 			{
   973 			*scale++ = ScaleFactor(*maxValues++);
   974 			}
   975 		}
   976 	}
   977 
   978 /**
   979 This function joins two subband samples for Joint Stereo mode.
   980 @internalComponent
   981 @param aLeftSample
   982 Left channel subband sample 
   983 @param aRightSample
   984 Right channel subband sample 
   985 */
   986 static inline void JoinTwoSamples(TInt32& aLeftSample, TInt32& aRightSample)
   987 	{
   988 	aLeftSample = (aLeftSample + aRightSample) >> 1; // L1 = (L0 + R0) / 2
   989 	aRightSample = aLeftSample - aRightSample; // R1 = L1 - R0 = (L0 - R0) / 2
   990 	}
   991 
   992 /**
   993 This function sets the join flats for all subbands for one frame, 
   994 and joins those subbands if needed for this frame.
   995 @internalComponent
   996 */
   997 void CSBCFrameEncoder::JoinSubbands()
   998 	{
   999 	if (iParameters.ChannelMode() != TSBCFrameParameters::EJointStereo)
  1000 		{
  1001 		return;
  1002 		}
  1003 	
  1004 	const TUint8 numBlocks = iParameters.BlockLength();
  1005 	const TUint8 numSubbands = iParameters.Subbands();
  1006 	
  1007 	TInt32 maxJoinValues[2][KSbcMaxSubbands - 1]; // 2 channels
  1008 	
  1009 	// find maximum join subband values
  1010 	for (TUint8 block = 0; block < numBlocks; block++)
  1011 		{
  1012 		const TInt32* leftSamples = iOutputSamples[block][0];
  1013 		const TInt32* rightSamples = iOutputSamples[block][1];
  1014 		
  1015 		TInt32* maxLeftJoin = maxJoinValues[0];
  1016 		TInt32* maxRightJoin = maxJoinValues[1];
  1017 		
  1018 		for (TUint8 subband = 0; subband < numSubbands - 1; subband++)
  1019 			{
  1020 			TInt32 leftJoin = *leftSamples++;
  1021 			TInt32 rightJoin = *rightSamples++;
  1022 			
  1023 			JoinTwoSamples(leftJoin, rightJoin);
  1024 			
  1025 			if (block == 0 || Abs(leftJoin) > *maxLeftJoin)
  1026 				{
  1027 				*maxLeftJoin = Abs(leftJoin);
  1028 				}
  1029 			if (block == 0 || Abs(rightJoin) > *maxRightJoin)
  1030 				{
  1031 				*maxRightJoin = Abs(rightJoin);
  1032 				}
  1033 			maxLeftJoin++;
  1034 			maxRightJoin++;
  1035 			}
  1036 		}
  1037 	
  1038 	// calculate scale factors for all join subbands
  1039 	const TInt32* maxLeftJoin = maxJoinValues[0];
  1040 	const TInt32* maxRightJoin = maxJoinValues[1];
  1041 	
  1042 	TUint8* leftScale = iScaleFactors[0];
  1043 	TUint8* rightScale = iScaleFactors[1];
  1044 	
  1045 	for (TUint8 subband = 0; subband < numSubbands - 1; subband++)
  1046 		{
  1047 		const TUint8 leftJoinScale = ScaleFactor(*maxLeftJoin++);
  1048 		const TUint8 rightJoinScale = ScaleFactor(*maxRightJoin++);
  1049 		
  1050 		iJoin[subband] = 0;
  1051 		if (leftJoinScale + rightJoinScale < *leftScale + *rightScale)
  1052 			{
  1053 			iJoin[subband] = 1;
  1054 			*leftScale = leftJoinScale;
  1055 			*rightScale = rightJoinScale;
  1056 			}
  1057 		leftScale++;
  1058 		rightScale++;
  1059 		}
  1060 	iJoin[numSubbands - 1] = 0; // join[subband - 1] is always 0
  1061 	
  1062 	// now do the joining job
  1063 	DoJoinSubbands();
  1064 	}
  1065 	
  1066 /**
  1067 This function joins all subbands if needed for this frame.
  1068 @internalComponent
  1069 */
  1070 void CSBCFrameEncoder::DoJoinSubbands()
  1071 	{
  1072 	const TUint8 numBlocks = iParameters.BlockLength();
  1073 	const TUint8 numSubbands = iParameters.Subbands();
  1074 	
  1075 	for (TUint8 block = 0; block < numBlocks; block++)
  1076 		{
  1077 		TInt32* leftSamples = iOutputSamples[block][0];
  1078 		TInt32* rightSamples = iOutputSamples[block][1];
  1079 		
  1080 		for (TUint8 subband = 0; subband < numSubbands - 1; subband++)
  1081 			{
  1082 			if (iJoin[subband])
  1083 				{
  1084 				JoinTwoSamples(*leftSamples, *rightSamples);
  1085 				}
  1086 			leftSamples++;
  1087 			rightSamples++;
  1088 			}
  1089 		}
  1090 	}
  1091 	
  1092 /**
  1093 This function quantizes one sample according to:
  1094 	sample = (sample / scale + 1.0) * level / 2.0
  1095 	scale = 2 ^ (scale_factor + 1)
  1096 	level = (2 ^ bits) - 1
  1097 @internalComponent
  1098 @param aSample
  1099 A sample to be quantized.
  1100 @param aScaleFactor
  1101 The scale factor value.
  1102 @param aBits
  1103 The number of bits for this sample
  1104 @panic if quantized sample overflow
  1105 */
  1106 static void QuantizeOneSample(TInt32& aSample, TUint8 aScaleFactor, TUint8 aBits)
  1107 	{
  1108 	// output = sample + scale
  1109 	TInt64 temp = (TInt)aSample + (0x1 << (aScaleFactor + 1) ); 
  1110 	// output = (sample + scale) * level / scale
  1111 	temp = ( (temp << aBits) - temp) >> (aScaleFactor + 2);
  1112 
  1113 	aSample = static_cast<TInt32>(temp);
  1114 
  1115 	// check bounce
  1116 	__ASSERT_DEBUG(aSample >= 0 && aSample <= (TInt32)0xffff, Panic(ESbcSampleOverflow) );
  1117 	// extra code to handle exception for URel version
  1118 	if (aSample < 0)
  1119 		{
  1120 		aSample = 0;
  1121 		}
  1122 	if (aSample > (TInt32)0xffff)
  1123 		{
  1124 		aSample = (TInt32)0xffff;
  1125 		}
  1126 	}
  1127 	
  1128 /**
  1129 This function quantizes all samples in one sbc frame.
  1130 @internalComponent
  1131 */
  1132 void CSBCFrameEncoder::Quantize()
  1133 	{
  1134 	const TUint8 numBlocks = iParameters.BlockLength();
  1135 	const TUint8 numChannels = iParameters.Channels();
  1136 	const TUint8 numSubbands = iParameters.Subbands();
  1137 	
  1138 	for (TUint8 block = 0; block < numBlocks; block++)
  1139 		{
  1140 		for (TUint8 channel = 0; channel < numChannels; channel++)
  1141 			{
  1142 			const TUint8* bits = iBits[channel];
  1143 			const TUint8* scale = iScaleFactors[channel];
  1144 			TInt32* samples = iOutputSamples[block][channel];
  1145 
  1146 			for (TUint8 subband = 0; subband < numSubbands; subband++)
  1147 				{
  1148 				QuantizeOneSample(*samples++, *scale++, *bits++);
  1149 				}
  1150 			}
  1151 		}
  1152 	}
  1153 	
  1154 /**
  1155 This function calculates bit allocation for all samples in one sbc frame using scale factors.
  1156 @internalComponent
  1157 */
  1158 void CSBCFrameEncoder::CalcBitAllocation()
  1159 	{
  1160 	switch (iParameters.ChannelMode())
  1161 		{
  1162 		case TSBCFrameParameters::EMono:
  1163 		case TSBCFrameParameters::EDualChannel:
  1164 			CalcBitAllocIndependent();
  1165 			break;
  1166 		
  1167 		case TSBCFrameParameters::EStereo:
  1168 		case TSBCFrameParameters::EJointStereo:
  1169 			CalcBitAllocCombined();
  1170 			break;
  1171 		}
  1172 	}
  1173 
  1174 /**
  1175 This function calculates bit allocation for one channel for Mono and Dual Channel.
  1176 @internalComponent
  1177 */
  1178 void CSBCFrameEncoder::CalcBitAllocIndependent()
  1179 	{
  1180 	const TUint8 numChannels = iParameters.Channels();
  1181 	for (TUint8 channel = 0; channel < numChannels; channel++)
  1182 		{
  1183 		TInt8 bitneed[KSbcMaxSubbands];
  1184 		CalcBitneedIndependent(bitneed, iScaleFactors[channel]);
  1185 		DistributeBitsIndependent(bitneed, iBits[channel]);
  1186 		}
  1187 	}
  1188 
  1189 /**
  1190 This function calculates bitneed for one channel for Mono and Dual Channel.
  1191 @internalComponent
  1192 @param aBitneed
  1193 Array of bitneed to hold the result
  1194 @param aScaleFactors
  1195 The scale factors used for this calculation
  1196 */
  1197 void CSBCFrameEncoder::CalcBitneedIndependent(TInt8 aBitneed[], const TUint8 aScaleFactors[])
  1198 	{
  1199 	// see A2DP spec for reference
  1200 	const TUint8 numSubbands = iParameters.Subbands();
  1201 	
  1202 	if (iParameters.AllocationMethod() == TSBCFrameParameters::ESNR)
  1203 		{
  1204 		for (TUint8 subband = 0; subband < numSubbands; subband++)
  1205 			{
  1206 			*aBitneed++ = *aScaleFactors++;
  1207 			}
  1208 		}
  1209 	else // Loudness
  1210 		{
  1211 		const TInt8* offset = NULL;
  1212 		if (numSubbands == 4)
  1213 			{
  1214 			offset = KSBCOffset4[iParameters.SamplingFrequencyEnum()];
  1215 			}
  1216 		else
  1217 			{
  1218 			offset = KSBCOffset8[iParameters.SamplingFrequencyEnum()];
  1219 			}
  1220 			
  1221 		for (TUint8 subband = 0; subband < numSubbands; subband++)
  1222 			{
  1223 			if (*aScaleFactors == 0)
  1224 				{
  1225 				*aBitneed = -5;
  1226 				}
  1227 			else if ( (*aBitneed = static_cast<TUint8>(*aScaleFactors - *offset) ) > 0)
  1228 				{
  1229 				(*aBitneed) >>= 1;
  1230 				}
  1231 			aScaleFactors++;
  1232 			aBitneed++;
  1233 			offset++;
  1234 			}
  1235 		}
  1236 	}
  1237 	
  1238 /**
  1239 This function gets the maximum bitneed in one channel for Mono and Dual Channel.
  1240 @internalComponent
  1241 @param aBitneed
  1242 Array of bitneed.
  1243 */
  1244 TInt8 CSBCFrameEncoder::MaxBitneedIndependent(const TInt8 aBitneed[])
  1245 	{
  1246 	// see A2DP spec for reference
  1247 	TInt8 maxBitneed = 0;
  1248 	const TUint8 numSubbands = iParameters.Subbands();
  1249 	
  1250 	for (TUint8 subband = 0; subband < numSubbands; subband++)
  1251 		{
  1252 		if (*aBitneed > maxBitneed)
  1253 			{
  1254 			maxBitneed = *aBitneed;
  1255 			}
  1256 		aBitneed++;
  1257 		}
  1258 		
  1259 	return maxBitneed;
  1260 	}
  1261 	
  1262 /**
  1263 This function calculates how many bitslices fit into the bitpool for one channel 
  1264 for Mono and Dual Channel.
  1265 @internalComponent
  1266 @param aBitneed
  1267 Array of bitneed.
  1268 @param aBitCount
  1269 The bit count, counts how many bits used
  1270 @return the number of bitslices
  1271 */
  1272 TInt8 CSBCFrameEncoder::CalcBitSlicesIndependent(const TInt8 aBitneed[], TInt& aBitCount)
  1273 	{
  1274 	// see A2DP spec for reference
  1275 	aBitCount = 0;
  1276 	TInt8 sliceCount = 0;
  1277 	TInt8 bitSlices = static_cast<TInt8>(MaxBitneedIndependent(aBitneed) + 1);
  1278 	
  1279 	const TUint8 numSubbands = iParameters.Subbands();
  1280 	const TUint8 bitpool = iParameters.Bitpool();
  1281 	
  1282 	do {
  1283 		bitSlices--;
  1284 		aBitCount += sliceCount;
  1285 		sliceCount = 0;
  1286 		
  1287 		const TInt8* bitneed = aBitneed;
  1288 		for (TUint8 subband = 0; subband < numSubbands; subband++)
  1289 			{
  1290 			if (*bitneed > bitSlices + 1 && *bitneed < bitSlices + 16)
  1291 				{
  1292 				sliceCount++;
  1293 				}
  1294 			else if (*bitneed == bitSlices + 1)
  1295 				{
  1296 				sliceCount += 2;
  1297 				}
  1298 			bitneed++;
  1299 			}
  1300 		} while (aBitCount + sliceCount < bitpool);
  1301 	
  1302 	if (aBitCount + sliceCount == bitpool)
  1303 		{
  1304 		aBitCount += sliceCount;
  1305 		bitSlices--;
  1306 		}
  1307 		
  1308 	return bitSlices;
  1309 	}
  1310 
  1311 /**
  1312 This function distributes number of bits to each subband for all samples
  1313 for Mono and Dual Channel.
  1314 @internalComponent
  1315 @param aBitneed
  1316 Array of bitneed.
  1317 @param aBits
  1318 Bits allocated for each subbands
  1319 */
  1320 void CSBCFrameEncoder::DistributeBitsIndependent(const TInt8 aBitneed[], TUint8 aBits[])
  1321 	{
  1322 	// see A2DP spec for reference
  1323 	TInt bitCount = 0;
  1324 	TInt8 bitSlices = CalcBitSlicesIndependent(aBitneed, bitCount);
  1325 	
  1326 	const TUint8 numSubbands = iParameters.Subbands();
  1327 	
  1328 	// distribute bits until the last bitslice is reached
  1329 	TUint8 subband = 0;
  1330 	for (; subband < numSubbands; subband++)
  1331 		{
  1332 		if (aBitneed[subband] < bitSlices + 2)
  1333 			{
  1334 			aBits[subband] = 0;
  1335 			}
  1336 		else
  1337 			{
  1338 			aBits[subband] = static_cast<TUint8>(Min(aBitneed[subband] - bitSlices, 16) ); 
  1339 			}
  1340 		}
  1341 	
  1342 	// distribute the remaining bits
  1343 	const TUint8 bitpool = iParameters.Bitpool();
  1344 	
  1345 	subband = 0;
  1346 	while (bitCount < bitpool && subband < numSubbands)
  1347 		{
  1348 		if (aBits[subband] >= 2 && aBits[subband] < 16)
  1349 			{
  1350 			aBits[subband]++;
  1351 			bitCount++;
  1352 			}
  1353 		else if (aBitneed[subband] == bitSlices + 1 && bitpool > bitCount + 1)
  1354 			{
  1355 			aBits[subband] += 2; // ? bits[ch][sb] = 2 in A2DP spec, a bug in the spec?
  1356 			bitCount += 2;
  1357 			}
  1358 		subband++;
  1359 		}
  1360 	
  1361 	subband = 0;
  1362 	while (bitCount < bitpool && subband < numSubbands)
  1363 		{
  1364 		if (aBits[subband] < 16)
  1365 			{
  1366 			aBits[subband]++;
  1367 			bitCount++;
  1368 			}
  1369 		subband++;
  1370 		}
  1371 	}
  1372 
  1373 /**
  1374 This function calculates bit allocation for both channels for Stereo and Joint Stereo.
  1375 @internalComponent
  1376 */
  1377 void CSBCFrameEncoder::CalcBitAllocCombined()
  1378 	{
  1379 	TInt8 bitneed[2][KSbcMaxSubbands];
  1380 	
  1381 	CalcBitneedCombined(bitneed);
  1382 	DistributeBitsCombined(bitneed);
  1383 	}
  1384 
  1385 /**
  1386 This function calculates bitneed for both channels for Stereo and Joint Stereo.
  1387 @internalComponent
  1388 @param aBitneed
  1389 Array of bitneed to hold the result
  1390 */
  1391 void CSBCFrameEncoder::CalcBitneedCombined(TInt8 aBitneed[][KSbcMaxSubbands])
  1392 	{
  1393 	// see A2DP spec for reference
  1394 	const TUint8 numSubbands = iParameters.Subbands();
  1395 	
  1396 	if (iParameters.AllocationMethod() == TSBCFrameParameters::ESNR)
  1397 		{
  1398 		for (TInt8 channel = 0; channel < 2; channel++)
  1399 			{
  1400 			const TUint8* scaleFactor = iScaleFactors[channel];
  1401 			TInt8* bitneed = aBitneed[channel];
  1402 			for (TInt8 subband = 0; subband < numSubbands; subband++)
  1403 				{
  1404 				*bitneed++ = *scaleFactor++;
  1405 				}
  1406 			}
  1407 		}
  1408 	else // Loudness
  1409 		{
  1410 		const TInt8* offset = NULL;
  1411 		if (numSubbands == 4)
  1412 			{
  1413 			offset = KSBCOffset4[iParameters.SamplingFrequencyEnum()];
  1414 			}
  1415 		else
  1416 			{
  1417 			offset = KSBCOffset8[iParameters.SamplingFrequencyEnum()];
  1418 			}
  1419 			
  1420 		for (TInt8 channel = 0; channel < 2; channel++)
  1421 			{
  1422 			const TUint8* scaleFactor = iScaleFactors[channel];
  1423 			TInt8* bitneed = aBitneed[channel];
  1424 			for (TUint8 subband = 0; subband < numSubbands; subband++)
  1425 				{
  1426 				if (*scaleFactor == 0)
  1427 					{
  1428 					*bitneed = -5;
  1429 					}
  1430 				else if ( (*bitneed = static_cast<TUint8>(*scaleFactor - offset[subband]) ) > 0)
  1431 					{
  1432 					(*bitneed) >>= 1;
  1433 					}
  1434 				scaleFactor++;
  1435 				bitneed++;
  1436 				} // for subband
  1437 			} // for channel
  1438 		}
  1439 	}
  1440 
  1441 /**
  1442 This function gets the maximum bitneed of both channels subbands for Stereo and Joint Stereo.
  1443 @internalComponent
  1444 @param aBitneed
  1445 Array of bitneed.
  1446 */
  1447 TInt8 CSBCFrameEncoder::MaxBitneedCombined(const TInt8 aBitneed[][KSbcMaxSubbands])
  1448 	{
  1449 	// see A2DP spec for reference
  1450 	TInt8 maxBitneed = 0;
  1451 	const TUint8 numSubbands = iParameters.Subbands();
  1452 	
  1453 	for (TInt8 channel = 0; channel < 2; channel++)
  1454 		{
  1455 		const TInt8* bitneed = aBitneed[channel];
  1456 		for (TInt8 subband = 0; subband < numSubbands; subband++)
  1457 			{
  1458 			if (*bitneed > maxBitneed)
  1459 				{
  1460 				maxBitneed = *bitneed;
  1461 				}
  1462 			bitneed++;
  1463 			}
  1464 		}
  1465 	return maxBitneed;
  1466 	}
  1467 	
  1468 /**
  1469 This function calculates how many bitslices fit into the bitpool for both channels 
  1470 for Stereo and Joint Stereo.
  1471 @internalComponent
  1472 @param aBitneed
  1473 Array of bitneed.
  1474 @param aBitCount
  1475 The bit count, counts how many bits used
  1476 @return the number of bitslices
  1477 */
  1478 TInt8 CSBCFrameEncoder::CalcBitSlicesCombined(const TInt8 aBitneed[][KSbcMaxSubbands], TInt& aBitCount)
  1479 	{
  1480 	// see A2DP spec for reference
  1481 	aBitCount = 0;
  1482 	TInt8 sliceCount = 0;
  1483 	TInt8 bitSlices = static_cast<TUint8>(MaxBitneedCombined(aBitneed) + 1);
  1484 	
  1485 	const TUint8 numSubbands = iParameters.Subbands();
  1486 	const TUint8 bitpool = iParameters.Bitpool();
  1487 	
  1488 	do {
  1489 		bitSlices--;
  1490 		aBitCount += sliceCount;
  1491 		sliceCount = 0;
  1492 		
  1493 		for (TInt8 channel = 0; channel < 2; channel++)
  1494 			{
  1495 			const TInt8* bitneed = aBitneed[channel];
  1496 			for (TInt8 subband = 0; subband < numSubbands; subband++)
  1497 				{
  1498 				if (*bitneed > bitSlices + 1 && *bitneed < bitSlices + 16) 
  1499 					{
  1500 					sliceCount++;
  1501 					}
  1502 				else if (*bitneed == bitSlices + 1)
  1503 					{
  1504 					sliceCount += 2;
  1505 					}
  1506 				bitneed++;
  1507 				}
  1508 			}
  1509 		} while (aBitCount + sliceCount < bitpool);
  1510 	
  1511 	if (aBitCount + sliceCount == bitpool)
  1512 		{
  1513 		aBitCount += sliceCount;
  1514 		bitSlices--;
  1515 		}
  1516 		
  1517 	return bitSlices;
  1518 	}
  1519 	
  1520 /**
  1521 This function distributes number of bits to each subband for all samples 
  1522 for Stereo and Joint Stereo.
  1523 @internalComponent
  1524 @param aBitneed
  1525 Array of bitneed.
  1526 */
  1527 void CSBCFrameEncoder::DistributeBitsCombined(const TInt8 aBitneed[][KSbcMaxSubbands])
  1528 	{
  1529 	// see A2DP spec for reference
  1530 	TInt bitCount = 0;
  1531 	TInt bitSlices = CalcBitSlicesCombined(aBitneed, bitCount);
  1532 
  1533 	const TUint8 numSubbands = iParameters.Subbands();
  1534 	const TUint8 bitpool = iParameters.Bitpool();
  1535 	
  1536 	// distribute bits until the last bitslice is reached
  1537 	TInt8 channel = 0;
  1538 	TInt8 subband = 0;
  1539 	for (; channel < 2; channel++)
  1540 		{
  1541 		const TInt8* bitneed = aBitneed[channel];
  1542 		TUint8* bits = iBits[channel];
  1543 		for (subband = 0; subband < numSubbands; subband++)
  1544 			{
  1545 			if (*bitneed < bitSlices + 2)
  1546 				{
  1547 				*bits = 0;
  1548 				}
  1549 			else
  1550 				{
  1551 				*bits = static_cast<TUint8>(Min(*bitneed - bitSlices, 16) );
  1552 				}
  1553 			bitneed++;
  1554 			bits++;
  1555 			}
  1556 		}
  1557 	
  1558 	// distribute the remaining bits
  1559 	channel = 0;
  1560 	subband = 0;
  1561 	while (bitCount < bitpool && subband < numSubbands)
  1562 		{
  1563 		TUint8& bits = iBits[channel][subband];
  1564 		if (bits >= 2 && bits < 16)
  1565 			{
  1566 			bits++;
  1567 			bitCount++;
  1568 			}
  1569 		else if (aBitneed[channel][subband] == bitSlices + 1 && bitpool > bitCount + 1) 
  1570 			{
  1571 			bits += 2; // ? bits[ch][sb] = 2 in A2DP spec, a bug in the spec?
  1572 			bitCount += 2;
  1573 			}
  1574 						
  1575 		if (channel == 1)
  1576 			{
  1577 			channel = 0;
  1578 			subband++;
  1579 			}
  1580 		else
  1581 			{
  1582 			channel = 1;
  1583 			}
  1584 		}
  1585 
  1586 	channel = 0;	
  1587 	subband = 0;
  1588 	while (bitCount < bitpool && subband < numSubbands)
  1589 		{
  1590 		TUint8& bits = iBits[channel][subband];
  1591 		if (bits < 16) 
  1592 			{
  1593 			bits++; 
  1594 			bitCount++;
  1595 			}
  1596 		
  1597 		if (channel == 1)
  1598 			{
  1599 			channel = 0 ;
  1600 			subband++;
  1601 			}
  1602 		else
  1603 			{
  1604 			channel = 1;
  1605 			}
  1606 		}
  1607 	}
  1608 
  1609 /**
  1610 This function calculates the CRC code for sbc frame.
  1611 @internalComponent
  1612 @return sbc CRC value
  1613 */
  1614 TUint8 CSBCFrameEncoder::CalcCRC()
  1615 	{
  1616 	CSbcCRCCalculator crc;
  1617 	
  1618 	crc.InputByte(iParameters.Parameters() ); // 5 parameters
  1619 	crc.InputByte(iParameters.Bitpool() ); // bitpool
  1620 
  1621 	// join[] & RFA bits
  1622 	const TUint8 numSubbands = iParameters.Subbands();
  1623 	if (iParameters.ChannelMode() == TSBCFrameParameters::EJointStereo)
  1624 		{
  1625 		for (TUint8 subband = 0; subband < numSubbands; subband++)
  1626 			{
  1627 			crc.InputBit(iJoin[subband]);
  1628 			}
  1629 		}
  1630 		
  1631 	// scale factors
  1632 	const TUint8 numChannels = iParameters.Channels();
  1633 	for (TUint8 channel = 0; channel < numChannels; channel++)
  1634 		{
  1635 		const TUint8* scaleFactors = iScaleFactors[channel];
  1636 		for (TUint8 subband = 0; subband < numSubbands; subband++)
  1637 			{
  1638 			crc.InputBits(4, *scaleFactors++);
  1639 			}
  1640 		}
  1641 		
  1642 	return crc.ShiftRegister();
  1643 	}
  1644 	
  1645 /**
  1646 This function outputs the encoded sbc frame into the destination buffer.
  1647 @internalComponent
  1648 @param aFrame
  1649 The destination buffer
  1650 @leave if out of memory
  1651 */
  1652 void CSBCFrameEncoder::WriteFrameL(TDes8& aFrame)
  1653 	{
  1654 	CBitStreamParser* parser = CBitStreamParser::NewLC(aFrame);
  1655 	
  1656 	WriteHeader(*parser);
  1657 	WriteScaleFactors(*parser);
  1658 	WriteData(*parser);
  1659 	WritePaddingL(*parser);
  1660 	
  1661 	CleanupStack::PopAndDestroy(parser);
  1662 	}
  1663 
  1664 /**
  1665 This function writes the sbc frame header into the destination buffer.
  1666 @internalComponent
  1667 @param aParser
  1668 The bit stream parser which manipulates the destination buffer bit stream
  1669 */
  1670 void CSBCFrameEncoder::WriteHeader(CBitStreamParser& aParser)
  1671 	{
  1672 	// syncword
  1673 	aParser.WriteByte(KSBCFrameSyncWord);
  1674 	// sampling frequency, blocklength, channel mode, allocatin method, subbands
  1675 	aParser.WriteByte(iParameters.Parameters() );
  1676 	// bitpool
  1677 	aParser.WriteByte(iParameters.Bitpool() );
  1678 	// crc check
  1679 	aParser.WriteByte(CalcCRC() );
  1680 
  1681 	if (iParameters.ChannelMode() == TSBCFrameParameters::EJointStereo)
  1682 		{
  1683 		// join[] & RFA
  1684 		const TUint8 numSubbands = iParameters.Subbands();
  1685 		for (TUint8 subband = 0; subband < numSubbands; subband++)
  1686 			{
  1687 			aParser.WriteBits(1, iJoin[subband]);
  1688 			}
  1689 		}
  1690 	}
  1691 	
  1692 /**
  1693 This function writes the sbc frame scale factors into the destination buffer.
  1694 @internalComponent
  1695 @param aParser
  1696 The bit stream parser which manipulates the destination buffer bit stream
  1697 */
  1698 void CSBCFrameEncoder::WriteScaleFactors(CBitStreamParser& aParser)
  1699 	{
  1700 	const TUint8 numChannels = iParameters.Channels();
  1701 	const TUint8 numSubbands = iParameters.Subbands();
  1702 	
  1703 	for (TUint8 channel = 0; channel < numChannels; channel++)
  1704 		{
  1705 		const TUint8* scaleFactors = iScaleFactors[channel];
  1706 		for (TUint8 subband = 0; subband < numSubbands; subband++)
  1707 			{
  1708 			aParser.WriteBits(4, *scaleFactors++);
  1709 			}
  1710 		}
  1711 	}
  1712 
  1713 /**
  1714 This function writes one sbc subband sample into the destination buffer.
  1715 @internalComponent
  1716 @param aParser
  1717 The bit stream parser which manipulates the destination buffer bit stream
  1718 @param aBits
  1719 The number of bits to write
  1720 @param aSample
  1721 The sample value to write
  1722 */
  1723 static void WriteOneSample(CBitStreamParser& aParser, TUint8 aBits, TInt32 aSample)
  1724 	{
  1725 	if (aBits >= 8)
  1726 		{
  1727 		aBits -= 8;
  1728 		aParser.WriteByte(static_cast<TUint8>( (aSample >> aBits) & 0xff) );
  1729 		}
  1730 	if (aBits > 0)
  1731 		{
  1732 		aParser.WriteBits(aBits, static_cast<TUint8>(aSample & 0xff) );
  1733 		}
  1734 	}
  1735 	
  1736 /**
  1737 This function writes the sbc frame data into the destination buffer.
  1738 @internalComponent
  1739 @param aParser
  1740 The bit stream parser which manipulates the destination buffer bit stream
  1741 */
  1742 void CSBCFrameEncoder::WriteData(CBitStreamParser& aParser)
  1743 	{
  1744 	const TUint8 numBlocks = iParameters.BlockLength();
  1745 	const TUint8 numChannels = iParameters.Channels();
  1746 	const TUint8 numSubbands = iParameters.Subbands();
  1747 	
  1748 	for (TUint8 block = 0; block < numBlocks; block++)
  1749 		{
  1750 		for (TUint8 channel = 0; channel < numChannels; channel++)
  1751 			{
  1752 			const TUint8* bits = iBits[channel];
  1753 			const TInt32* samples = iOutputSamples[block][channel];
  1754 			
  1755 			for (TUint8 subband = 0; subband < numSubbands; subband++)
  1756 				{
  1757 				if (*bits > 0)
  1758 					{
  1759 					WriteOneSample(aParser, *bits, *samples);
  1760 					}
  1761 				bits++;
  1762 				samples++;
  1763 				}
  1764 			}
  1765 		}
  1766 	}
  1767 	
  1768 /**
  1769 This function writes the sbc frame padding bits into the destination buffer.
  1770 @internalComponent
  1771 @param aParser
  1772 The bit stream parser which manipulates the destination buffer bit stream
  1773 @panic if output frame length is not the same as expected
  1774 */
  1775 void CSBCFrameEncoder::WritePaddingL(CBitStreamParser& aParser)
  1776 	{
  1777 	TUint byteOffset;
  1778 	TUint8 bitOffset;
  1779 	
  1780 	aParser.Position(byteOffset, bitOffset);
  1781 	
  1782 	if (bitOffset != 0)
  1783 		{
  1784 		aParser.WriteBits(8 - bitOffset, 0);
  1785 		byteOffset++;
  1786 		}
  1787 		
  1788 	if (byteOffset != iParameters.CalcFrameLength() )
  1789 		{
  1790 		User::Leave(KErrCorrupt);
  1791 		}
  1792 	}