Files
sdrtrunk/src/main/java/io/github/dsheirer/dsp/afsk/AFSKTest.java
Denny 9dda1f95a1 [WIP] Creates a new AFSK-1200 correlation decoder and updates the
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).
2018-06-09 08:17:18 -04:00

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++;
}
}
}