forked from cduck/morse
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmorse.py
executable file
·127 lines (111 loc) · 4.23 KB
/
morse.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#!/usr/bin/env python3
import numpy as np
from morseTable import forwardTable, DOT, DASH, DASH_WIDTH, CHAR_SPACE, WORD_SPACE
def letterToMorse(letter):
if letter in forwardTable:
return forwardTable[letter]
elif letter.isspace():
return ' '
else:
return ''
def stringToMorse(string):
codeArr = [letterToMorse(l) for l in string.upper()]
trimmedArr = [code for code in codeArr if code]
return ' '.join(trimmedArr)
def morseSampleDuration(code, sps, wpm, fs=None):
dps = wpmToDps(wpm) # dots per second
baseSampleCount = sps/dps
samplesPerDot = int(round(baseSampleCount))
samplesPerDash = int(round(baseSampleCount * DASH_WIDTH))
samplesBetweenElements = int(round(baseSampleCount))
farnsworthScale = farnsworthScaleFactor(wpm, fs)
samplesBetweenLetters = int(round(baseSampleCount * CHAR_SPACE * farnsworthScale))
samplesBetweenWords = int(round(baseSampleCount * WORD_SPACE * farnsworthScale))
dotArr = np.ones(samplesPerDot, dtype=np.bool_)
dashArr = np.ones(samplesPerDash, dtype=np.bool_)
eGapArr = np.zeros(samplesBetweenElements, dtype=np.bool_)
cGapArr = np.zeros(samplesBetweenLetters, dtype=np.bool_)
wGapArr = np.zeros(samplesBetweenWords, dtype=np.bool_)
duration = 0
prevSpaces = 0
prevWasElement = False
for c in code:
if (c == DOT or c == DASH) and prevWasElement:
duration += samplesBetweenElements
if c == DOT:
duration += samplesPerDot
prevSpaces, prevWasElement = 0, True
elif c == DASH:
duration += samplesPerDash
prevSpaces, prevWasElement = 0, True
else: # Assume the char is a space otherwise
if prevSpaces == 1:
duration += samplesBetweenWords-samplesBetweenLetters
elif prevSpaces == 0:
duration += samplesBetweenLetters
prevSpaces += 1
prevWasElement = False
return duration
def morseToBoolArr(code, sps, wpm, fs=None):
dps = wpmToDps(wpm) # dots per second
baseSampleCount = sps/dps
samplesPerDot = int(round(baseSampleCount))
samplesPerDash = int(round(baseSampleCount * DASH_WIDTH))
samplesBetweenElements = int(round(baseSampleCount))
farnsworthScale = farnsworthScaleFactor(wpm, fs)
samplesBetweenLetters = int(round(baseSampleCount * CHAR_SPACE * farnsworthScale))
samplesBetweenWords = int(round(baseSampleCount * WORD_SPACE * farnsworthScale))
dotArr = np.ones(samplesPerDot, dtype=np.bool_)
dashArr = np.ones(samplesPerDash, dtype=np.bool_)
eGapArr = np.zeros(samplesBetweenElements, dtype=np.bool_)
cGapArr = np.zeros(samplesBetweenLetters, dtype=np.bool_)
wGapArr = np.zeros(samplesBetweenWords, dtype=np.bool_)
pieces = []
prevWasSpace = False
prevWasElement = False
for c in code:
if (c == DOT or c == DASH) and prevWasElement:
pieces.append(eGapArr)
if c == DOT:
pieces.append(dotArr)
prevWasSpace, prevWasElement = False, True
elif c == DASH:
pieces.append(dashArr)
prevWasSpace, prevWasElement = False, True
else: # Assume the char is a space otherwise
if prevWasSpace:
pieces[-1] = wGapArr
else:
pieces.append(cGapArr)
prevWasSpace, prevWasElement = True, False
return np.concatenate(pieces)
def wpmToDps(wpm):
''' Words per minute = number of times PARIS can be sent per minute.
PARIS takes 50 dot lengths to send. Returns dots per seconds. '''
return wpm*50/60.0
def farnsworthScaleFactor(wpm, fs=None):
''' Returns the multiple that character and word spacing should be multiplied by. '''
if fs is None:
return 1 # Standard (not Farnsworth) word spacing
slowWordInterval = 1.0/fs # Minutes per word
standardWordInterval = 1.0/wpm
extraSpace = slowWordInterval-standardWordInterval
extraSpaceDots = (extraSpace/standardWordInterval) * (9+10+4*DASH_WIDTH+4*CHAR_SPACE+WORD_SPACE)
standardSpaceDots = 4*CHAR_SPACE + WORD_SPACE # For the word PARIS
totalSpaceDots = standardSpaceDots + extraSpaceDots
scaleFactor = totalSpaceDots / standardSpaceDots
if scaleFactor < 1:
return 1
return scaleFactor
if __name__ == '__main__':
import sys
if len(sys.argv) >= 2:
message = ' '.join(sys.argv[1:])
print(stringToMorse(message))
else:
try:
while True:
message = input()
print(stringToMorse(message))
except EOFError:
pass