blob: ae13bb11330547f348915a7fbbb358226e75f1d6 [file] [log] [blame]
#ifndef __BITSTREAM_H_
#define __BITSTREAM_H_
#define KPackedFrameLen 10
#define KUnpackedFrameLen 22
// Below values are taken from the APS design document
const TUint8 KG729FullPayloadBits[] = { 8, 10, 8, 1, 13, 4, 7, 5, 13, 4, 7 };
const TUint KNumFullFrameParams = 11;
const TUint8 KG729SIDPayloadBits[] = { 1, 5, 4, 5 };
const TUint KNumSIDFrameParams = 4;
/*!
@class TBitStream
@discussion Provides compression from 16-bit-word-aligned G.729 audio frames
(used in S60 G.729 DSP codec) to 8-bit stream, and vice versa.
*/
class TBitStream
{
public:
/*!
@function TBitStream
@discussion Constructor
*/
TBitStream():iDes(iData,KUnpackedFrameLen){}
/*!
@function CompressG729Frame
@discussion Compress either a 22-byte G.729 full rate frame to 10 bytes
or a 8-byte G.729 Annex.B SID frame to 2 bytes.
@param aSrc Reference to the uncompressed source frame data
@param aIsSIDFrame True if the source is a SID frame
@result a reference to the compressed frame
*/
const TDesC8& CompressG729Frame( const TDesC8& aSrc, TBool aIsSIDFrame = EFalse );
/*!
@function ExpandG729Frame
@discussion Expand a 10-byte G.729 full rate frame to 22 bytes
or a 2-byte G.729 Annex.B SID frame to 8(22) bytes.
@param aSrc Reference to the compressed source frame data
@param aIsSIDFrame True if the source is a SID frame
@result a reference to a descriptor representing the uncompressed frame.
Note that SID frames are zero-padded to 22 bytes as well.
*/
const TDesC8& ExpandG729Frame( const TDesC8& aSrc, TBool aIsSIDFrame = EFalse );
private:
void Compress( TUint8 aValue, TUint8 aNumOfBits );
void Expand( const TUint8* aSrc, TInt aDstIdx, TUint8 aNumOfBits );
private:
TUint8 iData[KUnpackedFrameLen];
TPtr8 iDes;
TInt iIdx;
TInt iBitOffset;
};
const TDesC8& TBitStream::CompressG729Frame( const TDesC8& aSrc, TBool aIsSIDFrame )
{
// reset data
iDes.FillZ(iDes.MaxLength());
iIdx = iBitOffset = 0;
TInt numParams = (aIsSIDFrame) ? KNumSIDFrameParams : KNumFullFrameParams;
const TUint8* p = const_cast<TUint8*>(aSrc.Ptr());
for(TInt i = 0, pIdx = 0; i < numParams; i++, pIdx += 2)
{
TUint8 paramBits = (aIsSIDFrame) ? KG729SIDPayloadBits[i] : KG729FullPayloadBits[i];
if(paramBits > 8)
{
Compress(p[pIdx+1], paramBits - 8); // msb
paramBits = 8;
}
Compress(p[pIdx], paramBits); // lsb
}
if( iBitOffset )
iIdx++;
iDes.SetLength(iIdx);
return iDes;
}
const TDesC8& TBitStream::ExpandG729Frame( const TDesC8& aSrc, TBool aIsSIDFrame )
{
// reset data
iDes.FillZ(iDes.MaxLength());
iIdx = iBitOffset = 0;
TInt numParams = (aIsSIDFrame) ? KNumSIDFrameParams : KNumFullFrameParams;
const TUint8* p = const_cast<TUint8*>(aSrc.Ptr());
for(TInt i = 0, dIdx = 0; i < numParams; i++, dIdx += 2)
{
TUint8 paramBits = (aIsSIDFrame) ? KG729SIDPayloadBits[i] : KG729FullPayloadBits[i];
if(paramBits > 8)
{
Expand(p, dIdx+1, paramBits - 8); // msb
paramBits = 8;
}
Expand(p, dIdx, paramBits); // lsb
}
iDes.SetLength(KUnpackedFrameLen);
return iDes;
}
void TBitStream::Compress( TUint8 aValue, TUint8 aNumOfBits )
{
// clear bits that will be discarded
aValue &= (0xff >> (8 - aNumOfBits));
// calculate required bitwise left shift
TInt shl = 8 - (iBitOffset + aNumOfBits);
if (shl == 0) // no shift required
{
iData[iIdx++] |= aValue;
iBitOffset = 0;
}
else if (shl > 0) // bits fit into current byte
{
iData[iIdx] |= (aValue << shl);
iBitOffset += aNumOfBits;
}
else
{
iBitOffset = -shl;
iData[iIdx] |= (aValue >> iBitOffset); // right shift
iData[++iIdx] |= (aValue << (8-iBitOffset)); // push remaining bits to next byte
}
}
void TBitStream::Expand( const TUint8* aSrc, TInt aDstIdx, TUint8 aNumOfBits )
{
TUint8 aValue = aSrc[iIdx] & (0xff >> iBitOffset);
// calculate required bitwise right shift
TInt shr = 8 - (iBitOffset + aNumOfBits);
if (shr == 0) // no shift required
{
iData[aDstIdx] = aValue;
iIdx++;
iBitOffset = 0;
}
else if (shr > 0) // right shift
{
iData[aDstIdx] = (aValue >> shr);
iBitOffset += aNumOfBits;
}
else // shift left and take remaining bits from the next src byte
{
iBitOffset = -shr;
iData[aDstIdx] = aValue << iBitOffset;
iData[aDstIdx] |= aSrc[++iIdx] >> (8 - iBitOffset);
}
}
#endif // __BITSTREAM_H_
// eof