I am moving a filter that currently uses the vDSP vdSP function for Apple (Accelerate) vDSP_deq22 for Android (where acceleration is not available). A filter block is a set of band-pass filters, each of which returns an RMS value for its respective band. Currently, the code (ObjectiveC ++ adapted from NVDSP) is as follows:
- (float) filterContiguousData: (float *)data numFrames:(UInt32)numFrames channel:(UInt32)channel {
As you can see here , deq22 implements a biquad filter on a given input vector through a recursive function. This is a description of the function from the docs: 
- A =: real input vector with one precision
- IA =: Stride for A.
- B =: 5 inputs with one precision (filter coefficients), in increments of 1.
- C =: real output vector with one precision.
- IC =: Stride for C.
- N =: number of new output elements to create.
This is what I have so far (this is in Swift, like the rest of the code base that I already ran on Android):
// N is fixed on init to be the same size as buffer.count, below // 'input' and 'output' are initialised with (N+2) length and filled with 0s func getFilteredRMSMagnitudeFromBuffer(var buffer: [Float]) -> Float { let inputStride = 1 // hardcoded for now let outputStride = 1 input[0] = input[N] input[1] = input[N+1] output[0] = output[N] output[1] = output[N+1] // copy the current buffer into input input[2 ... N+1] = buffer[0 ..< N] // Not sure if this is neccessary, just here to duplicate NVDSP behaviour: output[2 ... N+1] = [Float](count: N, repeatedValue: 0)[0 ..< N] // Again duplicating NVDSP behaviour, can probably just start at 0: var sumOfSquares = (input[0] * input[0]) + (input[1] * input[1]) for n in (2 ... N+1) { let sumG = (0...2).reduce(Float(0)) { total, p in return total + input[(n - p) * inputStride] * coefficients[p] } let sumH = (3...4).reduce(Float(0)) { total, p in return total + output[(n - p + 2) * outputStride] * coefficients[p] } let filteredFrame = sumG - sumH output[n] = filteredFrame sumOfSquares = filteredFrame * filteredFrame } let meanSquare = sumOfSquares / Float(N + 2) // we added 2 values by hand, before the loop let rootMeanSquare = sqrt(meanSquare) return rootMeanSquare }
The filter gives a different output signal for deq22, although it apparently has a circular circular βnoiseβ in it (with a constant input tone, this frequency measures up and down).
I have verified that the coefficient arrays are identical between each implementation. It seems that each filter "works" in that it selects the correct frequency (and only this frequency), it is just this pumping, and that the output power of the RMS is much quieter than vDSP, often in order:
Naive | vDSP 3.24305e-06 0.000108608 1.57104e-06 5.53645e-05 1.96445e-06 4.33506e-05 2.05422e-06 2.09781e-05 1.44778e-06 1.8729e-05 4.28997e-07 2.72648e-05
Can anyone see a problem with my logic?
Edit: here is a video of the gif result with a constant tone of 440 Hz. The various green bars are separate filter bands. The third range (shown here) is the one that is tuned to 440 Hz.

The NVDSP version displays a constant (non-fluctuating) value, proportional to the input volume, as expected.