/**
 * 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);
}
Example #2
0
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;
}