+class MorseDistanceModulator(object):
+ def __init__(self, period_min, period_max, pulse_min, pulse_max,
+ inter_symbol_distance):
+ self.set_parameters(period_min, period_max,
+ pulse_min, pulse_max,
+ inter_symbol_distance)
+
+ def set_parameters(self, period_min, period_max, pulse_min, pulse_max,
+ inter_symbol_distance):
+ self.period_min = period_min
+ self.period_max = period_max
+ self.pulse_min = pulse_min
+ self.pulse_max = pulse_max
+ self.inter_symbol_distance = inter_symbol_distance
+
+ self.dot_time = SymbolTime(period_min,
+ period_max, 0,
+ inter_symbol_distance)
+ self.dash_time = SymbolTime(period_min,
+ period_max, 1,
+ inter_symbol_distance)
+ self.signalspace_time = SymbolTime(period_min,
+ period_max, 2,
+ inter_symbol_distance)
+ self.wordspace_time = SymbolTime(period_min,
+ period_max, 3,
+ inter_symbol_distance)
+ self.eom_time = SymbolTime(period_min,
+ period_max, 4,
+ inter_symbol_distance)
+
+ def symbol_to_distance(self, symbol):
+ if symbol == ".":
+ return self.dot_time.dist
+ elif symbol == "-":
+ return self.dash_time.dist
+ elif symbol == " ":
+ return self.signalspace_time.dist
+ elif symbol == "/" or symbol == " / ":
+ return self.wordspace_time.dist
+ elif symbol == "EOM":
+ return self.eom_time.dist
+
+ raise ValueError("Unexpected symbol %s" % symbol)
+
+ def is_same_period(self, distance):
+ return distance > self.pulse_min and distance <= self.pulse_max
+
+ def distance_to_symbol(self, distance):
+ if distance > self.dot_time.min and \
+ distance <= self.dot_time.max:
+ return "."
+
+ if distance > self.dash_time.min and \
+ distance <= self.dash_time.max:
+ return "-"
+
+ if distance > self.signalspace_time.min and \
+ distance <= self.signalspace_time.max:
+ return " "
+
+ if distance > self.wordspace_time.min and \
+ distance <= self.wordspace_time.max:
+ return "/"
+
+ if distance > self.eom_time.min:
+ return "EOM"
+
+ raise ValueError("Unexpected distance %.2f" % distance)
+
+ def modulate(self, morse):
+ signals = morse.split(' ')
+ distances = []
+ for i, signal in enumerate(signals):
+ for symbol in signal:
+ distances.append(self.symbol_to_distance(symbol))
+
+ # Transmit a signal separator only when strictly necessary.
+ #
+ # Avoid it in these cases:
+ # - after the last symbol, because EOM is going to ne transmitted
+ # anyway and that will mark the end of the last symbol.
+ # - between words, because the word separator act as a symbol
+ # separator too.
+ if i != len(signals) - 1 and signals[i + 1] != "/" and signal != "/":
+ distances.append(self.symbol_to_distance(" "))
+
+ distances.append(self.symbol_to_distance("EOM"))
+
+ # Since the Morse signals are encoded in the distance between calls, an
+ # extra call is needed in order for receiver actually get the EOM and
+ # see that the transmission has terminated.
+ distances.append(0)
+
+ return distances
+
+
+def log_symbol(distance, symbol, extra_info=""):
+ logging.info("distance: %.2f Received \"%s\"%s", distance, symbol,
+ extra_info)
+
+