2014-12-11 3 views
0

Моя цель - прочитать волновой файл и отредактировать его данные, добавив случайное число к каждому биту данных в диапазоне от -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. Я думаю, что я неправильно создаю волновой файл. Как его правильно построить?

ответ

0

Если вы не намерены писать поддержку WAV-файлов самостоятельно по какой-то другой причине (получать опыт работы с бинарными файлами и т. Д.), Не делайте этого. Python поставляется с модулем wave, который обрабатывает все проблемы с форматом файлов и позволяет вам просто работать с данными.

+0

Я не могу использовать волновую библиотеку печально, так как мой менеджер проекта хочет, чтобы я расширил этот проект позже, чтобы работать с файлами ЭКГ, которые похожи на аудиофайлы. Это должно быть сделано с бинарными, к сожалению. – Nanor

+0

А, это имеет смысл. Довольно точно *, что * не входит в стандартную библиотеку lib. :) – bgporter

Смежные вопросы