sl@0: // Copyright (c) 2004-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 __SBCFRAMEPARAMETERS_H__ sl@0: #define __SBCFRAMEPARAMETERS_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( (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( (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( (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( (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 // __SBCFRAMEPARAMETERS_H__ sl@0: