使用 wave 模块在 2GB WAV 文件中搜索 dropouts
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()
不会,但根本不使用范围帮助更多。
并使用 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 秒的块读取文件。
`使用 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()
不会,但根本不使用范围帮助更多。
并使用 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 秒的块读取文件。