|
1 /* |
|
2 * Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: PayloadFormat plugin capable to read RTP payload containing |
|
15 * AMR audio. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 // INCLUDE FILES |
|
23 #include "amrcommonutil.h" |
|
24 |
|
25 // LOCAL CONSTANTS AND MACROS |
|
26 |
|
27 // The size of AMR header, header must include bits for determining frame length |
|
28 const TInt KRawAmrFrameHeaderSize = 1; |
|
29 |
|
30 // Frame length table ( number of frame bytes ) |
|
31 const TInt KRawAmrNbFrameLength[16] = { 13,14,16,18,20,21,27,32,6,0,0,0,0,0,0,1 }; |
|
32 |
|
33 // Stuffing length table ( number of stuffing bits ) |
|
34 const TInt KRawAmrNbStuffLength[16] = { 4, 4, 5, 5, 7, 4, 7, 7, 4,0,0,0,0,0,0,3 }; |
|
35 |
|
36 // Maximum sampling rate |
|
37 const TInt KRawAmrNbMaxSampleRate = 8000; |
|
38 |
|
39 // Maximum number of channels |
|
40 const TInt KRawAmrMaxChannels = 1; |
|
41 |
|
42 // Maximum number of PCM samples in one AMR frame |
|
43 const TInt KRawAmrNbMaxSamplesPerFrame = 160; |
|
44 |
|
45 // Frame length table ( number of frame bytes ) |
|
46 const TInt KRawAmrWbFrameLength[16] = { 18,24,33,37,41,47,51,59,61,6,0,0,0,0,0,1 }; |
|
47 |
|
48 // Stuffing length table ( number of stuffing bits ) |
|
49 const TInt KRawAmrWbStuffLength[16] = { 4, 7, 3, 3, 3, 3, 3, 3, 3,0,0,0,0,0,0,3 }; |
|
50 |
|
51 // Maximum sampling rate |
|
52 const TInt KRawAmrWbMaxSampleRate = 16000; |
|
53 |
|
54 // Maximum number of PCM samples in one AMR-WB frame |
|
55 const TInt KRawAmrWbMaxSamplesPerFrame = 320; |
|
56 |
|
57 // ============================ MEMBER FUNCTIONS =============================== |
|
58 |
|
59 // ----------------------------------------------------------------------------- |
|
60 // CAmrCommonUtility::FrameInfo |
|
61 // |
|
62 // Calculates the frame size and returns information about the frame which |
|
63 // starts from the beginning of aBuf. Returns 0, if the frame bit syntax is |
|
64 // incorrect or not enough bits are available for calculating the frame size |
|
65 // and the frame parameters ( aBufLen < TAmrCodecParams::FrameHeaderSize ). |
|
66 // |
|
67 // The frame parameters returned via aInfo are: mode, sampling frequency, |
|
68 // number of channels, frame size ( same as return value ) and number of |
|
69 // samples in this frame. |
|
70 // ----------------------------------------------------------------------------- |
|
71 // |
|
72 TInt CAmrCommonUtility::FrameInfo( const TUint8* aBuf, TInt aBufLen, |
|
73 TAmrFrameInfo& aInfo, TBool aIsNb ) |
|
74 { |
|
75 TInt length = 0; |
|
76 aInfo.iBitrate = 0; |
|
77 |
|
78 if( aBufLen >= KRawAmrFrameHeaderSize ) |
|
79 { |
|
80 // extract mode information |
|
81 const TInt mode = ( aBuf[0] & 0x78 ) >> 3; // 1st byte 0b.MODE... |
|
82 // get length |
|
83 length = |
|
84 ( aIsNb ? KRawAmrNbFrameLength[mode] : KRawAmrWbFrameLength[mode] ); |
|
85 |
|
86 // check start stuffing bits |
|
87 if( ( aBuf[0] & 0x83 ) != 0 ) |
|
88 { |
|
89 length = 0; // syntax error |
|
90 } |
|
91 |
|
92 // check end stuffing bits |
|
93 if( length > 0 && aBufLen >= length ) |
|
94 { |
|
95 TUint32 stuffBits = aBuf[length-1]; |
|
96 TInt stuffLength = |
|
97 ( aIsNb ? KRawAmrNbStuffLength[mode] : KRawAmrWbStuffLength[mode] ); |
|
98 stuffBits <<= ( KNumValue11 - stuffLength ); |
|
99 if( ( stuffBits & 0x0000FF ) != 0 ) |
|
100 { |
|
101 length = 0; // syntax error |
|
102 } |
|
103 } |
|
104 |
|
105 // update frame parameters |
|
106 aInfo.iMode = mode; |
|
107 // Frames are 20 ms long -> 50 frames/s. Frame length is in 8 bit bytes. |
|
108 // Hence the number 400. This same for both nb and wb. |
|
109 aInfo.iBitrate = length * KNumValue400; |
|
110 aInfo.iSamplingRate = |
|
111 ( aIsNb ? KRawAmrNbMaxSampleRate : KRawAmrWbMaxSampleRate ); |
|
112 aInfo.iChannels = KRawAmrMaxChannels; |
|
113 aInfo.iFrameSize = length; |
|
114 aInfo.iFrameSamples = |
|
115 ( aIsNb ? KRawAmrNbMaxSamplesPerFrame : KRawAmrWbMaxSamplesPerFrame ); |
|
116 aInfo.iSamplingRateOut = aInfo.iSamplingRate; |
|
117 aInfo.iChannelsOut = aInfo.iChannels; |
|
118 aInfo.iFrameSamplesOut= aInfo.iFrameSamples; |
|
119 } |
|
120 |
|
121 return length; |
|
122 } |
|
123 |
|
124 // ----------------------------------------------------------------------------- |
|
125 // CAmrCommonUtility::SeekSync |
|
126 // |
|
127 // This routine seeks the start position of the next frame and returns |
|
128 // the byte position of its header. Returns aBufLen, if no valid frame |
|
129 // can not be found ( see FrameInfo ). The seek progresses from the start |
|
130 // of aBuf ( 0 ) toward the end of aBuf( aBufLen - 1 ). |
|
131 // |
|
132 // The level of syntax check depends on the number of bits available. At |
|
133 // minimum the first frame header bits are checked only, but if more |
|
134 // bits are available, they can be used to make the sync seek more robust. |
|
135 // For succesfull seek the whole frame does not need to exist in aBuf. |
|
136 // ----------------------------------------------------------------------------- |
|
137 // |
|
138 TInt CAmrCommonUtility::SeekSync( const TUint8* aBuf, TInt aBufLen, TBool aIsNb ) |
|
139 { |
|
140 const TInt KMaxFrames = 3; // number of frames to check |
|
141 const TInt KNotFound = aBufLen; // sync not found position |
|
142 TAmrFrameInfo frameInfo; // frame parameters |
|
143 |
|
144 TInt i = 0; |
|
145 TInt syncPos = KNotFound; |
|
146 TInt maxSeek = KMaxFrames; |
|
147 const TUint8* endPtr = aBuf + aBufLen; |
|
148 |
|
149 // Seek a valid frame candidate byte by byte until a valid frame |
|
150 // is found or all bytes have been checked. |
|
151 while( aBuf < endPtr && syncPos == KNotFound ) |
|
152 { |
|
153 TInt seekCount = 0; |
|
154 const TUint8* framePtr = aBuf; |
|
155 TInt frameBufLen = aBufLen; |
|
156 syncPos = i; |
|
157 // Check the validity of this frame candidate and the nearest next |
|
158 // frames. If they are not OK, syncPos will be set to KNotFound. |
|
159 while( framePtr < endPtr && syncPos != KNotFound && seekCount < maxSeek ) |
|
160 { |
|
161 TInt length = FrameInfo( framePtr, frameBufLen, frameInfo, aIsNb ); |
|
162 |
|
163 if( frameBufLen >= KRawAmrFrameHeaderSize && length == 0 ) |
|
164 { |
|
165 syncPos = KNotFound; |
|
166 } |
|
167 |
|
168 framePtr += length; |
|
169 frameBufLen -= length; |
|
170 seekCount++; |
|
171 } |
|
172 |
|
173 aBuf++; |
|
174 aBufLen--; |
|
175 i++; |
|
176 } |
|
177 |
|
178 return syncPos; |
|
179 }; |
|
180 |
|
181 // ----------------------------------------------------------------------------- |
|
182 // CAmrCommonUtility::FrameSize |
|
183 // Returns the size of frame described by given coding parameters. The only |
|
184 // parameter used in calculation is the coding mode ( iMode ). |
|
185 // ----------------------------------------------------------------------------- |
|
186 // |
|
187 TInt CAmrCommonUtility::FrameSize( const TAmrFrameInfo& aInfo, TBool aIsNb ) |
|
188 { |
|
189 if ( aIsNb ) |
|
190 { |
|
191 return KRawAmrNbFrameLength[ aInfo.iMode ]; |
|
192 } |
|
193 else |
|
194 { |
|
195 return KRawAmrWbFrameLength[ aInfo.iMode ]; |
|
196 } |
|
197 }; |
|
198 |
|
199 // ----------------------------------------------------------------------------- |
|
200 // CAmrCommonUtility::FrameHeaderSize |
|
201 // Returns the size of one AMR frame header in bytes. The header must include |
|
202 // all bits needed for determining the actual frame length. |
|
203 // ----------------------------------------------------------------------------- |
|
204 // |
|
205 TInt CAmrCommonUtility::FrameHeaderSize( ) |
|
206 { |
|
207 return KRawAmrFrameHeaderSize; |
|
208 }; |
|
209 |
|
210 // ================= OTHER EXPORTED FUNCTIONS ============== |
|
211 |
|
212 // End of File |
|
213 |