使用波形模块分析音频丢失的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()
答案 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秒的方式读取文件。