使用波形模块搜索2GB WAV文件以获取丢失

时间:2016-08-01 19:45:10

标签: python wav

使用波形模块分析音频丢失的2GB WAV文件(1khz Tone)的最佳方法是什么?我试过下面的剧本

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()

3 个答案:

答案 0 :(得分:1)

我认为一个简单的解决方案是考虑音频文件的帧速率非常高。我的计算机上的示例文件恰好具有8,000的帧速率。这意味着对于每秒音频,我有8,000个样本。如果您丢失了音频,我确信它会在一秒钟内存在多个帧,因此您可以根据标准允许的方式大幅减少您的比较。如果我是你,我会尝试迭代每1000个样本而不是音频文件中的每个样本。这基本上意味着它将检查每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()

答案 1 :(得分:1)

目前,您正在将整个文件读入内存,这并不理想。如果你看一下" 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()

希望这有帮助!

答案 2 :(得分:1)

之前我没有使用过wave模块,但是file1.readframes(i)看起来像是在第一帧时读取1帧,在第二帧时读取2帧,10当你处于第十帧时帧,2Gb CD质量文件可能有一百万帧 - 当你在帧100,000帧读取100,000帧时......每次循环也变慢?

根据我的评论,在Python 2中range()首先生成一个完整大小的内存数组,xrange()没有,但是根本不使用范围有助于更多。

使用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秒的方式读取文件。