// http://en.wikipedia.org/wiki/High-pass_filter void DspHighpassFilter::processDspToIndex(float blockIndex) { float *inputBuffer = localDspBufferAtInlet[0]; float *outputBuffer = localDspBufferAtOutlet[0]; int startSampleIndex = getStartSampleIndex(); int endSampleIndex = getEndSampleIndex(blockIndex); if (ArrayArithmetic::hasAccelerate) { #if __APPLE__ const int duration = endSampleIndex - startSampleIndex; const int durationBytes = duration * sizeof(float); memcpy(filterInputBuffer+2, inputBuffer+startSampleIndex, durationBytes); vDSP_deq22(filterInputBuffer, 1, coefficients, filterOutputBuffer, 1, duration); memcpy(outputBuffer+startSampleIndex, filterOutputBuffer+2, durationBytes); memcpy(filterInputBuffer, filterInputBuffer+duration, 2 * sizeof(float)); memcpy(filterOutputBuffer, filterOutputBuffer+duration, 2 * sizeof(float)); #endif } else { outputBuffer[startSampleIndex] = alpha * (tapOut + inputBuffer[startSampleIndex] - tapIn); for (int i = startSampleIndex+1; i < endSampleIndex; i++) { outputBuffer[i] = alpha * (outputBuffer[i-1] + inputBuffer[i] - inputBuffer[i-1]); } tapIn = inputBuffer[endSampleIndex-1]; tapOut = outputBuffer[endSampleIndex-1]; } blockIndexOfLastMessage = blockIndex; }
/******************************************************************************* BiquadFilterProcess */ Error_t BiquadFilterProcess(BiquadFilter *filter, float *outBuffer, const float *inBuffer, unsigned n_samples) { #ifdef __APPLE__ // Use accelerate if we have it float coeffs[5] = { filter->b[0], filter->b[1], filter->b[2], filter->a[0], filter->a[1] }; float temp_in[n_samples + 2]; float temp_out[n_samples + 2]; // Put filter overlaps into beginning of input and output vectors cblas_scopy(2, filter->x, 1, temp_in, 1); cblas_scopy(2, filter->y, 1, temp_out, 1); cblas_scopy(n_samples, inBuffer, 1, (temp_in + 2), 1); // Process vDSP_deq22(temp_in, 1, coeffs, temp_out, 1, n_samples); // Write overlaps to filter x and y arrays cblas_scopy(2, (temp_in + n_samples), 1, filter->x, 1); cblas_scopy(2, (temp_out + n_samples), 1, filter->y, 1); // Write output cblas_scopy(n_samples, (temp_out + 2), 1, outBuffer, 1); #else float 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 CopyBuffer(outBuffer, buffer, n_samples); #endif return NOERR; }
void DspLowpassFilter::processDspWithIndex(int fromIndex, int toIndex) { switch (signalPrecedence) { case MESSAGE_MESSAGE: { ArrayArithmetic::fill(dspBufferAtOutlet0, signalConstant, fromIndex, toIndex); // allow fallthrough } case DSP_MESSAGE: { #if __APPLE__ const int duration = toIndex - fromIndex; float filterInputBuffer[duration+2]; filterInputBuffer[0] = filterInputBuffer[1] = 0.0f; memcpy(filterInputBuffer+2, dspBufferAtInlet0+fromIndex, duration * sizeof(float)); float filterOutputBuffer[duration+2]; filterOutputBuffer[0] = 0.0f; filterOutputBuffer[1] = tap_0; // vDSP_deq22 = // out[i] = coeff[0]*in[i] + coeff[1]*in[i-1] + coeff[2]*in[i-2] - coeff[3]*out[i-1] - coeff[4]*out[i-2] vDSP_deq22(filterInputBuffer, 1, coefficients, filterOutputBuffer, 1, duration); memcpy(dspBufferAtOutlet0+fromIndex, filterOutputBuffer+2, duration * sizeof(float)); // retain last output tap_0 = dspBufferAtOutlet0[toIndex-1]; #else ArrayArithmetic::multiply(dspBufferAtInlet0, alpha, dspBufferAtOutlet0, fromIndex, toIndex); dspBufferAtOutlet0[fromIndex] += beta * tap_0; for (int i = fromIndex+1; i < toIndex; i++) { dspBufferAtOutlet0[i] += beta * dspBufferAtOutlet0[i-1]; } tap_0 = dspBufferAtOutlet0[toIndex-1]; #endif break; } case MESSAGE_DSP: case DSP_DSP: default: { break; } } }