/* * Represent Morse code symbols using time intervals * * Copyright (C) 2015 Antonio Ospite * * 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 . */ package it.ao2.util.morse; import java.util.List; import java.util.Vector; public class MorseDistanceModulator { public static final double DEFAULT_PERIOD_MIN = 7; public static final double DEFAULT_PERIOD_MAX = 16.5; public static final double DEFAULT_PULSE_MIN = 4.9; public static final double DEFAULT_PULSE_MAX = 5.2; public static final double DEFAULT_INTER_SYMBOL_DISTANCE = DEFAULT_PULSE_MAX; private double mPeriodMin; private double mPeriodMax; private double mPulseMin; private double mPulseMax; private SymbolTime mDotTime; private SymbolTime mDashTime; private SymbolTime mSignalspaceTime; private SymbolTime mWordspaceTime; private SymbolTime mEOMTime; private class SymbolTime { private double dist; private double min; private double max; SymbolTime(double periodMin, double periodMax, double multiplier, double minInterSymbolDistance) { if (multiplier < 0) { throw new IllegalArgumentException("multiplier must me non-negative"); } if (periodMin == periodMax && minInterSymbolDistance == 0) { throw new IllegalArgumentException("If (periodMin == periodMax) a non zero " + "inter-symbol distance MUST be specified"); } double symbolDistance = 2 * (periodMax - periodMin); if (symbolDistance == 0) { symbolDistance = minInterSymbolDistance; } dist = minInterSymbolDistance + symbolDistance * multiplier; min = minInterSymbolDistance + periodMin + symbolDistance * multiplier; max = minInterSymbolDistance + periodMin + symbolDistance * (multiplier + 1); } SymbolTime(double periodMin, double periodMax, double multiplier) { this(periodMin, periodMax, multiplier, 0.0); } public double getDist() { return dist; } public double getMin() { return min; } public double getMax() { return max; } } public MorseDistanceModulator() { setParameters(DEFAULT_PERIOD_MIN, DEFAULT_PERIOD_MAX, DEFAULT_PULSE_MIN, DEFAULT_PULSE_MAX, DEFAULT_INTER_SYMBOL_DISTANCE); } public void setParameters(double newPeriodMin, double newPeriodMax, double newPulseMin, double newPulseMax, double interSymbolDistance) { mPeriodMin = newPeriodMin; mPeriodMax = newPeriodMax; mPulseMin = newPulseMin; mPulseMax = newPulseMax; mDotTime = new SymbolTime(mPeriodMin, mPeriodMax, 0, interSymbolDistance); mDashTime = new SymbolTime(mPeriodMin, mPeriodMax, 1, interSymbolDistance); mSignalspaceTime = new SymbolTime(mPeriodMin, mPeriodMax, 2, interSymbolDistance); mWordspaceTime = new SymbolTime(mPeriodMin, mPeriodMax, 3, interSymbolDistance); mEOMTime = new SymbolTime(mPeriodMin, mPeriodMax, 4, interSymbolDistance); } public double getPeriod() { return mPeriodMax; } public double symbolToDistance(String symbol) { switch (symbol) { case ".": return mDotTime.getDist(); case "-": return mDashTime.getDist(); case " ": return mSignalspaceTime.getDist(); case "/": case " / ": return mWordspaceTime.getDist(); case "EOM": return mEOMTime.getDist(); default: throw new IllegalArgumentException("Invalid Morse Symbol: " + symbol); } } // Multiple pulses in the same period public boolean isSamePeriod(double pulseDistance) { return (pulseDistance > mPulseMin && pulseDistance <= mPulseMax); } public String distanceToSymbol(double distance) { if (distance > mDotTime.getMin() && distance <= mDotTime.getMax()) { return "."; } else if (distance > mDashTime.getMin() && distance <= mDashTime.getMax()) { return "-"; } else if (distance > mSignalspaceTime.getMin() && distance <= mSignalspaceTime.getMax()) { return " "; } else if (distance > mWordspaceTime.getMin() && distance <= mWordspaceTime.getMax()) { return "/"; } else if (distance > mEOMTime.getMin()) { return "EOM"; } throw new IllegalArgumentException("Unexpected distance: " + distance); } public List modulate(String morse) { List distances = new Vector(); String[] signals = morse.split(" "); for (int i = 0; i < signals.length; i++) { String signal = signals[i]; double distance; for (int j = 0; j < signal.length(); j++) { String symbol = Character.toString(signal.charAt(j)); distance = symbolToDistance(symbol); distances.add(distance); } if (i != (signals.length - 1) && !signal.equals("/") && !signals[i + 1].equals("/")) { distance = symbolToDistance(" "); distances.add(distance); } } distances.add(symbolToDistance("EOM")); distances.add(0.0); return distances; } }