package de.tu.darmstadt.seemoo.ansian.model.demodulation; import de.tu.darmstadt.seemoo.ansian.control.threads.Demodulator; import de.tu.darmstadt.seemoo.ansian.model.SamplePacket; public class FM extends Demodulation { private int deviation; private SamplePacket demodulatorHistory; private DemoType type; public FM(DemoType type) { this.type = type; switch (type) { case WFM: MIN_USER_FILTER_WIDTH = 50000; MAX_USER_FILTER_WIDTH = 120000; deviation = 75000; quadratureRate = 8 * Demodulator.AUDIO_RATE; break; case NFM: deviation = 5000; MIN_USER_FILTER_WIDTH = 3000; MAX_USER_FILTER_WIDTH = 15000; break; default: // throw new WrongDemodulationTypeException(); } } /** * Will FM demodulate the samples in input. Use ~75000 deviation for wide * band FM and ~3000 deviation for narrow band FM. Demodulated samples are * stored in the real array of output. Note: All samples in output will * always be overwritten! * * @param input * incoming (modulated) samples * @param output * outgoing (demodulated) samples */ @Override public void demodulate(SamplePacket input, SamplePacket output) { float[] reIn = input.getRe(); float[] imIn = input.getIm(); float[] reOut = output.getRe(); float[] imOut = output.getIm(); int inputSize = input.size(); float quadratureGain = quadratureRate / (2 * (float) Math.PI * deviation); if (demodulatorHistory == null) { demodulatorHistory = new SamplePacket(1); demodulatorHistory.getRe()[0] = reIn[0]; demodulatorHistory.getIm()[0] = reOut[0]; } // Quadrature demodulation: reOut[0] = reIn[0] * demodulatorHistory.re(0) + imIn[0] * demodulatorHistory.im(0); imOut[0] = imIn[0] * demodulatorHistory.re(0) - reIn[0] * demodulatorHistory.im(0); reOut[0] = quadratureGain * (float) Math.atan2(imOut[0], reOut[0]); for (int i = 1; i < inputSize; i++) { reOut[i] = reIn[i] * reIn[i - 1] + imIn[i] * imIn[i - 1]; imOut[i] = imIn[i] * reIn[i - 1] - reIn[i] * imIn[i - 1]; reOut[i] = quadratureGain * (float) Math.atan2(imOut[i], reOut[i]); } demodulatorHistory.getRe()[0] = reIn[inputSize - 1]; demodulatorHistory.getIm()[0] = imIn[inputSize - 1]; output.setSize(inputSize); output.setSampleRate(quadratureRate); } @Override public DemoType getType() { return type; } }