python - 用结构重建我的波形文件

标签 python audio struct

我的目标是读取波形文件并通过在 -1 到 1 范围内的每一位数据中添加一个随机数来编辑它的数据,希望产生一些失真,然后将其保存为编辑后的波形文件。我像这样阅读和编辑波形文件:

riffTag = fileIn.read(4)
if riffTag != 'RIFF':
    print 'not a valid RIFF file'
    exit(1)

riffLength = struct.unpack('<L', fileIn.read(4))[0]
riffType = fileIn.read(4)
if riffType != 'WAVE':
    print 'not a WAV file'
    exit(1)

# now read children
while fileIn.tell() < 8 + riffLength:
    tag = fileIn.read(4)
    length = struct.unpack('<L', fileIn.read(4))[0]

    if tag == 'fmt ':  # format element
        fmtData = fileIn.read(length)
        fmt, numChannels, sampleRate, byteRate, blockAlign, bitsPerSample = struct.unpack('<HHLLHH', fmtData)
        stHeaderFields['AudioFormat'] = fmt
        stHeaderFields['NumChannels'] = numChannels
        stHeaderFields['SampleRate'] = sampleRate
        stHeaderFields['ByteRate'] = byteRate
        stHeaderFields['BlockAlign'] = blockAlign
        stHeaderFields['BitsPerSample'] = bitsPerSample

    elif tag == 'data': # data element
        rawData = fileIn.read(length)

    else: # some other element, just skip it
        fileIn.seek(length, 1)

numChannels = stHeaderFields['NumChannels']

# some sanity checks
assert(stHeaderFields['BitsPerSample'] == 16)
assert(numChannels * stHeaderFields['BitsPerSample'] == blockAlign * 8)

samples = []
edited_samples = []

for offset in range(0, len(rawData), blockAlign):
    samples.append(struct.unpack('<h', rawData[offset:offset+blockAlign]))

for sample in samples:
    edited_samples.append(sample[0] + random.randint(-1, 1))

完成此操作后,我尝试通过执行以下操作将数据保存为新编辑的波形文件:
foo = []
for sample in edited_samples:
    foo.append(struct.pack('<h', int(sample)))

with open(fileIn.name + ' edited.wav', 'w') as file_out:
    file_out.write('RIFF')
    file_out.write(struct.pack('<L', riffLength))
    file_out.write('WAVE')
    file_out.write(ur'fmt\u0020')
    file_out.write(struct.pack('<H', fmt))
    file_out.write(struct.pack('<H', numChannels))
    file_out.write(struct.pack('<L', sampleRate))
    file_out.write(struct.pack('<L', byteRate))
    file_out.write(struct.pack('<H', blockAlign))
    file_out.write(struct.pack('<H', bitsPerSample))
    file_out.write('data')
    for item in foo:
        file_out.write(item)

虽然它没有给我任何错误,但我无法在媒体播放器中播放新的波形文件。当我尝试打开我的新波形文件时,fmt, numChannels, sampleRate, byteRate, blockAlign, bitsPerSample = struct.unpack('<HHLLHH', fmtData) 行出现崩溃。出现错误 error: unpack requires a string argument of length 16 .我想我正在构建错误的波形文件。如何正确构建它?

最佳答案

除非您出于某些其他原因(获得处理二进制文件的经验等)打算自己编写对 .wav 文件的支持,否则不要这样做。 Python 自带 wave 处理所有文件格式问题并让您只处理数据的模块。

关于python - 用结构重建我的波形文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27424712/

相关文章:

python - 如何更改日期时间分辨率

iPhone超声波检测(超过22kHz)

c++ - Arduino/C++ : Access specific header file of structs from library

c - 在 .m 文件中访问作为全局变量的结构

c - 为什么我的文件输出被覆盖?

python - Python 会在完成写入之前打开文件吗?

python - 在Google App Engine中寻找与python混合使用的openid + oauth混合的良好示例/模板

Python:如何从 script2 运行 script1 并在 script2 中复制 script1 的输出(stdout、stderr)以进行日志记录(到文件中)

javascript - 从音频文件输入创建MediaElementSource?

android - MediaRecorder.prepare() 异常 - 没有这样的文件或目录