Python 使用wave模块搜索2GB WAV文件以查找辍学者
`使用wave模块分析2GB WAV文件(1khz音调)音频丢失的最佳方法是什么?我试过下面的脚本Python 使用wave模块搜索2GB WAV文件以查找辍学者,python,wav,Python,Wav,`使用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)):
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()
我认为一个简单的解决办法是考虑音频文件的帧速率很高。我计算机上的一个示例文件的帧率恰好为8000。这意味着每秒钟的音频,我有8000个样本。如果您缺少音频,我相信它将在一秒钟内跨多个帧存在,因此您可以在标准允许的范围内大幅减少比较。如果我是你,我会尝试迭代每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()
目前,您正在将整个文件读入内存,这并不理想。如果您查看“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()
导入波
file1=wave.open(“testdropout.wav”、“r”)
file2=打开(“silent.log”,“w”)
def扫描_帧(帧):
对于范围内的j(透镜(帧)):
#检查振幅是否小于0
#在这里,检查所需情况(低振幅)更有意义
#而不是在更高的振幅下断裂
如果ord(frame[j])>file2,'在第二个%s%%处退出(file1.tell()/file1.getframerate())
pos=file1.tell()#表示当前文件位置
file1.setpos(pos+len(frame))或pos+1,或任何波形中的单个单元
#文件是,我不完全确定
file1.close()
file2.close()
希望这能有所帮助 我以前没有使用过
wave
模块,但是file1.readframes(I)
看起来它在第一帧读取1帧,在第二帧读取2帧,在第十帧读取10帧,一个2Gb CD质量的文件可能有一百万帧-当你在第100000帧读取100000帧时。。。每次循环都会变慢吗
从我的评论来看,在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秒为单位读取文件。无论如何,您没有联机的示例文件吗?哪种版本的Python?在2.x中,使用
xrange()
而不是range()
作为开始。我在哪里检查振幅是否大于0?@sam我昨天看到你的评论说这不起作用,我在这里测试了一个随机的.wav文件,但不确定它是否是同一种退出。这个测试是any(ord(sample)表示块中的sample)
-一个生成器,它使用ord()
将从磁盘读取的所有值转换为数字,Python中的数字转换为True/False,如下所示:0->False,其他任何值->True。因此,如果任何样本大于0,则any()
将返回True。如果它们都为0,则为False。这可能就是问题所在——只有在整个第二个页面都处于静默状态时才会打印。可能任何(不是ord(样本)…)
?