4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (C) 4Front Technologies 1996-2008.
24 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
29 * Purpose: GRC3 Sample Rate Converter
31 * GRC library version 3.1
34 #include <sys/types.h>
35 #include "audio_grc3.h"
37 extern const int32_t filter_data_L
[];
38 extern const int32_t filter_data_M
[];
39 extern const int32_t filter_data_H
[];
40 extern const int32_t filter_data_P
[];
42 #define filter_data_HX filter_data_H
43 #define filter_data_PX filter_data_P
46 _muldivu64(uint32_t a
, uint32_t val1
, uint32_t val2
)
48 uint64_t v
= ((uint64_t)a
) * val1
/ val2
;
49 return ((uint32_t)(v
));
54 _grc_sat6(int32_t a
, int32_t b
)
56 int64_t v
= ((int64_t)a
) * b
+ (1 << 5);
57 return ((int32_t)(v
>> 6));
61 _grc_sat31(int32_t a
, int32_t b
)
63 int64_t v
= ((int64_t)a
) * b
+ (1 << 30);
64 return ((int32_t)(v
>> 31));
68 #define DEFINE_FILTER(T) \
70 _filt31_##T(int32_t a, int32_t idx) \
72 int64_t v = ((int64_t)a) * filter_data_##T[idx >> 15]; \
73 return ((int32_t)(v >> 31)); \
76 #define DEFINE_FILTER_HQ(T) \
78 _filt31_##T(int32_t a, int32_t idx) \
80 int32_t idx2 = idx>>15; \
81 int64_t v = ((int64_t)a) * \
83 (filter_data_##T[idx2] + \
84 (((int64_t)(idx & 32767)) * (filter_data_##T[idx2 + 1] - \
85 filter_data_##T[idx2]) >> 15)); \
86 return ((int32_t)(v>>31)); \
97 #define DEFINE_CONVD(T, SZ) \
99 _conv31d_##T(int32_t *history, uint32_t filter, uint32_t incv) \
103 filter = (1024 << 15) - filter; \
105 while (filter < ((uint32_t)(SZ << 15))) { \
106 accum += _filt31_##T(*history, filter); \
114 DEFINE_CONVD(L
, 4096)
115 DEFINE_CONVD(M
, 8192)
116 DEFINE_CONVD(H
, 16384)
117 DEFINE_CONVD(HX
, 16384)
118 DEFINE_CONVD(P
, 32768)
119 DEFINE_CONVD(PX
, 32768)
122 _conv31_L(int32_t *history
, uint32_t filter
)
126 #define ITERATION(p) \
127 accum += _filt31_##p(*history, filter); \
128 filter += (1024 << 15); \
131 ITERATION(L
); ITERATION(L
); ITERATION(L
); ITERATION(L
);
137 _conv31_M(int32_t *history
, uint32_t filter
)
141 ITERATION(M
); ITERATION(M
); ITERATION(M
); ITERATION(M
);
142 ITERATION(M
); ITERATION(M
); ITERATION(M
); ITERATION(M
);
147 _conv31_H(int32_t *history
, uint32_t filter
)
151 ITERATION(H
); ITERATION(H
); ITERATION(H
); ITERATION(H
);
152 ITERATION(H
); ITERATION(H
); ITERATION(H
); ITERATION(H
);
153 ITERATION(H
); ITERATION(H
); ITERATION(H
); ITERATION(H
);
154 ITERATION(H
); ITERATION(H
); ITERATION(H
); ITERATION(H
);
159 _conv31_HX(int32_t *history
, uint32_t filter
)
163 ITERATION(HX
); ITERATION(HX
); ITERATION(HX
); ITERATION(HX
);
164 ITERATION(HX
); ITERATION(HX
); ITERATION(HX
); ITERATION(HX
);
165 ITERATION(HX
); ITERATION(HX
); ITERATION(HX
); ITERATION(HX
);
166 ITERATION(HX
); ITERATION(HX
); ITERATION(HX
); ITERATION(HX
);
171 _conv31_P(int32_t *history
, uint32_t filter
)
175 ITERATION(P
); ITERATION(P
); ITERATION(P
); ITERATION(P
);
176 ITERATION(P
); ITERATION(P
); ITERATION(P
); ITERATION(P
);
177 ITERATION(P
); ITERATION(P
); ITERATION(P
); ITERATION(P
);
178 ITERATION(P
); ITERATION(P
); ITERATION(P
); ITERATION(P
);
179 ITERATION(P
); ITERATION(P
); ITERATION(P
); ITERATION(P
);
180 ITERATION(P
); ITERATION(P
); ITERATION(P
); ITERATION(P
);
181 ITERATION(P
); ITERATION(P
); ITERATION(P
); ITERATION(P
);
182 ITERATION(P
); ITERATION(P
); ITERATION(P
); ITERATION(P
);
187 _conv31_PX(int32_t *history
, uint32_t filter
)
191 ITERATION(PX
); ITERATION(PX
); ITERATION(PX
); ITERATION(PX
);
192 ITERATION(PX
); ITERATION(PX
); ITERATION(PX
); ITERATION(PX
);
193 ITERATION(PX
); ITERATION(PX
); ITERATION(PX
); ITERATION(PX
);
194 ITERATION(PX
); ITERATION(PX
); ITERATION(PX
); ITERATION(PX
);
195 ITERATION(PX
); ITERATION(PX
); ITERATION(PX
); ITERATION(PX
);
196 ITERATION(PX
); ITERATION(PX
); ITERATION(PX
); ITERATION(PX
);
197 ITERATION(PX
); ITERATION(PX
); ITERATION(PX
); ITERATION(PX
);
198 ITERATION(PX
); ITERATION(PX
); ITERATION(PX
); ITERATION(PX
);
202 #define GRC3_RESAMPLE(QUAL) \
204 grc3_upsample_##QUAL(grc3state_t *grc, const int32_t *src, \
205 int32_t *dst, uint32_t sz, uint32_t bufsz, int inc, int offset) \
207 int32_t ptr = grc->ptr; \
208 int32_t srcrate = grc->srcrate; \
209 int32_t dstrate = grc->dstrate; \
210 int32_t *history = grc->historyptr; \
211 int32_t filtfactor = grc->filtfactor; \
212 uint32_t dstsz = 0; \
218 while (ptr < dstrate) { \
219 if (dstsz >= bufsz) \
221 dst[0] = (_conv31_##QUAL(history, \
222 _grc_sat6(ptr, filtfactor))); \
229 if (history >= (grc->history + GRC3_MAXHISTORY * 2)) \
230 history -= GRC3_MAXHISTORY; \
232 history[0] = history[-GRC3_MAXHISTORY] = (*src); \
242 grc->historyptr = history; \
243 grc->outsz = dstsz; \
247 grc3_dnsample_##QUAL(grc3state_t *grc, const int32_t *src, \
248 int32_t *dst, uint32_t sz, uint32_t bufsz, int inc, int offset) \
250 int32_t ptr = grc->ptr; \
251 int32_t srcrate = grc->srcrate; \
252 int32_t dstrate = grc->dstrate; \
253 int32_t sat = grc->sat; \
254 int32_t *history = grc->historyptr; \
255 int32_t filtfactor = grc->filtfactor; \
256 uint32_t dstsz = 0; \
262 while (ptr >= srcrate) { \
263 if (dstsz >= bufsz) \
266 dst[0] = (_conv31d_##QUAL(history, \
267 _grc_sat6(ptr, filtfactor), \
274 if (history >= (grc->history + GRC3_MAXHISTORY * 2)) \
275 history -= GRC3_MAXHISTORY; \
278 * TODO: for better quality multiplier is worth moving \
279 * to output cascade \
281 history[0] = history[-GRC3_MAXHISTORY] = \
282 _grc_sat31((*src), sat); \
292 grc->historyptr = history; \
293 grc->outsz = dstsz; \
297 grc3_resample_##QUAL(grc3state_t *grc, const void *src, void *dst, \
298 uint32_t sz, uint32_t bufsz, int inc, int offset) \
300 if (grc->srcrate <= grc->dstrate) \
301 grc3_upsample_##QUAL(grc, src, dst, sz, \
302 bufsz, inc, offset); \
304 grc3_dnsample_##QUAL(grc, src, dst, sz, \
305 bufsz, inc, offset); \
316 * For performance reasons, we only support 24-bit SRC.
319 grc3_convert(grc3state_t
*grc
, int quality
, const void *src
,
320 void *dst
, int sz
, int bufsz
, int inc
, int offset
)
327 grc3_resample_L(grc
, src
, dst
, sz
, bufsz
, inc
, offset
);
330 grc3_resample_M(grc
, src
, dst
, sz
, bufsz
, inc
, offset
);
333 grc3_resample_H(grc
, src
, dst
, sz
, bufsz
, inc
, offset
);
336 grc3_resample_HX(grc
, src
, dst
, sz
, bufsz
, inc
, offset
);
339 grc3_resample_P(grc
, src
, dst
, sz
, bufsz
, inc
, offset
);
342 grc3_resample_PX(grc
, src
, dst
, sz
, bufsz
, inc
, offset
);
348 grc3_reset(grc3state_t
*grc
)
352 grc
->historyptr
= grc
->history
+ GRC3_MAXHISTORY
;
354 for (t
= 0; t
< GRC3_MAXHISTORY
* 2; t
++)
359 grc3_setup_up(grc3state_t
*grc
, uint32_t fromRate
, uint32_t toRate
)
361 grc
->srcrate
= fromRate
;
362 grc
->dstrate
= toRate
;
363 grc
->filtfactor
= 0x80000000U
/ toRate
;
367 grc3_setup_dn(grc3state_t
*grc
, uint32_t fromRate
, uint32_t toRate
)
369 grc
->srcrate
= fromRate
;
370 grc
->dstrate
= toRate
;
371 grc
->filtfactor
= 0x80000000U
/ fromRate
;
372 grc
->ptr_incv
= _muldivu64(1024 << 15, toRate
, fromRate
);
373 grc
->sat
= _muldivu64(0x80000000U
, toRate
, fromRate
);
377 grc3_setup(grc3state_t
*grc
, uint32_t fromRate
, uint32_t toRate
)
379 while ((!(fromRate
& 1)) && (!(toRate
& 1)) && (fromRate
> 0)) {
384 if (fromRate
<= toRate
)
385 grc3_setup_up(grc
, fromRate
, toRate
);
387 grc3_setup_dn(grc
, fromRate
, toRate
);