package de.tu.darmstadt.seemoo.ansian.model.demodulation; import android.util.Log; import de.tu.darmstadt.seemoo.ansian.model.SamplePacket; import de.tu.darmstadt.seemoo.ansian.model.filter.ComplexFirFilter; public abstract class SSB extends Demodulation { private ComplexFirFilter bandPassFilter = null; // used for SSB demodulation private static final int BAND_PASS_ATTENUATION = 40; private static int userFilterCutOff = 0; // DEMODULATION private float lastMax = 0; // used for gain control in AM / SSB demodulation private String LOGTAG = "SSB"; /** * Will SSB demodulate the samples in input. 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 * @param upperBand * if true: USB; if false: LSB */ protected void demodulateSSB(SamplePacket input, SamplePacket output, boolean upperBand) { float[] reOut = output.getRe(); // complex band pass: if (bandPassFilter == null || (upperBand && (((int) bandPassFilter.getHighCutOffFrequency()) != userFilterCutOff)) || (!upperBand && (((int) bandPassFilter.getLowCutOffFrequency()) != -userFilterCutOff))) { // We have to (re-)create the band pass filter: this.bandPassFilter = ComplexFirFilter.createBandPass(2, // Decimate // by 2; // => // AUDIO_RATE 1, input.getSampleRate(), upperBand ? 200f : -userFilterCutOff, upperBand ? userFilterCutOff : -200f, input.getSampleRate() * 0.01f, BAND_PASS_ATTENUATION); if (bandPassFilter == null) return; // This may happen if input samples changed rate or // demodulation was turned off. Just skip the filtering. Log.d(LOGTAG, "demodulateSSB: created new band pass filter with " + bandPassFilter.getNumberOfTaps() + " taps. Decimation=" + bandPassFilter.getDecimation() + " Low-Cut-Off=" + bandPassFilter.getLowCutOffFrequency() + " High-Cut-Off=" + bandPassFilter.getHighCutOffFrequency() + " transition=" + bandPassFilter.getTransitionWidth()); } output.setSize(0); // mark buffer as empty if (bandPassFilter.filter(input, output, 0, input.size()) < input.size()) { Log.e(LOGTAG, "demodulateSSB: could not filter all samples from input packet."); } // gain control: searching for max: lastMax *= 0.95; // simplest AGC for (int i = 0; i < output.size(); i++) { if (reOut[i] > lastMax) lastMax = reOut[i]; } // normalize values: float gain = 0.75f / lastMax; for (int i = 0; i < output.size(); i++) reOut[i] *= gain; } }