mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
Fleetsync II decoder to use it. Adds instrumented version of the decoder and a new Fleetsync2 FX pane to the DemodulatorViewerFX tool. Note: the remaining AFSK-1200 based decoders will all be ported to use this new AFSK1200 decoder (MDC1200, Tait1200, LowJack1200).
123 lines
4.9 KiB
Java
123 lines
4.9 KiB
Java
/*******************************************************************************
|
|
* sdr-trunk
|
|
* Copyright (C) 2014-2018 Dennis Sheirer
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
|
|
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
|
|
* later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with this program.
|
|
* If not, see <http://www.gnu.org/licenses/>
|
|
*
|
|
******************************************************************************/
|
|
package io.github.dsheirer.dsp.afsk;
|
|
|
|
import io.github.dsheirer.buffer.FloatAveragingBuffer;
|
|
import io.github.dsheirer.dsp.mixer.IOscillator;
|
|
import io.github.dsheirer.dsp.mixer.Oscillator;
|
|
import io.github.dsheirer.sample.complex.Complex;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.text.DecimalFormat;
|
|
|
|
public class AFSKTest
|
|
{
|
|
private final static Logger mLog = LoggerFactory.getLogger(AFSK1200Decoder.class);
|
|
|
|
private static final DecimalFormat df = new DecimalFormat("00.000");
|
|
|
|
public static String format(double value)
|
|
{
|
|
if(value > 0)
|
|
{
|
|
return " " + df.format(value);
|
|
}
|
|
else
|
|
{
|
|
return df.format(value);
|
|
}
|
|
}
|
|
|
|
public static float[] generateAFSK1200(boolean[] symbols, int samplesPerSymbol, float gain)
|
|
{
|
|
float[] samples = new float[symbols.length * samplesPerSymbol];
|
|
|
|
Oscillator oscillator = new Oscillator(1200.0, (double)samplesPerSymbol * 1200);
|
|
|
|
for(int x = 0; x < symbols.length; x++)
|
|
{
|
|
oscillator.setFrequency(symbols[x] ? 1200.0 : 1800.0);
|
|
|
|
for(int y = 0; y < samplesPerSymbol; y++)
|
|
{
|
|
Complex sample = new Complex(oscillator.inphase(), oscillator.quadrature());
|
|
sample.multiply(gain);
|
|
samples[x * samplesPerSymbol + y] = sample.inphase();
|
|
oscillator.rotate();
|
|
}
|
|
}
|
|
|
|
return samples;
|
|
}
|
|
|
|
public static void main(String[] args)
|
|
{
|
|
int sampleSize = 6;
|
|
|
|
FloatAveragingBuffer avg1200 = new FloatAveragingBuffer(sampleSize);
|
|
FloatAveragingBuffer avg1800 = new FloatAveragingBuffer(sampleSize);
|
|
|
|
IOscillator oscillator1200 = new Oscillator(1200.0, 7200.0);
|
|
IOscillator oscillator1800 = new Oscillator(1800.0, 7200.0);
|
|
oscillator1200.generateReal(1);
|
|
oscillator1800.generateReal(1);
|
|
|
|
float[] reference1200 = oscillator1200.generateReal(sampleSize);
|
|
float[] reference1800 = oscillator1800.generateReal(sampleSize);
|
|
|
|
boolean[] symbols = new boolean[]{true,false,true,false,true,false,true,false,true,true,true,false,true,false,
|
|
false,false,true,false,false,false,false,true,false,true,true,true,true,false,true,true,false,true,false,
|
|
true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,
|
|
false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,
|
|
true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,
|
|
false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,
|
|
true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,
|
|
false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,true,false,
|
|
true,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,
|
|
false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false};
|
|
|
|
float[] samples = generateAFSK1200(symbols, 6, 0.5f);
|
|
|
|
mLog.debug("Length:" + samples.length);
|
|
|
|
int offset = 0;
|
|
|
|
float correlation1200 = 0.0f;
|
|
float correlation1800 = 0.0f;
|
|
|
|
while(offset + sampleSize < samples.length)
|
|
{
|
|
correlation1200 = 0.0f;
|
|
correlation1800 = 0.0f;
|
|
|
|
for(int x = 0; x < sampleSize; x++)
|
|
{
|
|
correlation1200 += reference1200[x] * samples[x + offset];
|
|
correlation1800 += reference1800[x] * samples[x + offset];
|
|
}
|
|
|
|
correlation1200 = avg1200.get(Math.abs(correlation1200));
|
|
correlation1800 = avg1800.get(Math.abs(correlation1800));
|
|
|
|
mLog.debug(offset + " 1200:" + format(correlation1200) + " 1800:" + format(correlation1800) +
|
|
" Decision: " + (correlation1200 > correlation1800 ? "0" : "1"));
|
|
|
|
offset++;
|
|
}
|
|
}
|
|
}
|