1/*
2 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3 *
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 * This header file contains some internal resampling functions.
14 *
15 */
16
17#include "webrtc/common_audio/signal_processing/resample_by_2_internal.h"
18
19// allpass filter coefficients.
20static const int16_t kResampleAllpass[2][3] = {
21        {821, 6110, 12382},
22        {3050, 9368, 15063}
23};
24
25//
26//   decimator
27// input:  int32_t (shifted 15 positions to the left, + offset 16384) OVERWRITTEN!
28// output: int16_t (saturated) (of length len/2)
29// state:  filter state array; length = 8
30
31void WebRtcSpl_DownBy2IntToShort(int32_t *in, int32_t len, int16_t *out,
32                                 int32_t *state)
33{
34    int32_t tmp0, tmp1, diff;
35    int32_t i;
36
37    len >>= 1;
38
39    // lower allpass filter (operates on even input samples)
40    for (i = 0; i < len; i++)
41    {
42        tmp0 = in[i << 1];
43        diff = tmp0 - state[1];
44        // scale down and round
45        diff = (diff + (1 << 13)) >> 14;
46        tmp1 = state[0] + diff * kResampleAllpass[1][0];
47        state[0] = tmp0;
48        diff = tmp1 - state[2];
49        // scale down and truncate
50        diff = diff >> 14;
51        if (diff < 0)
52            diff += 1;
53        tmp0 = state[1] + diff * kResampleAllpass[1][1];
54        state[1] = tmp1;
55        diff = tmp0 - state[3];
56        // scale down and truncate
57        diff = diff >> 14;
58        if (diff < 0)
59            diff += 1;
60        state[3] = state[2] + diff * kResampleAllpass[1][2];
61        state[2] = tmp0;
62
63        // divide by two and store temporarily
64        in[i << 1] = (state[3] >> 1);
65    }
66
67    in++;
68
69    // upper allpass filter (operates on odd input samples)
70    for (i = 0; i < len; i++)
71    {
72        tmp0 = in[i << 1];
73        diff = tmp0 - state[5];
74        // scale down and round
75        diff = (diff + (1 << 13)) >> 14;
76        tmp1 = state[4] + diff * kResampleAllpass[0][0];
77        state[4] = tmp0;
78        diff = tmp1 - state[6];
79        // scale down and round
80        diff = diff >> 14;
81        if (diff < 0)
82            diff += 1;
83        tmp0 = state[5] + diff * kResampleAllpass[0][1];
84        state[5] = tmp1;
85        diff = tmp0 - state[7];
86        // scale down and truncate
87        diff = diff >> 14;
88        if (diff < 0)
89            diff += 1;
90        state[7] = state[6] + diff * kResampleAllpass[0][2];
91        state[6] = tmp0;
92
93        // divide by two and store temporarily
94        in[i << 1] = (state[7] >> 1);
95    }
96
97    in--;
98
99    // combine allpass outputs
100    for (i = 0; i < len; i += 2)
101    {
102        // divide by two, add both allpass outputs and round
103        tmp0 = (in[i << 1] + in[(i << 1) + 1]) >> 15;
104        tmp1 = (in[(i << 1) + 2] + in[(i << 1) + 3]) >> 15;
105        if (tmp0 > (int32_t)0x00007FFF)
106            tmp0 = 0x00007FFF;
107        if (tmp0 < (int32_t)0xFFFF8000)
108            tmp0 = 0xFFFF8000;
109        out[i] = (int16_t)tmp0;
110        if (tmp1 > (int32_t)0x00007FFF)
111            tmp1 = 0x00007FFF;
112        if (tmp1 < (int32_t)0xFFFF8000)
113            tmp1 = 0xFFFF8000;
114        out[i + 1] = (int16_t)tmp1;
115    }
116}
117
118//
119//   decimator
120// input:  int16_t
121// output: int32_t (shifted 15 positions to the left, + offset 16384) (of length len/2)
122// state:  filter state array; length = 8
123
124void WebRtcSpl_DownBy2ShortToInt(const int16_t *in,
125                                  int32_t len,
126                                  int32_t *out,
127                                  int32_t *state)
128{
129    int32_t tmp0, tmp1, diff;
130    int32_t i;
131
132    len >>= 1;
133
134    // lower allpass filter (operates on even input samples)
135    for (i = 0; i < len; i++)
136    {
137        tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
138        diff = tmp0 - state[1];
139        // scale down and round
140        diff = (diff + (1 << 13)) >> 14;
141        tmp1 = state[0] + diff * kResampleAllpass[1][0];
142        state[0] = tmp0;
143        diff = tmp1 - state[2];
144        // scale down and truncate
145        diff = diff >> 14;
146        if (diff < 0)
147            diff += 1;
148        tmp0 = state[1] + diff * kResampleAllpass[1][1];
149        state[1] = tmp1;
150        diff = tmp0 - state[3];
151        // scale down and truncate
152        diff = diff >> 14;
153        if (diff < 0)
154            diff += 1;
155        state[3] = state[2] + diff * kResampleAllpass[1][2];
156        state[2] = tmp0;
157
158        // divide by two and store temporarily
159        out[i] = (state[3] >> 1);
160    }
161
162    in++;
163
164    // upper allpass filter (operates on odd input samples)
165    for (i = 0; i < len; i++)
166    {
167        tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
168        diff = tmp0 - state[5];
169        // scale down and round
170        diff = (diff + (1 << 13)) >> 14;
171        tmp1 = state[4] + diff * kResampleAllpass[0][0];
172        state[4] = tmp0;
173        diff = tmp1 - state[6];
174        // scale down and round
175        diff = diff >> 14;
176        if (diff < 0)
177            diff += 1;
178        tmp0 = state[5] + diff * kResampleAllpass[0][1];
179        state[5] = tmp1;
180        diff = tmp0 - state[7];
181        // scale down and truncate
182        diff = diff >> 14;
183        if (diff < 0)
184            diff += 1;
185        state[7] = state[6] + diff * kResampleAllpass[0][2];
186        state[6] = tmp0;
187
188        // divide by two and store temporarily
189        out[i] += (state[7] >> 1);
190    }
191
192    in--;
193}
194
195//
196//   interpolator
197// input:  int16_t
198// output: int32_t (normalized, not saturated) (of length len*2)
199// state:  filter state array; length = 8
200void WebRtcSpl_UpBy2ShortToInt(const int16_t *in, int32_t len, int32_t *out,
201                               int32_t *state)
202{
203    int32_t tmp0, tmp1, diff;
204    int32_t i;
205
206    // upper allpass filter (generates odd output samples)
207    for (i = 0; i < len; i++)
208    {
209        tmp0 = ((int32_t)in[i] << 15) + (1 << 14);
210        diff = tmp0 - state[5];
211        // scale down and round
212        diff = (diff + (1 << 13)) >> 14;
213        tmp1 = state[4] + diff * kResampleAllpass[0][0];
214        state[4] = tmp0;
215        diff = tmp1 - state[6];
216        // scale down and truncate
217        diff = diff >> 14;
218        if (diff < 0)
219            diff += 1;
220        tmp0 = state[5] + diff * kResampleAllpass[0][1];
221        state[5] = tmp1;
222        diff = tmp0 - state[7];
223        // scale down and truncate
224        diff = diff >> 14;
225        if (diff < 0)
226            diff += 1;
227        state[7] = state[6] + diff * kResampleAllpass[0][2];
228        state[6] = tmp0;
229
230        // scale down, round and store
231        out[i << 1] = state[7] >> 15;
232    }
233
234    out++;
235
236    // lower allpass filter (generates even output samples)
237    for (i = 0; i < len; i++)
238    {
239        tmp0 = ((int32_t)in[i] << 15) + (1 << 14);
240        diff = tmp0 - state[1];
241        // scale down and round
242        diff = (diff + (1 << 13)) >> 14;
243        tmp1 = state[0] + diff * kResampleAllpass[1][0];
244        state[0] = tmp0;
245        diff = tmp1 - state[2];
246        // scale down and truncate
247        diff = diff >> 14;
248        if (diff < 0)
249            diff += 1;
250        tmp0 = state[1] + diff * kResampleAllpass[1][1];
251        state[1] = tmp1;
252        diff = tmp0 - state[3];
253        // scale down and truncate
254        diff = diff >> 14;
255        if (diff < 0)
256            diff += 1;
257        state[3] = state[2] + diff * kResampleAllpass[1][2];
258        state[2] = tmp0;
259
260        // scale down, round and store
261        out[i << 1] = state[3] >> 15;
262    }
263}
264
265//
266//   interpolator
267// input:  int32_t (shifted 15 positions to the left, + offset 16384)
268// output: int32_t (shifted 15 positions to the left, + offset 16384) (of length len*2)
269// state:  filter state array; length = 8
270void WebRtcSpl_UpBy2IntToInt(const int32_t *in, int32_t len, int32_t *out,
271                             int32_t *state)
272{
273    int32_t tmp0, tmp1, diff;
274    int32_t i;
275
276    // upper allpass filter (generates odd output samples)
277    for (i = 0; i < len; i++)
278    {
279        tmp0 = in[i];
280        diff = tmp0 - state[5];
281        // scale down and round
282        diff = (diff + (1 << 13)) >> 14;
283        tmp1 = state[4] + diff * kResampleAllpass[0][0];
284        state[4] = tmp0;
285        diff = tmp1 - state[6];
286        // scale down and truncate
287        diff = diff >> 14;
288        if (diff < 0)
289            diff += 1;
290        tmp0 = state[5] + diff * kResampleAllpass[0][1];
291        state[5] = tmp1;
292        diff = tmp0 - state[7];
293        // scale down and truncate
294        diff = diff >> 14;
295        if (diff < 0)
296            diff += 1;
297        state[7] = state[6] + diff * kResampleAllpass[0][2];
298        state[6] = tmp0;
299
300        // scale down, round and store
301        out[i << 1] = state[7];
302    }
303
304    out++;
305
306    // lower allpass filter (generates even output samples)
307    for (i = 0; i < len; i++)
308    {
309        tmp0 = in[i];
310        diff = tmp0 - state[1];
311        // scale down and round
312        diff = (diff + (1 << 13)) >> 14;
313        tmp1 = state[0] + diff * kResampleAllpass[1][0];
314        state[0] = tmp0;
315        diff = tmp1 - state[2];
316        // scale down and truncate
317        diff = diff >> 14;
318        if (diff < 0)
319            diff += 1;
320        tmp0 = state[1] + diff * kResampleAllpass[1][1];
321        state[1] = tmp1;
322        diff = tmp0 - state[3];
323        // scale down and truncate
324        diff = diff >> 14;
325        if (diff < 0)
326            diff += 1;
327        state[3] = state[2] + diff * kResampleAllpass[1][2];
328        state[2] = tmp0;
329
330        // scale down, round and store
331        out[i << 1] = state[3];
332    }
333}
334
335//
336//   interpolator
337// input:  int32_t (shifted 15 positions to the left, + offset 16384)
338// output: int16_t (saturated) (of length len*2)
339// state:  filter state array; length = 8
340void WebRtcSpl_UpBy2IntToShort(const int32_t *in, int32_t len, int16_t *out,
341                               int32_t *state)
342{
343    int32_t tmp0, tmp1, diff;
344    int32_t i;
345
346    // upper allpass filter (generates odd output samples)
347    for (i = 0; i < len; i++)
348    {
349        tmp0 = in[i];
350        diff = tmp0 - state[5];
351        // scale down and round
352        diff = (diff + (1 << 13)) >> 14;
353        tmp1 = state[4] + diff * kResampleAllpass[0][0];
354        state[4] = tmp0;
355        diff = tmp1 - state[6];
356        // scale down and round
357        diff = diff >> 14;
358        if (diff < 0)
359            diff += 1;
360        tmp0 = state[5] + diff * kResampleAllpass[0][1];
361        state[5] = tmp1;
362        diff = tmp0 - state[7];
363        // scale down and truncate
364        diff = diff >> 14;
365        if (diff < 0)
366            diff += 1;
367        state[7] = state[6] + diff * kResampleAllpass[0][2];
368        state[6] = tmp0;
369
370        // scale down, saturate and store
371        tmp1 = state[7] >> 15;
372        if (tmp1 > (int32_t)0x00007FFF)
373            tmp1 = 0x00007FFF;
374        if (tmp1 < (int32_t)0xFFFF8000)
375            tmp1 = 0xFFFF8000;
376        out[i << 1] = (int16_t)tmp1;
377    }
378
379    out++;
380
381    // lower allpass filter (generates even output samples)
382    for (i = 0; i < len; i++)
383    {
384        tmp0 = in[i];
385        diff = tmp0 - state[1];
386        // scale down and round
387        diff = (diff + (1 << 13)) >> 14;
388        tmp1 = state[0] + diff * kResampleAllpass[1][0];
389        state[0] = tmp0;
390        diff = tmp1 - state[2];
391        // scale down and truncate
392        diff = diff >> 14;
393        if (diff < 0)
394            diff += 1;
395        tmp0 = state[1] + diff * kResampleAllpass[1][1];
396        state[1] = tmp1;
397        diff = tmp0 - state[3];
398        // scale down and truncate
399        diff = diff >> 14;
400        if (diff < 0)
401            diff += 1;
402        state[3] = state[2] + diff * kResampleAllpass[1][2];
403        state[2] = tmp0;
404
405        // scale down, saturate and store
406        tmp1 = state[3] >> 15;
407        if (tmp1 > (int32_t)0x00007FFF)
408            tmp1 = 0x00007FFF;
409        if (tmp1 < (int32_t)0xFFFF8000)
410            tmp1 = 0xFFFF8000;
411        out[i << 1] = (int16_t)tmp1;
412    }
413}
414
415//   lowpass filter
416// input:  int16_t
417// output: int32_t (normalized, not saturated)
418// state:  filter state array; length = 8
419void WebRtcSpl_LPBy2ShortToInt(const int16_t* in, int32_t len, int32_t* out,
420                               int32_t* state)
421{
422    int32_t tmp0, tmp1, diff;
423    int32_t i;
424
425    len >>= 1;
426
427    // lower allpass filter: odd input -> even output samples
428    in++;
429    // initial state of polyphase delay element
430    tmp0 = state[12];
431    for (i = 0; i < len; i++)
432    {
433        diff = tmp0 - state[1];
434        // scale down and round
435        diff = (diff + (1 << 13)) >> 14;
436        tmp1 = state[0] + diff * kResampleAllpass[1][0];
437        state[0] = tmp0;
438        diff = tmp1 - state[2];
439        // scale down and truncate
440        diff = diff >> 14;
441        if (diff < 0)
442            diff += 1;
443        tmp0 = state[1] + diff * kResampleAllpass[1][1];
444        state[1] = tmp1;
445        diff = tmp0 - state[3];
446        // scale down and truncate
447        diff = diff >> 14;
448        if (diff < 0)
449            diff += 1;
450        state[3] = state[2] + diff * kResampleAllpass[1][2];
451        state[2] = tmp0;
452
453        // scale down, round and store
454        out[i << 1] = state[3] >> 1;
455        tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
456    }
457    in--;
458
459    // upper allpass filter: even input -> even output samples
460    for (i = 0; i < len; i++)
461    {
462        tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
463        diff = tmp0 - state[5];
464        // scale down and round
465        diff = (diff + (1 << 13)) >> 14;
466        tmp1 = state[4] + diff * kResampleAllpass[0][0];
467        state[4] = tmp0;
468        diff = tmp1 - state[6];
469        // scale down and round
470        diff = diff >> 14;
471        if (diff < 0)
472            diff += 1;
473        tmp0 = state[5] + diff * kResampleAllpass[0][1];
474        state[5] = tmp1;
475        diff = tmp0 - state[7];
476        // scale down and truncate
477        diff = diff >> 14;
478        if (diff < 0)
479            diff += 1;
480        state[7] = state[6] + diff * kResampleAllpass[0][2];
481        state[6] = tmp0;
482
483        // average the two allpass outputs, scale down and store
484        out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
485    }
486
487    // switch to odd output samples
488    out++;
489
490    // lower allpass filter: even input -> odd output samples
491    for (i = 0; i < len; i++)
492    {
493        tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
494        diff = tmp0 - state[9];
495        // scale down and round
496        diff = (diff + (1 << 13)) >> 14;
497        tmp1 = state[8] + diff * kResampleAllpass[1][0];
498        state[8] = tmp0;
499        diff = tmp1 - state[10];
500        // scale down and truncate
501        diff = diff >> 14;
502        if (diff < 0)
503            diff += 1;
504        tmp0 = state[9] + diff * kResampleAllpass[1][1];
505        state[9] = tmp1;
506        diff = tmp0 - state[11];
507        // scale down and truncate
508        diff = diff >> 14;
509        if (diff < 0)
510            diff += 1;
511        state[11] = state[10] + diff * kResampleAllpass[1][2];
512        state[10] = tmp0;
513
514        // scale down, round and store
515        out[i << 1] = state[11] >> 1;
516    }
517
518    // upper allpass filter: odd input -> odd output samples
519    in++;
520    for (i = 0; i < len; i++)
521    {
522        tmp0 = ((int32_t)in[i << 1] << 15) + (1 << 14);
523        diff = tmp0 - state[13];
524        // scale down and round
525        diff = (diff + (1 << 13)) >> 14;
526        tmp1 = state[12] + diff * kResampleAllpass[0][0];
527        state[12] = tmp0;
528        diff = tmp1 - state[14];
529        // scale down and round
530        diff = diff >> 14;
531        if (diff < 0)
532            diff += 1;
533        tmp0 = state[13] + diff * kResampleAllpass[0][1];
534        state[13] = tmp1;
535        diff = tmp0 - state[15];
536        // scale down and truncate
537        diff = diff >> 14;
538        if (diff < 0)
539            diff += 1;
540        state[15] = state[14] + diff * kResampleAllpass[0][2];
541        state[14] = tmp0;
542
543        // average the two allpass outputs, scale down and store
544        out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
545    }
546}
547
548//   lowpass filter
549// input:  int32_t (shifted 15 positions to the left, + offset 16384)
550// output: int32_t (normalized, not saturated)
551// state:  filter state array; length = 8
552void WebRtcSpl_LPBy2IntToInt(const int32_t* in, int32_t len, int32_t* out,
553                             int32_t* state)
554{
555    int32_t tmp0, tmp1, diff;
556    int32_t i;
557
558    len >>= 1;
559
560    // lower allpass filter: odd input -> even output samples
561    in++;
562    // initial state of polyphase delay element
563    tmp0 = state[12];
564    for (i = 0; i < len; i++)
565    {
566        diff = tmp0 - state[1];
567        // scale down and round
568        diff = (diff + (1 << 13)) >> 14;
569        tmp1 = state[0] + diff * kResampleAllpass[1][0];
570        state[0] = tmp0;
571        diff = tmp1 - state[2];
572        // scale down and truncate
573        diff = diff >> 14;
574        if (diff < 0)
575            diff += 1;
576        tmp0 = state[1] + diff * kResampleAllpass[1][1];
577        state[1] = tmp1;
578        diff = tmp0 - state[3];
579        // scale down and truncate
580        diff = diff >> 14;
581        if (diff < 0)
582            diff += 1;
583        state[3] = state[2] + diff * kResampleAllpass[1][2];
584        state[2] = tmp0;
585
586        // scale down, round and store
587        out[i << 1] = state[3] >> 1;
588        tmp0 = in[i << 1];
589    }
590    in--;
591
592    // upper allpass filter: even input -> even output samples
593    for (i = 0; i < len; i++)
594    {
595        tmp0 = in[i << 1];
596        diff = tmp0 - state[5];
597        // scale down and round
598        diff = (diff + (1 << 13)) >> 14;
599        tmp1 = state[4] + diff * kResampleAllpass[0][0];
600        state[4] = tmp0;
601        diff = tmp1 - state[6];
602        // scale down and round
603        diff = diff >> 14;
604        if (diff < 0)
605            diff += 1;
606        tmp0 = state[5] + diff * kResampleAllpass[0][1];
607        state[5] = tmp1;
608        diff = tmp0 - state[7];
609        // scale down and truncate
610        diff = diff >> 14;
611        if (diff < 0)
612            diff += 1;
613        state[7] = state[6] + diff * kResampleAllpass[0][2];
614        state[6] = tmp0;
615
616        // average the two allpass outputs, scale down and store
617        out[i << 1] = (out[i << 1] + (state[7] >> 1)) >> 15;
618    }
619
620    // switch to odd output samples
621    out++;
622
623    // lower allpass filter: even input -> odd output samples
624    for (i = 0; i < len; i++)
625    {
626        tmp0 = in[i << 1];
627        diff = tmp0 - state[9];
628        // scale down and round
629        diff = (diff + (1 << 13)) >> 14;
630        tmp1 = state[8] + diff * kResampleAllpass[1][0];
631        state[8] = tmp0;
632        diff = tmp1 - state[10];
633        // scale down and truncate
634        diff = diff >> 14;
635        if (diff < 0)
636            diff += 1;
637        tmp0 = state[9] + diff * kResampleAllpass[1][1];
638        state[9] = tmp1;
639        diff = tmp0 - state[11];
640        // scale down and truncate
641        diff = diff >> 14;
642        if (diff < 0)
643            diff += 1;
644        state[11] = state[10] + diff * kResampleAllpass[1][2];
645        state[10] = tmp0;
646
647        // scale down, round and store
648        out[i << 1] = state[11] >> 1;
649    }
650
651    // upper allpass filter: odd input -> odd output samples
652    in++;
653    for (i = 0; i < len; i++)
654    {
655        tmp0 = in[i << 1];
656        diff = tmp0 - state[13];
657        // scale down and round
658        diff = (diff + (1 << 13)) >> 14;
659        tmp1 = state[12] + diff * kResampleAllpass[0][0];
660        state[12] = tmp0;
661        diff = tmp1 - state[14];
662        // scale down and round
663        diff = diff >> 14;
664        if (diff < 0)
665            diff += 1;
666        tmp0 = state[13] + diff * kResampleAllpass[0][1];
667        state[13] = tmp1;
668        diff = tmp0 - state[15];
669        // scale down and truncate
670        diff = diff >> 14;
671        if (diff < 0)
672            diff += 1;
673        state[15] = state[14] + diff * kResampleAllpass[0][2];
674        state[14] = tmp0;
675
676        // average the two allpass outputs, scale down and store
677        out[i << 1] = (out[i << 1] + (state[15] >> 1)) >> 15;
678    }
679}
680