/** * Initialize a resampler object * * @param rs Resampler to initialize */ void auresamp_init(struct auresamp *rs) { if (!rs) return; memset(rs, 0, sizeof(*rs)); fir_reset(&rs->fir); }
struct fir_filter * fir_init(const float *taps, size_t length) { struct fir_filter *filt; filt = calloc(1, sizeof(filt[0])); if (!filt) { perror("calloc"); return NULL; } /* Filter state is a sliding window implemented with 2 copies of data */ filt->i = calloc(2 * length, sizeof(filt->i[0])); if (!filt->i) { perror("calloc"); fir_deinit(filt); return NULL; } filt->q = calloc(2 * length, sizeof(filt->q[0])); if (!filt->i) { perror("calloc"); fir_deinit(filt); return NULL; } filt->taps = calloc(length, sizeof(filt->taps[0])); if (!filt->taps) { perror("calloc"); fir_deinit(filt); return NULL; } memcpy(filt->taps, taps, length * sizeof(filt->taps[0])); filt->length = length; fir_reset(filt); return filt; }
/** * Configure a resampler object * * @note The sample rate ratio must be an integer * * @param rs Resampler * @param irate Input sample rate * @param ich Input channel count * @param orate Output sample rate * @param och Output channel count * * @return 0 if success, otherwise error code */ int auresamp_setup(struct auresamp *rs, uint32_t irate, unsigned ich, uint32_t orate, unsigned och) { if (!rs || !irate || !ich || !orate || !och) return EINVAL; if (orate == irate && och == ich) { auresamp_init(rs); return 0; } if (orate >= irate) { if (orate % irate) return ENOTSUP; if (ich == 1 && och == 1) rs->resample = upsample_mono2mono; else if (ich == 1 && och == 2) rs->resample = upsample_mono2stereo; else if (ich == 2 && och == 1) rs->resample = upsample_stereo2mono; else if (ich == 2 && och == 2) rs->resample = upsample_stereo2stereo; else return ENOTSUP; if (!rs->up || orate != rs->orate || och != rs->och) fir_reset(&rs->fir); rs->ratio = orate / irate; rs->up = true; if (orate == 48000 && irate == 16000) { rs->tapv = fir_48_8; rs->tapc = ARRAY_SIZE(fir_48_8); } else { rs->tapv = fir_48_4; rs->tapc = ARRAY_SIZE(fir_48_4); } } else { if (irate % orate) return ENOTSUP; if (ich == 1 && och == 1) rs->resample = downsample_mono2mono; else if (ich == 1 && och == 2) rs->resample = downsample_mono2stereo; else if (ich == 2 && och == 1) rs->resample = downsample_stereo2mono; else if (ich == 2 && och == 2) rs->resample = downsample_stereo2stereo; else return ENOTSUP; if (rs->up || irate != rs->irate || ich != rs->ich) fir_reset(&rs->fir); rs->ratio = irate / orate; rs->up = false; if (irate == 48000 && orate == 16000) { rs->tapv = fir_48_8; rs->tapc = ARRAY_SIZE(fir_48_8); } else { rs->tapv = fir_48_4; rs->tapc = ARRAY_SIZE(fir_48_4); } } rs->orate = orate; rs->och = och; rs->irate = irate; rs->ich = ich; return 0; }