我创建了一个莫尔斯代码生成器,可将英语句子转换为莫尔斯代码。它还将基于文本的莫尔斯代码转换为音频文件。如果字符是dot
,我会将dot.wave
文件附加到输出wave文件,如果下一个字符是dash.wav
,则会附加dash
文件。
我现在想打开这个wave文件并阅读其内容,以确定这些破折号和点的放置顺序。
我尝试过以下代码:
waveFile = wave.open(r"C:\Users\Gaurav Keswani\Documents\Eclipse\Morse Code Converter\src\resources\sound\morse.wav", 'r')
x =waveFile.readframes(20)
print (struct.unpack("<40H", x))
这给出了输出:
(65089,65089,3093,3093,11895,11895,18629,18629,25196,25196, 29325,29325,31986,31986,32767,32767,31265,31265,27532,27532, 22485,22485,15762,15762,7895,7895,103,103,57228,57228,49571, 49571,42790,42790,37667,37667,34362,34362,32776,32776)
我不知道该输出的内容。有人可以帮忙吗?
答案 0 :(得分:0)
如果你想要一个通用的解决方案来检测摩尔斯电码,你将不得不看看它看起来像波形(tom10&this question的链接应该有帮助,如果你能安装numpy
和matplotlib
;如果没有,您可以使用stdlib的csv
模块导出您可以在您喜欢的电子表格程序中使用的文件);弄清楚你作为一个人如何区分点,破折号和空格;把它变成一个算法(即使是文字头脑的白痴也可以遵循的一系列步骤);然后将该算法转换为代码。或者您可以找到一个已经为您完成此操作的图书馆。
但是对于您的具体情况,您只需要检测较大文件中dot.wav
和dash.wav
内容的确切副本。 (至少假设你没有使用任何有损压缩,通常你不在.wav文件中。)所以,这实际上只是一个子串搜索。
考虑如何在'dot'
之类的字符串中检测字符串'dash'
和'dash dash dash dash dash dot dash dot dot dot dot dot '
。对于这样一个简单的问题,你可以使用一个愚蠢的暴力算法,它会很好:
def find(haystack, needle, start):
for i in range(start, len(haystack)):
if haystack[i:i+len(needle)] == needle:
return i
return len(haystack)
def decode_morse(morse):
i = 0
while i < len(morse):
next_dot = find(morse, 'dot', i)
next_dash = find(morse, 'dash', i)
if next_dot < next_dash:
if next_dot < len(morse):
yield '.'
i = next_dot
else:
if next_dash < len(morse):
yield '-'
i = next_dash
现在,如果您正在搜索数字列表而不是字符串,那么这又如何改变?几乎没有;你可以切片列表,比较两个列表等,就像你可以用字符串一样。
您遇到的唯一真正问题是,您不能同时将整个列表放在内存中,一次只有20帧。如果dot
在第19帧开始并在第20帧结束,会发生什么?如果你的文件不是太大,这很容易解决:只需将所有帧读入一个巨大的列表中的内存,然后搜索整个文件。但除此之外,你必须做一些缓冲。
例如(忽略错误处理并正确处理文件的结尾,并且为了简单起见仅处理破折号 - 当然,您必须在实际代码中正确地执行这两个操作):
buf = []
while True:
while len(buf) < 2*len(dash):
buf.extend(waveFile.readFrames(20))
next_dash = find(buf, dot)
if next_dash < len(buf):
yield '.'
buf = buf[next_dash:]
else:
buf = buf[-len(dash):]
我们确保在缓冲区中始终至少有两个短划线长度。并且我们总是在缓冲区中的第一个点或短划线(如果找到一个)或完整的短划线长度(如果没有)之后保留剩余部分,并将下一个缓冲区添加到该缓冲区。这实际上是矫枉过正;仔细思考并仔细思考你需要什么,以确保我们永远不会错过两个缓冲区之间的破折号。但问题是,只要你做对了,你就不会错过任何点或破折号。