sl@0: // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: //
sl@0: 
sl@0: #ifndef __BTSBCFRAMEPARAMETERS_H__
sl@0: #define __BTSBCFRAMEPARAMETERS_H__
sl@0: 
sl@0: /**
sl@0: This class contains 6 SBC frame parameters: sampling frequency, block length, 
sl@0: channel mode, allocation mode, subbands and bitpool. It can validate all the 
sl@0: parameters, calculate frame length and bit rate.
sl@0: @internalComponent
sl@0: */
sl@0: class TSBCFrameParameters
sl@0: 	{
sl@0: public:
sl@0: 	/**
sl@0: 	This enum list all the possible sampling frequency settings
sl@0: 	*/
sl@0: 	enum TSamplingFrequency
sl@0: 		{
sl@0: 		/**
sl@0: 		sampling frequency is 16000 Hz
sl@0: 		*/
sl@0: 		E16000Hz = 0,
sl@0: 		/**
sl@0: 		sampling frequency is 32000 Hz
sl@0: 		*/
sl@0: 		E32000Hz,
sl@0: 		/**
sl@0: 		sampling frequency is 44100 Hz
sl@0: 		*/
sl@0: 		E44100Hz,
sl@0: 		/**
sl@0: 		sampling frequency is 48000 Hz
sl@0: 		*/
sl@0: 		E48000Hz
sl@0: 		};
sl@0: 
sl@0: 	/**
sl@0: 	This enum list all the possible block length settings
sl@0: 	*/
sl@0: 	enum TBlockLength
sl@0: 		{
sl@0: 		/**
sl@0: 		block length is 4, one frame contains 4 blocks of audio samples
sl@0: 		*/
sl@0: 		E4Blocks = 0,
sl@0: 		/**
sl@0: 		block length is 8, one frame contains 8 blocks of audio samples
sl@0: 		*/
sl@0: 		E8Blocks,
sl@0: 		/**
sl@0: 		block length is 12, one frame contains 12 blocks of audio samples
sl@0: 		*/
sl@0: 		E12Blocks,
sl@0: 		/**
sl@0: 		block length is 16, one frame contains 16 blocks of audio samples
sl@0: 		*/
sl@0: 		E16Blocks
sl@0: 		};
sl@0: 
sl@0: 	/**
sl@0: 	This enum list all the possible channel mode settings
sl@0: 	*/
sl@0: 	enum TChannelMode
sl@0: 		{
sl@0: 		/**
sl@0: 		channel mode is Mono, in this mode,
sl@0: 		only one channel contains audio samples.
sl@0: 		*/
sl@0: 		EMono = 0,
sl@0: 		/**
sl@0: 		channel mode is Dual Channel, in this mode,
sl@0: 		it contains two seperate mono audio samples.
sl@0: 		*/
sl@0: 		EDualChannel,
sl@0: 		/**
sl@0: 		channel mode is Stereo, in this mode,
sl@0: 		it contains stereo audio samples.
sl@0: 		*/
sl@0: 		EStereo,
sl@0: 		/**
sl@0: 		channel mode is Joint Stereo, in this mode,
sl@0: 		the left channel stores half of sum of both channels, 
sl@0: 		the right channel stores half of difference of both channels. 
sl@0: 		*/
sl@0: 		EJointStereo
sl@0: 		};
sl@0: 
sl@0: 	/**
sl@0: 	This enum list all the possible allocation method settings
sl@0: 	*/
sl@0: 	enum TAllocationMethod
sl@0: 		{
sl@0: 		/**
sl@0: 		allocation method is Loudness, in this mode, 
sl@0: 		the bit allocation calculation uses Table offset4 or offset8 as well as scale factors
sl@0: 		*/
sl@0: 		ELoudness = 0,
sl@0: 		/**
sl@0: 		allocation method is SNR, in this mode,
sl@0: 		bit allocation only uses scale factors
sl@0: 		*/
sl@0: 		ESNR
sl@0: 		};
sl@0: 
sl@0: 	/**
sl@0: 	This enum list all the possible subbands settings
sl@0: 	*/
sl@0: 	enum TSubbands
sl@0: 		{
sl@0: 		/**
sl@0: 		subbands is 4, each channel contains 4 subbands in each block, 
sl@0: 		each subband contains one sample
sl@0: 		*/
sl@0: 		E4Subbands = 0,
sl@0: 		/**
sl@0: 		subbands is 8, each channel contains 8 subbands in each block, 
sl@0: 		each subband contains one sample
sl@0: 		*/
sl@0: 		E8Subbands
sl@0: 		};
sl@0: 		
sl@0: public:
sl@0: 	inline TSBCFrameParameters();
sl@0: 	
sl@0: 	inline void Reset();
sl@0: 
sl@0: 	inline TUint8 	SamplingFrequencyEnum() const;
sl@0: 	inline TUint	SamplingFrequencyHz() const;
sl@0: 	inline void		SetSamplingFrequency(TSamplingFrequency aSamplingFrequency);
sl@0: 	
sl@0: 	inline TUint8	BlockLength() const;
sl@0: 	inline void		SetBlockLength(TBlockLength aBlockLength);
sl@0: 	
sl@0: 	inline TUint8 	ChannelMode() const;
sl@0: 	inline TUint8	Channels() const;
sl@0: 	inline void 	SetChannelMode(TChannelMode aChannelMode);
sl@0: 	
sl@0: 	inline TUint8 	AllocationMethod() const;
sl@0: 	inline void 	SetAllocationMethod(TAllocationMethod aAllocationMethod);
sl@0: 	
sl@0: 	inline TUint8	SubbandsEnum() const;
sl@0: 	inline TUint8	Subbands() const;
sl@0: 	inline void 	SetSubbands(TSubbands aSubbands);
sl@0: 	
sl@0: 	inline TUint8	Bitpool() const;
sl@0: 	inline void		SetBitpool(TUint8 aBitpool);
sl@0: 	
sl@0: 	inline TUint8	Parameters() const;
sl@0: 	inline TInt 	Validate() const;
sl@0: 
sl@0: 	inline TUint 	CalcFrameLength() const;
sl@0: 	inline TUint 	CalcBitRate(TUint aFrameLength) const;
sl@0: 
sl@0: private:
sl@0: 	TUint8 	iParameters;
sl@0: 	TUint8 	iBitpool;
sl@0: 	};
sl@0: 
sl@0: /**
sl@0: The minimum SBC bitpool value is 2 
sl@0: */	
sl@0: const TUint8 KSBCMinBitpoolValue = 2;
sl@0: /**
sl@0: The maximum SBC bitpool value is 250 
sl@0: */	
sl@0: const TUint8 KSBCMaxBitpoolValue = 250;
sl@0: 
sl@0: /**
sl@0: The sampling frequency bits mask is 0b11, 2 bits
sl@0: */	
sl@0: const TUint8 KSBCSampFreqBitsMask  = 0x3;
sl@0: /**
sl@0: The bit offset of sampling frequency field in TSBCFrameParameters::iParameters is 6
sl@0: */
sl@0: const TUint8 KSBCSampFreqBitOffset = 6;
sl@0: 
sl@0: /**
sl@0: The block length bits mask is 0b11, 2 bits
sl@0: */	
sl@0: const TUint8 KSBCBlckLengBitsMask  = 0x3;
sl@0: /**
sl@0: The bit offset of block length field in TSBCFrameParameters::iParameters is 4
sl@0: */
sl@0: const TUint8 KSBCBlckLengBitOffset = 4;
sl@0: 
sl@0: /**
sl@0: The block length bits mask is 0b11, 2 bits
sl@0: */	
sl@0: const TUint8 KSBCChnlModeBitsMask  = 0x3;
sl@0: /**
sl@0: The bit offset of block length field in TSBCFrameParameters::iParameters is 2
sl@0: */
sl@0: const TUint8 KSBCChnlModeBitOffset = 2;
sl@0: 
sl@0: /**
sl@0: The block length bits mask is 0b01, 1 bit
sl@0: */	
sl@0: const TUint8 KSBCAllcMthdBitsMask  = 0x1;
sl@0: /**
sl@0: The bit offset of block length field in TSBCFrameParameters::iParameters is 1
sl@0: */
sl@0: const TUint8 KSBCAllcMthdBitOffset = 1;
sl@0: 
sl@0: /**
sl@0: The block length bits mask is 0b01, 1 bit
sl@0: */	
sl@0: const TUint8 KSBCSubbandsBitsMask  = 0x1;
sl@0: /**
sl@0: The bit offset of block length field in TSBCFrameParameters::iParameters is 0
sl@0: */
sl@0: const TUint8 KSBCSubbandsBitOffset = 0;
sl@0: 
sl@0: /**
sl@0: Constructor
sl@0: @internalComponent
sl@0: */
sl@0: inline TSBCFrameParameters::TSBCFrameParameters() : iParameters(0), iBitpool(0)
sl@0: 	{
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0: This function reset all the parameters
sl@0: @internalComponent
sl@0: */
sl@0: inline void TSBCFrameParameters::Reset()
sl@0: 	{
sl@0: 	iParameters = 0;
sl@0: 	iBitpool = 0;
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0: This function gets the sampling frequency enum value
sl@0: @internalComponent
sl@0: @return enum value of sampling frequency
sl@0: */
sl@0: inline TUint8 TSBCFrameParameters::SamplingFrequencyEnum() const
sl@0: 	{
sl@0: 	return static_cast<TUint8>( (iParameters >> KSBCSampFreqBitOffset) & KSBCSampFreqBitsMask);
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0: This function gets the sampling frequency value in Hz
sl@0: @internalComponent
sl@0: @return samplinng frequency value in Hz
sl@0: */
sl@0: inline TUint TSBCFrameParameters::SamplingFrequencyHz() const
sl@0: 	{
sl@0: 	switch (SamplingFrequencyEnum() )
sl@0: 		{
sl@0: 		case E16000Hz:
sl@0: 			return 16000;
sl@0: 			
sl@0: 		case E32000Hz:
sl@0: 			return 32000;
sl@0: 			
sl@0: 		case E44100Hz:
sl@0: 			return 44100;
sl@0: 			
sl@0: 		case E48000Hz:
sl@0: 			return 48000;
sl@0: 		}
sl@0: 	return 0;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function sets the sampling frequency value
sl@0: @internalComponent
sl@0: @param aSampFreq
sl@0: New sampling frequency enum value to set
sl@0: */
sl@0: inline void TSBCFrameParameters::SetSamplingFrequency(TSamplingFrequency aSampFreq)
sl@0: 	{
sl@0: 	// clear sampling frequency bits
sl@0: 	iParameters &= ~(KSBCSampFreqBitsMask << KSBCSampFreqBitOffset);
sl@0: 	// set new sampling frequency bits
sl@0: 	iParameters |= ( (aSampFreq & KSBCSampFreqBitsMask) << KSBCSampFreqBitOffset);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function gets the block length value
sl@0: @internalComponent
sl@0: @return number of blocks in one frame
sl@0: */
sl@0: inline TUint8 TSBCFrameParameters::BlockLength() const
sl@0: 	{
sl@0: 	switch ( (iParameters >> KSBCBlckLengBitOffset) & KSBCBlckLengBitsMask)
sl@0: 		{
sl@0: 		case E4Blocks:
sl@0: 			return 4;
sl@0: 			
sl@0: 		case E8Blocks:
sl@0: 			return 8;
sl@0: 			
sl@0: 		case E12Blocks:
sl@0: 			return 12;
sl@0: 			
sl@0: 		case E16Blocks:
sl@0: 			return 16;
sl@0: 		}
sl@0: 	return 0;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function sets the block length value
sl@0: @internalComponent
sl@0: @param aBlockLen
sl@0: New block length value to set
sl@0: */
sl@0: inline void TSBCFrameParameters::SetBlockLength(TBlockLength aBlockLen)
sl@0: 	{
sl@0: 	// clear block length bits
sl@0: 	iParameters &= ~(KSBCBlckLengBitsMask << KSBCBlckLengBitOffset);
sl@0: 	// set new block length bits
sl@0: 	iParameters |= ( (aBlockLen & KSBCBlckLengBitsMask) << KSBCBlckLengBitOffset);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function gets the channel mode enum value
sl@0: @internalComponent
sl@0: @return channel mode enum value
sl@0: */
sl@0: inline TUint8 TSBCFrameParameters::ChannelMode() const
sl@0: 	{
sl@0: 	return static_cast<TUint8>( (iParameters >> KSBCChnlModeBitOffset) & KSBCChnlModeBitsMask);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function gets number of channels
sl@0: @internalComponent
sl@0: @return number of channels
sl@0: */
sl@0: inline TUint8 TSBCFrameParameters::Channels() const
sl@0: 	{
sl@0: 	switch (ChannelMode() )
sl@0: 		{
sl@0: 		case EMono:
sl@0: 			return 1;
sl@0: 			
sl@0: 		case EDualChannel:
sl@0: 		case EStereo:
sl@0: 		case EJointStereo:
sl@0: 			return 2;
sl@0: 		}
sl@0: 	return 0;
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0: This function sets the channel mode enum value
sl@0: @internalComponent
sl@0: @param aChnlMode
sl@0: New channel mode enum value to set
sl@0: */
sl@0: inline void TSBCFrameParameters::SetChannelMode(TChannelMode aChnlMode)
sl@0: 	{
sl@0: 	// clear channel mode bits
sl@0: 	iParameters &= ~(KSBCChnlModeBitsMask << KSBCChnlModeBitOffset);
sl@0: 	// set new channel mode bits
sl@0: 	iParameters |= ( (aChnlMode & KSBCChnlModeBitsMask) << KSBCChnlModeBitOffset);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function gets the allocation method enum value
sl@0: @internalComponent
sl@0: @return allocation method enum value
sl@0: */
sl@0: inline TUint8 TSBCFrameParameters::AllocationMethod() const
sl@0: 	{
sl@0: 	return static_cast<TUint8>( (iParameters >> KSBCAllcMthdBitOffset) & KSBCAllcMthdBitsMask);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function sets the channel mode enum value
sl@0: @internalComponent
sl@0: @param aAllocMethod
sl@0: New channel mode enum value to set
sl@0: */
sl@0: inline void TSBCFrameParameters::SetAllocationMethod(TAllocationMethod aAllocMethod)
sl@0: 	{
sl@0: 	// clear allocation method bits
sl@0: 	iParameters &= ~(KSBCAllcMthdBitsMask << KSBCAllcMthdBitOffset);
sl@0: 	// set new allocation method bits
sl@0: 	iParameters |= ( (aAllocMethod & KSBCAllcMthdBitsMask) << KSBCAllcMthdBitOffset);
sl@0: 	}		
sl@0: 
sl@0: /**
sl@0: This function gets the subbands enum value
sl@0: @internalComponent
sl@0: @return subbands enum value
sl@0: */
sl@0: inline TUint8 TSBCFrameParameters::SubbandsEnum() const
sl@0: 	{
sl@0: 	return static_cast<TUint8>( (iParameters >> KSBCSubbandsBitOffset) & KSBCSubbandsBitsMask);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function gets the subbands value
sl@0: @internalComponent
sl@0: @return subbands value, i.e 4, 8
sl@0: */
sl@0: inline TUint8 TSBCFrameParameters::Subbands() const
sl@0: 	{
sl@0: 	switch (SubbandsEnum() )
sl@0: 		{
sl@0: 		case E4Subbands:
sl@0: 			return 4;
sl@0: 			
sl@0: 		case E8Subbands:
sl@0: 			return 8;
sl@0: 		}
sl@0: 	return 0;
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0: This function sets the subbands enum value
sl@0: @internalComponent
sl@0: @param aSubbands
sl@0: New subbands enum value to set
sl@0: */
sl@0: inline void TSBCFrameParameters::SetSubbands(TSubbands aSubbands)
sl@0: 	{
sl@0: 	// clear subbands bits
sl@0: 	iParameters &= ~(KSBCSubbandsBitsMask << KSBCSubbandsBitOffset);
sl@0: 	// set new subbands bits
sl@0: 	iParameters |= ( (aSubbands & KSBCSubbandsBitsMask) << KSBCSubbandsBitOffset);
sl@0: 	}		
sl@0: 
sl@0: /**
sl@0: This function gets the bitpool value
sl@0: @internalComponent
sl@0: @return bitpool value
sl@0: */
sl@0: inline TUint8 TSBCFrameParameters::Bitpool() const
sl@0: 	{
sl@0: 	return iBitpool;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function sets the bitpool enum value
sl@0: @internalComponent
sl@0: @param aSubbands
sl@0: New bitpool enum value to set
sl@0: */
sl@0: inline void TSBCFrameParameters::SetBitpool(TUint8 aBitpool)
sl@0: 	{
sl@0: 	iBitpool = aBitpool;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function gets the 5 parameters (except bitpool) byte value
sl@0: @internalComponent
sl@0: @return 5 parameters byte value
sl@0: */
sl@0: inline TUint8 TSBCFrameParameters::Parameters() const
sl@0: 	{
sl@0: 	return iParameters;
sl@0: 	}
sl@0: 	
sl@0: /**
sl@0: This function checks the bitpool value according to:
sl@0: 1. bitpool >= 2 and bitpool <= 250
sl@0: 2. bitpool <= 16 * subbands for Mono and Dual Channel,
sl@0:    bitpool <= 32 * subbands for Stereo and Joint Stereo 
sl@0: 3. results in bit_rate <= 320 kbps for Mono
sl@0:    results in bit_rate <= 512 kpbs for two-channel modes
sl@0: @internalComponent
sl@0: @return -1 if invalid; 0 if valid
sl@0: */
sl@0: inline TInt TSBCFrameParameters::Validate() const
sl@0: 	{
sl@0: 	if (iBitpool < KSBCMinBitpoolValue || iBitpool > KSBCMaxBitpoolValue)
sl@0: 		{
sl@0: 		return -1;
sl@0: 		}
sl@0: 		
sl@0: 	const TUint16 numSubbands = Subbands(); // use 16 bits to avoid overflow
sl@0: 	const TUint8 channelMode = ChannelMode();
sl@0: 	
sl@0: 	if (channelMode == EMono || channelMode == EDualChannel)
sl@0: 		{
sl@0: 		// bitpool <= 16 * subbands, for Mono and Dual_Channel modes
sl@0: 		if (iBitpool > (numSubbands << 4) )
sl@0: 			{
sl@0: 			return -1;
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		// bitpool <= 32 * subbands, for Stereo and Joint_Stereo modes
sl@0: 		if (iBitpool > (numSubbands << 5) )
sl@0: 			{
sl@0: 			return -1;
sl@0: 			}
sl@0: 		}
sl@0: 	
sl@0: 	if (channelMode == EMono)
sl@0: 		{
sl@0: 		// bit rate <= 320kbps for Mono mode
sl@0: 		if (CalcBitRate(CalcFrameLength() ) > 320)
sl@0: 			{
sl@0: 			return -1;
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		// bit rate <= 512kpbs for two-channels modes
sl@0: 		if (CalcBitRate(CalcFrameLength() ) > 512)
sl@0: 			{
sl@0: 			return -1;
sl@0: 			}
sl@0: 		}
sl@0: 	
sl@0: 	return 0;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function calculates the frame length value according to:
sl@0: 1. for MONO or DUAL_CHANNEL
sl@0:    frame_len = 4 + (4 * subbands * channels) / 8 + ceil(blocks * channels * bitpool / 8)
sl@0: 2. for STEREO
sl@0:    frame_len = 4 + (4 * subbands * channels) / 8 + ceil(blocks * bitpool / 8)
sl@0: 3. for JOINT_STEREO
sl@0:    frame_len = 4 + (4 * subbands * channels) / 8 + ceil((subbands + blocks * bitpool) / 8)
sl@0: ceil(), taking the upper integer value
sl@0: @internalComponent
sl@0: @return frame length value
sl@0: */
sl@0: inline TUint TSBCFrameParameters::CalcFrameLength() const
sl@0: 	{
sl@0: 	TUint temp = 0;
sl@0: 	switch (ChannelMode() )
sl@0: 		{
sl@0: 		case EMono:
sl@0: 			temp = BlockLength() * Bitpool(); // blocks * bitpool
sl@0: 			break;
sl@0: 			
sl@0: 		case EDualChannel:
sl@0: 			temp = (BlockLength() * Bitpool() ) << 1; // blocks * bitpool * 2
sl@0: 			break;
sl@0: 			
sl@0: 		case EStereo:
sl@0: 			temp = BlockLength() * Bitpool(); // blocks * bitpool
sl@0: 			break;
sl@0: 			
sl@0: 		case EJointStereo:
sl@0: 			temp = Subbands() + BlockLength() * Bitpool(); // subbands + blocks * bitpool
sl@0: 			break;
sl@0: 			
sl@0: 		default:
sl@0: 			User::Panic(_L("Invalid channel mode"), KErrNotSupported);
sl@0: 			break;
sl@0: 		}
sl@0: 		
sl@0: 	TUint frameLen = 4 + ( (Subbands() * Channels() ) >> 1) + (temp >> 3);
sl@0: 	if (temp & 0x7)
sl@0: 		{
sl@0: 		frameLen++;
sl@0: 		}
sl@0: 		
sl@0: 	return frameLen;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: This function calculates the bit rate value according to:
sl@0: 	bit_rate = 8 * frame_len * sampling_freq / subbands / blocks
sl@0: @internalComponent
sl@0: @return bit rate value in kHz
sl@0: */
sl@0: inline TUint TSBCFrameParameters::CalcBitRate(TUint aFrameLen) const
sl@0: 	{
sl@0: 	return (aFrameLen << 3) * SamplingFrequencyHz() / (Subbands() * BlockLength() * 1000);
sl@0: 	}
sl@0: 
sl@0: #endif // __BTSBCFRAMEPARAMETERS_H__
sl@0: