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