blob: ae13bb11330547f348915a7fbbb358226e75f1d6 [file] [log] [blame]
Alexandre Lision67916dd2014-01-24 13:33:04 -05001#ifndef __BITSTREAM_H_
2#define __BITSTREAM_H_
3
4#define KPackedFrameLen 10
5#define KUnpackedFrameLen 22
6
7// Below values are taken from the APS design document
8const TUint8 KG729FullPayloadBits[] = { 8, 10, 8, 1, 13, 4, 7, 5, 13, 4, 7 };
9const TUint KNumFullFrameParams = 11;
10const TUint8 KG729SIDPayloadBits[] = { 1, 5, 4, 5 };
11const TUint KNumSIDFrameParams = 4;
12
13/*!
14 @class TBitStream
15
16 @discussion Provides compression from 16-bit-word-aligned G.729 audio frames
17 (used in S60 G.729 DSP codec) to 8-bit stream, and vice versa.
18 */
19class TBitStream
20 {
21public:
22 /*!
23 @function TBitStream
24
25 @discussion Constructor
26 */
27 TBitStream():iDes(iData,KUnpackedFrameLen){}
28 /*!
29 @function CompressG729Frame
30
31 @discussion Compress either a 22-byte G.729 full rate frame to 10 bytes
32 or a 8-byte G.729 Annex.B SID frame to 2 bytes.
33 @param aSrc Reference to the uncompressed source frame data
34 @param aIsSIDFrame True if the source is a SID frame
35 @result a reference to the compressed frame
36 */
37 const TDesC8& CompressG729Frame( const TDesC8& aSrc, TBool aIsSIDFrame = EFalse );
38
39 /*!
40 @function ExpandG729Frame
41
42 @discussion Expand a 10-byte G.729 full rate frame to 22 bytes
43 or a 2-byte G.729 Annex.B SID frame to 8(22) bytes.
44 @param aSrc Reference to the compressed source frame data
45 @param aIsSIDFrame True if the source is a SID frame
46 @result a reference to a descriptor representing the uncompressed frame.
47 Note that SID frames are zero-padded to 22 bytes as well.
48 */
49 const TDesC8& ExpandG729Frame( const TDesC8& aSrc, TBool aIsSIDFrame = EFalse );
50
51private:
52 void Compress( TUint8 aValue, TUint8 aNumOfBits );
53 void Expand( const TUint8* aSrc, TInt aDstIdx, TUint8 aNumOfBits );
54
55private:
56 TUint8 iData[KUnpackedFrameLen];
57 TPtr8 iDes;
58 TInt iIdx;
59 TInt iBitOffset;
60 };
61
62
63const TDesC8& TBitStream::CompressG729Frame( const TDesC8& aSrc, TBool aIsSIDFrame )
64 {
65 // reset data
66 iDes.FillZ(iDes.MaxLength());
67 iIdx = iBitOffset = 0;
68
69 TInt numParams = (aIsSIDFrame) ? KNumSIDFrameParams : KNumFullFrameParams;
70 const TUint8* p = const_cast<TUint8*>(aSrc.Ptr());
71
72 for(TInt i = 0, pIdx = 0; i < numParams; i++, pIdx += 2)
73 {
74 TUint8 paramBits = (aIsSIDFrame) ? KG729SIDPayloadBits[i] : KG729FullPayloadBits[i];
75 if(paramBits > 8)
76 {
77 Compress(p[pIdx+1], paramBits - 8); // msb
78 paramBits = 8;
79 }
80 Compress(p[pIdx], paramBits); // lsb
81 }
82
83 if( iBitOffset )
84 iIdx++;
85
86 iDes.SetLength(iIdx);
87 return iDes;
88 }
89
90
91const TDesC8& TBitStream::ExpandG729Frame( const TDesC8& aSrc, TBool aIsSIDFrame )
92 {
93 // reset data
94 iDes.FillZ(iDes.MaxLength());
95 iIdx = iBitOffset = 0;
96
97 TInt numParams = (aIsSIDFrame) ? KNumSIDFrameParams : KNumFullFrameParams;
98 const TUint8* p = const_cast<TUint8*>(aSrc.Ptr());
99
100 for(TInt i = 0, dIdx = 0; i < numParams; i++, dIdx += 2)
101 {
102 TUint8 paramBits = (aIsSIDFrame) ? KG729SIDPayloadBits[i] : KG729FullPayloadBits[i];
103 if(paramBits > 8)
104 {
105 Expand(p, dIdx+1, paramBits - 8); // msb
106 paramBits = 8;
107 }
108 Expand(p, dIdx, paramBits); // lsb
109 }
110
111 iDes.SetLength(KUnpackedFrameLen);
112 return iDes;
113 }
114
115
116void TBitStream::Compress( TUint8 aValue, TUint8 aNumOfBits )
117 {
118 // clear bits that will be discarded
119 aValue &= (0xff >> (8 - aNumOfBits));
120
121 // calculate required bitwise left shift
122 TInt shl = 8 - (iBitOffset + aNumOfBits);
123
124 if (shl == 0) // no shift required
125 {
126 iData[iIdx++] |= aValue;
127 iBitOffset = 0;
128 }
129 else if (shl > 0) // bits fit into current byte
130 {
131 iData[iIdx] |= (aValue << shl);
132 iBitOffset += aNumOfBits;
133 }
134 else
135 {
136 iBitOffset = -shl;
137 iData[iIdx] |= (aValue >> iBitOffset); // right shift
138 iData[++iIdx] |= (aValue << (8-iBitOffset)); // push remaining bits to next byte
139 }
140 }
141
142
143void TBitStream::Expand( const TUint8* aSrc, TInt aDstIdx, TUint8 aNumOfBits )
144 {
145 TUint8 aValue = aSrc[iIdx] & (0xff >> iBitOffset);
146
147 // calculate required bitwise right shift
148 TInt shr = 8 - (iBitOffset + aNumOfBits);
149
150 if (shr == 0) // no shift required
151 {
152 iData[aDstIdx] = aValue;
153 iIdx++;
154 iBitOffset = 0;
155 }
156 else if (shr > 0) // right shift
157 {
158 iData[aDstIdx] = (aValue >> shr);
159 iBitOffset += aNumOfBits;
160 }
161 else // shift left and take remaining bits from the next src byte
162 {
163 iBitOffset = -shr;
164 iData[aDstIdx] = aValue << iBitOffset;
165 iData[aDstIdx] |= aSrc[++iIdx] >> (8 - iBitOffset);
166 }
167 }
168
169#endif // __BITSTREAM_H_
170
171// eof