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