Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-utils / dsp.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol client.
3  * Digital Sound Processing
4  *
5  * Copyright 2010-2011 Vic Lee
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <freerdp/types.h>
24 #include <freerdp/utils/memory.h>
25 #include <freerdp/utils/dsp.h>
26
27 uint8* dsp_resample(uint8* src, int bytes_per_sample,
28         uint32 schan, uint32 srate, int sframes,
29         uint32 rchan, uint32 rrate, int * prframes)
30 {
31         uint8* dst;
32         uint8* p;
33         int rframes;
34         int rsize;
35         int i, j;
36         int n1, n2;
37         int sbytes, rbytes;
38
39         sbytes = bytes_per_sample * schan;
40         rbytes = bytes_per_sample * rchan;
41         rframes = sframes * rrate / srate;
42         *prframes = rframes;
43         rsize = rbytes * rframes;
44         dst = (uint8*) xzalloc(rsize);
45
46         p = dst;
47         for (i = 0; i < rframes; i++)
48         {
49                 n1 = i * srate / rrate;
50                 if (n1 >= sframes)
51                         n1 = sframes - 1;
52                 n2 = (n1 * rrate == i * srate || n1 == sframes - 1 ? n1 : n1 + 1);
53                 for (j = 0; j < rbytes; j++)
54                 {
55                         /* Nearest Interpolation, probably the easiest, but works */
56                         *p++ = (i * srate - n1 * rrate > n2 * rrate - i * srate ?
57                                 src[n2 * sbytes + (j % sbytes)] :
58                                 src[n1 * sbytes + (j % sbytes)]);
59                 }
60         }
61
62         return dst;
63 }
64
65 /**
66  * Microsoft IMA ADPCM specification:
67  *
68  * http://wiki.multimedia.cx/index.php?title=Microsoft_IMA_ADPCM
69  * http://wiki.multimedia.cx/index.php?title=IMA_ADPCM
70  */
71
72 static const sint16 ima_step_index_table[] =
73 {
74         -1, -1, -1, -1, 2, 4, 6, 8,
75         -1, -1, -1, -1, 2, 4, 6, 8
76 };
77
78 static const sint16 ima_step_size_table[] =
79 {
80         7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 
81         19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 
82         50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 
83         130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
84         337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
85         876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 
86         2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
87         5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 
88         15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 
89 };
90
91 static uint16 dsp_decode_ima_adpcm_sample(ADPCM* adpcm,
92         int channel, uint8 sample)
93 {
94         sint32 ss;
95         sint32 d;
96
97         ss = ima_step_size_table[adpcm->last_step[channel]];
98         d = (ss >> 3);
99         if (sample & 1)
100                 d += (ss >> 2);
101         if (sample & 2)
102                 d += (ss >> 1);
103         if (sample & 4)
104                 d += ss;
105         if (sample & 8)
106                 d = -d;
107         d += adpcm->last_sample[channel];
108
109         if (d < -32768)
110                 d = -32768;
111         else if (d > 32767)
112                 d = 32767;
113
114         adpcm->last_sample[channel] = (sint16) d;
115
116         adpcm->last_step[channel] += ima_step_index_table[sample];
117         if (adpcm->last_step[channel] < 0)
118                 adpcm->last_step[channel] = 0;
119         else if (adpcm->last_step[channel] > 88)
120                 adpcm->last_step[channel] = 88;
121
122         return (uint16) d;
123 }
124
125 uint8* dsp_decode_ima_adpcm(ADPCM* adpcm,
126         uint8* src, int size, int channels, int block_size, int* out_size)
127 {
128         uint8* out;
129         uint8* dst;
130         uint8 sample;
131         uint16 decoded;
132         int channel;
133         int i;
134
135         *out_size = size * 4;
136         out = (uint8 *) xzalloc(*out_size);
137         dst = out;
138         while (size > 0)
139         {
140                 if (size % block_size == 0)
141                 {
142                         adpcm->last_sample[0] = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
143                         adpcm->last_step[0] = (sint16) (*(src + 2));
144                         src += 4;
145                         size -= 4;
146                         *out_size -= 16;
147                         if (channels > 1)
148                         {
149                                 adpcm->last_sample[1] = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
150                                 adpcm->last_step[1] = (sint16) (*(src + 2));
151                                 src += 4;
152                                 size -= 4;
153                                 *out_size -= 16;
154                         }
155                 }
156
157                 if (channels > 1)
158                 {
159                         for (i = 0; i < 8; i++)
160                         {
161                                 channel = (i < 4 ? 0 : 1);
162                                 sample = ((*src) & 0x0f);
163                                 decoded = dsp_decode_ima_adpcm_sample(adpcm, channel, sample);
164                                 dst[((i & 3) << 3) + (channel << 1)] = (decoded & 0xff);
165                                 dst[((i & 3) << 3) + (channel << 1) + 1] = (decoded >> 8);
166                                 sample = ((*src) >> 4);
167                                 decoded = dsp_decode_ima_adpcm_sample(adpcm, channel, sample);
168                                 dst[((i & 3) << 3) + (channel << 1) + 4] = (decoded & 0xff);
169                                 dst[((i & 3) << 3) + (channel << 1) + 5] = (decoded >> 8);
170                                 src++;
171                         }
172                         dst += 32;
173                         size -= 8;
174                 }
175                 else
176                 {
177                         sample = ((*src) & 0x0f);
178                         decoded = dsp_decode_ima_adpcm_sample(adpcm, 0, sample);
179                         *dst++ = (decoded & 0xff);
180                         *dst++ = (decoded >> 8);
181                         sample = ((*src) >> 4);
182                         decoded = dsp_decode_ima_adpcm_sample(adpcm, 0, sample);
183                         *dst++ = (decoded & 0xff);
184                         *dst++ = (decoded >> 8);
185                         src++;
186                         size--;
187                 }
188         }
189         return out;
190 }
191
192 /**
193  * 0     1     2     3
194  * 2 0   6 4   10 8  14 12   <left>
195  *
196  * 4     5     6     7
197  * 3 1   7 5   11 9  15 13   <right>
198  */
199 static const struct
200 {
201         uint8 byte_num;
202         uint8 byte_shift;
203 } ima_stereo_encode_map[] =
204 {
205         { 0, 0 },
206         { 4, 0 },
207         { 0, 4 },
208         { 4, 4 },
209         { 1, 0 },
210         { 5, 0 },
211         { 1, 4 },
212         { 5, 4 },
213         { 2, 0 },
214         { 6, 0 },
215         { 2, 4 },
216         { 6, 4 },
217         { 3, 0 },
218         { 7, 0 },
219         { 3, 4 },
220         { 7, 4 }
221 };
222
223 static uint8 dsp_encode_ima_adpcm_sample(ADPCM* adpcm,
224         int channel, sint16 sample)
225 {
226         sint32 e;
227         sint32 d;
228         sint32 ss;
229         uint8 enc;
230         sint32 diff;
231
232         ss = ima_step_size_table[adpcm->last_step[channel]];
233         d = e = sample - adpcm->last_sample[channel];
234         diff = ss >> 3;
235         enc = 0;
236         if (e < 0)
237         {
238                 enc = 8;
239                 e = -e;
240         }
241         if (e >= ss)
242         {
243                 enc |= 4;
244                 e -= ss;
245         }
246         ss >>= 1;
247         if (e >= ss)
248         {
249                 enc |= 2;
250                 e -= ss;
251         }
252         ss >>= 1;
253         if (e >= ss)
254         {
255                 enc |= 1;
256                 e -= ss;
257         }
258
259         if (d < 0)
260                 diff = d + e - diff;
261         else
262                 diff = d - e + diff;
263
264         diff += adpcm->last_sample[channel];
265         if (diff < -32768)
266                 diff = -32768;
267         else if (diff > 32767)
268                 diff = 32767;
269         adpcm->last_sample[channel] = (sint16) diff;
270
271         adpcm->last_step[channel] += ima_step_index_table[enc];
272         if (adpcm->last_step[channel] < 0)
273                 adpcm->last_step[channel] = 0;
274         else if (adpcm->last_step[channel] > 88)
275                 adpcm->last_step[channel] = 88;
276
277         return enc;
278 }
279
280 uint8* dsp_encode_ima_adpcm(ADPCM* adpcm,
281         uint8* src, int size, int channels, int block_size, int* out_size)
282 {
283         uint8* out;
284         uint8* dst;
285         sint16 sample;
286         uint8 encoded;
287         int i;
288
289         out = (uint8*) xzalloc(size / 2);
290         dst = out;
291         while (size > 0)
292         {
293                 if ((dst - out) % block_size == 0)
294                 {
295                         *dst++ = adpcm->last_sample[0] & 0xff;
296                         *dst++ = (adpcm->last_sample[0] >> 8) & 0xff;
297                         *dst++ = (uint8) adpcm->last_step[0];
298                         *dst++ = 0;
299                         if (channels > 1)
300                         {
301                                 *dst++ = adpcm->last_sample[1] & 0xff;
302                                 *dst++ = (adpcm->last_sample[1] >> 8) & 0xff;
303                                 *dst++ = (uint8) adpcm->last_step[1];
304                                 *dst++ = 0;
305                         }
306                 }
307
308                 if (channels > 1)
309                 {
310                         memset(dst, 0, 8);
311                         for (i = 0; i < 16; i++)
312                         {
313                                 sample = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
314                                 src += 2;
315                                 encoded = dsp_encode_ima_adpcm_sample(adpcm, i % 2, sample);
316                                 dst[ima_stereo_encode_map[i].byte_num] |= encoded << ima_stereo_encode_map[i].byte_shift;
317                         }
318                         dst += 8;
319                         size -= 32;
320                 }
321                 else
322                 {
323                         sample = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
324                         src += 2;
325                         encoded = dsp_encode_ima_adpcm_sample(adpcm, 0, sample);
326                         sample = (sint16) (((uint16)(*src)) | (((uint16)(*(src + 1))) << 8));
327                         src += 2;
328                         encoded |= dsp_encode_ima_adpcm_sample(adpcm, 0, sample) << 4;
329                         *dst++ = encoded;
330                         size -= 4;
331                 }
332         }
333         *out_size = dst - out;
334         return out;
335 }
336