blob: c456a6d49be38df0aefad7162b4ae4dd4d628659 [file] [log] [blame]
Gregory Maxwellae231142011-07-30 08:18:48 -04001/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, (subject to the limitations in the disclaimer below)
5are permitted provided that the following conditions are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Skype Limited, nor the names of specific
12contributors, may be used to endorse or promote products derived from
13this software without specific prior written permission.
14NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
15BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
16CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
17BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
Jean-Marc Valin1c2f5632011-09-16 01:16:53 -070031#include "API.h"
32#include "main.h"
Gregory Maxwellae231142011-07-30 08:18:48 -040033
34/************************/
35/* Decoder Super Struct */
36/************************/
37typedef struct {
38 silk_decoder_state channel_state[ DECODER_NUM_CHANNELS ];
39 stereo_dec_state sStereo;
40 opus_int nChannelsAPI;
41 opus_int nChannelsInternal;
Jean-Marc Valinb24e5742011-10-11 21:09:14 -040042 opus_int prev_decode_only_middle;
Gregory Maxwellae231142011-07-30 08:18:48 -040043} silk_decoder;
44
45/*********************/
46/* Decoder functions */
47/*********************/
48
Koen Vosacc7a6c2011-10-28 19:44:26 -040049opus_int silk_Get_Decoder_Size( /* O Returns error code */
50 opus_int *decSizeBytes /* O Number of bytes in SILK decoder state */
51)
Gregory Maxwellae231142011-07-30 08:18:48 -040052{
53 opus_int ret = SILK_NO_ERROR;
54
55 *decSizeBytes = sizeof( silk_decoder );
56
57 return ret;
58}
59
60/* Reset decoder state */
Koen Vosacc7a6c2011-10-28 19:44:26 -040061opus_int silk_InitDecoder( /* O Returns error code */
62 void *decState /* I/O State */
Gregory Maxwellae231142011-07-30 08:18:48 -040063)
64{
65 opus_int n, ret = SILK_NO_ERROR;
66 silk_decoder_state *channel_state = ((silk_decoder *)decState)->channel_state;
67
68 for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) {
69 ret = silk_init_decoder( &channel_state[ n ] );
70 }
71
72 return ret;
73}
74
75/* Decode a frame */
Koen Vosacc7a6c2011-10-28 19:44:26 -040076opus_int silk_Decode( /* O Returns error code */
77 void* decState, /* I/O State */
78 silk_DecControlStruct* decControl, /* I/O Control Structure */
79 opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */
80 opus_int newPacketFlag, /* I Indicates first decoder call for this packet */
81 ec_dec *psRangeDec, /* I/O Compressor data structure */
82 opus_int16 *samplesOut, /* O Decoded output speech vector */
83 opus_int32 *nSamplesOut /* O Number of samples decoded */
Gregory Maxwellae231142011-07-30 08:18:48 -040084)
85{
Koen Vosbf75c8e2011-12-13 14:47:31 -050086 opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR;
Gregory Maxwellae231142011-07-30 08:18:48 -040087 opus_int32 nSamplesOutDec, LBRR_symbol;
Koen Vosbf75c8e2011-12-13 14:47:31 -050088 opus_int16 samplesOut1_tmp[ 2 ][ MAX_FS_KHZ * MAX_FRAME_LENGTH_MS + 2 ];
Gregory Maxwellae231142011-07-30 08:18:48 -040089 opus_int16 samplesOut2_tmp[ MAX_API_FS_KHZ * MAX_FRAME_LENGTH_MS ];
Gregory Maxwell64a35412011-09-02 10:31:17 -040090 opus_int32 MS_pred_Q13[ 2 ] = { 0 };
Gregory Maxwellae231142011-07-30 08:18:48 -040091 opus_int16 *resample_out_ptr;
92 silk_decoder *psDec = ( silk_decoder * )decState;
93 silk_decoder_state *channel_state = psDec->channel_state;
Jean-Marc Valinec1ebf82011-10-24 20:07:00 -040094 opus_int has_side;
Gregory Maxwellae231142011-07-30 08:18:48 -040095
96 /**********************************/
97 /* Test if first frame in payload */
98 /**********************************/
99 if( newPacketFlag ) {
100 for( n = 0; n < decControl->nChannelsInternal; n++ ) {
101 channel_state[ n ].nFramesDecoded = 0; /* Used to count frames in packet */
102 }
103 }
104
Gregory Maxwellae231142011-07-30 08:18:48 -0400105 /* If Mono -> Stereo transition in bitstream: init state of second channel */
106 if( decControl->nChannelsInternal > psDec->nChannelsInternal ) {
107 ret += silk_init_decoder( &channel_state[ 1 ] );
Gregory Maxwellae231142011-07-30 08:18:48 -0400108 }
109
Timothy B. Terriberry1e03a6e2011-10-14 16:14:36 -0700110 if( channel_state[ 0 ].nFramesDecoded == 0 ) {
111 for( n = 0; n < decControl->nChannelsInternal; n++ ) {
Gregory Maxwellae231142011-07-30 08:18:48 -0400112 opus_int fs_kHz_dec;
113 if( decControl->payloadSize_ms == 0 ) {
114 /* Assuming packet loss, use 10 ms */
115 channel_state[ n ].nFramesPerPacket = 1;
116 channel_state[ n ].nb_subfr = 2;
117 } else if( decControl->payloadSize_ms == 10 ) {
118 channel_state[ n ].nFramesPerPacket = 1;
119 channel_state[ n ].nb_subfr = 2;
120 } else if( decControl->payloadSize_ms == 20 ) {
121 channel_state[ n ].nFramesPerPacket = 1;
122 channel_state[ n ].nb_subfr = 4;
123 } else if( decControl->payloadSize_ms == 40 ) {
124 channel_state[ n ].nFramesPerPacket = 2;
125 channel_state[ n ].nb_subfr = 4;
126 } else if( decControl->payloadSize_ms == 60 ) {
127 channel_state[ n ].nFramesPerPacket = 3;
128 channel_state[ n ].nb_subfr = 4;
129 } else {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700130 silk_assert( 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400131 return SILK_DEC_INVALID_FRAME_SIZE;
132 }
133 fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1;
134 if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700135 silk_assert( 0 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400136 return SILK_DEC_INVALID_SAMPLING_FREQUENCY;
137 }
Jean-Marc Valinb24e5742011-10-11 21:09:14 -0400138 ret += silk_decoder_set_fs( &channel_state[ n ], fs_kHz_dec, decControl->API_sampleRate );
Gregory Maxwellae231142011-07-30 08:18:48 -0400139 }
140 }
141
Gregory Maxwellae231142011-07-30 08:18:48 -0400142 if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 && ( psDec->nChannelsAPI == 1 || psDec->nChannelsInternal == 1 ) ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700143 silk_memset( psDec->sStereo.pred_prev_Q13, 0, sizeof( psDec->sStereo.pred_prev_Q13 ) );
144 silk_memset( psDec->sStereo.sSide, 0, sizeof( psDec->sStereo.sSide ) );
Jean-Marc Valinb24e5742011-10-11 21:09:14 -0400145 silk_memcpy( &channel_state[ 1 ].resampler_state, &channel_state[ 0 ].resampler_state, sizeof( silk_resampler_state_struct ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400146 }
147 psDec->nChannelsAPI = decControl->nChannelsAPI;
148 psDec->nChannelsInternal = decControl->nChannelsInternal;
149
150 if( decControl->API_sampleRate > MAX_API_FS_KHZ * 1000 || decControl->API_sampleRate < 8000 ) {
151 ret = SILK_DEC_INVALID_SAMPLING_FREQUENCY;
152 return( ret );
153 }
154
155 if( lostFlag != FLAG_PACKET_LOST && channel_state[ 0 ].nFramesDecoded == 0 ) {
156 /* First decoder call for this payload */
157 /* Decode VAD flags and LBRR flag */
158 for( n = 0; n < decControl->nChannelsInternal; n++ ) {
159 for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) {
160 channel_state[ n ].VAD_flags[ i ] = ec_dec_bit_logp(psRangeDec, 1);
161 }
162 channel_state[ n ].LBRR_flag = ec_dec_bit_logp(psRangeDec, 1);
163 }
164 /* Decode LBRR flags */
165 for( n = 0; n < decControl->nChannelsInternal; n++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700166 silk_memset( channel_state[ n ].LBRR_flags, 0, sizeof( channel_state[ n ].LBRR_flags ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400167 if( channel_state[ n ].LBRR_flag ) {
168 if( channel_state[ n ].nFramesPerPacket == 1 ) {
169 channel_state[ n ].LBRR_flags[ 0 ] = 1;
170 } else {
171 LBRR_symbol = ec_dec_icdf( psRangeDec, silk_LBRR_flags_iCDF_ptr[ channel_state[ n ].nFramesPerPacket - 2 ], 8 ) + 1;
172 for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700173 channel_state[ n ].LBRR_flags[ i ] = silk_RSHIFT( LBRR_symbol, i ) & 1;
Gregory Maxwellae231142011-07-30 08:18:48 -0400174 }
175 }
176 }
177 }
178
179 if( lostFlag == FLAG_DECODE_NORMAL ) {
180 /* Regular decoding: skip all LBRR data */
181 for( i = 0; i < channel_state[ 0 ].nFramesPerPacket; i++ ) {
182 for( n = 0; n < decControl->nChannelsInternal; n++ ) {
183 if( channel_state[ n ].LBRR_flags[ i ] ) {
184 opus_int pulses[ MAX_FRAME_LENGTH ];
Timothy B. Terriberry53cc1a02011-10-14 13:38:24 -0700185 opus_int condCoding;
186
Gregory Maxwellae231142011-07-30 08:18:48 -0400187 if( decControl->nChannelsInternal == 2 && n == 0 ) {
Koen Vos4e1ce382011-08-25 13:50:21 -0400188 silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 );
189 if( channel_state[ 1 ].LBRR_flags[ i ] == 0 ) {
190 silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle );
191 }
Gregory Maxwellae231142011-07-30 08:18:48 -0400192 }
Timothy B. Terriberry53cc1a02011-10-14 13:38:24 -0700193 /* Use conditional coding if previous frame available */
194 if( i > 0 && channel_state[ n ].LBRR_flags[ i - 1 ] ) {
195 condCoding = CODE_CONDITIONALLY;
196 } else {
197 condCoding = CODE_INDEPENDENTLY;
198 }
199 silk_decode_indices( &channel_state[ n ], psRangeDec, i, 1, condCoding );
Gregory Maxwellae231142011-07-30 08:18:48 -0400200 silk_decode_pulses( psRangeDec, pulses, channel_state[ n ].indices.signalType,
201 channel_state[ n ].indices.quantOffsetType, channel_state[ n ].frame_length );
202 }
203 }
204 }
205 }
206 }
207
208 /* Get MS predictor index */
209 if( decControl->nChannelsInternal == 2 ) {
210 if( lostFlag == FLAG_DECODE_NORMAL ||
211 ( lostFlag == FLAG_DECODE_LBRR && channel_state[ 0 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 1 ) )
212 {
Koen Vos4e1ce382011-08-25 13:50:21 -0400213 silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 );
Koen Vos3195f6c2011-10-10 20:46:32 -0400214 /* For LBRR data, decode mid-only flag only if side-channel's LBRR flag is false */
Timothy B. Terriberry6559d362011-10-17 14:20:55 -0700215 if( ( lostFlag == FLAG_DECODE_NORMAL && channel_state[ 1 ].VAD_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) ||
Koen Vos4e1ce382011-08-25 13:50:21 -0400216 ( lostFlag == FLAG_DECODE_LBRR && channel_state[ 1 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) )
217 {
218 silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle );
219 } else {
220 decode_only_middle = 0;
221 }
Gregory Maxwellae231142011-07-30 08:18:48 -0400222 } else {
Gregory Maxwell5c3d1552011-08-15 13:18:52 -0400223 for( n = 0; n < 2; n++ ) {
Jean-Marc Valinb24e5742011-10-11 21:09:14 -0400224 MS_pred_Q13[ n ] = psDec->sStereo.pred_prev_Q13[ n ];
Gregory Maxwell5c3d1552011-08-15 13:18:52 -0400225 }
Gregory Maxwellae231142011-07-30 08:18:48 -0400226 }
227 }
228
Jean-Marc Valinb24e5742011-10-11 21:09:14 -0400229 /* Reset side channel decoder prediction memory for first frame with side coding */
230 if( decControl->nChannelsInternal == 2 && decode_only_middle == 0 && psDec->prev_decode_only_middle == 1 ) {
231 silk_memset( psDec->channel_state[ 1 ].outBuf, 0, sizeof(psDec->channel_state[ 1 ].outBuf) );
232 silk_memset( psDec->channel_state[ 1 ].sLPC_Q14_buf, 0, sizeof(psDec->channel_state[ 1 ].sLPC_Q14_buf) );
233 psDec->channel_state[ 1 ].lagPrev = 100;
234 psDec->channel_state[ 1 ].LastGainIndex = 10;
235 psDec->channel_state[ 1 ].prevSignalType = TYPE_NO_VOICE_ACTIVITY;
Gregory Maxwell52de5362011-10-19 00:20:46 -0400236 psDec->channel_state[ 1 ].first_frame_after_reset = 1;
Jean-Marc Valinb24e5742011-10-11 21:09:14 -0400237 }
238
Koen Vosacc7a6c2011-10-28 19:44:26 -0400239 if( lostFlag == FLAG_DECODE_NORMAL ) {
Jean-Marc Valinec1ebf82011-10-24 20:07:00 -0400240 has_side = !decode_only_middle;
241 } else {
242 has_side = !psDec->prev_decode_only_middle
243 || (decControl->nChannelsInternal == 2 && lostFlag == FLAG_DECODE_LBRR && channel_state[1].LBRR_flags[ channel_state[1].nFramesDecoded ] == 1 );
244 }
Gregory Maxwellae231142011-07-30 08:18:48 -0400245 /* Call decoder for one frame */
246 for( n = 0; n < decControl->nChannelsInternal; n++ ) {
Jean-Marc Valinec1ebf82011-10-24 20:07:00 -0400247 if( n == 0 || has_side ) {
Timothy B. Terriberry53cc1a02011-10-14 13:38:24 -0700248 opus_int FrameIndex;
249 opus_int condCoding;
250
251 FrameIndex = channel_state[ 0 ].nFramesDecoded - n;
252 /* Use independent coding if no previous frame available */
253 if( FrameIndex <= 0 ) {
254 condCoding = CODE_INDEPENDENTLY;
255 } else if( lostFlag == FLAG_DECODE_LBRR ) {
256 condCoding = channel_state[ n ].LBRR_flags[ FrameIndex - 1 ] ? CODE_CONDITIONALLY : CODE_INDEPENDENTLY;
257 } else if( n > 0 && psDec->prev_decode_only_middle ) {
258 /* If we skipped a side frame in this packet, we don't
259 need LTP scaling; the LTP state is well-defined. */
260 condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING;
261 } else {
262 condCoding = CODE_CONDITIONALLY;
263 }
Koen Vosbf75c8e2011-12-13 14:47:31 -0500264 ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding);
Gregory Maxwellae231142011-07-30 08:18:48 -0400265 } else {
Koen Vosbf75c8e2011-12-13 14:47:31 -0500266 silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400267 }
Timothy B. Terriberry1e03a6e2011-10-14 16:14:36 -0700268 channel_state[ n ].nFramesDecoded++;
Gregory Maxwellae231142011-07-30 08:18:48 -0400269 }
270
271 if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 ) {
272 /* Convert Mid/Side to Left/Right */
Koen Vosbf75c8e2011-12-13 14:47:31 -0500273 silk_stereo_MS_to_LR( &psDec->sStereo, samplesOut1_tmp[ 0 ], samplesOut1_tmp[ 1 ], MS_pred_Q13, channel_state[ 0 ].fs_kHz, nSamplesOutDec );
Gregory Maxwellae231142011-07-30 08:18:48 -0400274 } else {
275 /* Buffering */
Koen Vosbf75c8e2011-12-13 14:47:31 -0500276 silk_memcpy( samplesOut1_tmp[ 0 ], psDec->sStereo.sMid, 2 * sizeof( opus_int16 ) );
277 silk_memcpy( psDec->sStereo.sMid, &samplesOut1_tmp[ 0 ][ nSamplesOutDec ], 2 * sizeof( opus_int16 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400278 }
279
280 /* Number of output samples */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700281 *nSamplesOut = silk_DIV32( nSamplesOutDec * decControl->API_sampleRate, silk_SMULBB( channel_state[ 0 ].fs_kHz, 1000 ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400282
283 /* Set up pointers to temp buffers */
284 if( decControl->nChannelsAPI == 2 ) {
285 resample_out_ptr = samplesOut2_tmp;
286 } else {
287 resample_out_ptr = samplesOut;
288 }
289
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700290 for( n = 0; n < silk_min( decControl->nChannelsAPI, decControl->nChannelsInternal ); n++ ) {
Jean-Marc Valinb5972382011-10-07 08:38:27 -0400291
Gregory Maxwellae231142011-07-30 08:18:48 -0400292 /* Resample decoded signal to API_sampleRate */
293 ret += silk_resampler( &channel_state[ n ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ n ][ 1 ], nSamplesOutDec );
294
295 /* Interleave if stereo output and stereo stream */
296 if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 ) {
297 for( i = 0; i < *nSamplesOut; i++ ) {
298 samplesOut[ n + 2 * i ] = resample_out_ptr[ i ];
299 }
300 }
301 }
302
303 /* Create two channel output from mono stream */
304 if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 1 ) {
305 for( i = 0; i < *nSamplesOut; i++ ) {
306 samplesOut[ 0 + 2 * i ] = samplesOut[ 1 + 2 * i ] = resample_out_ptr[ i ];
307 }
308 }
309
Jean-Marc Valinb24e5742011-10-11 21:09:14 -0400310 /* Export pitch lag, measured at 48 kHz sampling rate */
311 if( channel_state[ 0 ].prevSignalType == TYPE_VOICED ) {
312 int mult_tab[ 3 ] = { 6, 4, 3 };
313 decControl->prevPitchLag = channel_state[ 0 ].lagPrev * mult_tab[ ( channel_state[ 0 ].fs_kHz - 8 ) >> 2 ];
314 } else {
315 decControl->prevPitchLag = 0;
316 }
317
Koen Vosacc7a6c2011-10-28 19:44:26 -0400318 if( lostFlag != FLAG_PACKET_LOST ) {
Jean-Marc Valin4f1b7da2011-10-12 15:09:13 -0400319 psDec->prev_decode_only_middle = decode_only_middle;
320 }
Gregory Maxwellae231142011-07-30 08:18:48 -0400321 return ret;
322}
323
324/* Getting table of contents for a packet */
325opus_int silk_get_TOC(
Koen Vosacc7a6c2011-10-28 19:44:26 -0400326 const opus_uint8 *payload, /* I Payload data */
327 const opus_int nBytesIn, /* I Number of input bytes */
328 const opus_int nFramesPerPayload, /* I Number of SILK frames per payload */
329 silk_TOC_struct *Silk_TOC /* O Type of content */
Gregory Maxwellae231142011-07-30 08:18:48 -0400330)
331{
332 opus_int i, flags, ret = SILK_NO_ERROR;
333
334 if( nBytesIn < 1 ) {
335 return -1;
336 }
337 if( nFramesPerPayload < 0 || nFramesPerPayload > 3 ) {
338 return -1;
339 }
340
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700341 silk_memset( Silk_TOC, 0, sizeof( Silk_TOC ) );
Gregory Maxwellae231142011-07-30 08:18:48 -0400342
343 /* For stereo, extract the flags for the mid channel */
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700344 flags = silk_RSHIFT( payload[ 0 ], 7 - nFramesPerPayload ) & ( silk_LSHIFT( 1, nFramesPerPayload + 1 ) - 1 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400345
346 Silk_TOC->inbandFECFlag = flags & 1;
347 for( i = nFramesPerPayload - 1; i >= 0 ; i-- ) {
Jean-Marc Valinfb3a4372011-09-16 00:58:26 -0700348 flags = silk_RSHIFT( flags, 1 );
Gregory Maxwellae231142011-07-30 08:18:48 -0400349 Silk_TOC->VADFlags[ i ] = flags & 1;
350 Silk_TOC->VADFlag |= flags & 1;
351 }
352
353 return ret;
354}