2 * Represent Morse code symbols using time intervals
4 * Copyright (C) 2015 Antonio Ospite <ao2@ao2.it>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 package it.ao2.util.morse;
22 import java.util.List;
23 import java.util.Vector;
25 public class MorseDistanceModulator {
26 public static final double DEFAULT_PERIOD_MIN = 7;
27 public static final double DEFAULT_PERIOD_MAX = 16.5;
28 public static final double DEFAULT_PULSE_MIN = 4.9;
29 public static final double DEFAULT_PULSE_MAX = 5.2;
30 public static final double DEFAULT_INTER_SYMBOL_DISTANCE = DEFAULT_PULSE_MAX;
32 private double mPeriodMin;
33 private double mPeriodMax;
34 private double mPulseMin;
35 private double mPulseMax;
37 private SymbolTime mDotTime;
38 private SymbolTime mDashTime;
39 private SymbolTime mSignalspaceTime;
40 private SymbolTime mWordspaceTime;
41 private SymbolTime mEOMTime;
43 private class SymbolTime {
48 SymbolTime(double periodMin, double periodMax, double multiplier,
49 double minInterSymbolDistance) {
51 throw new IllegalArgumentException("multiplier must me non-negative");
53 if (periodMin == periodMax && minInterSymbolDistance == 0) {
54 throw new IllegalArgumentException("If (periodMin == periodMax) a non zero "
55 + "inter-symbol distance MUST be specified");
58 double symbolDistance = 2 * (periodMax - periodMin);
59 if (symbolDistance == 0) {
60 symbolDistance = minInterSymbolDistance;
63 dist = minInterSymbolDistance + symbolDistance * multiplier;
64 min = minInterSymbolDistance + periodMin + symbolDistance * multiplier;
65 max = minInterSymbolDistance + periodMin + symbolDistance * (multiplier + 1);
68 SymbolTime(double periodMin, double periodMax, double multiplier) {
69 this(periodMin, periodMax, multiplier, 0.0);
72 public double getDist() {
76 public double getMin() {
80 public double getMax() {
85 public MorseDistanceModulator() {
86 setParameters(DEFAULT_PERIOD_MIN,
90 DEFAULT_INTER_SYMBOL_DISTANCE);
93 public void setParameters(double newPeriodMin,
97 double interSymbolDistance) {
98 mPeriodMin = newPeriodMin;
99 mPeriodMax = newPeriodMax;
100 mPulseMin = newPulseMin;
101 mPulseMax = newPulseMax;
103 mDotTime = new SymbolTime(mPeriodMin, mPeriodMax, 0, interSymbolDistance);
104 mDashTime = new SymbolTime(mPeriodMin, mPeriodMax, 1, interSymbolDistance);
105 mSignalspaceTime = new SymbolTime(mPeriodMin, mPeriodMax, 2, interSymbolDistance);
106 mWordspaceTime = new SymbolTime(mPeriodMin, mPeriodMax, 3, interSymbolDistance);
107 mEOMTime = new SymbolTime(mPeriodMin, mPeriodMax, 4, interSymbolDistance);
110 public double getPeriod() {
114 public double symbolToDistance(String symbol) {
117 return mDotTime.getDist();
119 return mDashTime.getDist();
121 return mSignalspaceTime.getDist();
124 return mWordspaceTime.getDist();
126 return mEOMTime.getDist();
128 throw new IllegalArgumentException("Invalid Morse Symbol: " + symbol);
132 // Multiple pulses in the same period
133 public boolean isSamePeriod(double pulseDistance) {
134 return (pulseDistance > mPulseMin && pulseDistance <= mPulseMax);
137 public String distanceToSymbol(double distance) {
138 if (distance > mDotTime.getMin() && distance <= mDotTime.getMax()) {
140 } else if (distance > mDashTime.getMin() && distance <= mDashTime.getMax()) {
142 } else if (distance > mSignalspaceTime.getMin() && distance <= mSignalspaceTime.getMax()) {
144 } else if (distance > mWordspaceTime.getMin() && distance <= mWordspaceTime.getMax()) {
146 } else if (distance > mEOMTime.getMin()) {
150 throw new IllegalArgumentException("Unexpected distance: " + distance);
153 public List<Double> modulate(String morse) {
154 List<Double> distances = new Vector<Double>();
156 String[] signals = morse.split(" ");
157 for (int i = 0; i < signals.length; i++) {
158 String signal = signals[i];
160 for (int j = 0; j < signal.length(); j++) {
161 String symbol = Character.toString(signal.charAt(j));
162 distance = symbolToDistance(symbol);
163 distances.add(distance);
165 if (i != (signals.length - 1) && !signal.equals("/") && !signals[i + 1].equals("/")) {
166 distance = symbolToDistance(" ");
167 distances.add(distance);
170 distances.add(symbolToDistance("EOM"));