2014-09-23 77 views
2

我創建了一個將英語句子轉換爲莫爾斯碼的莫爾斯碼生成器。它還將這種基於摩爾斯電碼的文本轉換爲音頻文件。如果字符是dot,則在輸出波形文件後附加一個dot.wave文件,如果下一個字符是dash,則附加dash.wav文件。在Python中讀取波形文件

我現在想要打開這個波形文件並閱讀它的內容來找出這些破折號和點的排列順序。

我曾嘗試下面的代碼:

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)

我不知道該怎麼做這個輸出。誰能幫忙?

+1

想象一下繪製它,你會看到一個波。聲音是波浪。您可能想要查看波浪振幅的變化情況,並記錄振幅和基點之間每次顯着變化之間需要花費多少時間,無論它是點還是虛線。 – icktoofay 2014-09-23 19:04:44

+0

嘿!謝謝回覆。當談到這件事時,我真的是一個新手。你能否詳細解釋一下? – 2014-09-23 19:07:55

+1

@GauravKeswani:如果你沒有理解這個概念,不要只是想象繪製它,而是要繪製它。如果你不知道如何使用'matplotlib',只需將這些幀導出到一個巨大的單列CSV文件中,在Excel/LibreOffice/Numbers /中打開它,然後繪製它。然後,您可以直觀地看到點,破折號和空格是什麼樣子,並開始考慮一種算法來區分它們。 – abarnert 2014-09-23 19:09:07

回答

0

如果要檢測莫爾斯電碼的通用解決方案,你將不得不看看是什麼樣子的波形(tom10的鏈接this question應該幫助在這裏如果你可以安裝numpymatplotlib;如果沒有,您可以使用stdlib的csv模塊來導出您可以在您喜歡的電子表格程序中使用的文件);研究你作爲一個人如何區分點,破折號和空格;把它變成一個算法(一系列的步驟,甚至一個文字頭腦的蠢蛋都可以遵循);然後將該算法轉換爲代碼。或者你也許能夠找到一個已經爲你完成的圖書館。

但是對於您的特定情況,您只需要在較大的文件中檢測到dot.wavdash.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):] 

我們確保我們的緩衝區中至少有兩條破折號。在緩衝區中的第一個點或短劃線(如果找到的話)或整個短劃線的長度(如果沒有)之後,我們總是保留剩餘的剩餘長度,並添加下一個緩衝區。這實際上是過度的;仔細考慮並仔細考慮你所需要的,以確保我們不會錯過落在兩個緩衝區之間的破折號。但重點是,只要你做對了,你就不會錯過任何點或破折號。