簡體   English   中英

使用wave模塊在2GB WAV文件中搜索輟學

[英]search a 2GB WAV file for dropouts using wave module

`使用wave模塊分析2GB WAV文件(1khz音頻)是否存在音頻丟失的最佳方法是什么? 我嘗試了以下腳本

import wave
file1 = wave.open("testdropout.wav", "r")
file2 = open("silence.log", "w")
for i in xrange(file1.getnframes()):
  frame = file1.readframes(i)

  zero = True

  for j in xrange(len(frame)):
      # check if amplitude is greater than 0
      # the ord() function converts the hex values to integers
    if ord(frame[j]) > 0:
      zero = False
      break

    if zero:
      print >> file2, 'dropout at second %s' % (file1.tell()/file1.getframerate())
file1.close()
file2.close()

我認為解決此問題的簡單方法是考慮音頻文件的幀率很高。 我的計算機上的樣本文件恰好具有8,000的幀率。 這意味着每秒鍾音頻,我就有8,000個樣本。 如果您缺少音頻,我相信它會在一秒鍾之內跨多個幀存在,因此您可以在標准允許的范圍內大幅度減少比較。 如果您是我,我將嘗試遍歷第1,000個樣本,而不是音頻文件中的每個樣本。 這基本上意味着它將每隔1/8秒的音頻檢查一次,看是否已消失。 不夠精確,但希望它能完成工作。

import wave

file1 = wave.open("testdropout.wav", "r")
file2 = open("silence.log", "w")
for i in range(file1.getnframes()):
  frame = file1.readframes(i)

  zero = True

  for j in range(0, len(frame), 1000):
      # check if amplitude is greater than 0
      # the ord() function converts the hex values to integers
    if ord(frame[j]) > 0:
      zero = False
      break

    if zero:
      print >> file2, 'dropout at second %s' % (file1.tell()/file1.getframerate())

file1.close()
file2.close()

目前,您正在將整個文件讀入內存,這並不理想。 如果查看“ Wave_read”對象可用的方法,則其中之一是setpos(pos) ,該方法將文件指針的位置設置為pos 如果更新此位置,則應該只能在任何給定時間將所需的幀保留在內存中,以防止發生錯誤。 下面是一個粗略的概述:

import wave

file1 = wave.open("testdropout.wav", "r")
file2 = open("silence.log", "w")

def scan_frame(frame):
    for j in range(len(frame)):
        # check if amplitude is less than 0
        # It makes more sense here to check for the desired case (low amplitude) 
        # rather than breaking at higher amplitudes 
        if ord(frame[j]) <= 0:
            return True

for i in range(file1.getnframes()):
    frame = file1.readframes(1) # only read the frame at the current file position

    zero = scan_frame(frame)

    if zero:
       print >> file2, 'dropout at second %s' % (file1.tell()/file1.getframerate())

    pos = file1.tell()  # States current file position
    file1.setpos(pos + len(frame)) # or pos + 1, or whatever a single unit in a wave 
                                   # file is, I'm not entirely sure

file1.close()
file2.close()

希望這會有所幫助!

我以前沒有使用過wave模塊,但是file1.readframes(i)看起來像是在第一幀時讀取1幀,在第二幀時讀取2幀,在進入時讀取10幀。第十幀,而一個2Gb CD質量文件可能有一百萬幀-到您達到100,000幀時讀取100,000幀時...每次循環的速度都變慢了嗎?

根據我的評論,在Python 2中, range()生成一個完整大小的內存數組,而xrange()不會,但完全不使用range會更有幫助。

並使用any()將循環向下推至較低層,以使代碼更短,甚至可能更快:

import wave

file1 = wave.open("testdropout.wav", "r")
file2 = open("silence.log", "w")

chunksize = file1.getframerate()
chunk = file1.readframes(chunksize)

while chunk:
  if not any(ord(sample) for sample in chunk):
    print >> file2, 'dropout at second %s' % (file1.tell()/chunksize)

  chunk = file1.readframes(chunksize)

file1.close()
file2.close()

這應該以1秒的塊讀取文件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM