blob: fae06f63397027f6ed82f0e850e7887115f5cf9f [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
turaj@webrtc.org837bc7b2012-07-14 00:34:54 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11/******************************************************************
12
13 iLBC Speech Coder ANSI-C Source Code
14
15 WebRtcIlbcfix_UnpackBits.c
16
17******************************************************************/
18
19#include "defines.h"
20
21/*----------------------------------------------------------------*
22 * unpacking of bits from bitstream, i.e., vector of bytes
23 *---------------------------------------------------------------*/
24
pbos@webrtc.org0946a562013-04-09 00:28:06 +000025int16_t WebRtcIlbcfix_UnpackBits( /* (o) "Empty" frame indicator */
26 const uint16_t *bitstream, /* (i) The packatized bitstream */
niklase@google.com470e71d2011-07-07 08:21:25 +000027 iLBC_bits *enc_bits, /* (o) Paramerers from bitstream */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000028 int16_t mode /* (i) Codec mode (20 or 30) */
niklase@google.com470e71d2011-07-07 08:21:25 +000029 ) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +000030 const uint16_t *bitstreamPtr;
niklase@google.com470e71d2011-07-07 08:21:25 +000031 int i, k;
pbos@webrtc.org0946a562013-04-09 00:28:06 +000032 int16_t *tmpPtr;
niklase@google.com470e71d2011-07-07 08:21:25 +000033
34 bitstreamPtr=bitstream;
35
pbos@webrtc.org0946a562013-04-09 00:28:06 +000036 /* First int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +000037 enc_bits->lsf[0] = (*bitstreamPtr)>>10; /* Bit 0..5 */
38 enc_bits->lsf[1] = ((*bitstreamPtr)>>3)&0x7F; /* Bit 6..12 */
39 enc_bits->lsf[2] = ((*bitstreamPtr)&0x7)<<4; /* Bit 13..15 */
40 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +000041 /* Second int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +000042 enc_bits->lsf[2] |= ((*bitstreamPtr)>>12)&0xF; /* Bit 0..3 */
43
44 if (mode==20) {
45 enc_bits->startIdx = ((*bitstreamPtr)>>10)&0x3; /* Bit 4..5 */
46 enc_bits->state_first = ((*bitstreamPtr)>>9)&0x1; /* Bit 6 */
47 enc_bits->idxForMax = ((*bitstreamPtr)>>3)&0x3F; /* Bit 7..12 */
48 enc_bits->cb_index[0] = ((*bitstreamPtr)&0x7)<<4; /* Bit 13..15 */
49 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +000050 /* Third int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +000051 enc_bits->cb_index[0] |= ((*bitstreamPtr)>>12)&0xE; /* Bit 0..2 */
52 enc_bits->gain_index[0] = ((*bitstreamPtr)>>8)&0x18; /* Bit 3..4 */
53 enc_bits->gain_index[1] = ((*bitstreamPtr)>>7)&0x8; /* Bit 5 */
54 enc_bits->cb_index[3] = ((*bitstreamPtr)>>2)&0xFE; /* Bit 6..12 */
55 enc_bits->gain_index[3] = ((*bitstreamPtr)<<2)&0x10; /* Bit 13 */
56 enc_bits->gain_index[4] = ((*bitstreamPtr)<<2)&0x8; /* Bit 14 */
57 enc_bits->gain_index[6] = ((*bitstreamPtr)<<4)&0x10; /* Bit 15 */
58 } else { /* mode==30 */
59 enc_bits->lsf[3] = ((*bitstreamPtr)>>6)&0x3F; /* Bit 4..9 */
60 enc_bits->lsf[4] = ((*bitstreamPtr)<<1)&0x7E; /* Bit 10..15 */
61 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +000062 /* Third int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +000063 enc_bits->lsf[4] |= ((*bitstreamPtr)>>15)&0x1; /* Bit 0 */
64 enc_bits->lsf[5] = ((*bitstreamPtr)>>8)&0x7F; /* Bit 1..7 */
65 enc_bits->startIdx = ((*bitstreamPtr)>>5)&0x7; /* Bit 8..10 */
66 enc_bits->state_first = ((*bitstreamPtr)>>4)&0x1; /* Bit 11 */
67 enc_bits->idxForMax = ((*bitstreamPtr)<<2)&0x3C; /* Bit 12..15 */
68 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +000069 /* 4:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +000070 enc_bits->idxForMax |= ((*bitstreamPtr)>>14)&0x3; /* Bit 0..1 */
71 enc_bits->cb_index[0] = ((*bitstreamPtr)>>7)&0x78; /* Bit 2..5 */
72 enc_bits->gain_index[0] = ((*bitstreamPtr)>>5)&0x10; /* Bit 6 */
73 enc_bits->gain_index[1] = ((*bitstreamPtr)>>5)&0x8; /* Bit 7 */
74 enc_bits->cb_index[3] = ((*bitstreamPtr))&0xFC; /* Bit 8..13 */
75 enc_bits->gain_index[3] = ((*bitstreamPtr)<<3)&0x10; /* Bit 14 */
76 enc_bits->gain_index[4] = ((*bitstreamPtr)<<3)&0x8; /* Bit 15 */
77 }
78 /* Class 2 bits of ULP */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000079 /* 4:th to 6:th int16_t for 20 ms case
80 5:th to 7:th int16_t for 30 ms case */
niklase@google.com470e71d2011-07-07 08:21:25 +000081 bitstreamPtr++;
82 tmpPtr=enc_bits->idxVec;
83 for (k=0; k<3; k++) {
84 for (i=15; i>=0; i--) {
85 (*tmpPtr) = (((*bitstreamPtr)>>i)<<2)&0x4;
86 /* Bit 15-i */
87 tmpPtr++;
88 }
89 bitstreamPtr++;
90 }
91
92 if (mode==20) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +000093 /* 7:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +000094 for (i=15; i>6; i--) {
95 (*tmpPtr) = (((*bitstreamPtr)>>i)<<2)&0x4;
96 /* Bit 15-i */
97 tmpPtr++;
98 }
99 enc_bits->gain_index[1] |= ((*bitstreamPtr)>>4)&0x4; /* Bit 9 */
100 enc_bits->gain_index[3] |= ((*bitstreamPtr)>>2)&0xC; /* Bit 10..11 */
101 enc_bits->gain_index[4] |= ((*bitstreamPtr)>>1)&0x4; /* Bit 12 */
102 enc_bits->gain_index[6] |= ((*bitstreamPtr)<<1)&0x8; /* Bit 13 */
103 enc_bits->gain_index[7] = ((*bitstreamPtr)<<2)&0xC; /* Bit 14..15 */
104
105 } else { /* mode==30 */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000106 /* 8:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000107 for (i=15; i>5; i--) {
108 (*tmpPtr) = (((*bitstreamPtr)>>i)<<2)&0x4;
109 /* Bit 15-i */
110 tmpPtr++;
111 }
112 enc_bits->cb_index[0] |= ((*bitstreamPtr)>>3)&0x6; /* Bit 10..11 */
113 enc_bits->gain_index[0] |= ((*bitstreamPtr))&0x8; /* Bit 12 */
114 enc_bits->gain_index[1] |= ((*bitstreamPtr))&0x4; /* Bit 13 */
115 enc_bits->cb_index[3] |= ((*bitstreamPtr))&0x2; /* Bit 14 */
116 enc_bits->cb_index[6] = ((*bitstreamPtr)<<7)&0x80; /* Bit 15 */
117 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000118 /* 9:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000119 enc_bits->cb_index[6] |= ((*bitstreamPtr)>>9)&0x7E; /* Bit 0..5 */
120 enc_bits->cb_index[9] = ((*bitstreamPtr)>>2)&0xFE; /* Bit 6..12 */
121 enc_bits->cb_index[12] = ((*bitstreamPtr)<<5)&0xE0; /* Bit 13..15 */
122 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000123 /* 10:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000124 enc_bits->cb_index[12] |= ((*bitstreamPtr)>>11)&0x1E;/* Bit 0..3 */
125 enc_bits->gain_index[3] |= ((*bitstreamPtr)>>8)&0xC; /* Bit 4..5 */
126 enc_bits->gain_index[4] |= ((*bitstreamPtr)>>7)&0x6; /* Bit 6..7 */
127 enc_bits->gain_index[6] = ((*bitstreamPtr)>>3)&0x18; /* Bit 8..9 */
128 enc_bits->gain_index[7] = ((*bitstreamPtr)>>2)&0xC; /* Bit 10..11 */
129 enc_bits->gain_index[9] = ((*bitstreamPtr)<<1)&0x10; /* Bit 12 */
130 enc_bits->gain_index[10] = ((*bitstreamPtr)<<1)&0x8; /* Bit 13 */
131 enc_bits->gain_index[12] = ((*bitstreamPtr)<<3)&0x10; /* Bit 14 */
132 enc_bits->gain_index[13] = ((*bitstreamPtr)<<3)&0x8; /* Bit 15 */
133 }
134 bitstreamPtr++;
135 /* Class 3 bits of ULP */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000136 /* 8:th to 14:th int16_t for 20 ms case
137 11:th to 17:th int16_t for 30 ms case */
niklase@google.com470e71d2011-07-07 08:21:25 +0000138 tmpPtr=enc_bits->idxVec;
139 for (k=0; k<7; k++) {
140 for (i=14; i>=0; i-=2) {
141 (*tmpPtr) |= ((*bitstreamPtr)>>i)&0x3; /* Bit 15-i..14-i*/
142 tmpPtr++;
143 }
144 bitstreamPtr++;
145 }
146
147 if (mode==20) {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000148 /* 15:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000149 enc_bits->idxVec[56] |= ((*bitstreamPtr)>>14)&0x3; /* Bit 0..1 */
150 enc_bits->cb_index[0] |= ((*bitstreamPtr)>>13)&0x1; /* Bit 2 */
151 enc_bits->cb_index[1] = ((*bitstreamPtr)>>6)&0x7F; /* Bit 3..9 */
152 enc_bits->cb_index[2] = ((*bitstreamPtr)<<1)&0x7E; /* Bit 10..15 */
153 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000154 /* 16:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000155 enc_bits->cb_index[2] |= ((*bitstreamPtr)>>15)&0x1; /* Bit 0 */
156 enc_bits->gain_index[0] |= ((*bitstreamPtr)>>12)&0x7; /* Bit 1..3 */
157 enc_bits->gain_index[1] |= ((*bitstreamPtr)>>10)&0x3; /* Bit 4..5 */
158 enc_bits->gain_index[2] = ((*bitstreamPtr)>>7)&0x7; /* Bit 6..8 */
159 enc_bits->cb_index[3] |= ((*bitstreamPtr)>>6)&0x1; /* Bit 9 */
160 enc_bits->cb_index[4] = ((*bitstreamPtr)<<1)&0x7E; /* Bit 10..15 */
161 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000162 /* 17:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000163 enc_bits->cb_index[4] |= ((*bitstreamPtr)>>15)&0x1; /* Bit 0 */
164 enc_bits->cb_index[5] = ((*bitstreamPtr)>>8)&0x7F; /* Bit 1..7 */
165 enc_bits->cb_index[6] = ((*bitstreamPtr))&0xFF; /* Bit 8..15 */
166 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000167 /* 18:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000168 enc_bits->cb_index[7] = (*bitstreamPtr)>>8; /* Bit 0..7 */
169 enc_bits->cb_index[8] = (*bitstreamPtr)&0xFF; /* Bit 8..15 */
170 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000171 /* 19:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000172 enc_bits->gain_index[3] |= ((*bitstreamPtr)>>14)&0x3; /* Bit 0..1 */
173 enc_bits->gain_index[4] |= ((*bitstreamPtr)>>12)&0x3; /* Bit 2..3 */
174 enc_bits->gain_index[5] = ((*bitstreamPtr)>>9)&0x7; /* Bit 4..6 */
175 enc_bits->gain_index[6] |= ((*bitstreamPtr)>>6)&0x7; /* Bit 7..9 */
176 enc_bits->gain_index[7] |= ((*bitstreamPtr)>>4)&0x3; /* Bit 10..11 */
177 enc_bits->gain_index[8] = ((*bitstreamPtr)>>1)&0x7; /* Bit 12..14 */
178 } else { /* mode==30 */
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000179 /* 18:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000180 enc_bits->idxVec[56] |= ((*bitstreamPtr)>>14)&0x3; /* Bit 0..1 */
181 enc_bits->idxVec[57] |= ((*bitstreamPtr)>>12)&0x3; /* Bit 2..3 */
182 enc_bits->cb_index[0] |= ((*bitstreamPtr)>>11)&1; /* Bit 4 */
183 enc_bits->cb_index[1] = ((*bitstreamPtr)>>4)&0x7F; /* Bit 5..11 */
184 enc_bits->cb_index[2] = ((*bitstreamPtr)<<3)&0x78; /* Bit 12..15 */
185 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000186 /* 19:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000187 enc_bits->cb_index[2] |= ((*bitstreamPtr)>>13)&0x7; /* Bit 0..2 */
188 enc_bits->gain_index[0] |= ((*bitstreamPtr)>>10)&0x7; /* Bit 3..5 */
189 enc_bits->gain_index[1] |= ((*bitstreamPtr)>>8)&0x3; /* Bit 6..7 */
190 enc_bits->gain_index[2] = ((*bitstreamPtr)>>5)&0x7; /* Bit 8..10 */
191 enc_bits->cb_index[3] |= ((*bitstreamPtr)>>4)&0x1; /* Bit 11 */
192 enc_bits->cb_index[4] = ((*bitstreamPtr)<<3)&0x78; /* Bit 12..15 */
193 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000194 /* 20:th int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000195 enc_bits->cb_index[4] |= ((*bitstreamPtr)>>13)&0x7; /* Bit 0..2 */
196 enc_bits->cb_index[5] = ((*bitstreamPtr)>>6)&0x7F; /* Bit 3..9 */
197 enc_bits->cb_index[6] |= ((*bitstreamPtr)>>5)&0x1; /* Bit 10 */
198 enc_bits->cb_index[7] = ((*bitstreamPtr)<<3)&0xF8; /* Bit 11..15 */
199 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000200 /* 21:st int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000201 enc_bits->cb_index[7] |= ((*bitstreamPtr)>>13)&0x7; /* Bit 0..2 */
202 enc_bits->cb_index[8] = ((*bitstreamPtr)>>5)&0xFF; /* Bit 3..10 */
203 enc_bits->cb_index[9] |= ((*bitstreamPtr)>>4)&0x1; /* Bit 11 */
204 enc_bits->cb_index[10] = ((*bitstreamPtr)<<4)&0xF0; /* Bit 12..15 */
205 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000206 /* 22:nd int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000207 enc_bits->cb_index[10] |= ((*bitstreamPtr)>>12)&0xF; /* Bit 0..3 */
208 enc_bits->cb_index[11] = ((*bitstreamPtr)>>4)&0xFF; /* Bit 4..11 */
209 enc_bits->cb_index[12] |= ((*bitstreamPtr)>>3)&0x1; /* Bit 12 */
210 enc_bits->cb_index[13] = ((*bitstreamPtr)<<5)&0xE0; /* Bit 13..15 */
211 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000212 /* 23:rd int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000213 enc_bits->cb_index[13] |= ((*bitstreamPtr)>>11)&0x1F;/* Bit 0..4 */
214 enc_bits->cb_index[14] = ((*bitstreamPtr)>>3)&0xFF; /* Bit 5..12 */
215 enc_bits->gain_index[3] |= ((*bitstreamPtr)>>1)&0x3; /* Bit 13..14 */
216 enc_bits->gain_index[4] |= ((*bitstreamPtr)&0x1); /* Bit 15 */
217 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000218 /* 24:rd int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000219 enc_bits->gain_index[5] = ((*bitstreamPtr)>>13)&0x7; /* Bit 0..2 */
220 enc_bits->gain_index[6] |= ((*bitstreamPtr)>>10)&0x7; /* Bit 3..5 */
221 enc_bits->gain_index[7] |= ((*bitstreamPtr)>>8)&0x3; /* Bit 6..7 */
222 enc_bits->gain_index[8] = ((*bitstreamPtr)>>5)&0x7; /* Bit 8..10 */
223 enc_bits->gain_index[9] |= ((*bitstreamPtr)>>1)&0xF; /* Bit 11..14 */
224 enc_bits->gain_index[10] |= ((*bitstreamPtr)<<2)&0x4; /* Bit 15 */
225 bitstreamPtr++;
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000226 /* 25:rd int16_t */
niklase@google.com470e71d2011-07-07 08:21:25 +0000227 enc_bits->gain_index[10] |= ((*bitstreamPtr)>>14)&0x3; /* Bit 0..1 */
228 enc_bits->gain_index[11] = ((*bitstreamPtr)>>11)&0x7; /* Bit 2..4 */
229 enc_bits->gain_index[12] |= ((*bitstreamPtr)>>7)&0xF; /* Bit 5..8 */
230 enc_bits->gain_index[13] |= ((*bitstreamPtr)>>4)&0x7; /* Bit 9..11 */
231 enc_bits->gain_index[14] = ((*bitstreamPtr)>>1)&0x7; /* Bit 12..14 */
232 }
233 /* Last bit should be zero, otherwise it's an "empty" frame */
234 if (((*bitstreamPtr)&0x1) == 1) {
235 return(1);
236 } else {
237 return(0);
238 }
239}