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 __A2DPCODECUTILITIES_H__
sl@0: #define __A2DPCODECUTILITIES_H__
sl@0: 
sl@0: 
sl@0: #include <bluetoothav.h> //TAvdtpSEPInfo, TSEID
sl@0: #include <mmf/server/sounddevice.h> //TMMFStereoSupport
sl@0: #include "BtSBCFrameParameters.h"
sl@0: 
sl@0: //[TODO] change this to 44100 when we have hardware that supports higher data rates
sl@0: const TUint KDefaultSampleRate = 32000;
sl@0: const TUint KDefaultBitPoolValue = 20;
sl@0: //[TODO] change this to EMMFStereo & EMMFInterleavedOnly when we have hardware that supports higher data rates
sl@0: const TUint KDefaultChannels = EMMFMono;
sl@0: const TMMFStereoSupport KDefaultStereoSupport = EMMFNone;
sl@0: 
sl@0: const TUint KMinBitPoolValue = 2;
sl@0: const TUint KMaxBitPoolValue = 250;
sl@0: 
sl@0: //A2DP codec specific data masks
sl@0: const TUint8 KA2dpMPEG12AudioChannelModeMask = 0x0F; //A2DP 4.4.2.3
sl@0: const TUint8 KA2dpMPEG12LayerMask = 0xE0; //A2DP 4.4.2.1
sl@0: const TUint8 KA2dpMPEG12LayerMP3Supported = 0x20; //A2DP 4.4.2.1
sl@0: const TUint8 KA2dpMPEG12SamplingFrequencyMask = 0x3F; //A2DP 4.4.2.5
sl@0: const TUint8 KA2dpMPEG12SupportedBitRateIndex = 0xFE; //A2DP 4.4.2.7 octet 3 all bit rates <=96kbs-1 except free
sl@0: 
sl@0: //RTP Codec profile specific constants
sl@0: const TUint KMPEG12RTPTimeStampClock = 90000; //RFC2250 3.3
sl@0: const TUint KSbcRTPPayloadType = 0; //A2DP 4.3.3.2 isn't too clear on this but 0 seems ok
sl@0: const TUint KMPEG12RTPAudioPayloadType = 14; //MPA MPEG12 PT RFC3551 6
sl@0: const TUint KSbcRTPMediaPayloadHeaderLength = 1;//A2DP 4.3.4
sl@0: const TUint KMPEG12RTPMediaPayloadHeaderLength = 4;//MPF-1 RFC2250 3.5 
sl@0: 
sl@0: //Frame header masks
sl@0: const TUint8 KSbcFrameHeaderSyncWord = 0x9C;
sl@0: const TUint8 KSbcFrameHeaderSamplingFrequencyMask = 0xC0;
sl@0: const TUint8 KSbcFrameHeaderBlocksMask = 0x30;
sl@0: const TUint8 KSbcFrameHeaderChannelModeMask = 0x0C;
sl@0: const TUint8 KSbcFrameHeaderSubbandsMask = 0x01;
sl@0: const TUint8 KMPEGAudioFrameHeaderSyncWord = 0xFF;
sl@0: const TUint8 KMp3AudioFrameHeaderIdMask = 0xFE;//mask out CRC
sl@0: const TUint8 KMp3AudioFrameHeaderId = 0xFA;
sl@0: const TUint8 KMp3FrameHeaderSamplingFrequencyMask = 0x0C;
sl@0: const TUint8 KMp3FrameHeaderBitRateIndexMask = 0xF0;
sl@0: 
sl@0: using namespace SymbianSBC;
sl@0: using namespace SymbianBluetoothAV;	
sl@0: 
sl@0: 
sl@0: typedef TUint8	TMPEG12SamplingFrequencyBitmask;
sl@0: 	
sl@0: /**
sl@0: Mask for configuring mp3 sampling frequencies
sl@0: */
sl@0: enum TMPEG12SamplingFrequency
sl@0: 	{
sl@0: 	EMPEG12_16kHz		= 0x20,
sl@0: 	EMPEG12_22050Hz		= 0x10,
sl@0: 	EMPEG12_24kHz		= 0x8,
sl@0: 	EMPEG12_32kHz		= 0x4,
sl@0: 	EMPEG12_44100Hz		= 0x2,
sl@0: 	EMPEG12_48kHz		= 0x1
sl@0: 	};
sl@0: 
sl@0: 
sl@0: /**
sl@0: mp3 bit rate index table
sl@0: */	
sl@0: enum TMp3BitRateIndex
sl@0: 	{
sl@0: 	EMp3BitRateIndex32000	= 0x01,
sl@0: 	EMp3BitRateIndex40000	= 0x02,
sl@0: 	EMp3BitRateIndex48000	= 0x03,
sl@0: 	EMp3BitRateIndex56000	= 0x04,
sl@0: 	EMp3BitRateIndex64000	= 0x05,
sl@0: 	EMp3BitRateIndex80000	= 0x06,
sl@0: 	EMp3BitRateIndex96000	= 0x07,
sl@0: 	EMp3BitRateIndex112000	= 0x08,
sl@0: 	EMp3BitRateIndex128000	= 0x09,
sl@0: 	EMp3BitRateIndex160000	= 0x0A,
sl@0: 	EMp3BitRateIndex192000	= 0x0B,
sl@0: 	EMp3BitRateIndex224000	= 0x0C,
sl@0: 	EMp3BitRateIndex256000	= 0x0D,
sl@0: 	EMp3BitRateIndex320000	= 0x0E
sl@0: 	};
sl@0: 
sl@0: /**
sl@0: Utility that parses the codec capabilities to get the supported sample rates and channels
sl@0: 
sl@0: @internalComponent
sl@0: */
sl@0: class TA2dpCodecCapabilityParser
sl@0: 	{
sl@0: public:
sl@0: 	static TInt GetSupportedSampleRates(const TAvdtpMediaCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedDiscreteRates);
sl@0: 	static TInt GetSupportedChannels(const TAvdtpMediaCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedChannels, TMMFStereoSupport& aStereoSupport);
sl@0: private:
sl@0: 	static TInt GetSupportedSBCSampleRates(const TSBCCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedDiscreteRates);
sl@0: 	static TInt GetSupportedMPEG12SampleRates(const TNonSBCCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedDiscreteRates);
sl@0: 	static TInt GetSupportedSBCChannels(const TSBCCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedChannels, TMMFStereoSupport& aStereoSupport);
sl@0: 	static TInt GetSupportedMPEG12Channels(const TNonSBCCodecCapabilities& aCodecCaps, RArray<TUint>& aSupportedChannels, TMMFStereoSupport& aStereoSupport);
sl@0: 	static TInt GetSupportedChannelsCommonCode(TSBCChannelModeBitmask aChannelModesBitMask, RArray<TUint>& aSupportedChannels, TMMFStereoSupport& aStereoSupport);
sl@0: 	};
sl@0: 
sl@0: 
sl@0: /**
sl@0: Utility to get codec specific RTP header parameters
sl@0: 
sl@0: @internalComponent
sl@0: */
sl@0: class TRTPa2dpCodecSpecificUtils
sl@0: 	{
sl@0: public:
sl@0: 	static TUint8 PayloadType(const TFourCC& aCodecDataType);
sl@0: 	static TUint MediaPayloadHeaderLength(const TFourCC& aCodecDataType);
sl@0: 	};
sl@0: 
sl@0: 
sl@0: /**
sl@0: Utility to calculate frame duration and time stamp increments
sl@0: 
sl@0: @internalComponent
sl@0: */	
sl@0: class TFrameTimingUtils
sl@0: 	{
sl@0: public:
sl@0: 	static TTimeIntervalMicroSeconds32 FrameDuration(TUint aFrameLength, TUint aBitRate);
sl@0: 	static TUint TimeStampIncrementPerFrame(const TFourCC& aCodecDataType, TUint aFrameLength, TUint aBitRate, TUint aSampleRate);
sl@0: private:
sl@0: 	static TUint CalculateSBCTimeStampIncrementPerFrame(TUint aFrameLength, TUint aBitRate, TUint aSampleRate);
sl@0: 	static TUint CalculateMPEG12TimeStampIncrementPerFrame(TUint aFrameLength, TUint aBitRate);
sl@0: 	};
sl@0: 
sl@0: 
sl@0: /**
sl@0: Utility class to store the local SEP codec capabilities
sl@0: 
sl@0: @internalComponent
sl@0: */
sl@0: NONSHARABLE_CLASS(CA2dpLocalCodecCapabilities) : public CBase
sl@0: 	{
sl@0: public:
sl@0: 	static CA2dpLocalCodecCapabilities* NewL();
sl@0: 	~CA2dpLocalCodecCapabilities();
sl@0: 	TAvdtpMediaCodecCapabilities* LocalCodecCapabilities(const TFourCC& aCodecDataType);
sl@0: private:
sl@0: 	CA2dpLocalCodecCapabilities();
sl@0: 	TSBCCodecCapabilities* LocalSBCCodecCapabilities();
sl@0: 	TNonSBCCodecCapabilities* LocalMPEG12CodecCapabilities();
sl@0: private:
sl@0: 	TAvdtpMediaCodecCapabilities* iLocalCodecCapabilities; //this is owned
sl@0: 	};
sl@0: 
sl@0: 	
sl@0: /** 
sl@0: Utiltiy class to store remote (ie headset) codec configuration 
sl@0: and the local (ie symbian OS device) SBC codec configuration.
sl@0: An instance of this class is owned by CA2dpBTHeadsetAudioInterface 
sl@0: which sets the settings - the configuration is passed to the GAVDP state machine
sl@0: which needs the configuration to configure the SEPs and RTPStreeamer uses
sl@0: the configuration to calculate frame sizes and timings.
sl@0: 
sl@0: @internalComponent
sl@0: */
sl@0: NONSHARABLE_CLASS(CA2dpAudioCodecConfiguration) : public CBase 
sl@0: 	{
sl@0: public:
sl@0: 	static CA2dpAudioCodecConfiguration* NewL();
sl@0: 	~CA2dpAudioCodecConfiguration();
sl@0: 	void Reset();
sl@0: 	inline void SetHeadsetCodecDataType(const TFourCC& aHeadsetCodecDataType);
sl@0: 	inline void SetSampleRate(TUint aSampleRate);
sl@0: 	inline void SetChannels(TUint aChannels);
sl@0: 	inline void SetStereoSupport(TMMFStereoSupport aStereoSupport);
sl@0: 	inline const TFourCC& HeadsetCodecDataType() const;
sl@0: 	inline TUint SampleRate() const;
sl@0: 	inline TUint Channels() const;
sl@0: 	inline TMMFStereoSupport StereoSupport() const;
sl@0: 	TAvdtpMediaCodecCapabilities* UpdateRemoteCodecConfiguration(const TAvdtpMediaCodecCapabilities& aRemoteCodecCapabilities);
sl@0: 	TSBCFrameParameters& UpdateLocalSBCCodecConfiguration();
sl@0: 	inline TAvdtpMediaCodecCapabilities* RemoteCodecConfiguration() const;
sl@0: 	inline const TSBCFrameParameters& LocalSBCCodecConfiguration() const;
sl@0: 	TTimeIntervalMicroSeconds32 FrameDuration(TUint aFrameLength) const;
sl@0: 	TUint TimeStampIncrementPerFrame(TUint aFrameLength) const;
sl@0: 	TUint CalculateSBCBufferLength(TUint aPCM16BufferLength) const;
sl@0: 	void TEST_ForceRemoteSBCCodecConfiguration(const TSBCCodecCapabilities& aRemoteCodecConfiguration);
sl@0: private:
sl@0: 	CA2dpAudioCodecConfiguration();
sl@0: 	TSBCCodecCapabilities* GetRemoteSBCCodecConfiguration(const TSBCCodecCapabilities& aCodecCaps);
sl@0: 	TNonSBCCodecCapabilities* GetRemoteMPEG12CodecConfiguration(const TNonSBCCodecCapabilities& aCodecCaps);
sl@0: 	TTimeIntervalMicroSeconds32 CalculateSBCFrameDuration() const;
sl@0: 	TTimeIntervalMicroSeconds32 CalculateMPEG12FrameDuration() const;
sl@0: 	TUint CalculateSBCTimeStampIncrementPerFrame() const;
sl@0: 	TUint CalculateMPEG12TimeStampIncrementPerFrame() const;
sl@0: private:
sl@0: 	TFourCC iHeadsetCodecDataType;
sl@0: 	TUint	iSampleRate;
sl@0: 	TUint	iChannels;
sl@0: 	TMMFStereoSupport	iStereoSupport;
sl@0: 	TUint	iBitRate;
sl@0: 	TAvdtpMediaCodecCapabilities* iRemoteCodecConfiguration;
sl@0: 	TSBCFrameParameters iLocalSBCCodecConfiguration;
sl@0: 	TSBCCodecCapabilities* iForcedRemoteSBCCodecConfiguration;//just used for unit test purposes	
sl@0: 	};
sl@0: 
sl@0: 
sl@0: /**
sl@0: Utiltiy class to parse the header of non pcm16 data in order to obtain
sl@0: the frame length and bit rate
sl@0: 
sl@0: @internalComponent
sl@0: */
sl@0: NONSHARABLE_CLASS(CA2dpCodecFrameHeaderParser)
sl@0: 	{
sl@0: public:
sl@0: 	static CA2dpCodecFrameHeaderParser* NewL(const TFourCC& aCodecDataType, const TDesC8& aHeader);
sl@0: 	~CA2dpCodecFrameHeaderParser();
sl@0: 	inline TUint FrameLength() const;
sl@0: 	inline TUint BitRate() const;
sl@0: private:
sl@0: 	CA2dpCodecFrameHeaderParser();
sl@0: 	void ConstructL(const TFourCC& aCodecDataType, const TDesC8& aHeader);
sl@0: 	void ParseSBCHeaderL(const TDesC8& aHeader);
sl@0: 	void ParseMPEG12HeaderL(const TDesC8& aHeader);
sl@0: private:
sl@0: 	TUint iFrameLength;
sl@0: 	TUint iSampleRate;
sl@0: 	TUint iBitRate;
sl@0: 	};
sl@0: 
sl@0: #include "A2dpCodecUtilities.inl"
sl@0: 		
sl@0: #endif
sl@0: