1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "AudioResamplerSinc"
18//#define LOG_NDEBUG 0
19
20#define __STDC_CONSTANT_MACROS
21#include <malloc.h>
22#include <string.h>
23#include <stdlib.h>
24#include <dlfcn.h>
25
26#include <cutils/compiler.h>
27#include <cutils/properties.h>
28
29#include <utils/Log.h>
30#include <audio_utils/primitives.h>
31
32#include "AudioResamplerSinc.h"
33
34
35
36#if defined(__arm__) && !defined(__thumb__)
37#define USE_INLINE_ASSEMBLY (true)
38#else
39#define USE_INLINE_ASSEMBLY (false)
40#endif
41
42#if defined(__aarch64__) || defined(__ARM_NEON__)
43#include <arm_neon.h>
44#define USE_NEON
45#else
46#undef USE_NEON
47#endif
48
49#define UNUSED(x) ((void)(x))
50
51namespace android {
52// ----------------------------------------------------------------------------
53
54
55/*
56 * These coeficients are computed with the "fir" utility found in
57 * tools/resampler_tools
58 * cmd-line: fir -l 7 -s 48000 -c 20478
59 */
60const uint32_t AudioResamplerSinc::mFirCoefsUp[] __attribute__ ((aligned (32))) = {
61        0x6d374bc7, 0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300,
62        0x6d35278a, 0x103e8192, 0xf36b9dfd, 0x07bdfaa5, 0xfc5102d0, 0x013d618d, 0xffc663b9, 0xfffd9592,
63        0x6d2ebafe, 0x0f62811a, 0xf3b3d8ac, 0x07a9f399, 0xfc51d9a6, 0x0140bea5, 0xffc41212, 0xfffe631e,
64        0x6d24069d, 0x0e8875ad, 0xf3fcb43e, 0x07953976, 0xfc53216f, 0x0143e67c, 0xffc1d373, 0xffff2b9f,
65        0x6d150b35, 0x0db06a89, 0xf4462690, 0x077fd0ac, 0xfc54d8ae, 0x0146d965, 0xffbfa7d9, 0xffffef10,
66        0x6d01c9e3, 0x0cda6ab5, 0xf4902587, 0x0769bdaf, 0xfc56fdda, 0x014997bb, 0xffbd8f40, 0x0000ad6e,
67        0x6cea4418, 0x0c0680fe, 0xf4daa718, 0x07530501, 0xfc598f60, 0x014c21db, 0xffbb89a1, 0x000166b6,
68        0x6cce7b97, 0x0b34b7f5, 0xf525a143, 0x073bab28, 0xfc5c8ba5, 0x014e782a, 0xffb996f3, 0x00021ae5,
69        0x6cae7272, 0x0a6519f4, 0xf5710a17, 0x0723b4b4, 0xfc5ff105, 0x01509b14, 0xffb7b728, 0x0002c9fd,
70        0x6c8a2b0f, 0x0997b116, 0xf5bcd7b1, 0x070b2639, 0xfc63bdd3, 0x01528b08, 0xffb5ea31, 0x000373fb,
71        0x6c61a823, 0x08cc873c, 0xf609003f, 0x06f20453, 0xfc67f05a, 0x0154487b, 0xffb42ffc, 0x000418e2,
72        0x6c34ecb5, 0x0803a60a, 0xf6557a00, 0x06d853a2, 0xfc6c86dd, 0x0155d3e8, 0xffb28876, 0x0004b8b3,
73        0x6c03fc1c, 0x073d16e7, 0xf6a23b44, 0x06be18cd, 0xfc717f97, 0x01572dcf, 0xffb0f388, 0x00055371,
74        0x6bced9ff, 0x0678e2fc, 0xf6ef3a6e, 0x06a3587e, 0xfc76d8bc, 0x015856b6, 0xffaf7118, 0x0005e921,
75        0x6b958a54, 0x05b71332, 0xf73c6df4, 0x06881761, 0xfc7c9079, 0x01594f25, 0xffae010b, 0x000679c5,
76        0x6b581163, 0x04f7b037, 0xf789cc61, 0x066c5a27, 0xfc82a4f4, 0x015a17ab, 0xffaca344, 0x00070564,
77        0x6b1673c1, 0x043ac276, 0xf7d74c53, 0x06502583, 0xfc89144d, 0x015ab0db, 0xffab57a1, 0x00078c04,
78        0x6ad0b652, 0x0380521c, 0xf824e480, 0x06337e2a, 0xfc8fdc9f, 0x015b1b4e, 0xffaa1e02, 0x00080dab,
79        0x6a86de48, 0x02c86715, 0xf8728bb3, 0x061668d2, 0xfc96fbfc, 0x015b579e, 0xffa8f641, 0x00088a62,
80        0x6a38f123, 0x0213090c, 0xf8c038d0, 0x05f8ea30, 0xfc9e7074, 0x015b666c, 0xffa7e039, 0x00090230,
81        0x69e6f4b1, 0x01603f6e, 0xf90de2d1, 0x05db06fc, 0xfca63810, 0x015b485b, 0xffa6dbc0, 0x0009751e,
82        0x6990ef0b, 0x00b01162, 0xf95b80cb, 0x05bcc3ed, 0xfcae50d6, 0x015afe14, 0xffa5e8ad, 0x0009e337,
83        0x6936e697, 0x000285d0, 0xf9a909ea, 0x059e25b5, 0xfcb6b8c4, 0x015a8843, 0xffa506d2, 0x000a4c85,
84        0x68d8e206, 0xff57a35e, 0xf9f67577, 0x057f310a, 0xfcbf6dd8, 0x0159e796, 0xffa43603, 0x000ab112,
85        0x6876e855, 0xfeaf706f, 0xfa43bad2, 0x055fea9d, 0xfcc86e09, 0x01591cc0, 0xffa3760e, 0x000b10ec,
86        0x681100c9, 0xfe09f323, 0xfa90d17b, 0x0540571a, 0xfcd1b74c, 0x01582878, 0xffa2c6c2, 0x000b6c1d,
87        0x67a732f4, 0xfd673159, 0xfaddb10c, 0x05207b2f, 0xfcdb4793, 0x01570b77, 0xffa227ec, 0x000bc2b3,
88        0x673986ac, 0xfcc730aa, 0xfb2a513b, 0x05005b82, 0xfce51ccb, 0x0155c678, 0xffa19957, 0x000c14bb,
89        0x66c80413, 0xfc29f670, 0xfb76a9dd, 0x04dffcb6, 0xfcef34e1, 0x01545a3c, 0xffa11acb, 0x000c6244,
90        0x6652b392, 0xfb8f87bd, 0xfbc2b2e4, 0x04bf6369, 0xfcf98dbe, 0x0152c783, 0xffa0ac11, 0x000cab5c,
91        0x65d99dd5, 0xfaf7e963, 0xfc0e6461, 0x049e9433, 0xfd04254a, 0x01510f13, 0xffa04cf0, 0x000cf012,
92        0x655ccbd3, 0xfa631fef, 0xfc59b685, 0x047d93a8, 0xfd0ef969, 0x014f31b2, 0xff9ffd2c, 0x000d3075,
93        0x64dc46c3, 0xf9d12fab, 0xfca4a19f, 0x045c6654, 0xfd1a0801, 0x014d3029, 0xff9fbc89, 0x000d6c97,
94        0x64581823, 0xf9421c9d, 0xfcef1e20, 0x043b10bd, 0xfd254ef4, 0x014b0b45, 0xff9f8ac9, 0x000da486,
95        0x63d049b4, 0xf8b5ea87, 0xfd392498, 0x04199760, 0xfd30cc24, 0x0148c3d2, 0xff9f67ae, 0x000dd854,
96        0x6344e578, 0xf82c9ce7, 0xfd82adba, 0x03f7feb4, 0xfd3c7d73, 0x01465a9f, 0xff9f52f7, 0x000e0812,
97        0x62b5f5b2, 0xf7a636fa, 0xfdcbb25a, 0x03d64b27, 0xfd4860c2, 0x0143d07f, 0xff9f4c65, 0x000e33d3,
98        0x622384e8, 0xf722bbb5, 0xfe142b6e, 0x03b4811d, 0xfd5473f3, 0x01412643, 0xff9f53b4, 0x000e5ba7,
99        0x618d9ddc, 0xf6a22dcf, 0xfe5c120f, 0x0392a4f4, 0xfd60b4e7, 0x013e5cc0, 0xff9f68a1, 0x000e7fa1,
100        0x60f44b91, 0xf6248fb6, 0xfea35f79, 0x0370bafc, 0xfd6d2180, 0x013b74ca, 0xff9f8ae9, 0x000e9fd5,
101        0x60579947, 0xf5a9e398, 0xfeea0d0c, 0x034ec77f, 0xfd79b7a1, 0x01386f3a, 0xff9fba47, 0x000ebc54,
102        0x5fb79278, 0xf5322b61, 0xff30144a, 0x032ccebb, 0xfd86752e, 0x01354ce7, 0xff9ff674, 0x000ed533,
103        0x5f1442dc, 0xf4bd68b6, 0xff756edc, 0x030ad4e1, 0xfd93580d, 0x01320ea9, 0xffa03f2b, 0x000eea84,
104        0x5e6db665, 0xf44b9cfe, 0xffba168d, 0x02e8de19, 0xfda05e23, 0x012eb55a, 0xffa09425, 0x000efc5c,
105        0x5dc3f93c, 0xf3dcc959, 0xfffe054e, 0x02c6ee7f, 0xfdad855b, 0x012b41d3, 0xffa0f519, 0x000f0ace,
106        0x5d1717c4, 0xf370eea9, 0x00413536, 0x02a50a22, 0xfdbacb9e, 0x0127b4f1, 0xffa161bf, 0x000f15ef,
107        0x5c671e96, 0xf3080d8c, 0x0083a081, 0x02833506, 0xfdc82edb, 0x01240f8e, 0xffa1d9cf, 0x000f1dd2,
108        0x5bb41a80, 0xf2a2265e, 0x00c54190, 0x02617321, 0xfdd5ad01, 0x01205285, 0xffa25cfe, 0x000f228d,
109        0x5afe1886, 0xf23f393b, 0x010612eb, 0x023fc85c, 0xfde34403, 0x011c7eb2, 0xffa2eb04, 0x000f2434,
110        0x5a4525df, 0xf1df45fd, 0x01460f41, 0x021e3891, 0xfdf0f1d6, 0x011894f0, 0xffa38395, 0x000f22dc,
111        0x59894ff3, 0xf1824c3e, 0x01853165, 0x01fcc78f, 0xfdfeb475, 0x0114961b, 0xffa42668, 0x000f1e99,
112        0x58caa45b, 0xf1284b58, 0x01c37452, 0x01db7914, 0xfe0c89db, 0x0110830f, 0xffa4d332, 0x000f1781,
113        0x580930e1, 0xf0d14267, 0x0200d32c, 0x01ba50d2, 0xfe1a7009, 0x010c5ca6, 0xffa589a6, 0x000f0da8,
114        0x5745037c, 0xf07d3043, 0x023d493c, 0x0199526b, 0xfe286505, 0x010823ba, 0xffa6497c, 0x000f0125,
115        0x567e2a51, 0xf02c138a, 0x0278d1f2, 0x01788170, 0xfe3666d5, 0x0103d927, 0xffa71266, 0x000ef20b,
116        0x55b4b3af, 0xefddea9a, 0x02b368e6, 0x0157e166, 0xfe447389, 0x00ff7dc4, 0xffa7e41a, 0x000ee070,
117        0x54e8ae13, 0xef92b393, 0x02ed09d7, 0x013775bf, 0xfe528931, 0x00fb126b, 0xffa8be4c, 0x000ecc69,
118        0x541a281e, 0xef4a6c58, 0x0325b0ad, 0x011741df, 0xfe60a5e5, 0x00f697f3, 0xffa9a0b1, 0x000eb60b,
119        0x5349309e, 0xef051290, 0x035d5977, 0x00f7491a, 0xfe6ec7c0, 0x00f20f32, 0xffaa8afe, 0x000e9d6b,
120        0x5275d684, 0xeec2a3a3, 0x0394006a, 0x00d78eb3, 0xfe7cece2, 0x00ed78ff, 0xffab7ce7, 0x000e829e,
121        0x51a028e8, 0xee831cc3, 0x03c9a1e5, 0x00b815da, 0xfe8b1373, 0x00e8d62d, 0xffac7621, 0x000e65ba,
122        0x50c83704, 0xee467ae1, 0x03fe3a6f, 0x0098e1b3, 0xfe99399f, 0x00e4278f, 0xffad7662, 0x000e46d3,
123        0x4fee1037, 0xee0cbab9, 0x0431c6b5, 0x0079f54c, 0xfea75d97, 0x00df6df7, 0xffae7d5f, 0x000e25fd,
124        0x4f11c3fe, 0xedd5d8ca, 0x0464438c, 0x005b53a4, 0xfeb57d92, 0x00daaa34, 0xffaf8acd, 0x000e034f,
125        0x4e3361f7, 0xeda1d15c, 0x0495adf2, 0x003cffa9, 0xfec397cf, 0x00d5dd16, 0xffb09e63, 0x000ddedb,
126        0x4d52f9df, 0xed70a07d, 0x04c6030d, 0x001efc35, 0xfed1aa92, 0x00d10769, 0xffb1b7d8, 0x000db8b7,
127        0x4c709b8e, 0xed424205, 0x04f54029, 0x00014c12, 0xfedfb425, 0x00cc29f7, 0xffb2d6e1, 0x000d90f6,
128        0x4b8c56f8, 0xed16b196, 0x052362ba, 0xffe3f1f7, 0xfeedb2da, 0x00c7458a, 0xffb3fb37, 0x000d67ae,
129        0x4aa63c2c, 0xecedea99, 0x0550685d, 0xffc6f08a, 0xfefba508, 0x00c25ae8, 0xffb52490, 0x000d3cf1,
130        0x49be5b50, 0xecc7e845, 0x057c4ed4, 0xffaa4a5d, 0xff09890f, 0x00bd6ad7, 0xffb652a7, 0x000d10d5,
131        0x48d4c4a2, 0xeca4a59b, 0x05a7140b, 0xff8e01f1, 0xff175d53, 0x00b87619, 0xffb78533, 0x000ce36b,
132        0x47e98874, 0xec841d68, 0x05d0b612, 0xff7219b3, 0xff252042, 0x00b37d70, 0xffb8bbed, 0x000cb4c8,
133        0x46fcb72d, 0xec664a48, 0x05f93324, 0xff5693fe, 0xff32d04f, 0x00ae8198, 0xffb9f691, 0x000c84ff,
134        0x460e6148, 0xec4b26a2, 0x0620899e, 0xff3b731b, 0xff406bf8, 0x00a9834e, 0xffbb34d8, 0x000c5422,
135        0x451e9750, 0xec32acb0, 0x0646b808, 0xff20b93e, 0xff4df1be, 0x00a4834c, 0xffbc767f, 0x000c2245,
136        0x442d69de, 0xec1cd677, 0x066bbd0d, 0xff066889, 0xff5b602c, 0x009f8249, 0xffbdbb42, 0x000bef79,
137        0x433ae99c, 0xec099dcf, 0x068f9781, 0xfeec830d, 0xff68b5d5, 0x009a80f8, 0xffbf02dd, 0x000bbbd2,
138        0x4247273f, 0xebf8fc64, 0x06b2465b, 0xfed30ac5, 0xff75f153, 0x0095800c, 0xffc04d0f, 0x000b8760,
139        0x41523389, 0xebeaebaf, 0x06d3c8bb, 0xfeba0199, 0xff831148, 0x00908034, 0xffc19996, 0x000b5235,
140        0x405c1f43, 0xebdf6500, 0x06f41de3, 0xfea16960, 0xff90145e, 0x008b821b, 0xffc2e832, 0x000b1c64,
141        0x3f64fb40, 0xebd6617b, 0x0713453d, 0xfe8943dc, 0xff9cf947, 0x0086866b, 0xffc438a3, 0x000ae5fc,
142        0x3e6cd85b, 0xebcfda19, 0x07313e56, 0xfe7192bd, 0xffa9bebe, 0x00818dcb, 0xffc58aaa, 0x000aaf0f,
143        0x3d73c772, 0xebcbc7a7, 0x074e08e0, 0xfe5a579d, 0xffb66386, 0x007c98de, 0xffc6de09, 0x000a77ac,
144        0x3c79d968, 0xebca22cc, 0x0769a4b2, 0xfe439407, 0xffc2e669, 0x0077a845, 0xffc83285, 0x000a3fe5,
145        0x3b7f1f23, 0xebcae405, 0x078411c7, 0xfe2d496f, 0xffcf463a, 0x0072bc9d, 0xffc987e0, 0x000a07c9,
146        0x3a83a989, 0xebce03aa, 0x079d503b, 0xfe177937, 0xffdb81d6, 0x006dd680, 0xffcadde1, 0x0009cf67,
147        0x3987897f, 0xebd379eb, 0x07b56051, 0xfe0224b0, 0xffe79820, 0x0068f687, 0xffcc344c, 0x000996ce,
148        0x388acfe9, 0xebdb3ed5, 0x07cc426c, 0xfded4d13, 0xfff38806, 0x00641d44, 0xffcd8aeb, 0x00095e0e,
149        0x378d8da8, 0xebe54a4f, 0x07e1f712, 0xfdd8f38b, 0xffff507b, 0x005f4b4a, 0xffcee183, 0x00092535,
150        0x368fd397, 0xebf1941f, 0x07f67eec, 0xfdc5192d, 0x000af07f, 0x005a8125, 0xffd037e0, 0x0008ec50,
151        0x3591b28b, 0xec0013e8, 0x0809dac3, 0xfdb1befc, 0x00166718, 0x0055bf60, 0xffd18dcc, 0x0008b36e,
152        0x34933b50, 0xec10c12c, 0x081c0b84, 0xfd9ee5e7, 0x0021b355, 0x00510682, 0xffd2e311, 0x00087a9c,
153        0x33947eab, 0xec23934f, 0x082d1239, 0xfd8c8ecc, 0x002cd44d, 0x004c570f, 0xffd4377d, 0x000841e8,
154        0x32958d55, 0xec388194, 0x083cf010, 0xfd7aba74, 0x0037c922, 0x0047b186, 0xffd58ade, 0x0008095d,
155        0x319677fa, 0xec4f8322, 0x084ba654, 0xfd696998, 0x004290fc, 0x00431666, 0xffd6dd02, 0x0007d108,
156        0x30974f3b, 0xec688f02, 0x08593671, 0xfd589cdc, 0x004d2b0e, 0x003e8628, 0xffd82dba, 0x000798f5,
157        0x2f9823a8, 0xec839c22, 0x0865a1f1, 0xfd4854d3, 0x00579691, 0x003a0141, 0xffd97cd6, 0x00076130,
158        0x2e9905c1, 0xeca0a156, 0x0870ea7e, 0xfd3891fd, 0x0061d2ca, 0x00358824, 0xffdaca2a, 0x000729c4,
159        0x2d9a05f4, 0xecbf9558, 0x087b11de, 0xfd2954c8, 0x006bdf05, 0x00311b41, 0xffdc1588, 0x0006f2bb,
160        0x2c9b349e, 0xece06ecb, 0x088419f6, 0xfd1a9d91, 0x0075ba95, 0x002cbb03, 0xffdd5ec6, 0x0006bc21,
161        0x2b9ca203, 0xed032439, 0x088c04c8, 0xfd0c6ca2, 0x007f64da, 0x002867d2, 0xffdea5bb, 0x000685ff,
162        0x2a9e5e57, 0xed27ac16, 0x0892d470, 0xfcfec233, 0x0088dd38, 0x00242213, 0xffdfea3c, 0x0006505f,
163        0x29a079b2, 0xed4dfcc2, 0x08988b2a, 0xfcf19e6b, 0x0092231e, 0x001fea27, 0xffe12c22, 0x00061b4b,
164        0x28a30416, 0xed760c88, 0x089d2b4a, 0xfce50161, 0x009b3605, 0x001bc06b, 0xffe26b48, 0x0005e6cb,
165        0x27a60d6a, 0xed9fd1a2, 0x08a0b740, 0xfcd8eb17, 0x00a4156b, 0x0017a53b, 0xffe3a788, 0x0005b2e8,
166        0x26a9a57b, 0xedcb4237, 0x08a33196, 0xfccd5b82, 0x00acc0da, 0x001398ec, 0xffe4e0bf, 0x00057faa,
167        0x25addbf9, 0xedf8545b, 0x08a49cf0, 0xfcc25285, 0x00b537e1, 0x000f9bd2, 0xffe616c8, 0x00054d1a,
168        0x24b2c075, 0xee26fe17, 0x08a4fc0d, 0xfcb7cff0, 0x00bd7a1c, 0x000bae3c, 0xffe74984, 0x00051b3e,
169        0x23b86263, 0xee573562, 0x08a451c0, 0xfcadd386, 0x00c5872a, 0x0007d075, 0xffe878d3, 0x0004ea1d,
170        0x22bed116, 0xee88f026, 0x08a2a0f8, 0xfca45cf7, 0x00cd5eb7, 0x000402c8, 0xffe9a494, 0x0004b9c0,
171        0x21c61bc0, 0xeebc2444, 0x089fecbb, 0xfc9b6be5, 0x00d50075, 0x00004579, 0xffeaccaa, 0x00048a2b,
172        0x20ce516f, 0xeef0c78d, 0x089c3824, 0xfc92ffe1, 0x00dc6c1e, 0xfffc98c9, 0xffebf0fa, 0x00045b65,
173        0x1fd7810f, 0xef26cfca, 0x08978666, 0xfc8b186d, 0x00e3a175, 0xfff8fcf7, 0xffed1166, 0x00042d74,
174        0x1ee1b965, 0xef5e32bd, 0x0891dac8, 0xfc83b4fc, 0x00eaa045, 0xfff5723d, 0xffee2dd7, 0x0004005e,
175        0x1ded0911, 0xef96e61c, 0x088b38a9, 0xfc7cd4f0, 0x00f16861, 0xfff1f8d2, 0xffef4632, 0x0003d426,
176        0x1cf97e8b, 0xefd0df9a, 0x0883a378, 0xfc76779e, 0x00f7f9a3, 0xffee90eb, 0xfff05a60, 0x0003a8d2,
177        0x1c072823, 0xf00c14e1, 0x087b1ebc, 0xfc709c4d, 0x00fe53ef, 0xffeb3ab8, 0xfff16a4a, 0x00037e65,
178        0x1b1613ff, 0xf0487b98, 0x0871ae0d, 0xfc6b4233, 0x0104772e, 0xffe7f666, 0xfff275db, 0x000354e5,
179        0x1a26501b, 0xf0860962, 0x08675516, 0xfc66687a, 0x010a6353, 0xffe4c41e, 0xfff37d00, 0x00032c54,
180        0x1937ea47, 0xf0c4b3e0, 0x085c1794, 0xfc620e3d, 0x01101858, 0xffe1a408, 0xfff47fa5, 0x000304b7,
181        0x184af025, 0xf10470b0, 0x084ff957, 0xfc5e328c, 0x0115963d, 0xffde9646, 0xfff57db8, 0x0002de0e,
182        0x175f6f2b, 0xf1453571, 0x0842fe3d, 0xfc5ad465, 0x011add0b, 0xffdb9af8, 0xfff67729, 0x0002b85f,
183        0x1675749e, 0xf186f7c0, 0x08352a35, 0xfc57f2be, 0x011fecd3, 0xffd8b23b, 0xfff76be9, 0x000293aa,
184        0x158d0d95, 0xf1c9ad40, 0x0826813e, 0xfc558c7c, 0x0124c5ab, 0xffd5dc28, 0xfff85be8, 0x00026ff2,
185        0x14a646f6, 0xf20d4b92, 0x08170767, 0xfc53a07b, 0x012967b1, 0xffd318d6, 0xfff9471b, 0x00024d39,
186        0x13c12d73, 0xf251c85d, 0x0806c0cb, 0xfc522d88, 0x012dd30a, 0xffd06858, 0xfffa2d74, 0x00022b7f,
187        0x12ddcd8f, 0xf297194d, 0x07f5b193, 0xfc513266, 0x013207e4, 0xffcdcabe, 0xfffb0ee9, 0x00020ac7,
188        0x11fc3395, 0xf2dd3411, 0x07e3ddf7, 0xfc50adcc, 0x01360670, 0xffcb4014, 0xfffbeb70, 0x0001eb10,
189        0x111c6ba0, 0xf3240e61, 0x07d14a38, 0xfc509e64, 0x0139cee9, 0xffc8c866, 0xfffcc300, 0x0001cc5c,
190};
191
192/*
193 * These coefficients are optimized for 48KHz -> 44.1KHz
194 * cmd-line: fir -l 7 -s 48000 -c 17189
195 */
196const uint32_t AudioResamplerSinc::mFirCoefsDown[] __attribute__ ((aligned (32))) = {
197        0x5bacb6f4, 0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631,
198        0x5bab6c81, 0x1d3ddccd, 0xf0421d2c, 0x03af9995, 0x01818dc9, 0xfe6bb63e, 0x0079812a, 0xfffdc37d,
199        0x5ba78d37, 0x1c8f2cf9, 0xf04beb1d, 0x03c9a04a, 0x016f8aca, 0xfe70a511, 0x0079e34d, 0xfffd2545,
200        0x5ba1194f, 0x1be11231, 0xf056f2c7, 0x03e309fe, 0x015d9e64, 0xfe75a79f, 0x007a36e2, 0xfffc8b86,
201        0x5b981122, 0x1b3393f8, 0xf0632fb7, 0x03fbd625, 0x014bc9fa, 0xfe7abd23, 0x007a7c20, 0xfffbf639,
202        0x5b8c7530, 0x1a86b9bf, 0xf0709d74, 0x04140449, 0x013a0ee9, 0xfe7fe4db, 0x007ab33d, 0xfffb655b,
203        0x5b7e461a, 0x19da8ae5, 0xf07f3776, 0x042b93fd, 0x01286e86, 0xfe851e05, 0x007adc72, 0xfffad8e4,
204        0x5b6d84a8, 0x192f0eb7, 0xf08ef92d, 0x044284e6, 0x0116ea22, 0xfe8a67dd, 0x007af7f6, 0xfffa50ce,
205        0x5b5a31c6, 0x18844c70, 0xf09fddfe, 0x0458d6b7, 0x01058306, 0xfe8fc1a5, 0x007b0603, 0xfff9cd12,
206        0x5b444e81, 0x17da4b37, 0xf0b1e143, 0x046e8933, 0x00f43a74, 0xfe952a9b, 0x007b06d4, 0xfff94da9,
207        0x5b2bdc0e, 0x17311222, 0xf0c4fe50, 0x04839c29, 0x00e311a9, 0xfe9aa201, 0x007afaa1, 0xfff8d28c,
208        0x5b10dbc2, 0x1688a832, 0xf0d9306d, 0x04980f79, 0x00d209db, 0xfea02719, 0x007ae1a7, 0xfff85bb1,
209        0x5af34f18, 0x15e11453, 0xf0ee72db, 0x04abe310, 0x00c12439, 0xfea5b926, 0x007abc20, 0xfff7e910,
210        0x5ad337af, 0x153a5d5e, 0xf104c0d2, 0x04bf16e9, 0x00b061eb, 0xfeab576d, 0x007a8a49, 0xfff77a9f,
211        0x5ab09748, 0x14948a16, 0xf11c1583, 0x04d1ab0d, 0x009fc413, 0xfeb10134, 0x007a4c5d, 0xfff71057,
212        0x5a8b6fc7, 0x13efa12c, 0xf1346c17, 0x04e39f93, 0x008f4bcb, 0xfeb6b5c0, 0x007a029a, 0xfff6aa2b,
213        0x5a63c336, 0x134ba937, 0xf14dbfb1, 0x04f4f4a2, 0x007efa29, 0xfebc745c, 0x0079ad3d, 0xfff64812,
214        0x5a3993c0, 0x12a8a8bb, 0xf1680b6e, 0x0505aa6a, 0x006ed038, 0xfec23c50, 0x00794c82, 0xfff5ea02,
215        0x5a0ce3b2, 0x1206a625, 0xf1834a63, 0x0515c12d, 0x005ecf01, 0xfec80ce8, 0x0078e0a9, 0xfff58ff0,
216        0x59ddb57f, 0x1165a7cc, 0xf19f77a0, 0x05253938, 0x004ef782, 0xfecde571, 0x007869ee, 0xfff539cf,
217        0x59ac0bba, 0x10c5b3ef, 0xf1bc8e31, 0x053412e4, 0x003f4ab4, 0xfed3c538, 0x0077e891, 0xfff4e794,
218        0x5977e919, 0x1026d0b8, 0xf1da891b, 0x05424e9b, 0x002fc98a, 0xfed9ab8f, 0x00775ccf, 0xfff49934,
219        0x59415075, 0x0f890437, 0xf1f96360, 0x054feccf, 0x002074ed, 0xfedf97c6, 0x0076c6e8, 0xfff44ea3,
220        0x590844c9, 0x0eec5465, 0xf21917ff, 0x055cee03, 0x00114dc3, 0xfee58932, 0x00762719, 0xfff407d2,
221        0x58ccc930, 0x0e50c723, 0xf239a1ef, 0x056952c3, 0x000254e8, 0xfeeb7f27, 0x00757da3, 0xfff3c4b7,
222        0x588ee0ea, 0x0db6623b, 0xf25afc29, 0x05751baa, 0xfff38b32, 0xfef178fc, 0x0074cac4, 0xfff38542,
223        0x584e8f56, 0x0d1d2b5d, 0xf27d219f, 0x0580495c, 0xffe4f171, 0xfef7760c, 0x00740ebb, 0xfff34968,
224        0x580bd7f4, 0x0c85281f, 0xf2a00d43, 0x058adc8d, 0xffd6886d, 0xfefd75af, 0x007349c7, 0xfff3111b,
225        0x57c6be67, 0x0bee5dff, 0xf2c3ba04, 0x0594d5fa, 0xffc850e6, 0xff037744, 0x00727c27, 0xfff2dc4c,
226        0x577f4670, 0x0b58d262, 0xf2e822ce, 0x059e366c, 0xffba4b98, 0xff097a29, 0x0071a61b, 0xfff2aaef,
227        0x573573f2, 0x0ac48a92, 0xf30d428e, 0x05a6feb9, 0xffac7936, 0xff0f7dbf, 0x0070c7e1, 0xfff27cf3,
228        0x56e94af1, 0x0a318bc1, 0xf333142f, 0x05af2fbf, 0xff9eda6d, 0xff15816a, 0x006fe1b8, 0xfff2524c,
229        0x569acf90, 0x099fdb04, 0xf359929a, 0x05b6ca6b, 0xff916fe1, 0xff1b848e, 0x006ef3df, 0xfff22aea,
230        0x564a0610, 0x090f7d57, 0xf380b8ba, 0x05bdcfb2, 0xff843a32, 0xff218692, 0x006dfe94, 0xfff206bf,
231        0x55f6f2d3, 0x0880779d, 0xf3a88179, 0x05c44095, 0xff7739f7, 0xff2786e1, 0x006d0217, 0xfff1e5bb,
232        0x55a19a5c, 0x07f2ce9b, 0xf3d0e7c2, 0x05ca1e1f, 0xff6a6fc1, 0xff2d84e5, 0x006bfea4, 0xfff1c7d0,
233        0x554a0148, 0x076686fc, 0xf3f9e680, 0x05cf6965, 0xff5ddc1a, 0xff33800e, 0x006af47b, 0xfff1acef,
234        0x54f02c56, 0x06dba551, 0xf42378a0, 0x05d42387, 0xff517f86, 0xff3977cb, 0x0069e3d9, 0xfff19508,
235        0x54942061, 0x06522e0f, 0xf44d9912, 0x05d84daf, 0xff455a80, 0xff3f6b8f, 0x0068ccfa, 0xfff1800b,
236        0x5435e263, 0x05ca258f, 0xf47842c5, 0x05dbe90f, 0xff396d7f, 0xff455acf, 0x0067b01e, 0xfff16de9,
237        0x53d57774, 0x0543900d, 0xf4a370ad, 0x05def6e4, 0xff2db8f2, 0xff4b4503, 0x00668d80, 0xfff15e93,
238        0x5372e4c6, 0x04be71ab, 0xf4cf1dbf, 0x05e17873, 0xff223d40, 0xff5129a3, 0x0065655d, 0xfff151f9,
239        0x530e2fac, 0x043ace6e, 0xf4fb44f4, 0x05e36f0d, 0xff16faca, 0xff57082e, 0x006437f1, 0xfff1480b,
240        0x52a75d90, 0x03b8aa40, 0xf527e149, 0x05e4dc08, 0xff0bf1ed, 0xff5ce021, 0x00630577, 0xfff140b9,
241        0x523e73fd, 0x033808eb, 0xf554edbd, 0x05e5c0c6, 0xff0122fc, 0xff62b0fd, 0x0061ce2c, 0xfff13bf3,
242        0x51d37897, 0x02b8ee22, 0xf5826555, 0x05e61eae, 0xfef68e45, 0xff687a47, 0x00609249, 0xfff139aa,
243        0x5166711c, 0x023b5d76, 0xf5b0431a, 0x05e5f733, 0xfeec340f, 0xff6e3b84, 0x005f520a, 0xfff139cd,
244        0x50f76368, 0x01bf5a5e, 0xf5de8218, 0x05e54bcd, 0xfee2149b, 0xff73f43d, 0x005e0da8, 0xfff13c4c,
245        0x5086556f, 0x0144e834, 0xf60d1d63, 0x05e41dfe, 0xfed83023, 0xff79a3fe, 0x005cc55c, 0xfff14119,
246        0x50134d3e, 0x00cc0a36, 0xf63c1012, 0x05e26f4e, 0xfece86db, 0xff7f4a54, 0x005b7961, 0xfff14821,
247        0x4f9e50ff, 0x0054c382, 0xf66b5544, 0x05e0414d, 0xfec518f1, 0xff84e6d0, 0x005a29ed, 0xfff15156,
248        0x4f2766f2, 0xffdf171b, 0xf69ae81d, 0x05dd9593, 0xfebbe68c, 0xff8a7905, 0x0058d738, 0xfff15ca8,
249        0x4eae9571, 0xff6b07e7, 0xf6cac3c7, 0x05da6dbe, 0xfeb2efcd, 0xff900089, 0x0057817b, 0xfff16a07,
250        0x4e33e2ee, 0xfef898ae, 0xf6fae373, 0x05d6cb72, 0xfeaa34d0, 0xff957cf4, 0x005628ec, 0xfff17962,
251        0x4db755f3, 0xfe87cc1b, 0xf72b425b, 0x05d2b05c, 0xfea1b5a9, 0xff9aede0, 0x0054cdc0, 0xfff18aab,
252        0x4d38f520, 0xfe18a4bc, 0xf75bdbbd, 0x05ce1e2d, 0xfe997268, 0xffa052ec, 0x0053702d, 0xfff19dd1,
253        0x4cb8c72e, 0xfdab2501, 0xf78caae0, 0x05c9169d, 0xfe916b15, 0xffa5abb8, 0x00521068, 0xfff1b2c5,
254        0x4c36d2eb, 0xfd3f4f3d, 0xf7bdab16, 0x05c39b6a, 0xfe899fb2, 0xffaaf7e6, 0x0050aea5, 0xfff1c976,
255        0x4bb31f3c, 0xfcd525a5, 0xf7eed7b4, 0x05bdae57, 0xfe82103f, 0xffb0371c, 0x004f4b17, 0xfff1e1d6,
256        0x4b2db31a, 0xfc6caa53, 0xf8202c1c, 0x05b7512e, 0xfe7abcb1, 0xffb56902, 0x004de5f1, 0xfff1fbd5,
257        0x4aa69594, 0xfc05df40, 0xf851a3b6, 0x05b085bc, 0xfe73a4fb, 0xffba8d44, 0x004c7f66, 0xfff21764,
258        0x4a1dcdce, 0xfba0c64b, 0xf88339f5, 0x05a94dd5, 0xfe6cc909, 0xffbfa38d, 0x004b17a6, 0xfff23473,
259        0x499362ff, 0xfb3d6133, 0xf8b4ea55, 0x05a1ab52, 0xfe6628c1, 0xffc4ab8f, 0x0049aee3, 0xfff252f3,
260        0x49075c72, 0xfadbb19a, 0xf8e6b059, 0x0599a00e, 0xfe5fc405, 0xffc9a4fc, 0x0048454b, 0xfff272d6,
261        0x4879c185, 0xfa7bb908, 0xf9188793, 0x05912dea, 0xfe599aaf, 0xffce8f8a, 0x0046db0f, 0xfff2940b,
262        0x47ea99a9, 0xfa1d78e3, 0xf94a6b9b, 0x058856cd, 0xfe53ac97, 0xffd36af1, 0x0045705c, 0xfff2b686,
263        0x4759ec60, 0xf9c0f276, 0xf97c5815, 0x057f1c9e, 0xfe4df98e, 0xffd836eb, 0x00440561, 0xfff2da36,
264        0x46c7c140, 0xf96626f0, 0xf9ae48af, 0x0575814c, 0xfe48815e, 0xffdcf336, 0x00429a4a, 0xfff2ff0d,
265        0x46341fed, 0xf90d1761, 0xf9e03924, 0x056b86c6, 0xfe4343d0, 0xffe19f91, 0x00412f43, 0xfff324fd,
266        0x459f101d, 0xf8b5c4be, 0xfa122537, 0x05612f00, 0xfe3e40a6, 0xffe63bc0, 0x003fc478, 0xfff34bf9,
267        0x45089996, 0xf8602fdc, 0xfa4408ba, 0x05567bf1, 0xfe39779a, 0xffeac787, 0x003e5a12, 0xfff373f0,
268        0x4470c42d, 0xf80c5977, 0xfa75df87, 0x054b6f92, 0xfe34e867, 0xffef42af, 0x003cf03d, 0xfff39cd7,
269        0x43d797c7, 0xf7ba422b, 0xfaa7a586, 0x05400be1, 0xfe3092bf, 0xfff3ad01, 0x003b871f, 0xfff3c69f,
270        0x433d1c56, 0xf769ea78, 0xfad956ab, 0x053452dc, 0xfe2c7650, 0xfff8064b, 0x003a1ee3, 0xfff3f13a,
271        0x42a159dc, 0xf71b52c4, 0xfb0aeef6, 0x05284685, 0xfe2892c5, 0xfffc4e5c, 0x0038b7ae, 0xfff41c9c,
272        0x42045865, 0xf6ce7b57, 0xfb3c6a73, 0x051be8dd, 0xfe24e7c3, 0x00008507, 0x003751a7, 0xfff448b7,
273        0x4166200e, 0xf683645a, 0xfb6dc53c, 0x050f3bec, 0xfe2174ec, 0x0004aa1f, 0x0035ecf4, 0xfff4757e,
274        0x40c6b8fd, 0xf63a0ddf, 0xfb9efb77, 0x050241b6, 0xfe1e39da, 0x0008bd7c, 0x003489b9, 0xfff4a2e5,
275        0x40262b65, 0xf5f277d9, 0xfbd00956, 0x04f4fc46, 0xfe1b3628, 0x000cbef7, 0x0033281a, 0xfff4d0de,
276        0x3f847f83, 0xf5aca21f, 0xfc00eb1b, 0x04e76da3, 0xfe18696a, 0x0010ae6e, 0x0031c83a, 0xfff4ff5d,
277        0x3ee1bda2, 0xf5688c6d, 0xfc319d13, 0x04d997d8, 0xfe15d32f, 0x00148bbd, 0x00306a3b, 0xfff52e57,
278        0x3e3dee13, 0xf5263665, 0xfc621b9a, 0x04cb7cf2, 0xfe137304, 0x001856c7, 0x002f0e3f, 0xfff55dbf,
279        0x3d991932, 0xf4e59f8a, 0xfc926319, 0x04bd1efb, 0xfe114872, 0x001c0f6e, 0x002db466, 0xfff58d89,
280        0x3cf34766, 0xf4a6c748, 0xfcc27008, 0x04ae8000, 0xfe0f52fc, 0x001fb599, 0x002c5cd0, 0xfff5bdaa,
281        0x3c4c811c, 0xf469aced, 0xfcf23eec, 0x049fa20f, 0xfe0d9224, 0x0023492f, 0x002b079a, 0xfff5ee17,
282        0x3ba4cec9, 0xf42e4faf, 0xfd21cc59, 0x04908733, 0xfe0c0567, 0x0026ca1c, 0x0029b4e4, 0xfff61ec5,
283        0x3afc38eb, 0xf3f4aea6, 0xfd5114f0, 0x0481317a, 0xfe0aac3f, 0x002a384c, 0x002864c9, 0xfff64fa8,
284        0x3a52c805, 0xf3bcc8d3, 0xfd801564, 0x0471a2ef, 0xfe098622, 0x002d93ae, 0x00271766, 0xfff680b5,
285        0x39a884a1, 0xf3869d1a, 0xfdaeca73, 0x0461dda0, 0xfe089283, 0x0030dc34, 0x0025ccd7, 0xfff6b1e4,
286        0x38fd774e, 0xf3522a49, 0xfddd30eb, 0x0451e396, 0xfe07d0d3, 0x003411d2, 0x00248535, 0xfff6e329,
287        0x3851a8a2, 0xf31f6f0f, 0xfe0b45aa, 0x0441b6dd, 0xfe07407d, 0x0037347d, 0x0023409a, 0xfff7147a,
288        0x37a52135, 0xf2ee6a07, 0xfe39059b, 0x0431597d, 0xfe06e0eb, 0x003a442e, 0x0021ff1f, 0xfff745cd,
289        0x36f7e9a4, 0xf2bf19ae, 0xfe666dbc, 0x0420cd80, 0xfe06b184, 0x003d40e0, 0x0020c0dc, 0xfff7771a,
290        0x364a0a90, 0xf2917c6d, 0xfe937b15, 0x041014eb, 0xfe06b1ac, 0x00402a8e, 0x001f85e6, 0xfff7a857,
291        0x359b8c9d, 0xf265908f, 0xfec02ac2, 0x03ff31c3, 0xfe06e0c4, 0x00430137, 0x001e4e56, 0xfff7d97a,
292        0x34ec786f, 0xf23b544b, 0xfeec79ec, 0x03ee260d, 0xfe073e2a, 0x0045c4dd, 0x001d1a3f, 0xfff80a7c,
293        0x343cd6af, 0xf212c5be, 0xff1865cd, 0x03dcf3ca, 0xfe07c93a, 0x00487582, 0x001be9b7, 0xfff83b52,
294        0x338cb004, 0xf1ebe2ec, 0xff43ebac, 0x03cb9cf9, 0xfe08814e, 0x004b132b, 0x001abcd0, 0xfff86bf6,
295        0x32dc0d17, 0xf1c6a9c3, 0xff6f08e4, 0x03ba2398, 0xfe0965bc, 0x004d9dde, 0x0019939d, 0xfff89c60,
296        0x322af693, 0xf1a3181a, 0xff99badb, 0x03a889a1, 0xfe0a75da, 0x005015a5, 0x00186e31, 0xfff8cc86,
297        0x3179751f, 0xf1812bb0, 0xffc3ff0c, 0x0396d10c, 0xfe0bb0f9, 0x00527a8a, 0x00174c9c, 0xfff8fc62,
298        0x30c79163, 0xf160e22d, 0xffedd2fd, 0x0384fbd1, 0xfe0d166b, 0x0054cc9a, 0x00162eef, 0xfff92bec,
299        0x30155404, 0xf1423924, 0x00173447, 0x03730be0, 0xfe0ea57e, 0x00570be4, 0x00151538, 0xfff95b1e,
300        0x2f62c5a7, 0xf1252e0f, 0x00402092, 0x0361032a, 0xfe105d7e, 0x00593877, 0x0013ff88, 0xfff989ef,
301        0x2eafeeed, 0xf109be56, 0x00689598, 0x034ee39b, 0xfe123db6, 0x005b5267, 0x0012edea, 0xfff9b85b,
302        0x2dfcd873, 0xf0efe748, 0x0090911f, 0x033caf1d, 0xfe144570, 0x005d59c6, 0x0011e06d, 0xfff9e65a,
303        0x2d498ad3, 0xf0d7a622, 0x00b81102, 0x032a6796, 0xfe1673f2, 0x005f4eac, 0x0010d71d, 0xfffa13e5,
304        0x2c960ea3, 0xf0c0f808, 0x00df1328, 0x03180ee7, 0xfe18c884, 0x0061312e, 0x000fd205, 0xfffa40f8,
305        0x2be26c73, 0xf0abda0e, 0x0105958c, 0x0305a6f0, 0xfe1b4268, 0x00630167, 0x000ed130, 0xfffa6d8d,
306        0x2b2eaccf, 0xf0984931, 0x012b9635, 0x02f3318a, 0xfe1de0e2, 0x0064bf71, 0x000dd4a7, 0xfffa999d,
307        0x2a7ad83c, 0xf086425a, 0x0151133e, 0x02e0b08d, 0xfe20a335, 0x00666b68, 0x000cdc74, 0xfffac525,
308        0x29c6f738, 0xf075c260, 0x01760ad1, 0x02ce25ca, 0xfe2388a1, 0x0068056b, 0x000be89f, 0xfffaf01e,
309        0x2913123c, 0xf066c606, 0x019a7b27, 0x02bb9310, 0xfe269065, 0x00698d98, 0x000af931, 0xfffb1a84,
310        0x285f31b7, 0xf05949fb, 0x01be628c, 0x02a8fa2a, 0xfe29b9c1, 0x006b0411, 0x000a0e2f, 0xfffb4453,
311        0x27ab5e12, 0xf04d4ade, 0x01e1bf58, 0x02965cdb, 0xfe2d03f2, 0x006c68f8, 0x000927a0, 0xfffb6d86,
312        0x26f79fab, 0xf042c539, 0x02048ff8, 0x0283bce6, 0xfe306e35, 0x006dbc71, 0x00084589, 0xfffb961a,
313        0x2643feda, 0xf039b587, 0x0226d2e6, 0x02711c05, 0xfe33f7c7, 0x006efea0, 0x000767f0, 0xfffbbe09,
314        0x259083eb, 0xf032182f, 0x024886ad, 0x025e7bf0, 0xfe379fe3, 0x00702fae, 0x00068ed8, 0xfffbe552,
315        0x24dd3721, 0xf02be98a, 0x0269a9e9, 0x024bde5a, 0xfe3b65c4, 0x00714fc0, 0x0005ba46, 0xfffc0bef,
316        0x242a20b3, 0xf02725dc, 0x028a3b44, 0x023944ee, 0xfe3f48a5, 0x00725f02, 0x0004ea3a, 0xfffc31df,
317        0x237748cf, 0xf023c95d, 0x02aa397b, 0x0226b156, 0xfe4347c0, 0x00735d9c, 0x00041eb9, 0xfffc571e,
318        0x22c4b795, 0xf021d031, 0x02c9a359, 0x02142533, 0xfe476250, 0x00744bba, 0x000357c2, 0xfffc7ba9,
319        0x2212751a, 0xf0213671, 0x02e877b9, 0x0201a223, 0xfe4b978e, 0x0075298a, 0x00029558, 0xfffc9f7e,
320        0x21608968, 0xf021f823, 0x0306b586, 0x01ef29be, 0xfe4fe6b3, 0x0075f739, 0x0001d779, 0xfffcc29a,
321        0x20aefc79, 0xf0241140, 0x03245bbc, 0x01dcbd96, 0xfe544efb, 0x0076b4f5, 0x00011e26, 0xfffce4fc,
322        0x1ffdd63b, 0xf0277db1, 0x03416966, 0x01ca5f37, 0xfe58cf9d, 0x007762f0, 0x0000695e, 0xfffd06a1,
323        0x1f4d1e8e, 0xf02c3953, 0x035ddd9e, 0x01b81028, 0xfe5d67d4, 0x0078015a, 0xffffb91f, 0xfffd2787,
324        0x1e9cdd43, 0xf0323ff5, 0x0379b790, 0x01a5d1ea, 0xfe6216db, 0x00789065, 0xffff0d66, 0xfffd47ae,
325        0x1ded1a1d, 0xf0398d56, 0x0394f674, 0x0193a5f9, 0xfe66dbeb, 0x00791043, 0xfffe6631, 0xfffd6713,
326};
327
328// we use 15 bits to interpolate between these samples
329// this cannot change because the mul below rely on it.
330static const int pLerpBits = 15;
331
332static pthread_once_t once_control = PTHREAD_ONCE_INIT;
333static readCoefficientsFn readResampleCoefficients = NULL;
334
335/*static*/ AudioResamplerSinc::Constants AudioResamplerSinc::highQualityConstants;
336/*static*/ AudioResamplerSinc::Constants AudioResamplerSinc::veryHighQualityConstants;
337
338void AudioResamplerSinc::init_routine()
339{
340    // for high quality resampler, the parameters for coefficients are compile-time constants
341    Constants *c = &highQualityConstants;
342    c->coefsBits = RESAMPLE_FIR_LERP_INT_BITS;
343    c->cShift = kNumPhaseBits - c->coefsBits;
344    c->cMask = ((1<< c->coefsBits)-1) << c->cShift;
345    c->pShift = kNumPhaseBits - c->coefsBits - pLerpBits;
346    c->pMask = ((1<< pLerpBits)-1) << c->pShift;
347    c->halfNumCoefs = RESAMPLE_FIR_NUM_COEF;
348
349    // for very high quality resampler, the parameters are load-time constants
350    veryHighQualityConstants = highQualityConstants;
351
352    // Open the dll to get the coefficients for VERY_HIGH_QUALITY
353    void *resampleCoeffLib = dlopen("libaudio-resampler.so", RTLD_NOW);
354    ALOGV("Open libaudio-resampler library = %p", resampleCoeffLib);
355    if (resampleCoeffLib == NULL) {
356        ALOGE("Could not open audio-resampler library: %s", dlerror());
357        return;
358    }
359
360    readResampleFirNumCoeffFn readResampleFirNumCoeff;
361    readResampleFirLerpIntBitsFn readResampleFirLerpIntBits;
362
363    readResampleCoefficients = (readCoefficientsFn)
364            dlsym(resampleCoeffLib, "readResamplerCoefficients");
365    readResampleFirNumCoeff = (readResampleFirNumCoeffFn)
366            dlsym(resampleCoeffLib, "readResampleFirNumCoeff");
367    readResampleFirLerpIntBits = (readResampleFirLerpIntBitsFn)
368            dlsym(resampleCoeffLib, "readResampleFirLerpIntBits");
369
370    if (!readResampleCoefficients || !readResampleFirNumCoeff || !readResampleFirLerpIntBits) {
371        readResampleCoefficients = NULL;
372        dlclose(resampleCoeffLib);
373        resampleCoeffLib = NULL;
374        ALOGE("Could not find symbol: %s", dlerror());
375        return;
376    }
377
378    c = &veryHighQualityConstants;
379    c->coefsBits = readResampleFirLerpIntBits();
380    c->cShift = kNumPhaseBits - c->coefsBits;
381    c->cMask = ((1<<c->coefsBits)-1) << c->cShift;
382    c->pShift = kNumPhaseBits - c->coefsBits - pLerpBits;
383    c->pMask = ((1<<pLerpBits)-1) << c->pShift;
384    // number of zero-crossing on each side
385    c->halfNumCoefs = readResampleFirNumCoeff();
386    ALOGV("coefsBits = %d", c->coefsBits);
387    ALOGV("halfNumCoefs = %d", c->halfNumCoefs);
388    // note that we "leak" resampleCoeffLib until the process exits
389}
390
391// ----------------------------------------------------------------------------
392
393static inline
394int32_t mulRL(int left, int32_t in, uint32_t vRL)
395{
396#if USE_INLINE_ASSEMBLY
397    int32_t out;
398    if (left) {
399        asm( "smultb %[out], %[in], %[vRL] \n"
400             : [out]"=r"(out)
401             : [in]"%r"(in), [vRL]"r"(vRL)
402             : );
403    } else {
404        asm( "smultt %[out], %[in], %[vRL] \n"
405             : [out]"=r"(out)
406             : [in]"%r"(in), [vRL]"r"(vRL)
407             : );
408    }
409    return out;
410#else
411    int16_t v = left ? int16_t(vRL) : int16_t(vRL>>16);
412    return int32_t((int64_t(in) * v) >> 16);
413#endif
414}
415
416static inline
417int32_t mulAdd(int16_t in, int32_t v, int32_t a)
418{
419#if USE_INLINE_ASSEMBLY
420    int32_t out;
421    asm( "smlawb %[out], %[v], %[in], %[a] \n"
422         : [out]"=r"(out)
423         : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
424         : );
425    return out;
426#else
427    return a + int32_t((int64_t(v) * in) >> 16);
428#endif
429}
430
431static inline
432int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
433{
434#if USE_INLINE_ASSEMBLY
435    int32_t out;
436    if (left) {
437        asm( "smlawb %[out], %[v], %[inRL], %[a] \n"
438             : [out]"=r"(out)
439             : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
440             : );
441    } else {
442        asm( "smlawt %[out], %[v], %[inRL], %[a] \n"
443             : [out]"=r"(out)
444             : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
445             : );
446    }
447    return out;
448#else
449    int16_t s = left ? int16_t(inRL) : int16_t(inRL>>16);
450    return a + int32_t((int64_t(v) * s) >> 16);
451#endif
452}
453
454// ----------------------------------------------------------------------------
455
456AudioResamplerSinc::AudioResamplerSinc(
457        int inChannelCount, int32_t sampleRate, src_quality quality)
458    : AudioResampler(inChannelCount, sampleRate, quality),
459    mState(0), mImpulse(0), mRingFull(0), mFirCoefs(0)
460{
461    /*
462     * Layout of the state buffer for 32 tap:
463     *
464     * "present" sample            beginning of 2nd buffer
465     *                 v                v
466     *  0              01               2              23              3
467     *  0              F0               0              F0              F
468     * [pppppppppppppppInnnnnnnnnnnnnnnnpppppppppppppppInnnnnnnnnnnnnnnn]
469     *                 ^               ^ head
470     *
471     * p = past samples, convoluted with the (p)ositive side of sinc()
472     * n = future samples, convoluted with the (n)egative side of sinc()
473     * r = extra space for implementing the ring buffer
474     *
475     */
476
477    mVolumeSIMD[0] = 0;
478    mVolumeSIMD[1] = 0;
479
480    // Load the constants for coefficients
481    int ok = pthread_once(&once_control, init_routine);
482    if (ok != 0) {
483        ALOGE("%s pthread_once failed: %d", __func__, ok);
484    }
485    mConstants = (quality == VERY_HIGH_QUALITY) ?
486            &veryHighQualityConstants : &highQualityConstants;
487}
488
489
490AudioResamplerSinc::~AudioResamplerSinc() {
491    free(mState);
492}
493
494void AudioResamplerSinc::init() {
495    const Constants& c(*mConstants);
496    const size_t numCoefs = 2 * c.halfNumCoefs;
497    const size_t stateSize = numCoefs * mChannelCount * 2;
498    mState = (int16_t*)memalign(32, stateSize*sizeof(int16_t));
499    memset(mState, 0, sizeof(int16_t)*stateSize);
500    mImpulse  = mState   + (c.halfNumCoefs-1)*mChannelCount;
501    mRingFull = mImpulse + (numCoefs+1)*mChannelCount;
502}
503
504void AudioResamplerSinc::setVolume(float left, float right) {
505    AudioResampler::setVolume(left, right);
506    // convert to U4_28 (rounding down).
507    // integer volume values are clamped to 0 to UNITY_GAIN.
508    mVolumeSIMD[0] = u4_28_from_float(clampFloatVol(left));
509    mVolumeSIMD[1] = u4_28_from_float(clampFloatVol(right));
510}
511
512void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
513            AudioBufferProvider* provider)
514{
515    // FIXME store current state (up or down sample) and only load the coefs when the state
516    // changes. Or load two pointers one for up and one for down in the init function.
517    // Not critical now since the read functions are fast, but would be important if read was slow.
518    if (mConstants == &veryHighQualityConstants && readResampleCoefficients) {
519        mFirCoefs = readResampleCoefficients( mInSampleRate <= mSampleRate );
520    } else {
521        mFirCoefs = (const int32_t *) ((mInSampleRate <= mSampleRate) ? mFirCoefsUp : mFirCoefsDown);
522    }
523
524    // select the appropriate resampler
525    switch (mChannelCount) {
526    case 1:
527        resample<1>(out, outFrameCount, provider);
528        break;
529    case 2:
530        resample<2>(out, outFrameCount, provider);
531        break;
532    }
533}
534
535
536template<int CHANNELS>
537void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
538        AudioBufferProvider* provider)
539{
540    const Constants& c(*mConstants);
541    const size_t headOffset = c.halfNumCoefs*CHANNELS;
542    int16_t* impulse = mImpulse;
543    uint32_t vRL = mVolumeRL;
544    size_t inputIndex = mInputIndex;
545    uint32_t phaseFraction = mPhaseFraction;
546    uint32_t phaseIncrement = mPhaseIncrement;
547    size_t outputIndex = 0;
548    size_t outputSampleCount = outFrameCount * 2;
549    size_t inFrameCount = getInFrameCountRequired(outFrameCount);
550
551    while (outputIndex < outputSampleCount) {
552        // buffer is empty, fetch a new one
553        while (mBuffer.frameCount == 0) {
554            mBuffer.frameCount = inFrameCount;
555            provider->getNextBuffer(&mBuffer,
556                                    calculateOutputPTS(outputIndex / 2));
557            if (mBuffer.raw == NULL) {
558                goto resample_exit;
559            }
560            const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
561            if (phaseIndex == 1) {
562                // read one frame
563                read<CHANNELS>(impulse, phaseFraction, mBuffer.i16, inputIndex);
564            } else if (phaseIndex == 2) {
565                // read 2 frames
566                read<CHANNELS>(impulse, phaseFraction, mBuffer.i16, inputIndex);
567                inputIndex++;
568                if (inputIndex >= mBuffer.frameCount) {
569                    inputIndex -= mBuffer.frameCount;
570                    provider->releaseBuffer(&mBuffer);
571                } else {
572                    read<CHANNELS>(impulse, phaseFraction, mBuffer.i16, inputIndex);
573                }
574            }
575        }
576        int16_t const * const in = mBuffer.i16;
577        const size_t frameCount = mBuffer.frameCount;
578
579        // Always read-in the first samples from the input buffer
580        int16_t* head = impulse + headOffset;
581        for (size_t i=0 ; i<CHANNELS ; i++) {
582            head[i] = in[inputIndex*CHANNELS + i];
583        }
584
585        // handle boundary case
586        while (CC_LIKELY(outputIndex < outputSampleCount)) {
587            filterCoefficient<CHANNELS>(&out[outputIndex], phaseFraction, impulse, vRL);
588            outputIndex += 2;
589
590            phaseFraction += phaseIncrement;
591            const size_t phaseIndex = phaseFraction >> kNumPhaseBits;
592            for (size_t i=0 ; i<phaseIndex ; i++) {
593                inputIndex++;
594                if (inputIndex >= frameCount) {
595                    goto done;  // need a new buffer
596                }
597                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
598            }
599        }
600done:
601        // if done with buffer, save samples
602        if (inputIndex >= frameCount) {
603            inputIndex -= frameCount;
604            provider->releaseBuffer(&mBuffer);
605        }
606    }
607
608resample_exit:
609    mImpulse = impulse;
610    mInputIndex = inputIndex;
611    mPhaseFraction = phaseFraction;
612}
613
614template<int CHANNELS>
615/***
616* read()
617*
618* This function reads only one frame from input buffer and writes it in
619* state buffer
620*
621**/
622void AudioResamplerSinc::read(
623        int16_t*& impulse, uint32_t& phaseFraction,
624        const int16_t* in, size_t inputIndex)
625{
626    impulse += CHANNELS;
627    phaseFraction -= 1LU<<kNumPhaseBits;
628
629    const Constants& c(*mConstants);
630    if (CC_UNLIKELY(impulse >= mRingFull)) {
631        const size_t stateSize = (c.halfNumCoefs*2)*CHANNELS;
632        memcpy(mState, mState+stateSize, sizeof(int16_t)*stateSize);
633        impulse -= stateSize;
634    }
635
636    int16_t* head = impulse + c.halfNumCoefs*CHANNELS;
637    for (size_t i=0 ; i<CHANNELS ; i++) {
638        head[i] = in[inputIndex*CHANNELS + i];
639    }
640}
641
642template<int CHANNELS>
643void AudioResamplerSinc::filterCoefficient(int32_t* out, uint32_t phase,
644         const int16_t *samples, uint32_t vRL)
645{
646    // NOTE: be very careful when modifying the code here. register
647    // pressure is very high and a small change might cause the compiler
648    // to generate far less efficient code.
649    // Always sanity check the result with objdump or test-resample.
650
651    // compute the index of the coefficient on the positive side and
652    // negative side
653    const Constants& c(*mConstants);
654    const int32_t ONE = c.cMask | c.pMask;
655    uint32_t indexP = ( phase & c.cMask) >> c.cShift;
656    uint32_t lerpP  = ( phase & c.pMask) >> c.pShift;
657    uint32_t indexN = ((ONE-phase) & c.cMask) >> c.cShift;
658    uint32_t lerpN  = ((ONE-phase) & c.pMask) >> c.pShift;
659
660    const size_t offset = c.halfNumCoefs;
661    indexP *= offset;
662    indexN *= offset;
663
664    int32_t const* coefsP = mFirCoefs + indexP;
665    int32_t const* coefsN = mFirCoefs + indexN;
666    int16_t const* sP = samples;
667    int16_t const* sN = samples + CHANNELS;
668
669    size_t count = offset;
670
671#ifndef USE_NEON
672    int32_t l = 0;
673    int32_t r = 0;
674    for (size_t i=0 ; i<count ; i++) {
675        interpolate<CHANNELS>(l, r, coefsP++, offset, lerpP, sP);
676        sP -= CHANNELS;
677        interpolate<CHANNELS>(l, r, coefsN++, offset, lerpN, sN);
678        sN += CHANNELS;
679    }
680    out[0] += 2 * mulRL(1, l, vRL);
681    out[1] += 2 * mulRL(0, r, vRL);
682#else
683    UNUSED(vRL);
684    if (CHANNELS == 1) {
685        int32_t const* coefsP1 = coefsP + offset;
686        int32_t const* coefsN1 = coefsN + offset;
687        sP -= CHANNELS*3;
688
689        int32x4_t sum;
690        int32x2_t lerpPN;
691        lerpPN = vdup_n_s32(0);
692        lerpPN = vld1_lane_s32((int32_t *)&lerpP, lerpPN, 0);
693        lerpPN = vld1_lane_s32((int32_t *)&lerpN, lerpPN, 1);
694        lerpPN = vshl_n_s32(lerpPN, 16);
695        sum = vdupq_n_s32(0);
696
697        int16x4_t sampleP, sampleN;
698        int32x4_t samplePExt, sampleNExt;
699        int32x4_t coefsPV0, coefsPV1, coefsNV0, coefsNV1;
700
701        coefsP = (const int32_t*)__builtin_assume_aligned(coefsP, 16);
702        coefsN = (const int32_t*)__builtin_assume_aligned(coefsN, 16);
703        coefsP1 = (const int32_t*)__builtin_assume_aligned(coefsP1, 16);
704        coefsN1 = (const int32_t*)__builtin_assume_aligned(coefsN1, 16);
705        for (; count > 0; count -= 4) {
706            sampleP = vld1_s16(sP);
707            sampleN = vld1_s16(sN);
708            coefsPV0 = vld1q_s32(coefsP);
709            coefsNV0 = vld1q_s32(coefsN);
710            coefsPV1 = vld1q_s32(coefsP1);
711            coefsNV1 = vld1q_s32(coefsN1);
712            sP -= 4;
713            sN += 4;
714            coefsP += 4;
715            coefsN += 4;
716            coefsP1 += 4;
717            coefsN1 += 4;
718
719            sampleP = vrev64_s16(sampleP);
720
721            // interpolate (step1)
722            coefsPV1 = vsubq_s32(coefsPV1, coefsPV0);
723            coefsNV1 = vsubq_s32(coefsNV1, coefsNV0);
724            samplePExt = vshll_n_s16(sampleP, 15);
725            // interpolate (step2)
726            coefsPV1 = vqrdmulhq_lane_s32(coefsPV1, lerpPN, 0);
727            coefsNV1 = vqrdmulhq_lane_s32(coefsNV1, lerpPN, 1);
728            sampleNExt = vshll_n_s16(sampleN, 15);
729            // interpolate (step3)
730            coefsPV0 = vaddq_s32(coefsPV0, coefsPV1);
731            coefsNV0 = vaddq_s32(coefsNV0, coefsNV1);
732
733            samplePExt = vqrdmulhq_s32(samplePExt, coefsPV0);
734            sampleNExt = vqrdmulhq_s32(sampleNExt, coefsNV0);
735            sum = vaddq_s32(sum, samplePExt);
736            sum = vaddq_s32(sum, sampleNExt);
737        }
738        int32x2_t volumesV, outV;
739        volumesV = vld1_s32(mVolumeSIMD);
740        outV = vld1_s32(out);
741
742        //add all 4 partial sums
743        int32x2_t sumLow, sumHigh;
744        sumLow = vget_low_s32(sum);
745        sumHigh = vget_high_s32(sum);
746        sumLow = vpadd_s32(sumLow, sumHigh);
747        sumLow = vpadd_s32(sumLow, sumLow);
748
749        sumLow = vqrdmulh_s32(sumLow, volumesV);
750        outV = vadd_s32(outV, sumLow);
751        vst1_s32(out, outV);
752    } else if (CHANNELS == 2) {
753        int32_t const* coefsP1 = coefsP + offset;
754        int32_t const* coefsN1 = coefsN + offset;
755        sP -= CHANNELS*3;
756
757        int32x4_t sum0, sum1;
758        int32x2_t lerpPN;
759
760        lerpPN = vdup_n_s32(0);
761        lerpPN = vld1_lane_s32((int32_t *)&lerpP, lerpPN, 0);
762        lerpPN = vld1_lane_s32((int32_t *)&lerpN, lerpPN, 1);
763        lerpPN = vshl_n_s32(lerpPN, 16);
764        sum0 = vdupq_n_s32(0);
765        sum1 = vdupq_n_s32(0);
766
767        int16x4x2_t sampleP, sampleN;
768        int32x4x2_t samplePExt, sampleNExt;
769        int32x4_t coefsPV0, coefsPV1, coefsNV0, coefsNV1;
770
771        coefsP = (const int32_t*)__builtin_assume_aligned(coefsP, 16);
772        coefsN = (const int32_t*)__builtin_assume_aligned(coefsN, 16);
773        coefsP1 = (const int32_t*)__builtin_assume_aligned(coefsP1, 16);
774        coefsN1 = (const int32_t*)__builtin_assume_aligned(coefsN1, 16);
775        for (; count > 0; count -= 4) {
776            sampleP = vld2_s16(sP);
777            sampleN = vld2_s16(sN);
778            coefsPV0 = vld1q_s32(coefsP);
779            coefsNV0 = vld1q_s32(coefsN);
780            coefsPV1 = vld1q_s32(coefsP1);
781            coefsNV1 = vld1q_s32(coefsN1);
782            sP -= 8;
783            sN += 8;
784            coefsP += 4;
785            coefsN += 4;
786            coefsP1 += 4;
787            coefsN1 += 4;
788
789            sampleP.val[0] = vrev64_s16(sampleP.val[0]);
790            sampleP.val[1] = vrev64_s16(sampleP.val[1]);
791
792            // interpolate (step1)
793            coefsPV1 = vsubq_s32(coefsPV1, coefsPV0);
794            coefsNV1 = vsubq_s32(coefsNV1, coefsNV0);
795            samplePExt.val[0] = vshll_n_s16(sampleP.val[0], 15);
796            samplePExt.val[1] = vshll_n_s16(sampleP.val[1], 15);
797            // interpolate (step2)
798            coefsPV1 = vqrdmulhq_lane_s32(coefsPV1, lerpPN, 0);
799            coefsNV1 = vqrdmulhq_lane_s32(coefsNV1, lerpPN, 1);
800            sampleNExt.val[0] = vshll_n_s16(sampleN.val[0], 15);
801            sampleNExt.val[1] = vshll_n_s16(sampleN.val[1], 15);
802            // interpolate (step3)
803            coefsPV0 = vaddq_s32(coefsPV0, coefsPV1);
804            coefsNV0 = vaddq_s32(coefsNV0, coefsNV1);
805
806            samplePExt.val[0] = vqrdmulhq_s32(samplePExt.val[0], coefsPV0);
807            samplePExt.val[1] = vqrdmulhq_s32(samplePExt.val[1], coefsPV0);
808            sampleNExt.val[0] = vqrdmulhq_s32(sampleNExt.val[0], coefsNV0);
809            sampleNExt.val[1] = vqrdmulhq_s32(sampleNExt.val[1], coefsNV0);
810            sum0 = vaddq_s32(sum0, samplePExt.val[0]);
811            sum1 = vaddq_s32(sum1, samplePExt.val[1]);
812            sum0 = vaddq_s32(sum0, sampleNExt.val[0]);
813            sum1 = vaddq_s32(sum1, sampleNExt.val[1]);
814        }
815        int32x2_t volumesV, outV;
816        volumesV = vld1_s32(mVolumeSIMD);
817        outV = vld1_s32(out);
818
819        //add all 4 partial sums
820        int32x2_t sumLow0, sumHigh0, sumLow1, sumHigh1;
821        sumLow0 = vget_low_s32(sum0);
822        sumHigh0 = vget_high_s32(sum0);
823        sumLow1 = vget_low_s32(sum1);
824        sumHigh1 = vget_high_s32(sum1);
825        sumLow0 = vpadd_s32(sumLow0, sumHigh0);
826        sumLow0 = vpadd_s32(sumLow0, sumLow0);
827        sumLow1 = vpadd_s32(sumLow1, sumHigh1);
828        sumLow1 = vpadd_s32(sumLow1, sumLow1);
829
830        sumLow0 = vtrn_s32(sumLow0, sumLow1).val[0];
831        sumLow0 = vqrdmulh_s32(sumLow0, volumesV);
832        outV = vadd_s32(outV, sumLow0);
833        vst1_s32(out, outV);
834    }
835#endif
836}
837
838template<int CHANNELS>
839void AudioResamplerSinc::interpolate(
840        int32_t& l, int32_t& r,
841        const int32_t* coefs, size_t offset,
842        int32_t lerp, const int16_t* samples)
843{
844    int32_t c0 = coefs[0];
845    int32_t c1 = coefs[offset];
846    int32_t sinc = mulAdd(lerp, (c1-c0)<<1, c0);
847    if (CHANNELS == 2) {
848        uint32_t rl = *reinterpret_cast<const uint32_t*>(samples);
849        l = mulAddRL(1, rl, sinc, l);
850        r = mulAddRL(0, rl, sinc, r);
851    } else {
852        r = l = mulAdd(samples[0], sinc, l);
853    }
854}
855// ----------------------------------------------------------------------------
856}; // namespace android
857