go-dsp icon indicating copy to clipboard operation
go-dsp copied to clipboard

Arctan-less Frequency Demodulation

Open bemasher opened this issue 10 years ago • 0 comments

Have you given any thought to implementing a frequency demodulator that doesn't require atan2? The trigonometric calculations can be avoided by calculating the time-derivative of atan(imag(i)/real(i)):

png

Which simplifies out to something like:

func Discriminate(in []complex64, out []float32) {
        for idx := range out {
                n := in[idx]    // n
                np := in[idx+1] // n'

                out[idx] = -(real(n)*imag(np) - imag(n)*real(np)) / (real(n)*real(n) + imag(n)*imag(n))
        }
}
BenchmarkPolarDiscriminator32-4 10000000               140 ns/op
BenchmarkFMDemodulation-4           5000            349066 ns/op          11.73 MB/s
BenchmarkFMDemodulation_Go-4        3000            572701 ns/op           7.15 MB/s
BenchmarkDiscriminate-4             5000            337096 ns/op          12.15 MB/s

Where input is of length n+1 and output of length n.

I've compared this with your implementation on an RPi2 and the code go generates for ARM (GOARM=7) is slightly faster than your optimized assembly version. I imagine there's some room for improvement if this was implemented in asm.

bemasher avatar Dec 31 '15 04:12 bemasher