feeder_rate.c revision 195689
1139749Simp/*- 2193640Sariff * Copyright (c) 2005-2009 Ariff Abdullah <ariff@FreeBSD.org> 375320Scg * All rights reserved. 475320Scg * 575320Scg * Redistribution and use in source and binary forms, with or without 675320Scg * modification, are permitted provided that the following conditions 775320Scg * are met: 875320Scg * 1. Redistributions of source code must retain the above copyright 975320Scg * notice, this list of conditions and the following disclaimer. 1075320Scg * 2. Redistributions in binary form must reproduce the above copyright 1175320Scg * notice, this list of conditions and the following disclaimer in the 1275320Scg * documentation and/or other materials provided with the distribution. 1375320Scg * 1475320Scg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1575320Scg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1675320Scg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1775320Scg * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1875320Scg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1975320Scg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2075320Scg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2175320Scg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2275320Scg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2375320Scg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2475320Scg * SUCH DAMAGE. 25170206Sjoel */ 26170206Sjoel 27170206Sjoel/* 28193640Sariff * feeder_rate: (Codename: Z Resampler), which means any effort to create 29193640Sariff * future replacement for this resampler are simply absurd unless 30193640Sariff * the world decide to add new alphabet after Z. 31164614Sariff * 32193640Sariff * FreeBSD bandlimited sinc interpolator, technically based on 33193640Sariff * "Digital Audio Resampling" by Julius O. Smith III 34193640Sariff * - http://ccrma.stanford.edu/~jos/resample/ 35164614Sariff * 36193640Sariff * The Good: 37193640Sariff * + all out fixed point integer operations, no soft-float or anything like 38193640Sariff * that. 39193640Sariff * + classic polyphase converters with high quality coefficient's polynomial 40193640Sariff * interpolators. 41193640Sariff * + fast, faster, or the fastest of its kind. 42193640Sariff * + compile time configurable. 43193640Sariff * + etc etc.. 44109547Sorion * 45193640Sariff * The Bad: 46193640Sariff * - The z, z_, and Z_ . Due to mental block (or maybe just 0x7a69), I 47193640Sariff * couldn't think of anything simpler than that (feeder_rate_xxx is just 48193640Sariff * too long). Expect possible clashes with other zitizens (any?). 4975320Scg */ 5075320Scg 51193640Sariff#ifdef _KERNEL 52193640Sariff#ifdef HAVE_KERNEL_OPTION_HEADERS 53193640Sariff#include "opt_snd.h" 54193640Sariff#endif 5575320Scg#include <dev/sound/pcm/sound.h> 56193640Sariff#include <dev/sound/pcm/pcm.h> 5775320Scg#include "feeder_if.h" 5875320Scg 59193640Sariff#define SND_USE_FXDIV 60193640Sariff#include "snd_fxdiv_gen.h" 61193640Sariff 6282180ScgSND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/feeder_rate.c 195689 2009-07-14 18:53:34Z ariff $"); 63193640Sariff#endif 64110466Sorion 65193640Sariff#include "feeder_rate_gen.h" 66110466Sorion 67193640Sariff#if !defined(_KERNEL) && defined(SND_DIAGNOSTIC) 68193640Sariff#undef Z_DIAGNOSTIC 69193640Sariff#define Z_DIAGNOSTIC 1 70193640Sariff#elif defined(_KERNEL) 71193640Sariff#undef Z_DIAGNOSTIC 72193640Sariff#endif 7375320Scg 74193640Sariff#ifndef Z_QUALITY_DEFAULT 75193640Sariff#define Z_QUALITY_DEFAULT Z_QUALITY_LINEAR 76193640Sariff#endif 77109547Sorion 78193640Sariff#define Z_RESERVOIR 2048 79193640Sariff#define Z_RESERVOIR_MAX 131072 80109547Sorion 81193640Sariff#define Z_SINC_MAX 0x3fffff 82193640Sariff#define Z_SINC_DOWNMAX 48 /* 384000 / 8000 */ 83110466Sorion 84193640Sariff#ifdef _KERNEL 85193640Sariff#define Z_POLYPHASE_MAX 183040 /* 286 taps, 640 phases */ 86193640Sariff#else 87193640Sariff#define Z_POLYPHASE_MAX 1464320 /* 286 taps, 5120 phases */ 88167646Sariff#endif 89193640Sariff 90193640Sariff#define Z_RATE_DEFAULT 48000 91193640Sariff 92193640Sariff#define Z_RATE_MIN FEEDRATE_RATEMIN 93193640Sariff#define Z_RATE_MAX FEEDRATE_RATEMAX 94193640Sariff#define Z_ROUNDHZ FEEDRATE_ROUNDHZ 95193640Sariff#define Z_ROUNDHZ_MIN FEEDRATE_ROUNDHZ_MIN 96193640Sariff#define Z_ROUNDHZ_MAX FEEDRATE_ROUNDHZ_MAX 97193640Sariff 98193640Sariff#define Z_RATE_SRC FEEDRATE_SRC 99193640Sariff#define Z_RATE_DST FEEDRATE_DST 100193640Sariff#define Z_RATE_QUALITY FEEDRATE_QUALITY 101193640Sariff#define Z_RATE_CHANNELS FEEDRATE_CHANNELS 102193640Sariff 103193640Sariff#define Z_PARANOID 1 104193640Sariff 105193640Sariff#define Z_MULTIFORMAT 1 106193640Sariff 107193640Sariff#ifdef _KERNEL 108193640Sariff#undef Z_USE_ALPHADRIFT 109193640Sariff#define Z_USE_ALPHADRIFT 1 110193640Sariff#endif 111193640Sariff 112193640Sariff#define Z_FACTOR_MIN 1 113193640Sariff#define Z_FACTOR_MAX Z_MASK 114193640Sariff#define Z_FACTOR_SAFE(v) (!((v) < Z_FACTOR_MIN || (v) > Z_FACTOR_MAX)) 115193640Sariff 116193640Sariffstruct z_info; 117193640Sariff 118193640Sarifftypedef void (*z_resampler_t)(struct z_info *, uint8_t *); 119193640Sariff 120193640Sariffstruct z_info { 121193640Sariff int32_t rsrc, rdst; /* original source / destination rates */ 122193640Sariff int32_t src, dst; /* rounded source / destination rates */ 123193640Sariff int32_t channels; /* total channels */ 124193640Sariff int32_t bps; /* bytes-per-sample */ 125193640Sariff int32_t quality; /* resampling quality */ 126193640Sariff 127193640Sariff int32_t z_gx, z_gy; /* interpolation / decimation ratio */ 128193640Sariff int32_t z_alpha; /* output sample time phase / drift */ 129193640Sariff uint8_t *z_delay; /* FIR delay line / linear buffer */ 130193640Sariff int32_t *z_coeff; /* FIR coefficients */ 131193640Sariff int32_t *z_dcoeff; /* FIR coefficients differences */ 132193640Sariff int32_t *z_pcoeff; /* FIR polyphase coefficients */ 133193640Sariff int32_t z_scale; /* output scaling */ 134193640Sariff int32_t z_dx; /* input sample drift increment */ 135193640Sariff int32_t z_dy; /* output sample drift increment */ 136193640Sariff#ifdef Z_USE_ALPHADRIFT 137193640Sariff int32_t z_alphadrift; /* alpha drift rate */ 138193640Sariff int32_t z_startdrift; /* buffer start position drift rate */ 139193640Sariff#endif 140193640Sariff int32_t z_mask; /* delay line full length mask */ 141193640Sariff int32_t z_size; /* half width of FIR taps */ 142193640Sariff int32_t z_full; /* full size of delay line */ 143193640Sariff int32_t z_alloc; /* largest allocated full size of delay line */ 144193640Sariff int32_t z_start; /* buffer processing start position */ 145193640Sariff int32_t z_pos; /* current position for the next feed */ 146193640Sariff#ifdef Z_DIAGNOSTIC 147193640Sariff uint32_t z_cycle; /* output cycle, purely for statistical */ 148193640Sariff#endif 149193640Sariff int32_t z_maxfeed; /* maximum feed to avoid 32bit overflow */ 150193640Sariff 151193640Sariff z_resampler_t z_resample; 152148606Snetchild}; 153148606Snetchild 154193640Sariffint feeder_rate_min = Z_RATE_MIN; 155193640Sariffint feeder_rate_max = Z_RATE_MAX; 156193640Sariffint feeder_rate_round = Z_ROUNDHZ; 157193640Sariffint feeder_rate_quality = Z_QUALITY_DEFAULT; 158148606Snetchild 159193640Sariffstatic int feeder_rate_polyphase_max = Z_POLYPHASE_MAX; 160193640Sariff 161193640Sariff#ifdef _KERNEL 162193640Sariffstatic const char feeder_rate_presets[] = FEEDER_RATE_PRESETS; 163193640SariffSYSCTL_STRING(_hw_snd, OID_AUTO, feeder_rate_presets, CTLFLAG_RD, 164193640Sariff &feeder_rate_presets, 0, "compile-time rate presets"); 165193640Sariff 166164614SariffTUNABLE_INT("hw.snd.feeder_rate_min", &feeder_rate_min); 167164614SariffTUNABLE_INT("hw.snd.feeder_rate_max", &feeder_rate_max); 168164614SariffTUNABLE_INT("hw.snd.feeder_rate_round", &feeder_rate_round); 169193640SariffTUNABLE_INT("hw.snd.feeder_rate_quality", &feeder_rate_quality); 170109547Sorion 171193640SariffTUNABLE_INT("hw.snd.feeder_rate_polyphase_max", &feeder_rate_polyphase_max); 172193640SariffSYSCTL_INT(_hw_snd, OID_AUTO, feeder_rate_polyphase_max, CTLFLAG_RW, 173193640Sariff &feeder_rate_polyphase_max, 0, "maximum allowable polyphase entries"); 174193640Sariff 175148606Snetchildstatic int 176164614Sariffsysctl_hw_snd_feeder_rate_min(SYSCTL_HANDLER_ARGS) 177148606Snetchild{ 178148606Snetchild int err, val; 179109547Sorion 180164614Sariff val = feeder_rate_min; 181170289Sdwmalone err = sysctl_handle_int(oidp, &val, 0, req); 182193640Sariff 183193640Sariff if (err != 0 || req->newptr == NULL || val == feeder_rate_min) 184167646Sariff return (err); 185193640Sariff 186193640Sariff if (!(Z_FACTOR_SAFE(val) && val < feeder_rate_max)) 187193640Sariff return (EINVAL); 188193640Sariff 189193640Sariff feeder_rate_min = val; 190193640Sariff 191193640Sariff return (0); 192148606Snetchild} 193164614SariffSYSCTL_PROC(_hw_snd, OID_AUTO, feeder_rate_min, CTLTYPE_INT | CTLFLAG_RW, 194193640Sariff 0, sizeof(int), sysctl_hw_snd_feeder_rate_min, "I", 195193640Sariff "minimum allowable rate"); 196109547Sorion 197148606Snetchildstatic int 198164614Sariffsysctl_hw_snd_feeder_rate_max(SYSCTL_HANDLER_ARGS) 199148606Snetchild{ 200148606Snetchild int err, val; 201109547Sorion 202164614Sariff val = feeder_rate_max; 203170289Sdwmalone err = sysctl_handle_int(oidp, &val, 0, req); 204193640Sariff 205193640Sariff if (err != 0 || req->newptr == NULL || val == feeder_rate_max) 206167646Sariff return (err); 207193640Sariff 208193640Sariff if (!(Z_FACTOR_SAFE(val) && val > feeder_rate_min)) 209193640Sariff return (EINVAL); 210193640Sariff 211193640Sariff feeder_rate_max = val; 212193640Sariff 213193640Sariff return (0); 214148606Snetchild} 215164614SariffSYSCTL_PROC(_hw_snd, OID_AUTO, feeder_rate_max, CTLTYPE_INT | CTLFLAG_RW, 216193640Sariff 0, sizeof(int), sysctl_hw_snd_feeder_rate_max, "I", 217193640Sariff "maximum allowable rate"); 218148606Snetchild 219109547Sorionstatic int 220164614Sariffsysctl_hw_snd_feeder_rate_round(SYSCTL_HANDLER_ARGS) 221148606Snetchild{ 222148606Snetchild int err, val; 223109547Sorion 224164614Sariff val = feeder_rate_round; 225170289Sdwmalone err = sysctl_handle_int(oidp, &val, 0, req); 226193640Sariff 227193640Sariff if (err != 0 || req->newptr == NULL || val == feeder_rate_round) 228167646Sariff return (err); 229193640Sariff 230193640Sariff if (val < Z_ROUNDHZ_MIN || val > Z_ROUNDHZ_MAX) 231193640Sariff return (EINVAL); 232193640Sariff 233193640Sariff feeder_rate_round = val - (val % Z_ROUNDHZ); 234193640Sariff 235193640Sariff return (0); 236148606Snetchild} 237164614SariffSYSCTL_PROC(_hw_snd, OID_AUTO, feeder_rate_round, CTLTYPE_INT | CTLFLAG_RW, 238193640Sariff 0, sizeof(int), sysctl_hw_snd_feeder_rate_round, "I", 239193640Sariff "sample rate converter rounding threshold"); 240109547Sorion 241193640Sariffstatic int 242193640Sariffsysctl_hw_snd_feeder_rate_quality(SYSCTL_HANDLER_ARGS) 243193640Sariff{ 244193640Sariff struct snddev_info *d; 245193640Sariff struct pcm_channel *c; 246193640Sariff struct pcm_feeder *f; 247193640Sariff int i, err, val; 248193640Sariff 249193640Sariff val = feeder_rate_quality; 250193640Sariff err = sysctl_handle_int(oidp, &val, 0, req); 251193640Sariff 252193640Sariff if (err != 0 || req->newptr == NULL || val == feeder_rate_quality) 253193640Sariff return (err); 254193640Sariff 255193640Sariff if (val < Z_QUALITY_MIN || val > Z_QUALITY_MAX) 256193640Sariff return (EINVAL); 257193640Sariff 258193640Sariff feeder_rate_quality = val; 259193640Sariff 260193640Sariff /* 261193640Sariff * Traverse all available channels on each device and try to 262193640Sariff * set resampler quality if and only if it is exist as 263193640Sariff * part of feeder chains and the channel is idle. 264193640Sariff */ 265193640Sariff for (i = 0; pcm_devclass != NULL && 266193640Sariff i < devclass_get_maxunit(pcm_devclass); i++) { 267193640Sariff d = devclass_get_softc(pcm_devclass, i); 268193640Sariff if (!PCM_REGISTERED(d)) 269193640Sariff continue; 270193640Sariff PCM_LOCK(d); 271193640Sariff PCM_WAIT(d); 272193640Sariff PCM_ACQUIRE(d); 273193640Sariff CHN_FOREACH(c, d, channels.pcm) { 274193640Sariff CHN_LOCK(c); 275193640Sariff f = chn_findfeeder(c, FEEDER_RATE); 276193640Sariff if (f == NULL || f->data == NULL || CHN_STARTED(c)) { 277193640Sariff CHN_UNLOCK(c); 278193640Sariff continue; 279193640Sariff } 280193640Sariff (void)FEEDER_SET(f, FEEDRATE_QUALITY, val); 281193640Sariff CHN_UNLOCK(c); 282193640Sariff } 283193640Sariff PCM_RELEASE(d); 284193640Sariff PCM_UNLOCK(d); 285193640Sariff } 286193640Sariff 287193640Sariff return (0); 288148606Snetchild} 289193640SariffSYSCTL_PROC(_hw_snd, OID_AUTO, feeder_rate_quality, CTLTYPE_INT | CTLFLAG_RW, 290193640Sariff 0, sizeof(int), sysctl_hw_snd_feeder_rate_quality, "I", 291193640Sariff "sample rate converter quality ("__XSTRING(Z_QUALITY_MIN)"=low .. " 292193640Sariff __XSTRING(Z_QUALITY_MAX)"=high)"); 293193640Sariff#endif /* _KERNEL */ 294109547Sorion 295164614Sariff 296193640Sariff/* 297193640Sariff * Resampler type. 298193640Sariff */ 299193640Sariff#define Z_IS_ZOH(i) ((i)->quality == Z_QUALITY_ZOH) 300193640Sariff#define Z_IS_LINEAR(i) ((i)->quality == Z_QUALITY_LINEAR) 301193640Sariff#define Z_IS_SINC(i) ((i)->quality > Z_QUALITY_LINEAR) 302193640Sariff 303193640Sariff/* 304193640Sariff * Macroses for accurate sample time drift calculations. 305193640Sariff * 306193640Sariff * gy2gx : given the amount of output, return the _exact_ required amount of 307193640Sariff * input. 308193640Sariff * gx2gy : given the amount of input, return the _maximum_ amount of output 309193640Sariff * that will be generated. 310193640Sariff * drift : given the amount of input and output, return the elapsed 311193640Sariff * sample-time. 312193640Sariff */ 313193640Sariff#define _Z_GCAST(x) ((uint64_t)(x)) 314193640Sariff 315193640Sariff#if defined(__GNUCLIKE_ASM) && defined(__i386__) 316193640Sariff/* 317193640Sariff * This is where i386 being beaten to a pulp. Fortunately this function is 318193640Sariff * rarely being called and if it is, it will decide the best (hopefully) 319193640Sariff * fastest way to do the division. If we can ensure that everything is dword 320193640Sariff * aligned, letting the compiler to call udivdi3 to do the division can be 321193640Sariff * faster compared to this. 322193640Sariff * 323193640Sariff * amd64 is the clear winner here, no question about it. 324193640Sariff */ 325193640Sariffstatic __inline uint32_t 326193640SariffZ_DIV(uint64_t v, uint32_t d) 327109547Sorion{ 328193640Sariff uint32_t hi, lo, quo, rem; 329148606Snetchild 330193640Sariff hi = v >> 32; 331193640Sariff lo = v & 0xffffffff; 332193640Sariff 333193640Sariff /* 334193640Sariff * As much as we can, try to avoid long division like a plague. 335193640Sariff */ 336193640Sariff if (hi == 0) 337193640Sariff quo = lo / d; 338193640Sariff else 339193640Sariff __asm("divl %2" 340193640Sariff : "=a" (quo), "=d" (rem) 341193640Sariff : "r" (d), "0" (lo), "1" (hi)); 342193640Sariff 343193640Sariff return (quo); 344193640Sariff} 345193640Sariff#else 346193640Sariff#define Z_DIV(x, y) ((x) / (y)) 347193640Sariff#endif 348193640Sariff 349193640Sariff#define _Z_GY2GX(i, a, v) \ 350193640Sariff Z_DIV(((_Z_GCAST((i)->z_gx) * (v)) + ((i)->z_gy - (a) - 1)), \ 351193640Sariff (i)->z_gy) 352193640Sariff 353193640Sariff#define _Z_GX2GY(i, a, v) \ 354193640Sariff Z_DIV(((_Z_GCAST((i)->z_gy) * (v)) + (a)), (i)->z_gx) 355193640Sariff 356193640Sariff#define _Z_DRIFT(i, x, y) \ 357193640Sariff ((_Z_GCAST((i)->z_gy) * (x)) - (_Z_GCAST((i)->z_gx) * (y))) 358193640Sariff 359193640Sariff#define z_gy2gx(i, v) _Z_GY2GX(i, (i)->z_alpha, v) 360193640Sariff#define z_gx2gy(i, v) _Z_GX2GY(i, (i)->z_alpha, v) 361193640Sariff#define z_drift(i, x, y) _Z_DRIFT(i, x, y) 362193640Sariff 363193640Sariff/* 364193640Sariff * Macroses for SINC coefficients table manipulations.. whatever. 365193640Sariff */ 366193640Sariff#define Z_SINC_COEFF_IDX(i) ((i)->quality - Z_QUALITY_LINEAR - 1) 367193640Sariff 368193640Sariff#define Z_SINC_LEN(i) \ 369193640Sariff ((int32_t)(((uint64_t)z_coeff_tab[Z_SINC_COEFF_IDX(i)].len << \ 370193640Sariff Z_SHIFT) / (i)->z_dy)) 371193640Sariff 372193640Sariff#define Z_SINC_BASE_LEN(i) \ 373193640Sariff ((z_coeff_tab[Z_SINC_COEFF_IDX(i)].len - 1) >> (Z_DRIFT_SHIFT - 1)) 374193640Sariff 375193640Sariff/* 376193640Sariff * Macroses for linear delay buffer operations. Alignment is not 377193640Sariff * really necessary since we're not using true circular buffer, but it 378193640Sariff * will help us guard against possible trespasser. To be honest, 379193640Sariff * the linear block operations does not need guarding at all due to 380193640Sariff * accurate drifting! 381193640Sariff */ 382193640Sariff#define z_align(i, v) ((v) & (i)->z_mask) 383193640Sariff#define z_next(i, o, v) z_align(i, (o) + (v)) 384193640Sariff#define z_prev(i, o, v) z_align(i, (o) - (v)) 385193640Sariff#define z_fetched(i) (z_align(i, (i)->z_pos - (i)->z_start) - 1) 386193640Sariff#define z_free(i) ((i)->z_full - (i)->z_pos) 387193640Sariff 388193640Sariff/* 389193640Sariff * Macroses for Bla Bla .. :) 390193640Sariff */ 391193640Sariff#define z_copy(src, dst, sz) (void)memcpy(dst, src, sz) 392193640Sariff#define z_feed(...) FEEDER_FEED(__VA_ARGS__) 393193640Sariff 394193640Sariffstatic __inline uint32_t 395193640Sariffz_min(uint32_t x, uint32_t y) 396193640Sariff{ 397193640Sariff 398193640Sariff return ((x < y) ? x : y); 399193640Sariff} 400193640Sariff 401193640Sariffstatic int32_t 402193640Sariffz_gcd(int32_t x, int32_t y) 403193640Sariff{ 404193640Sariff int32_t w; 405193640Sariff 406110108Sorion while (y != 0) { 407110108Sorion w = x % y; 408110108Sorion x = y; 409110108Sorion y = w; 410110108Sorion } 411193640Sariff 412193640Sariff return (x); 413109547Sorion} 414109547Sorion 415193640Sariffstatic int32_t 416193640Sariffz_roundpow2(int32_t v) 417193640Sariff{ 418193640Sariff int32_t i; 419193640Sariff 420193640Sariff i = 1; 421193640Sariff 422193640Sariff /* 423193640Sariff * Let it overflow at will.. 424193640Sariff */ 425193640Sariff while (i > 0 && i < v) 426193640Sariff i <<= 1; 427193640Sariff 428193640Sariff return (i); 429193640Sariff} 430193640Sariff 431193640Sariff/* 432193640Sariff * Zero Order Hold, the worst of the worst, an insult against quality, 433193640Sariff * but super fast. 434193640Sariff */ 435148606Snetchildstatic void 436193640Sariffz_feed_zoh(struct z_info *info, uint8_t *dst) 437148606Snetchild{ 438193640Sariff#if 0 439193640Sariff z_copy(info->z_delay + 440193640Sariff (info->z_start * info->channels * info->bps), dst, 441193640Sariff info->channels * info->bps); 442193640Sariff#else 443193640Sariff uint32_t cnt; 444193640Sariff uint8_t *src; 445193640Sariff 446193640Sariff cnt = info->channels * info->bps; 447193640Sariff src = info->z_delay + (info->z_start * cnt); 448193640Sariff 449193640Sariff /* 450193640Sariff * This is a bit faster than doing bcopy() since we're dealing 451193640Sariff * with possible unaligned samples. 452193640Sariff */ 453193640Sariff do { 454193640Sariff *dst++ = *src++; 455193640Sariff } while (--cnt != 0); 456167646Sariff#endif 457148606Snetchild} 458148606Snetchild 459193640Sariff/* 460193640Sariff * Linear Interpolation. This at least sounds better (perceptually) and fast, 461193640Sariff * but without any proper filtering which means aliasing still exist and 462193640Sariff * could become worst with a right sample. Interpolation centered within 463193640Sariff * Z_LINEAR_ONE between the present and previous sample and everything is 464193640Sariff * done with simple 32bit scaling arithmetic. 465193640Sariff */ 466193640Sariff#define Z_DECLARE_LINEAR(SIGN, BIT, ENDIAN) \ 467193640Sariffstatic void \ 468193640Sariffz_feed_linear_##SIGN##BIT##ENDIAN(struct z_info *info, uint8_t *dst) \ 469193640Sariff{ \ 470193640Sariff int32_t z; \ 471193640Sariff intpcm_t x, y; \ 472193640Sariff uint32_t ch; \ 473193640Sariff uint8_t *sx, *sy; \ 474193640Sariff \ 475193640Sariff z = ((uint32_t)info->z_alpha * info->z_dx) >> Z_LINEAR_UNSHIFT; \ 476193640Sariff \ 477193640Sariff sx = info->z_delay + (info->z_start * info->channels * \ 478193640Sariff PCM_##BIT##_BPS); \ 479193640Sariff sy = sx - (info->channels * PCM_##BIT##_BPS); \ 480193640Sariff \ 481193640Sariff ch = info->channels; \ 482193640Sariff \ 483193640Sariff do { \ 484193640Sariff x = _PCM_READ_##SIGN##BIT##_##ENDIAN(sx); \ 485193640Sariff y = _PCM_READ_##SIGN##BIT##_##ENDIAN(sy); \ 486193640Sariff x = Z_LINEAR_INTERPOLATE_##BIT(z, x, y); \ 487193640Sariff _PCM_WRITE_##SIGN##BIT##_##ENDIAN(dst, x); \ 488193640Sariff sx += PCM_##BIT##_BPS; \ 489193640Sariff sy += PCM_##BIT##_BPS; \ 490193640Sariff dst += PCM_##BIT##_BPS; \ 491193640Sariff } while (--ch != 0); \ 492193640Sariff} 493193640Sariff 494193640Sariff/* 495193640Sariff * Userland clipping diagnostic check, not enabled in kernel compilation. 496193640Sariff * While doing sinc interpolation, unrealistic samples like full scale sine 497193640Sariff * wav will clip, but for other things this will not make any noise at all. 498193640Sariff * Everybody should learn how to normalized perceived loudness of their own 499193640Sariff * music/sounds/samples (hint: ReplayGain). 500193640Sariff */ 501193640Sariff#ifdef Z_DIAGNOSTIC 502193640Sariff#define Z_CLIP_CHECK(v, BIT) do { \ 503193640Sariff if ((v) > PCM_S##BIT##_MAX) { \ 504193640Sariff fprintf(stderr, "Overflow: v=%jd, max=%jd\n", \ 505193640Sariff (intmax_t)(v), (intmax_t)PCM_S##BIT##_MAX); \ 506193640Sariff } else if ((v) < PCM_S##BIT##_MIN) { \ 507193640Sariff fprintf(stderr, "Underflow: v=%jd, min=%jd\n", \ 508193640Sariff (intmax_t)(v), (intmax_t)PCM_S##BIT##_MIN); \ 509193640Sariff } \ 510193640Sariff} while (0) 511193640Sariff#else 512193640Sariff#define Z_CLIP_CHECK(...) 513193640Sariff#endif 514193640Sariff 515193640Sariff#define Z_CLAMP(v, BIT) \ 516193640Sariff (((v) > PCM_S##BIT##_MAX) ? PCM_S##BIT##_MAX : \ 517193640Sariff (((v) < PCM_S##BIT##_MIN) ? PCM_S##BIT##_MIN : (v))) 518193640Sariff 519193640Sariff/* 520193640Sariff * Sine Cardinal (SINC) Interpolation. Scaling is done in 64 bit, so 521193640Sariff * there's no point to hold the plate any longer. All samples will be 522193640Sariff * shifted to a full 32 bit, scaled and restored during write for 523193640Sariff * maximum dynamic range (only for downsampling). 524193640Sariff */ 525193640Sariff#define _Z_SINC_ACCUMULATE(SIGN, BIT, ENDIAN, adv) \ 526193640Sariff c += z >> Z_SHIFT; \ 527193640Sariff z &= Z_MASK; \ 528193640Sariff coeff = Z_COEFF_INTERPOLATE(z, z_coeff[c], z_dcoeff[c]); \ 529193640Sariff x = _PCM_READ_##SIGN##BIT##_##ENDIAN(p); \ 530195378Sariff v += Z_NORM_##BIT((intpcm64_t)x * coeff); \ 531193640Sariff z += info->z_dy; \ 532193640Sariff p adv##= info->channels * PCM_##BIT##_BPS 533193640Sariff 534193640Sariff/* 535193640Sariff * XXX GCC4 optimization is such a !@#$%, need manual unrolling. 536193640Sariff */ 537193640Sariff#if defined(__GNUC__) && __GNUC__ >= 4 538193640Sariff#define Z_SINC_ACCUMULATE(...) do { \ 539193640Sariff _Z_SINC_ACCUMULATE(__VA_ARGS__); \ 540193640Sariff _Z_SINC_ACCUMULATE(__VA_ARGS__); \ 541193640Sariff} while (0) 542193640Sariff#define Z_SINC_ACCUMULATE_DECR 2 543193640Sariff#else 544193640Sariff#define Z_SINC_ACCUMULATE(...) do { \ 545193640Sariff _Z_SINC_ACCUMULATE(__VA_ARGS__); \ 546193640Sariff} while (0) 547193640Sariff#define Z_SINC_ACCUMULATE_DECR 1 548193640Sariff#endif 549193640Sariff 550193640Sariff#define Z_DECLARE_SINC(SIGN, BIT, ENDIAN) \ 551193640Sariffstatic void \ 552193640Sariffz_feed_sinc_##SIGN##BIT##ENDIAN(struct z_info *info, uint8_t *dst) \ 553193640Sariff{ \ 554193640Sariff intpcm64_t v; \ 555193640Sariff intpcm_t x; \ 556193640Sariff uint8_t *p; \ 557193640Sariff int32_t coeff, z, *z_coeff, *z_dcoeff; \ 558193640Sariff uint32_t c, center, ch, i; \ 559193640Sariff \ 560193640Sariff z_coeff = info->z_coeff; \ 561193640Sariff z_dcoeff = info->z_dcoeff; \ 562193640Sariff center = z_prev(info, info->z_start, info->z_size); \ 563193640Sariff ch = info->channels * PCM_##BIT##_BPS; \ 564193640Sariff dst += ch; \ 565193640Sariff \ 566193640Sariff do { \ 567193640Sariff dst -= PCM_##BIT##_BPS; \ 568193640Sariff ch -= PCM_##BIT##_BPS; \ 569193640Sariff v = 0; \ 570193640Sariff z = info->z_alpha * info->z_dx; \ 571193640Sariff c = 0; \ 572193640Sariff p = info->z_delay + (z_next(info, center, 1) * \ 573193640Sariff info->channels * PCM_##BIT##_BPS) + ch; \ 574193640Sariff for (i = info->z_size; i != 0; i -= Z_SINC_ACCUMULATE_DECR) \ 575193640Sariff Z_SINC_ACCUMULATE(SIGN, BIT, ENDIAN, +); \ 576193640Sariff z = info->z_dy - (info->z_alpha * info->z_dx); \ 577193640Sariff c = 0; \ 578193640Sariff p = info->z_delay + (center * info->channels * \ 579193640Sariff PCM_##BIT##_BPS) + ch; \ 580193640Sariff for (i = info->z_size; i != 0; i -= Z_SINC_ACCUMULATE_DECR) \ 581193640Sariff Z_SINC_ACCUMULATE(SIGN, BIT, ENDIAN, -); \ 582193640Sariff if (info->z_scale != Z_ONE) \ 583193640Sariff v = Z_SCALE_##BIT(v, info->z_scale); \ 584193640Sariff else \ 585195378Sariff v >>= Z_COEFF_SHIFT - Z_GUARD_BIT_##BIT; \ 586193640Sariff Z_CLIP_CHECK(v, BIT); \ 587193640Sariff _PCM_WRITE_##SIGN##BIT##_##ENDIAN(dst, Z_CLAMP(v, BIT)); \ 588193640Sariff } while (ch != 0); \ 589193640Sariff} 590193640Sariff 591193640Sariff#define Z_DECLARE_SINC_POLYPHASE(SIGN, BIT, ENDIAN) \ 592193640Sariffstatic void \ 593193640Sariffz_feed_sinc_polyphase_##SIGN##BIT##ENDIAN(struct z_info *info, uint8_t *dst) \ 594193640Sariff{ \ 595193640Sariff intpcm64_t v; \ 596193640Sariff intpcm_t x; \ 597193640Sariff uint8_t *p; \ 598193640Sariff int32_t ch, i, start, *z_pcoeff; \ 599193640Sariff \ 600193640Sariff ch = info->channels * PCM_##BIT##_BPS; \ 601193640Sariff dst += ch; \ 602193640Sariff start = z_prev(info, info->z_start, (info->z_size << 1) - 1) * ch; \ 603193640Sariff \ 604193640Sariff do { \ 605193640Sariff dst -= PCM_##BIT##_BPS; \ 606193640Sariff ch -= PCM_##BIT##_BPS; \ 607193640Sariff v = 0; \ 608193640Sariff p = info->z_delay + start + ch; \ 609193640Sariff z_pcoeff = info->z_pcoeff + \ 610193640Sariff ((info->z_alpha * info->z_size) << 1); \ 611193640Sariff for (i = info->z_size; i != 0; i--) { \ 612193640Sariff x = _PCM_READ_##SIGN##BIT##_##ENDIAN(p); \ 613195378Sariff v += Z_NORM_##BIT((intpcm64_t)x * *z_pcoeff); \ 614193640Sariff z_pcoeff++; \ 615193640Sariff p += info->channels * PCM_##BIT##_BPS; \ 616193640Sariff x = _PCM_READ_##SIGN##BIT##_##ENDIAN(p); \ 617195378Sariff v += Z_NORM_##BIT((intpcm64_t)x * *z_pcoeff); \ 618193640Sariff z_pcoeff++; \ 619193640Sariff p += info->channels * PCM_##BIT##_BPS; \ 620193640Sariff } \ 621193640Sariff if (info->z_scale != Z_ONE) \ 622193640Sariff v = Z_SCALE_##BIT(v, info->z_scale); \ 623193640Sariff else \ 624195378Sariff v >>= Z_COEFF_SHIFT - Z_GUARD_BIT_##BIT; \ 625193640Sariff Z_CLIP_CHECK(v, BIT); \ 626193640Sariff _PCM_WRITE_##SIGN##BIT##_##ENDIAN(dst, Z_CLAMP(v, BIT)); \ 627193640Sariff } while (ch != 0); \ 628193640Sariff} 629193640Sariff 630193640Sariff#define Z_DECLARE(SIGN, BIT, ENDIAN) \ 631193640Sariff Z_DECLARE_LINEAR(SIGN, BIT, ENDIAN) \ 632193640Sariff Z_DECLARE_SINC(SIGN, BIT, ENDIAN) \ 633193640Sariff Z_DECLARE_SINC_POLYPHASE(SIGN, BIT, ENDIAN) 634193640Sariff 635193640Sariff#if BYTE_ORDER == LITTLE_ENDIAN || defined(SND_FEEDER_MULTIFORMAT) 636193640SariffZ_DECLARE(S, 16, LE) 637193640SariffZ_DECLARE(S, 32, LE) 638193640Sariff#endif 639193640Sariff#if BYTE_ORDER == BIG_ENDIAN || defined(SND_FEEDER_MULTIFORMAT) 640193640SariffZ_DECLARE(S, 16, BE) 641193640SariffZ_DECLARE(S, 32, BE) 642193640Sariff#endif 643193640Sariff#ifdef SND_FEEDER_MULTIFORMAT 644193640SariffZ_DECLARE(S, 8, NE) 645193640SariffZ_DECLARE(S, 24, LE) 646193640SariffZ_DECLARE(S, 24, BE) 647193640SariffZ_DECLARE(U, 8, NE) 648193640SariffZ_DECLARE(U, 16, LE) 649193640SariffZ_DECLARE(U, 24, LE) 650193640SariffZ_DECLARE(U, 32, LE) 651193640SariffZ_DECLARE(U, 16, BE) 652193640SariffZ_DECLARE(U, 24, BE) 653193640SariffZ_DECLARE(U, 32, BE) 654193640Sariff#endif 655193640Sariff 656193640Sariffenum { 657193640Sariff Z_RESAMPLER_ZOH, 658193640Sariff Z_RESAMPLER_LINEAR, 659193640Sariff Z_RESAMPLER_SINC, 660193640Sariff Z_RESAMPLER_SINC_POLYPHASE, 661193640Sariff Z_RESAMPLER_LAST 662193640Sariff}; 663193640Sariff 664193640Sariff#define Z_RESAMPLER_IDX(i) \ 665193640Sariff (Z_IS_SINC(i) ? Z_RESAMPLER_SINC : (i)->quality) 666193640Sariff 667193640Sariff#define Z_RESAMPLER_ENTRY(SIGN, BIT, ENDIAN) \ 668193640Sariff { \ 669193640Sariff AFMT_##SIGN##BIT##_##ENDIAN, \ 670193640Sariff { \ 671193640Sariff [Z_RESAMPLER_ZOH] = z_feed_zoh, \ 672193640Sariff [Z_RESAMPLER_LINEAR] = z_feed_linear_##SIGN##BIT##ENDIAN, \ 673193640Sariff [Z_RESAMPLER_SINC] = z_feed_sinc_##SIGN##BIT##ENDIAN, \ 674193640Sariff [Z_RESAMPLER_SINC_POLYPHASE] = \ 675193640Sariff z_feed_sinc_polyphase_##SIGN##BIT##ENDIAN \ 676193640Sariff } \ 677193640Sariff } 678193640Sariff 679193640Sariffstatic const struct { 680193640Sariff uint32_t format; 681193640Sariff z_resampler_t resampler[Z_RESAMPLER_LAST]; 682193640Sariff} z_resampler_tab[] = { 683193640Sariff#if BYTE_ORDER == LITTLE_ENDIAN || defined(SND_FEEDER_MULTIFORMAT) 684193640Sariff Z_RESAMPLER_ENTRY(S, 16, LE), 685193640Sariff Z_RESAMPLER_ENTRY(S, 32, LE), 686193640Sariff#endif 687193640Sariff#if BYTE_ORDER == BIG_ENDIAN || defined(SND_FEEDER_MULTIFORMAT) 688193640Sariff Z_RESAMPLER_ENTRY(S, 16, BE), 689193640Sariff Z_RESAMPLER_ENTRY(S, 32, BE), 690193640Sariff#endif 691193640Sariff#ifdef SND_FEEDER_MULTIFORMAT 692193640Sariff Z_RESAMPLER_ENTRY(S, 8, NE), 693193640Sariff Z_RESAMPLER_ENTRY(S, 24, LE), 694193640Sariff Z_RESAMPLER_ENTRY(S, 24, BE), 695193640Sariff Z_RESAMPLER_ENTRY(U, 8, NE), 696193640Sariff Z_RESAMPLER_ENTRY(U, 16, LE), 697193640Sariff Z_RESAMPLER_ENTRY(U, 24, LE), 698193640Sariff Z_RESAMPLER_ENTRY(U, 32, LE), 699193640Sariff Z_RESAMPLER_ENTRY(U, 16, BE), 700193640Sariff Z_RESAMPLER_ENTRY(U, 24, BE), 701193640Sariff Z_RESAMPLER_ENTRY(U, 32, BE), 702193640Sariff#endif 703193640Sariff}; 704193640Sariff 705193640Sariff#define Z_RESAMPLER_TAB_SIZE \ 706193640Sariff ((int32_t)(sizeof(z_resampler_tab) / sizeof(z_resampler_tab[0]))) 707193640Sariff 708193640Sariffstatic void 709193640Sariffz_resampler_reset(struct z_info *info) 71075320Scg{ 71175320Scg 712193640Sariff info->src = info->rsrc - (info->rsrc % ((feeder_rate_round > 0 && 713193640Sariff info->rsrc > feeder_rate_round) ? feeder_rate_round : 1)); 714193640Sariff info->dst = info->rdst - (info->rdst % ((feeder_rate_round > 0 && 715193640Sariff info->rdst > feeder_rate_round) ? feeder_rate_round : 1)); 716193640Sariff info->z_gx = 1; 717193640Sariff info->z_gy = 1; 718193640Sariff info->z_alpha = 0; 719193640Sariff info->z_resample = NULL; 720193640Sariff info->z_size = 1; 721193640Sariff info->z_coeff = NULL; 722193640Sariff info->z_dcoeff = NULL; 723193640Sariff if (info->z_pcoeff != NULL) { 724193640Sariff free(info->z_pcoeff, M_DEVBUF); 725193640Sariff info->z_pcoeff = NULL; 726193640Sariff } 727193640Sariff info->z_scale = Z_ONE; 728193640Sariff info->z_dx = Z_FULL_ONE; 729193640Sariff info->z_dy = Z_FULL_ONE; 730193640Sariff#ifdef Z_DIAGNOSTIC 731193640Sariff info->z_cycle = 0; 732193640Sariff#endif 733193640Sariff if (info->quality < Z_QUALITY_MIN) 734193640Sariff info->quality = Z_QUALITY_MIN; 735193640Sariff else if (info->quality > Z_QUALITY_MAX) 736193640Sariff info->quality = Z_QUALITY_MAX; 737193640Sariff} 738164614Sariff 739193640Sariff#ifdef Z_PARANOID 740193640Sariffstatic int32_t 741193640Sariffz_resampler_sinc_len(struct z_info *info) 742193640Sariff{ 743193640Sariff int32_t c, z, len, lmax; 744164614Sariff 745193640Sariff if (!Z_IS_SINC(info)) 746193640Sariff return (1); 747193640Sariff 748193640Sariff /* 749193640Sariff * A rather careful (or useless) way to calculate filter length. 750193640Sariff * Z_SINC_LEN() itself is accurate enough to do its job. Extra 751193640Sariff * sanity checking is not going to hurt though.. 752193640Sariff */ 753193640Sariff c = 0; 754193640Sariff z = info->z_dy; 755193640Sariff len = 0; 756193640Sariff lmax = z_coeff_tab[Z_SINC_COEFF_IDX(info)].len; 757193640Sariff 758193640Sariff do { 759193640Sariff c += z >> Z_SHIFT; 760193640Sariff z &= Z_MASK; 761193640Sariff z += info->z_dy; 762193640Sariff } while (c < lmax && ++len > 0); 763193640Sariff 764193640Sariff if (len != Z_SINC_LEN(info)) { 765193640Sariff#ifdef _KERNEL 766193640Sariff printf("%s(): sinc l=%d != Z_SINC_LEN=%d\n", 767193640Sariff __func__, len, Z_SINC_LEN(info)); 768193640Sariff#else 769193640Sariff fprintf(stderr, "%s(): sinc l=%d != Z_SINC_LEN=%d\n", 770193640Sariff __func__, len, Z_SINC_LEN(info)); 771167646Sariff return (-1); 772193640Sariff#endif 773193640Sariff } 774164614Sariff 775193640Sariff return (len); 776193640Sariff} 777193640Sariff#else 778193640Sariff#define z_resampler_sinc_len(i) (Z_IS_SINC(i) ? Z_SINC_LEN(i) : 1) 779193640Sariff#endif 780193640Sariff 781193640Sariff#define Z_POLYPHASE_COEFF_SHIFT 0 782193640Sariff 783193640Sariff/* 784193640Sariff * Pick suitable polynomial interpolators based on filter oversampled ratio 785193640Sariff * (2 ^ Z_DRIFT_SHIFT). 786193640Sariff */ 787193640Sariff#if !(defined(Z_COEFF_INTERP_ZOH) || defined(Z_COEFF_INTERP_LINEAR) || \ 788193640Sariff defined(Z_COEFF_INTERP_QUADRATIC) || defined(Z_COEFF_INTERP_HERMITE) || \ 789193640Sariff defined(Z_COEFF_INTER_BSPLINE) || defined(Z_COEFF_INTERP_OPT32X) || \ 790193640Sariff defined(Z_COEFF_INTERP_OPT16X) || defined(Z_COEFF_INTERP_OPT8X) || \ 791193640Sariff defined(Z_COEFF_INTERP_OPT4X) || defined(Z_COEFF_INTERP_OPT2X)) 792195689Sariff#if Z_DRIFT_SHIFT >= 6 793195689Sariff#define Z_COEFF_INTERP_BSPLINE 1 794194232Sariff#elif Z_DRIFT_SHIFT >= 5 795193640Sariff#define Z_COEFF_INTERP_OPT32X 1 796193640Sariff#elif Z_DRIFT_SHIFT == 4 797193640Sariff#define Z_COEFF_INTERP_OPT16X 1 798193640Sariff#elif Z_DRIFT_SHIFT == 3 799193640Sariff#define Z_COEFF_INTERP_OPT8X 1 800193640Sariff#elif Z_DRIFT_SHIFT == 2 801193640Sariff#define Z_COEFF_INTERP_OPT4X 1 802193640Sariff#elif Z_DRIFT_SHIFT == 1 803193640Sariff#define Z_COEFF_INTERP_OPT2X 1 804193640Sariff#else 805193640Sariff#error "Z_DRIFT_SHIFT screwed!" 806193640Sariff#endif 807193640Sariff#endif 808193640Sariff 809193640Sariff/* 810193640Sariff * In classic polyphase mode, the actual coefficients for each phases need to 811193640Sariff * be calculated based on default prototype filters. For highly oversampled 812193640Sariff * filter, linear or quadradatic interpolator should be enough. Anything less 813193640Sariff * than that require 'special' interpolators to reduce interpolation errors. 814193640Sariff * 815193640Sariff * "Polynomial Interpolators for High-Quality Resampling of Oversampled Audio" 816193640Sariff * by Olli Niemitalo 817193640Sariff * - http://www.student.oulu.fi/~oniemita/dsp/deip.pdf 818193640Sariff * 819193640Sariff */ 820193640Sariffstatic int32_t 821193640Sariffz_coeff_interpolate(int32_t z, int32_t *z_coeff) 822193640Sariff{ 823193640Sariff int32_t coeff; 824193640Sariff#if defined(Z_COEFF_INTERP_ZOH) 825193640Sariff 826193640Sariff /* 1-point, 0th-order (Zero Order Hold) */ 827193640Sariff z = z; 828193640Sariff coeff = z_coeff[0]; 829193640Sariff#elif defined(Z_COEFF_INTERP_LINEAR) 830193640Sariff int32_t zl0, zl1; 831193640Sariff 832193640Sariff /* 2-point, 1st-order Linear */ 833193640Sariff zl0 = z_coeff[0]; 834193640Sariff zl1 = z_coeff[1] - z_coeff[0]; 835193640Sariff 836195689Sariff coeff = Z_RSHIFT((int64_t)zl1 * z, Z_SHIFT) + zl0; 837193640Sariff#elif defined(Z_COEFF_INTERP_QUADRATIC) 838193640Sariff int32_t zq0, zq1, zq2; 839193640Sariff 840193640Sariff /* 3-point, 2nd-order Quadratic */ 841193640Sariff zq0 = z_coeff[0]; 842193640Sariff zq1 = z_coeff[1] - z_coeff[-1]; 843193640Sariff zq2 = z_coeff[1] + z_coeff[-1] - (z_coeff[0] << 1); 844193640Sariff 845195689Sariff coeff = Z_RSHIFT((Z_RSHIFT((int64_t)zq2 * z, Z_SHIFT) + 846195689Sariff zq1) * z, Z_SHIFT + 1) + zq0; 847193640Sariff#elif defined(Z_COEFF_INTERP_HERMITE) 848193640Sariff int32_t zh0, zh1, zh2, zh3; 849193640Sariff 850193640Sariff /* 4-point, 3rd-order Hermite */ 851193640Sariff zh0 = z_coeff[0]; 852193640Sariff zh1 = z_coeff[1] - z_coeff[-1]; 853193640Sariff zh2 = (z_coeff[-1] << 1) - (z_coeff[0] * 5) + (z_coeff[1] << 2) - 854193640Sariff z_coeff[2]; 855193640Sariff zh3 = z_coeff[2] - z_coeff[-1] + ((z_coeff[0] - z_coeff[1]) * 3); 856193640Sariff 857195689Sariff coeff = Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((int64_t)zh3 * z, Z_SHIFT) + 858195689Sariff zh2) * z, Z_SHIFT) + zh1) * z, Z_SHIFT + 1) + zh0; 859193640Sariff#elif defined(Z_COEFF_INTERP_BSPLINE) 860193640Sariff int32_t zb0, zb1, zb2, zb3; 861193640Sariff 862193640Sariff /* 4-point, 3rd-order B-Spline */ 863195689Sariff zb0 = Z_RSHIFT(0x15555555LL * (((int64_t)z_coeff[0] << 2) + 864195689Sariff z_coeff[-1] + z_coeff[1]), 30); 865193640Sariff zb1 = z_coeff[1] - z_coeff[-1]; 866193640Sariff zb2 = z_coeff[-1] + z_coeff[1] - (z_coeff[0] << 1); 867195689Sariff zb3 = Z_RSHIFT(0x15555555LL * (((z_coeff[0] - z_coeff[1]) * 3) + 868195689Sariff z_coeff[2] - z_coeff[-1]), 30); 869193640Sariff 870195689Sariff coeff = (Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((int64_t)zb3 * z, Z_SHIFT) + 871195689Sariff zb2) * z, Z_SHIFT) + zb1) * z, Z_SHIFT) + zb0 + 1) >> 1; 872193640Sariff#elif defined(Z_COEFF_INTERP_OPT32X) 873193640Sariff int32_t zoz, zoe1, zoe2, zoe3, zoo1, zoo2, zoo3; 874193640Sariff int32_t zoc0, zoc1, zoc2, zoc3, zoc4, zoc5; 875193640Sariff 876193640Sariff /* 6-point, 5th-order Optimal 32x */ 877193640Sariff zoz = z - (Z_ONE >> 1); 878193640Sariff zoe1 = z_coeff[1] + z_coeff[0]; 879193640Sariff zoe2 = z_coeff[2] + z_coeff[-1]; 880193640Sariff zoe3 = z_coeff[3] + z_coeff[-2]; 881193640Sariff zoo1 = z_coeff[1] - z_coeff[0]; 882193640Sariff zoo2 = z_coeff[2] - z_coeff[-1]; 883193640Sariff zoo3 = z_coeff[3] - z_coeff[-2]; 884193640Sariff 885195689Sariff zoc0 = Z_RSHIFT((0x1ac2260dLL * zoe1) + (0x0526cdcaLL * zoe2) + 886195689Sariff (0x00170c29LL * zoe3), 30); 887195689Sariff zoc1 = Z_RSHIFT((0x14f8a49aLL * zoo1) + (0x0d6d1109LL * zoo2) + 888195689Sariff (0x008cd4dcLL * zoo3), 30); 889195689Sariff zoc2 = Z_RSHIFT((-0x0d3e94a4LL * zoe1) + (0x0bddded4LL * zoe2) + 890195689Sariff (0x0160b5d0LL * zoe3), 30); 891195689Sariff zoc3 = Z_RSHIFT((-0x0de10cc4LL * zoo1) + (0x019b2a7dLL * zoo2) + 892195689Sariff (0x01cfe914LL * zoo3), 30); 893195689Sariff zoc4 = Z_RSHIFT((0x02aa12d7LL * zoe1) + (-0x03ff1bb3LL * zoe2) + 894195689Sariff (0x015508ddLL * zoe3), 30); 895195689Sariff zoc5 = Z_RSHIFT((0x051d29e5LL * zoo1) + (-0x028e7647LL * zoo2) + 896195689Sariff (0x0082d81aLL * zoo3), 30); 897193640Sariff 898195689Sariff coeff = Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((Z_RSHIFT( 899195689Sariff (int64_t)zoc5 * zoz, Z_SHIFT) + 900195689Sariff zoc4) * zoz, Z_SHIFT) + zoc3) * zoz, Z_SHIFT) + 901195689Sariff zoc2) * zoz, Z_SHIFT) + zoc1) * zoz, Z_SHIFT) + zoc0; 902193640Sariff#elif defined(Z_COEFF_INTERP_OPT16X) 903193640Sariff int32_t zoz, zoe1, zoe2, zoe3, zoo1, zoo2, zoo3; 904193640Sariff int32_t zoc0, zoc1, zoc2, zoc3, zoc4, zoc5; 905193640Sariff 906193640Sariff /* 6-point, 5th-order Optimal 16x */ 907193640Sariff zoz = z - (Z_ONE >> 1); 908193640Sariff zoe1 = z_coeff[1] + z_coeff[0]; 909193640Sariff zoe2 = z_coeff[2] + z_coeff[-1]; 910193640Sariff zoe3 = z_coeff[3] + z_coeff[-2]; 911193640Sariff zoo1 = z_coeff[1] - z_coeff[0]; 912193640Sariff zoo2 = z_coeff[2] - z_coeff[-1]; 913193640Sariff zoo3 = z_coeff[3] - z_coeff[-2]; 914193640Sariff 915195689Sariff zoc0 = Z_RSHIFT((0x1ac2260dLL * zoe1) + (0x0526cdcaLL * zoe2) + 916195689Sariff (0x00170c29LL * zoe3), 30); 917195689Sariff zoc1 = Z_RSHIFT((0x14f8a49aLL * zoo1) + (0x0d6d1109LL * zoo2) + 918195689Sariff (0x008cd4dcLL * zoo3), 30); 919195689Sariff zoc2 = Z_RSHIFT((-0x0d3e94a4LL * zoe1) + (0x0bddded4LL * zoe2) + 920195689Sariff (0x0160b5d0LL * zoe3), 30); 921195689Sariff zoc3 = Z_RSHIFT((-0x0de10cc4LL * zoo1) + (0x019b2a7dLL * zoo2) + 922195689Sariff (0x01cfe914LL * zoo3), 30); 923195689Sariff zoc4 = Z_RSHIFT((0x02aa12d7LL * zoe1) + (-0x03ff1bb3LL * zoe2) + 924195689Sariff (0x015508ddLL * zoe3), 30); 925195689Sariff zoc5 = Z_RSHIFT((0x051d29e5LL * zoo1) + (-0x028e7647LL * zoo2) + 926195689Sariff (0x0082d81aLL * zoo3), 30); 927193640Sariff 928195689Sariff coeff = Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((Z_RSHIFT( 929195689Sariff (int64_t)zoc5 * zoz, Z_SHIFT) + 930195689Sariff zoc4) * zoz, Z_SHIFT) + zoc3) * zoz, Z_SHIFT) + 931195689Sariff zoc2) * zoz, Z_SHIFT) + zoc1) * zoz, Z_SHIFT) + zoc0; 932193640Sariff#elif defined(Z_COEFF_INTERP_OPT8X) 933193640Sariff int32_t zoz, zoe1, zoe2, zoe3, zoo1, zoo2, zoo3; 934193640Sariff int32_t zoc0, zoc1, zoc2, zoc3, zoc4, zoc5; 935193640Sariff 936193640Sariff /* 6-point, 5th-order Optimal 8x */ 937193640Sariff zoz = z - (Z_ONE >> 1); 938193640Sariff zoe1 = z_coeff[1] + z_coeff[0]; 939193640Sariff zoe2 = z_coeff[2] + z_coeff[-1]; 940193640Sariff zoe3 = z_coeff[3] + z_coeff[-2]; 941193640Sariff zoo1 = z_coeff[1] - z_coeff[0]; 942193640Sariff zoo2 = z_coeff[2] - z_coeff[-1]; 943193640Sariff zoo3 = z_coeff[3] - z_coeff[-2]; 944193640Sariff 945195689Sariff zoc0 = Z_RSHIFT((0x1aa9b47dLL * zoe1) + (0x053d9944LL * zoe2) + 946195689Sariff (0x0018b23fLL * zoe3), 30); 947195689Sariff zoc1 = Z_RSHIFT((0x14a104d1LL * zoo1) + (0x0d7d2504LL * zoo2) + 948195689Sariff (0x0094b599LL * zoo3), 30); 949195689Sariff zoc2 = Z_RSHIFT((-0x0d22530bLL * zoe1) + (0x0bb37a2cLL * zoe2) + 950195689Sariff (0x016ed8e0LL * zoe3), 30); 951195689Sariff zoc3 = Z_RSHIFT((-0x0d744b1cLL * zoo1) + (0x01649591LL * zoo2) + 952195689Sariff (0x01dae93aLL * zoo3), 30); 953195689Sariff zoc4 = Z_RSHIFT((0x02a7ee1bLL * zoe1) + (-0x03fbdb24LL * zoe2) + 954195689Sariff (0x0153ed07LL * zoe3), 30); 955195689Sariff zoc5 = Z_RSHIFT((0x04cf9b6cLL * zoo1) + (-0x0266b378LL * zoo2) + 956195689Sariff (0x007a7c26LL * zoo3), 30); 957193640Sariff 958195689Sariff coeff = Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((Z_RSHIFT( 959195689Sariff (int64_t)zoc5 * zoz, Z_SHIFT) + 960195689Sariff zoc4) * zoz, Z_SHIFT) + zoc3) * zoz, Z_SHIFT) + 961195689Sariff zoc2) * zoz, Z_SHIFT) + zoc1) * zoz, Z_SHIFT) + zoc0; 962193640Sariff#elif defined(Z_COEFF_INTERP_OPT4X) 963193640Sariff int32_t zoz, zoe1, zoe2, zoe3, zoo1, zoo2, zoo3; 964193640Sariff int32_t zoc0, zoc1, zoc2, zoc3, zoc4, zoc5; 965193640Sariff 966193640Sariff /* 6-point, 5th-order Optimal 4x */ 967193640Sariff zoz = z - (Z_ONE >> 1); 968193640Sariff zoe1 = z_coeff[1] + z_coeff[0]; 969193640Sariff zoe2 = z_coeff[2] + z_coeff[-1]; 970193640Sariff zoe3 = z_coeff[3] + z_coeff[-2]; 971193640Sariff zoo1 = z_coeff[1] - z_coeff[0]; 972193640Sariff zoo2 = z_coeff[2] - z_coeff[-1]; 973193640Sariff zoo3 = z_coeff[3] - z_coeff[-2]; 974193640Sariff 975195689Sariff zoc0 = Z_RSHIFT((0x1a8eda43LL * zoe1) + (0x0556ee38LL * zoe2) + 976195689Sariff (0x001a3784LL * zoe3), 30); 977195689Sariff zoc1 = Z_RSHIFT((0x143d863eLL * zoo1) + (0x0d910e36LL * zoo2) + 978195689Sariff (0x009ca889LL * zoo3), 30); 979195689Sariff zoc2 = Z_RSHIFT((-0x0d026821LL * zoe1) + (0x0b837773LL * zoe2) + 980195689Sariff (0x017ef0c6LL * zoe3), 30); 981195689Sariff zoc3 = Z_RSHIFT((-0x0cef1502LL * zoo1) + (0x01207a8eLL * zoo2) + 982195689Sariff (0x01e936dbLL * zoo3), 30); 983195689Sariff zoc4 = Z_RSHIFT((0x029fe643LL * zoe1) + (-0x03ef3fc8LL * zoe2) + 984195689Sariff (0x014f5923LL * zoe3), 30); 985195689Sariff zoc5 = Z_RSHIFT((0x043a9d08LL * zoo1) + (-0x02154febLL * zoo2) + 986195689Sariff (0x00670dbdLL * zoo3), 30); 987193640Sariff 988195689Sariff coeff = Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((Z_RSHIFT( 989195689Sariff (int64_t)zoc5 * zoz, Z_SHIFT) + 990195689Sariff zoc4) * zoz, Z_SHIFT) + zoc3) * zoz, Z_SHIFT) + 991195689Sariff zoc2) * zoz, Z_SHIFT) + zoc1) * zoz, Z_SHIFT) + zoc0; 992193640Sariff#elif defined(Z_COEFF_INTERP_OPT2X) 993193640Sariff int32_t zoz, zoe1, zoe2, zoe3, zoo1, zoo2, zoo3; 994193640Sariff int32_t zoc0, zoc1, zoc2, zoc3, zoc4, zoc5; 995193640Sariff 996193640Sariff /* 6-point, 5th-order Optimal 2x */ 997193640Sariff zoz = z - (Z_ONE >> 1); 998193640Sariff zoe1 = z_coeff[1] + z_coeff[0]; 999193640Sariff zoe2 = z_coeff[2] + z_coeff[-1]; 1000193640Sariff zoe3 = z_coeff[3] + z_coeff[-2]; 1001193640Sariff zoo1 = z_coeff[1] - z_coeff[0]; 1002193640Sariff zoo2 = z_coeff[2] - z_coeff[-1]; 1003193640Sariff zoo3 = z_coeff[3] - z_coeff[-2]; 1004193640Sariff 1005195689Sariff zoc0 = Z_RSHIFT((0x19edb6fdLL * zoe1) + (0x05ebd062LL * zoe2) + 1006195689Sariff (0x00267881LL * zoe3), 30); 1007195689Sariff zoc1 = Z_RSHIFT((0x1223af76LL * zoo1) + (0x0de3dd6bLL * zoo2) + 1008195689Sariff (0x00d683cdLL * zoo3), 30); 1009195689Sariff zoc2 = Z_RSHIFT((-0x0c3ee068LL * zoe1) + (0x0a5c3769LL * zoe2) + 1010195689Sariff (0x01e2aceaLL * zoe3), 30); 1011195689Sariff zoc3 = Z_RSHIFT((-0x0a8ab614LL * zoo1) + (-0x0019522eLL * zoo2) + 1012195689Sariff (0x022cefc7LL * zoo3), 30); 1013195689Sariff zoc4 = Z_RSHIFT((0x0276187dLL * zoe1) + (-0x03a801e8LL * zoe2) + 1014195689Sariff (0x0131d935LL * zoe3), 30); 1015195689Sariff zoc5 = Z_RSHIFT((0x02c373f5LL * zoo1) + (-0x01275f83LL * zoo2) + 1016195689Sariff (0x0018ee79LL * zoo3), 30); 1017193640Sariff 1018195689Sariff coeff = Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((Z_RSHIFT((Z_RSHIFT( 1019195689Sariff (int64_t)zoc5 * zoz, Z_SHIFT) + 1020195689Sariff zoc4) * zoz, Z_SHIFT) + zoc3) * zoz, Z_SHIFT) + 1021195689Sariff zoc2) * zoz, Z_SHIFT) + zoc1) * zoz, Z_SHIFT) + zoc0; 1022193640Sariff#else 1023193640Sariff#error "Interpolation type screwed!" 1024193640Sariff#endif 1025193640Sariff 1026193640Sariff#if Z_POLYPHASE_COEFF_SHIFT > 0 1027193640Sariff coeff = Z_RSHIFT(coeff, Z_POLYPHASE_COEFF_SHIFT); 1028193640Sariff#endif 1029193640Sariff return (coeff); 1030193640Sariff} 1031193640Sariff 1032193640Sariffstatic int 1033193640Sariffz_resampler_build_polyphase(struct z_info *info) 1034193640Sariff{ 1035193640Sariff int32_t alpha, c, i, z, idx; 1036193640Sariff 1037193640Sariff /* Let this be here first. */ 1038193640Sariff if (info->z_pcoeff != NULL) { 1039193640Sariff free(info->z_pcoeff, M_DEVBUF); 1040193640Sariff info->z_pcoeff = NULL; 1041193640Sariff } 1042193640Sariff 1043193640Sariff if (feeder_rate_polyphase_max < 1) 1044193640Sariff return (ENOTSUP); 1045193640Sariff 1046193640Sariff if (((int64_t)info->z_size * info->z_gy * 2) > 1047193640Sariff feeder_rate_polyphase_max) { 1048193640Sariff#ifndef _KERNEL 1049193640Sariff fprintf(stderr, "Polyphase entries exceed: [%d/%d] %jd > %d\n", 1050193640Sariff info->z_gx, info->z_gy, 1051193640Sariff (intmax_t)info->z_size * info->z_gy * 2, 1052193640Sariff feeder_rate_polyphase_max); 1053193640Sariff#endif 1054193640Sariff return (E2BIG); 1055193640Sariff } 1056193640Sariff 1057193640Sariff info->z_pcoeff = malloc(sizeof(int32_t) * 1058193640Sariff info->z_size * info->z_gy * 2, M_DEVBUF, M_NOWAIT | M_ZERO); 1059193640Sariff if (info->z_pcoeff == NULL) 1060193640Sariff return (ENOMEM); 1061193640Sariff 1062193640Sariff for (alpha = 0; alpha < info->z_gy; alpha++) { 1063193640Sariff z = alpha * info->z_dx; 1064193640Sariff c = 0; 1065193640Sariff for (i = info->z_size; i != 0; i--) { 1066193640Sariff c += z >> Z_SHIFT; 1067193640Sariff z &= Z_MASK; 1068193640Sariff idx = (alpha * info->z_size * 2) + 1069193640Sariff (info->z_size * 2) - i; 1070193640Sariff info->z_pcoeff[idx] = 1071193640Sariff z_coeff_interpolate(z, info->z_coeff + c); 1072193640Sariff z += info->z_dy; 1073193640Sariff } 1074193640Sariff z = info->z_dy - (alpha * info->z_dx); 1075193640Sariff c = 0; 1076193640Sariff for (i = info->z_size; i != 0; i--) { 1077193640Sariff c += z >> Z_SHIFT; 1078193640Sariff z &= Z_MASK; 1079193640Sariff idx = (alpha * info->z_size * 2) + i - 1; 1080193640Sariff info->z_pcoeff[idx] = 1081193640Sariff z_coeff_interpolate(z, info->z_coeff + c); 1082193640Sariff z += info->z_dy; 1083193640Sariff } 1084193640Sariff } 1085193640Sariff 1086193640Sariff#ifndef _KERNEL 1087193640Sariff fprintf(stderr, "Polyphase: [%d/%d] %d entries\n", 1088193640Sariff info->z_gx, info->z_gy, info->z_size * info->z_gy * 2); 1089193640Sariff#endif 1090193640Sariff 1091193640Sariff return (0); 1092193640Sariff} 1093193640Sariff 1094193640Sariffstatic int 1095193640Sariffz_resampler_setup(struct pcm_feeder *f) 1096193640Sariff{ 1097193640Sariff struct z_info *info; 1098193640Sariff int64_t gy2gx_max, gx2gy_max; 1099193640Sariff uint32_t format; 1100193640Sariff int32_t align, i, z_scale; 1101193640Sariff int adaptive; 1102193640Sariff 1103193640Sariff info = f->data; 1104193640Sariff z_resampler_reset(info); 1105193640Sariff 1106193640Sariff if (info->src == info->dst) 1107193640Sariff return (0); 1108193640Sariff 1109193640Sariff /* Shrink by greatest common divisor. */ 1110193640Sariff i = z_gcd(info->src, info->dst); 1111193640Sariff info->z_gx = info->src / i; 1112193640Sariff info->z_gy = info->dst / i; 1113193640Sariff 1114193640Sariff /* Too big, or too small. Bail out. */ 1115193640Sariff if (!(Z_FACTOR_SAFE(info->z_gx) && Z_FACTOR_SAFE(info->z_gy))) 1116193640Sariff return (EINVAL); 1117193640Sariff 1118193640Sariff format = f->desc->in; 1119193640Sariff adaptive = 0; 1120193640Sariff z_scale = 0; 1121193640Sariff 1122193640Sariff /* 1123193640Sariff * Setup everything: filter length, conversion factor, etc. 1124193640Sariff */ 1125193640Sariff if (Z_IS_SINC(info)) { 1126193640Sariff /* 1127193640Sariff * Downsampling, or upsampling scaling factor. As long as the 1128193640Sariff * factor can be represented by a fraction of 1 << Z_SHIFT, 1129193640Sariff * we're pretty much in business. Scaling is not needed for 1130193640Sariff * upsampling, so we just slap Z_ONE there. 1131193640Sariff */ 1132193640Sariff if (info->z_gx > info->z_gy) 1133193640Sariff /* 1134193640Sariff * If the downsampling ratio is beyond sanity, 1135193640Sariff * enable semi-adaptive mode. Although handling 1136193640Sariff * extreme ratio is possible, the result of the 1137193640Sariff * conversion is just pointless, unworthy, 1138193640Sariff * nonsensical noises, etc. 1139193640Sariff */ 1140193640Sariff if ((info->z_gx / info->z_gy) > Z_SINC_DOWNMAX) 1141193640Sariff z_scale = Z_ONE / Z_SINC_DOWNMAX; 1142193640Sariff else 1143193640Sariff z_scale = ((uint64_t)info->z_gy << Z_SHIFT) / 1144193640Sariff info->z_gx; 1145193640Sariff else 1146193640Sariff z_scale = Z_ONE; 1147193640Sariff 1148193640Sariff /* 1149193640Sariff * This is actually impossible, unless anything above 1150193640Sariff * overflow. 1151193640Sariff */ 1152193640Sariff if (z_scale < 1) 1153193640Sariff return (E2BIG); 1154193640Sariff 1155193640Sariff /* 1156193640Sariff * Calculate sample time/coefficients index drift. It is 1157193640Sariff * a constant for upsampling, but downsampling require 1158193640Sariff * heavy duty filtering with possible too long filters. 1159193640Sariff * If anything goes wrong, revisit again and enable 1160193640Sariff * adaptive mode. 1161193640Sariff */ 1162193640Sariffz_setup_adaptive_sinc: 1163193640Sariff if (info->z_pcoeff != NULL) { 1164193640Sariff free(info->z_pcoeff, M_DEVBUF); 1165193640Sariff info->z_pcoeff = NULL; 1166193640Sariff } 1167193640Sariff 1168193640Sariff if (adaptive == 0) { 1169193640Sariff info->z_dy = z_scale << Z_DRIFT_SHIFT; 1170193640Sariff if (info->z_dy < 1) 1171193640Sariff return (E2BIG); 1172193640Sariff info->z_scale = z_scale; 1173193640Sariff } else { 1174193640Sariff info->z_dy = Z_FULL_ONE; 1175193640Sariff info->z_scale = Z_ONE; 1176193640Sariff } 1177193640Sariff 1178193640Sariff#if 0 1179193640Sariff#define Z_SCALE_DIV 10000 1180193640Sariff#define Z_SCALE_LIMIT(s, v) \ 1181193640Sariff ((((uint64_t)(s) * (v)) + (Z_SCALE_DIV >> 1)) / Z_SCALE_DIV) 1182193640Sariff 1183193640Sariff info->z_scale = Z_SCALE_LIMIT(info->z_scale, 9780); 1184193640Sariff#endif 1185193640Sariff 1186193640Sariff /* Smallest drift increment. */ 1187193640Sariff info->z_dx = info->z_dy / info->z_gy; 1188193640Sariff 1189193640Sariff /* 1190193640Sariff * Overflow or underflow. Try adaptive, let it continue and 1191193640Sariff * retry. 1192193640Sariff */ 1193193640Sariff if (info->z_dx < 1) { 1194193640Sariff if (adaptive == 0) { 1195193640Sariff adaptive = 1; 1196193640Sariff goto z_setup_adaptive_sinc; 1197193640Sariff } 1198193640Sariff return (E2BIG); 1199193640Sariff } 1200193640Sariff 1201193640Sariff /* 1202193640Sariff * Round back output drift. 1203193640Sariff */ 1204193640Sariff info->z_dy = info->z_dx * info->z_gy; 1205193640Sariff 1206193640Sariff for (i = 0; i < Z_COEFF_TAB_SIZE; i++) { 1207193640Sariff if (Z_SINC_COEFF_IDX(info) != i) 1208193640Sariff continue; 1209193640Sariff /* 1210193640Sariff * Calculate required filter length and guard 1211193640Sariff * against possible abusive result. Note that 1212193640Sariff * this represents only 1/2 of the entire filter 1213193640Sariff * length. 1214193640Sariff */ 1215193640Sariff info->z_size = z_resampler_sinc_len(info); 1216193640Sariff 1217193640Sariff /* 1218193640Sariff * Multiple of 2 rounding, for better accumulator 1219193640Sariff * performance. 1220193640Sariff */ 1221193640Sariff info->z_size &= ~1; 1222193640Sariff 1223193640Sariff if (info->z_size < 2 || info->z_size > Z_SINC_MAX) { 1224193640Sariff if (adaptive == 0) { 1225193640Sariff adaptive = 1; 1226193640Sariff goto z_setup_adaptive_sinc; 1227193640Sariff } 1228193640Sariff return (E2BIG); 1229193640Sariff } 1230193640Sariff info->z_coeff = z_coeff_tab[i].coeff + Z_COEFF_OFFSET; 1231193640Sariff info->z_dcoeff = z_coeff_tab[i].dcoeff; 1232164614Sariff break; 1233148606Snetchild } 1234193640Sariff 1235193640Sariff if (info->z_coeff == NULL || info->z_dcoeff == NULL) 1236193640Sariff return (EINVAL); 1237193640Sariff } else if (Z_IS_LINEAR(info)) { 1238193640Sariff /* 1239193640Sariff * Don't put much effort if we're doing linear interpolation. 1240193640Sariff * Just center the interpolation distance within Z_LINEAR_ONE, 1241193640Sariff * and be happy about it. 1242193640Sariff */ 1243193640Sariff info->z_dx = Z_LINEAR_FULL_ONE / info->z_gy; 1244109547Sorion } 1245164614Sariff 1246164614Sariff /* 1247193640Sariff * We're safe for now, lets continue.. Look for our resampler 1248193640Sariff * depending on configured format and quality. 1249164614Sariff */ 1250193640Sariff for (i = 0; i < Z_RESAMPLER_TAB_SIZE; i++) { 1251193640Sariff int ridx; 1252164614Sariff 1253193640Sariff if (AFMT_ENCODING(format) != z_resampler_tab[i].format) 1254193640Sariff continue; 1255193640Sariff if (Z_IS_SINC(info) && adaptive == 0 && 1256193640Sariff z_resampler_build_polyphase(info) == 0) 1257193640Sariff ridx = Z_RESAMPLER_SINC_POLYPHASE; 1258193640Sariff else 1259193640Sariff ridx = Z_RESAMPLER_IDX(info); 1260193640Sariff info->z_resample = z_resampler_tab[i].resampler[ridx]; 1261193640Sariff break; 1262193640Sariff } 1263164614Sariff 1264193640Sariff if (info->z_resample == NULL) 1265193640Sariff return (EINVAL); 1266164614Sariff 1267193640Sariff info->bps = AFMT_BPS(format); 1268193640Sariff align = info->channels * info->bps; 1269164614Sariff 1270193640Sariff /* 1271193640Sariff * Calculate largest value that can be fed into z_gy2gx() and 1272193640Sariff * z_gx2gy() without causing (signed) 32bit overflow. z_gy2gx() will 1273193640Sariff * be called early during feeding process to determine how much input 1274193640Sariff * samples that is required to generate requested output, while 1275193640Sariff * z_gx2gy() will be called just before samples filtering / 1276193640Sariff * accumulation process based on available samples that has been 1277193640Sariff * calculated using z_gx2gy(). 1278193640Sariff * 1279193640Sariff * Now that is damn confusing, I guess ;-) . 1280193640Sariff */ 1281193640Sariff gy2gx_max = (((uint64_t)info->z_gy * INT32_MAX) - info->z_gy + 1) / 1282193640Sariff info->z_gx; 1283193640Sariff 1284193640Sariff if ((gy2gx_max * align) > SND_FXDIV_MAX) 1285193640Sariff gy2gx_max = SND_FXDIV_MAX / align; 1286193640Sariff 1287193640Sariff if (gy2gx_max < 1) 1288193640Sariff return (E2BIG); 1289193640Sariff 1290193640Sariff gx2gy_max = (((uint64_t)info->z_gx * INT32_MAX) - info->z_gy) / 1291193640Sariff info->z_gy; 1292193640Sariff 1293193640Sariff if (gx2gy_max > INT32_MAX) 1294193640Sariff gx2gy_max = INT32_MAX; 1295193640Sariff 1296193640Sariff if (gx2gy_max < 1) 1297193640Sariff return (E2BIG); 1298193640Sariff 1299193640Sariff /* 1300193640Sariff * Ensure that z_gy2gx() at its largest possible calculated value 1301193640Sariff * (alpha = 0) will not cause overflow further late during z_gx2gy() 1302193640Sariff * stage. 1303193640Sariff */ 1304193640Sariff if (z_gy2gx(info, gy2gx_max) > _Z_GCAST(gx2gy_max)) 1305193640Sariff return (E2BIG); 1306193640Sariff 1307193640Sariff info->z_maxfeed = gy2gx_max * align; 1308193640Sariff 1309193640Sariff#ifdef Z_USE_ALPHADRIFT 1310193640Sariff info->z_startdrift = z_gy2gx(info, 1); 1311193640Sariff info->z_alphadrift = z_drift(info, info->z_startdrift, 1); 1312193640Sariff#endif 1313193640Sariff 1314193640Sariff i = z_gy2gx(info, 1); 1315193640Sariff info->z_full = z_roundpow2((info->z_size << 1) + i); 1316193640Sariff 1317193640Sariff /* 1318193640Sariff * Too big to be true, and overflowing left and right like mad .. 1319193640Sariff */ 1320193640Sariff if ((info->z_full * align) < 1) { 1321193640Sariff if (adaptive == 0 && Z_IS_SINC(info)) { 1322193640Sariff adaptive = 1; 1323193640Sariff goto z_setup_adaptive_sinc; 1324193640Sariff } 1325193640Sariff return (E2BIG); 1326193640Sariff } 1327193640Sariff 1328193640Sariff /* 1329193640Sariff * Increase full buffer size if its too small to reduce cyclic 1330193640Sariff * buffer shifting in main conversion/feeder loop. 1331193640Sariff */ 1332193640Sariff while (info->z_full < Z_RESERVOIR_MAX && 1333193640Sariff (info->z_full - (info->z_size << 1)) < Z_RESERVOIR) 1334193640Sariff info->z_full <<= 1; 1335193640Sariff 1336193640Sariff /* Initialize buffer position. */ 1337193640Sariff info->z_mask = info->z_full - 1; 1338193640Sariff info->z_start = z_prev(info, info->z_size << 1, 1); 1339193640Sariff info->z_pos = z_next(info, info->z_start, 1); 1340193640Sariff 1341193640Sariff /* 1342193640Sariff * Allocate or reuse delay line buffer, whichever makes sense. 1343193640Sariff */ 1344193640Sariff i = info->z_full * align; 1345193640Sariff if (i < 1) 1346193640Sariff return (E2BIG); 1347193640Sariff 1348193640Sariff if (info->z_delay == NULL || info->z_alloc < i || 1349193640Sariff i <= (info->z_alloc >> 1)) { 1350193640Sariff if (info->z_delay != NULL) 1351193640Sariff free(info->z_delay, M_DEVBUF); 1352193640Sariff info->z_delay = malloc(i, M_DEVBUF, M_NOWAIT | M_ZERO); 1353193640Sariff if (info->z_delay == NULL) 1354193640Sariff return (ENOMEM); 1355193640Sariff info->z_alloc = i; 1356193640Sariff } 1357193640Sariff 1358193640Sariff /* 1359193640Sariff * Zero out head of buffer to avoid pops and clicks. 1360193640Sariff */ 1361193640Sariff memset(info->z_delay, sndbuf_zerodata(f->desc->out), 1362193640Sariff info->z_pos * align); 1363193640Sariff 1364193640Sariff#ifdef Z_DIAGNOSTIC 1365193640Sariff /* 1366193640Sariff * XXX Debuging mess !@#$%^ 1367193640Sariff */ 1368193640Sariff#define dumpz(x) fprintf(stderr, "\t%12s = %10u : %-11d\n", \ 1369193640Sariff "z_"__STRING(x), (uint32_t)info->z_##x, \ 1370193640Sariff (int32_t)info->z_##x) 1371193640Sariff fprintf(stderr, "\n%s():\n", __func__); 1372193640Sariff fprintf(stderr, "\tchannels=%d, bps=%d, format=0x%08x, quality=%d\n", 1373193640Sariff info->channels, info->bps, format, info->quality); 1374193640Sariff fprintf(stderr, "\t%d (%d) -> %d (%d), ", 1375193640Sariff info->src, info->rsrc, info->dst, info->rdst); 1376193640Sariff fprintf(stderr, "[%d/%d]\n", info->z_gx, info->z_gy); 1377193640Sariff fprintf(stderr, "\tminreq=%d, ", z_gy2gx(info, 1)); 1378193640Sariff if (adaptive != 0) 1379193640Sariff z_scale = Z_ONE; 1380193640Sariff fprintf(stderr, "factor=0x%08x/0x%08x (%f)\n", 1381193640Sariff z_scale, Z_ONE, (double)z_scale / Z_ONE); 1382193640Sariff fprintf(stderr, "\tbase_length=%d, ", Z_SINC_BASE_LEN(info)); 1383193640Sariff fprintf(stderr, "adaptive=%s\n", (adaptive != 0) ? "YES" : "NO"); 1384193640Sariff dumpz(size); 1385193640Sariff dumpz(alloc); 1386193640Sariff if (info->z_alloc < 1024) 1387193640Sariff fprintf(stderr, "\t%15s%10d Bytes\n", 1388193640Sariff "", info->z_alloc); 1389193640Sariff else if (info->z_alloc < (1024 << 10)) 1390193640Sariff fprintf(stderr, "\t%15s%10d KBytes\n", 1391193640Sariff "", info->z_alloc >> 10); 1392193640Sariff else if (info->z_alloc < (1024 << 20)) 1393193640Sariff fprintf(stderr, "\t%15s%10d MBytes\n", 1394193640Sariff "", info->z_alloc >> 20); 1395193640Sariff else 1396193640Sariff fprintf(stderr, "\t%15s%10d GBytes\n", 1397193640Sariff "", info->z_alloc >> 30); 1398193640Sariff fprintf(stderr, "\t%12s %10d (min output samples)\n", 1399193640Sariff "", 1400193640Sariff (int32_t)z_gx2gy(info, info->z_full - (info->z_size << 1))); 1401193640Sariff fprintf(stderr, "\t%12s %10d (min allocated output samples)\n", 1402193640Sariff "", 1403193640Sariff (int32_t)z_gx2gy(info, (info->z_alloc / align) - 1404193640Sariff (info->z_size << 1))); 1405193640Sariff fprintf(stderr, "\t%12s = %10d\n", 1406193640Sariff "z_gy2gx()", (int32_t)z_gy2gx(info, 1)); 1407193640Sariff fprintf(stderr, "\t%12s = %10d -> z_gy2gx() -> %d\n", 1408193640Sariff "Max", (int32_t)gy2gx_max, (int32_t)z_gy2gx(info, gy2gx_max)); 1409193640Sariff fprintf(stderr, "\t%12s = %10d\n", 1410193640Sariff "z_gx2gy()", (int32_t)z_gx2gy(info, 1)); 1411193640Sariff fprintf(stderr, "\t%12s = %10d -> z_gx2gy() -> %d\n", 1412193640Sariff "Max", (int32_t)gx2gy_max, (int32_t)z_gx2gy(info, gx2gy_max)); 1413193640Sariff dumpz(maxfeed); 1414193640Sariff dumpz(full); 1415193640Sariff dumpz(start); 1416193640Sariff dumpz(pos); 1417193640Sariff dumpz(scale); 1418193640Sariff fprintf(stderr, "\t%12s %10f\n", "", 1419193640Sariff (double)info->z_scale / Z_ONE); 1420193640Sariff dumpz(dx); 1421193640Sariff fprintf(stderr, "\t%12s %10f\n", "", 1422193640Sariff (double)info->z_dx / info->z_dy); 1423193640Sariff dumpz(dy); 1424193640Sariff fprintf(stderr, "\t%12s %10d (drift step)\n", "", 1425193640Sariff info->z_dy >> Z_SHIFT); 1426193640Sariff fprintf(stderr, "\t%12s %10d (scaling differences)\n", "", 1427193640Sariff (z_scale << Z_DRIFT_SHIFT) - info->z_dy); 1428193640Sariff fprintf(stderr, "\t%12s = %u bytes\n", 1429193640Sariff "intpcm32_t", sizeof(intpcm32_t)); 1430193640Sariff fprintf(stderr, "\t%12s = 0x%08x, smallest=%.16lf\n", 1431193640Sariff "Z_ONE", Z_ONE, (double)1.0 / (double)Z_ONE); 1432193640Sariff#endif 1433193640Sariff 1434167646Sariff return (0); 143575320Scg} 143675320Scg 143775320Scgstatic int 1438193640Sariffz_resampler_set(struct pcm_feeder *f, int what, int32_t value) 143975320Scg{ 1440193640Sariff struct z_info *info; 1441193640Sariff int32_t oquality; 1442148606Snetchild 1443193640Sariff info = f->data; 1444164614Sariff 1445148606Snetchild switch (what) { 1446193640Sariff case Z_RATE_SRC: 1447193640Sariff if (value < feeder_rate_min || value > feeder_rate_max) 1448193640Sariff return (E2BIG); 1449193640Sariff if (value == info->rsrc) 1450193640Sariff return (0); 1451164614Sariff info->rsrc = value; 1452164614Sariff break; 1453193640Sariff case Z_RATE_DST: 1454193640Sariff if (value < feeder_rate_min || value > feeder_rate_max) 1455193640Sariff return (E2BIG); 1456193640Sariff if (value == info->rdst) 1457193640Sariff return (0); 1458164614Sariff info->rdst = value; 1459164614Sariff break; 1460193640Sariff case Z_RATE_QUALITY: 1461193640Sariff if (value < Z_QUALITY_MIN || value > Z_QUALITY_MAX) 1462193640Sariff return (EINVAL); 1463193640Sariff if (value == info->quality) 1464193640Sariff return (0); 1465193640Sariff /* 1466193640Sariff * If we failed to set the requested quality, restore 1467193640Sariff * the old one. We cannot afford leaving it broken since 1468193640Sariff * passive feeder chains like vchans never reinitialize 1469193640Sariff * itself. 1470193640Sariff */ 1471193640Sariff oquality = info->quality; 1472193640Sariff info->quality = value; 1473193640Sariff if (z_resampler_setup(f) == 0) 1474193640Sariff return (0); 1475193640Sariff info->quality = oquality; 1476193640Sariff break; 1477193640Sariff case Z_RATE_CHANNELS: 1478193640Sariff if (value < SND_CHN_MIN || value > SND_CHN_MAX) 1479193640Sariff return (EINVAL); 1480193640Sariff if (value == info->channels) 1481193640Sariff return (0); 1482193640Sariff info->channels = value; 1483193640Sariff break; 1484164614Sariff default: 1485193640Sariff return (EINVAL); 1486193640Sariff break; 1487110108Sorion } 1488193640Sariff 1489193640Sariff return (z_resampler_setup(f)); 149075320Scg} 149175320Scg 149275320Scgstatic int 1493193640Sariffz_resampler_get(struct pcm_feeder *f, int what) 149477266Scg{ 1495193640Sariff struct z_info *info; 149677266Scg 1497193640Sariff info = f->data; 1498193640Sariff 1499148606Snetchild switch (what) { 1500193640Sariff case Z_RATE_SRC: 1501167646Sariff return (info->rsrc); 1502193640Sariff break; 1503193640Sariff case Z_RATE_DST: 1504167646Sariff return (info->rdst); 1505193640Sariff break; 1506193640Sariff case Z_RATE_QUALITY: 1507193640Sariff return (info->quality); 1508193640Sariff break; 1509193640Sariff case Z_RATE_CHANNELS: 1510193640Sariff return (info->channels); 1511193640Sariff break; 1512164614Sariff default: 1513193640Sariff break; 151477266Scg } 1515193640Sariff 1516167646Sariff return (-1); 151777266Scg} 151877266Scg 151977266Scgstatic int 1520193640Sariffz_resampler_init(struct pcm_feeder *f) 152175320Scg{ 1522193640Sariff struct z_info *info; 1523193640Sariff int ret; 152475320Scg 1525193640Sariff if (f->desc->in != f->desc->out) 1526167646Sariff return (EINVAL); 1527164614Sariff 1528193640Sariff info = malloc(sizeof(*info), M_DEVBUF, M_NOWAIT | M_ZERO); 1529113752Sorion if (info == NULL) 1530167646Sariff return (ENOMEM); 1531193640Sariff 1532193640Sariff info->rsrc = Z_RATE_DEFAULT; 1533193640Sariff info->rdst = Z_RATE_DEFAULT; 1534193640Sariff info->quality = feeder_rate_quality; 1535193640Sariff info->channels = AFMT_CHANNEL(f->desc->in); 1536193640Sariff 1537193640Sariff f->data = info; 1538193640Sariff 1539193640Sariff ret = z_resampler_setup(f); 1540193640Sariff if (ret != 0) { 1541193640Sariff if (info->z_pcoeff != NULL) 1542193640Sariff free(info->z_pcoeff, M_DEVBUF); 1543193640Sariff if (info->z_delay != NULL) 1544193640Sariff free(info->z_delay, M_DEVBUF); 1545193640Sariff free(info, M_DEVBUF); 1546193640Sariff f->data = NULL; 1547148606Snetchild } 1548193640Sariff 1549193640Sariff return (ret); 155075320Scg} 155175320Scg 155275320Scgstatic int 1553193640Sariffz_resampler_free(struct pcm_feeder *f) 155475320Scg{ 1555193640Sariff struct z_info *info; 155675320Scg 1557193640Sariff info = f->data; 1558167646Sariff if (info != NULL) { 1559193640Sariff if (info->z_pcoeff != NULL) 1560193640Sariff free(info->z_pcoeff, M_DEVBUF); 1561193640Sariff if (info->z_delay != NULL) 1562193640Sariff free(info->z_delay, M_DEVBUF); 1563193640Sariff free(info, M_DEVBUF); 156475320Scg } 1565193640Sariff 156675320Scg f->data = NULL; 1567193640Sariff 1568167646Sariff return (0); 156975320Scg} 157075320Scg 1571193640Sariffstatic uint32_t 1572193640Sariffz_resampler_feed_internal(struct pcm_feeder *f, struct pcm_channel *c, 1573193640Sariff uint8_t *b, uint32_t count, void *source) 1574109547Sorion{ 1575193640Sariff struct z_info *info; 1576193640Sariff int32_t alphadrift, startdrift, reqout, ocount, reqin, align; 1577193640Sariff int32_t fetch, fetched, start, cp; 1578193640Sariff uint8_t *dst; 1579164614Sariff 1580193640Sariff info = f->data; 1581193640Sariff if (info->z_resample == NULL) 1582193640Sariff return (z_feed(f->source, c, b, count, source)); 1583164614Sariff 1584148606Snetchild /* 1585193640Sariff * Calculate sample size alignment and amount of sample output. 1586193640Sariff * We will do everything in sample domain, but at the end we 1587193640Sariff * will jump back to byte domain. 1588148606Snetchild */ 1589193640Sariff align = info->channels * info->bps; 1590193640Sariff ocount = SND_FXDIV(count, align); 1591193640Sariff if (ocount == 0) 1592167646Sariff return (0); 1593193640Sariff 1594148606Snetchild /* 1595193640Sariff * Calculate amount of input samples that is needed to generate 1596193640Sariff * exact amount of output. 1597148606Snetchild */ 1598193640Sariff reqin = z_gy2gx(info, ocount) - z_fetched(info); 1599193640Sariff 1600193640Sariff#ifdef Z_USE_ALPHADRIFT 1601193640Sariff startdrift = info->z_startdrift; 1602193640Sariff alphadrift = info->z_alphadrift; 1603167646Sariff#else 1604193640Sariff startdrift = _Z_GY2GX(info, 0, 1); 1605193640Sariff alphadrift = z_drift(info, startdrift, 1); 1606167646Sariff#endif 1607193640Sariff 1608193640Sariff dst = b; 1609193640Sariff 1610193640Sariff do { 1611193640Sariff if (reqin != 0) { 1612193640Sariff fetch = z_min(z_free(info), reqin); 1613193640Sariff if (fetch == 0) { 1614193640Sariff /* 1615193640Sariff * No more free spaces, so wind enough 1616193640Sariff * samples back to the head of delay line 1617193640Sariff * in byte domain. 1618193640Sariff */ 1619193640Sariff fetched = z_fetched(info); 1620193640Sariff start = z_prev(info, info->z_start, 1621193640Sariff (info->z_size << 1) - 1); 1622193640Sariff cp = (info->z_size << 1) + fetched; 1623193640Sariff z_copy(info->z_delay + (start * align), 1624193640Sariff info->z_delay, cp * align); 1625193640Sariff info->z_start = 1626193640Sariff z_prev(info, info->z_size << 1, 1); 1627193640Sariff info->z_pos = 1628193640Sariff z_next(info, info->z_start, fetched + 1); 1629193640Sariff fetch = z_min(z_free(info), reqin); 1630193640Sariff#ifdef Z_DIAGNOSTIC 1631193640Sariff if (1) { 1632193640Sariff static uint32_t kk = 0; 1633193640Sariff fprintf(stderr, 1634193640Sariff "Buffer Move: " 1635193640Sariff "start=%d fetched=%d cp=%d " 1636193640Sariff "cycle=%u [%u]\r", 1637193640Sariff start, fetched, cp, info->z_cycle, 1638193640Sariff ++kk); 1639193640Sariff } 1640193640Sariff info->z_cycle = 0; 1641167646Sariff#endif 1642193640Sariff } 1643193640Sariff if (fetch != 0) { 1644193640Sariff /* 1645193640Sariff * Fetch in byte domain and jump back 1646193640Sariff * to sample domain. 1647193640Sariff */ 1648193640Sariff fetched = SND_FXDIV(z_feed(f->source, c, 1649193640Sariff info->z_delay + (info->z_pos * align), 1650193640Sariff fetch * align, source), align); 1651193640Sariff /* 1652193640Sariff * Prepare to convert fetched buffer, 1653193640Sariff * or mark us done if we cannot fulfill 1654193640Sariff * the request. 1655193640Sariff */ 1656193640Sariff reqin -= fetched; 1657193640Sariff info->z_pos += fetched; 1658193640Sariff if (fetched != fetch) 1659193640Sariff reqin = 0; 1660193640Sariff } 1661109547Sorion } 1662193640Sariff 1663193640Sariff reqout = z_min(z_gx2gy(info, z_fetched(info)), ocount); 1664193640Sariff if (reqout != 0) { 1665193640Sariff ocount -= reqout; 1666193640Sariff 1667148606Snetchild /* 1668193640Sariff * Drift.. drift.. drift.. 1669193640Sariff * 1670193640Sariff * Notice that there are 2 methods of doing the drift 1671193640Sariff * operations: The former is much cleaner (in a sense 1672194805Sariff * of mathematical readings of my eyes), but slower 1673194805Sariff * due to integer division in z_gy2gx(). Nevertheless, 1674194805Sariff * both should give the same exact accurate drifting 1675194805Sariff * results, so the later is favourable. 1676148606Snetchild */ 1677193640Sariff do { 1678193640Sariff info->z_resample(info, dst); 1679193640Sariff#if 0 1680193640Sariff startdrift = z_gy2gx(info, 1); 1681193640Sariff alphadrift = z_drift(info, startdrift, 1); 1682193640Sariff info->z_start += startdrift; 1683193640Sariff info->z_alpha += alphadrift; 1684193640Sariff#else 1685193640Sariff info->z_alpha += alphadrift; 1686193640Sariff if (info->z_alpha < info->z_gy) 1687193640Sariff info->z_start += startdrift; 1688193640Sariff else { 1689193640Sariff info->z_start += startdrift - 1; 1690193640Sariff info->z_alpha -= info->z_gy; 1691193640Sariff } 1692167646Sariff#endif 1693193640Sariff dst += align; 1694193640Sariff#ifdef Z_DIAGNOSTIC 1695193640Sariff info->z_cycle++; 1696193640Sariff#endif 1697193640Sariff } while (--reqout != 0); 1698148606Snetchild } 1699193640Sariff } while (reqin != 0 && ocount != 0); 1700164614Sariff 1701193640Sariff /* 1702193640Sariff * Back to byte domain.. 1703193640Sariff */ 1704193640Sariff return (dst - b); 1705193640Sariff} 1706164614Sariff 1707193640Sariffstatic int 1708193640Sariffz_resampler_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b, 1709193640Sariff uint32_t count, void *source) 1710193640Sariff{ 1711193640Sariff uint32_t feed, maxfeed, left; 1712164614Sariff 1713193640Sariff /* 1714193640Sariff * Split count to smaller chunks to avoid possible 32bit overflow. 1715193640Sariff */ 1716193640Sariff maxfeed = ((struct z_info *)(f->data))->z_maxfeed; 1717193640Sariff left = count; 1718193640Sariff 1719193640Sariff do { 1720193640Sariff feed = z_resampler_feed_internal(f, c, b, 1721193640Sariff z_min(maxfeed, left), source); 1722193640Sariff b += feed; 1723193640Sariff left -= feed; 1724193640Sariff } while (left != 0 && feed != 0); 1725193640Sariff 1726193640Sariff return (count - left); 1727109547Sorion} 1728109547Sorion 172975320Scgstatic struct pcm_feederdesc feeder_rate_desc[] = { 1730193640Sariff { FEEDER_RATE, 0, 0, 0, 0 }, 1731193640Sariff { 0, 0, 0, 0, 0 }, 173275320Scg}; 1733164614Sariff 173475320Scgstatic kobj_method_t feeder_rate_methods[] = { 1735193640Sariff KOBJMETHOD(feeder_init, z_resampler_init), 1736193640Sariff KOBJMETHOD(feeder_free, z_resampler_free), 1737193640Sariff KOBJMETHOD(feeder_set, z_resampler_set), 1738193640Sariff KOBJMETHOD(feeder_get, z_resampler_get), 1739193640Sariff KOBJMETHOD(feeder_feed, z_resampler_feed), 1740193640Sariff KOBJMETHOD_END 174175320Scg}; 1742164614Sariff 1743193640SariffFEEDER_DECLARE(feeder_rate, NULL); 1744