void AVFEqualizerBand::ApplyFilter(double *inSource, double *inDest, int frameCount, int channel) {
    if (mBypass && mEQ->GetSampleRate() > 0.0) {
        // Have a sample rate now, can recalculate
        RecalculateParams();
    }

    if (mBypass || channel < 0) {
        return;
    }

    // We may have more channels now than when we were initialized
    if (channel > mChannels) {
        mChannels = mEQ->GetChannelCount();
        SetChannelCount(mChannels);
    }

    if (mChannels > 0 && mHistory != NULL) {
        // copy source and dest history
        inSource[1] = mHistory[channel].x1;
        inSource[0] = mHistory[channel].x2;
        inDest[1] = mHistory[channel].y1;
        inDest[0] = mHistory[channel].y2;

        vDSP_deq22D(inSource, 1, mCoefficients, inDest, 1, frameCount);

        // update history
        mHistory[channel].x1 = inSource[frameCount+1];
        mHistory[channel].x2 = inSource[frameCount];
        mHistory[channel].y1 = inDest[frameCount+1];
        mHistory[channel].y2 = inDest[frameCount];
    }
}
Exemple #2
0
t_int *myObj_perform(t_int *w) {
	t_myObj *x = (t_myObj*)(w[1]);
	float	*in= (float *)(w[2]);
	float	*out= (float *)(w[3]);
	int		vs = w[4];
	int		k;
	double	*outfilt = x->outfilt;
	double	*infilt = x->infilt;
	double	*xms = x->xms;
	double	*yms = x->yms;
	int		poles2 = x->poles >> 1; 	//each biquad can calc 2 poles (and 2 zeros)
	
	
	if(!x->inputconnected || x->b_ob.z_disabled)
		return w+5;
	
	// copy input and use outfilt for that (this is so the recursion works)
	/*
	for(i=0; i<vs; i++) {
		outfilt[i+2] = in[i];
	}*/
	vDSP_vspdp(in, 1, outfilt+2, 1, vs);
	
	for(k=0; k<poles2; k++) {
		
		// restore last two input samps 
		infilt[0] = xms[k*2];	
		infilt[1] = xms[k*2+1];
		// copy from outfilt to infilt (recursion)
		memcpy(infilt+2, outfilt+2, vs*sizeof(double));
		
		// restore last two output samps
		outfilt[0] = yms[k*2];
		outfilt[1] = yms[k*2+1];
		
		// do the biquad!
		vDSP_deq22D(infilt, 1, x->coeffs+(k*5), outfilt, 1, vs);
		
		// save last two input & output samples for next vector
		xms[k*2] = infilt[vs];
		xms[k*2+1] = infilt[vs+1];
		yms[k*2] = outfilt[vs];
		yms[k*2+1] = outfilt[vs+1];
	}
	
	// TODO: check for denormals???
	/*
	for(i=0; i<vs; i++) {
		out[i] = outfilt[i+2];
	}*/
	vDSP_vdpsp(outfilt+2, 1, out, 1, vs);
	
	return w+5;		
}
Exemple #3
0
Error_t
BiquadFilterProcessD(BiquadFilterD  *filter,
                     double         *outBuffer,
                     const double   *inBuffer,
                     unsigned       n_samples)
{

#ifdef __APPLE__
    // Use accelerate if we have it
    double coeffs[5] = {
        filter->b[0], filter->b[1], filter->b[2],
        filter->a[0], filter->a[1]
    };
    double temp_in[n_samples + 2];
    double temp_out[n_samples + 2];


    // Put filter overlaps into beginning of input and output vectors
    cblas_dcopy(2, filter->x, 1, temp_in, 1);
    cblas_dcopy(2, filter->y, 1, temp_out, 1);
    cblas_dcopy(n_samples, inBuffer, 1, (temp_in + 2), 1);

    // Process
    vDSP_deq22D(temp_in, 1, coeffs, temp_out, 1, n_samples);

    // Write overlaps to filter x and y arrays
    cblas_dcopy(2, (temp_in + n_samples), 1, filter->x, 1);
    cblas_dcopy(2, (temp_out + n_samples), 1, filter->y, 1);

    // Write output
    cblas_dcopy(n_samples, (temp_out + 2), 1, outBuffer, 1);


#else

    double buffer[n_samples];
    for (unsigned buffer_idx = 0; buffer_idx < n_samples; ++buffer_idx)
    {

        // DF-II Implementation
        buffer[buffer_idx] = filter->b[0] * inBuffer[buffer_idx] + filter->w[0];
        filter->w[0] = filter->b[1] * inBuffer[buffer_idx] - filter->a[0] * \
        buffer[buffer_idx] + filter->w[1];
        filter->w[1] = filter->b[2] * inBuffer[buffer_idx] - filter->a[1] * \
        buffer[buffer_idx];

    }

    // Write output
    CopyBufferD(outBuffer, buffer, n_samples);

#endif
    return NOERR;
}
Exemple #4
0
void Biquad::processSliceFast(double* sourceP, double* destP, double* coefficientsP, size_t framesToProcess)
{
    // Use double-precision for filter stability
    vDSP_deq22D(sourceP, 1, coefficientsP, destP, 1, framesToProcess);

    // Save history.  Note that sourceP and destP reference m_inputBuffer and m_outputBuffer respectively.
    // These buffers are allocated (in the constructor) with space for two extra samples so it's OK to access
    // array values two beyond framesToProcess.
    sourceP[0] = sourceP[framesToProcess - 2 + 2];
    sourceP[1] = sourceP[framesToProcess - 1 + 2];
    destP[0] = destP[framesToProcess - 2 + 2];
    destP[1] = destP[framesToProcess - 1 + 2];
}
Exemple #5
0
void myObj_perform64(t_myObj *x, t_object *dsp64, double **ins, long numins, 
					 double **outs, long numouts, long sampleframes, long flags, void *userparam)
{
	t_double *in= ins[0];
	t_double *out= outs[0];
	int vs = sampleframes;
	int		k;
	double	*outfilt = x->outfilt;
	double	*infilt = x->infilt;
	double	*xms = x->xms;
	double	*yms = x->yms;
	int		poles2 = x->poles >> 1; 	//each biquad can calc 2 poles (and 2 zeros)

	
	if(!x->inputconnected || x->b_ob.z_disabled)
		return;
	
	// copy input and use outfilt for that (this is so the recursion works)
	memcpy(outfilt+2, in, vs*sizeof(double));		// dest, source, len

	for(k=0; k<poles2; k++) {
		
		// restore last two input samps 
		infilt[0] = xms[k*2];	
		infilt[1] = xms[k*2+1];
		// copy from outfilt to infilt (recursion)
		memcpy(infilt+2, outfilt+2, vs*sizeof(double));
		
		// restore last two output samps
		outfilt[0] = yms[k*2];
		outfilt[1] = yms[k*2+1];
		
		// do the biquad!
		vDSP_deq22D(infilt, 1, x->coeffs+(k*5), outfilt, 1, vs);
		
		// save last two input & output samples for next vector
		xms[k*2] = infilt[vs];
		xms[k*2+1] = infilt[vs+1];
		yms[k*2] = outfilt[vs];
		yms[k*2+1] = outfilt[vs+1];
	}
	
	// TODO: check for denormals???
	memcpy(out, outfilt+2, sizeof(double)*vs);
	
	
	// old version
	/*
	for(i=0; i<vs; i++) {
		
		input = *in++;
		output = 0;
		
		for(k=0; k<poles2; k++) {
			k2 = k<<1; k3 = k*3;
			
			 //output = input * a[k3] + xx[k2]*a[k3+1] + xx[k2+1]*a[k3+2]
			 //+ yy[k2]*b[k3+1] + yy[k2+1]*b[k3+2];	// biquad
			 
			ffw = input * a[k3] + xx[k2]*a[k3+1] + xx[k2+1]*a[k3+2];		// zeros
			fb =  yy[k2]*b[k3+1] + yy[k2+1]*b[k3+2];					// poles
			FIX_DENORM_DOUBLE(fb);
			output = ffw + fb;
			xx[k2+1] = xx[k2];
			xx[k2] = input;
			
			yy[k2+1] = yy[k2];
			yy[k2] = output;
			input = output;
			
		}
		*out++ = output;
	}*/
	
}