Какой формат требуется структуре модуля?

#python #struct

Вопрос:

Я впервые столкнулся со структурой модуля, и мой код выдает мне ошибку: «для распаковки требуется буфер размером 1486080 байт» Вот мой код:

 def speed_up(n):
source = wave.open('sound.wav', mode='rb')
dest = wave.open('out.wav', mode='wb')
dest.setparams(source.getparams())
frames_count = source.getnframes()
data = struct.unpack("<"   str(frames_count)   "h", source.readframes(frames_count))
new_data = []
for i in range(0, len(data), n):
    new_data.append(data[i])
newframes = struct.pack('<'   str(len(new_data))   'h', new_data)
dest.writeframes(newframes)
source.close()
dest.close()
 

Как определить, какой формат мне следует использовать?

Комментарии:

1. Вы проверили тип и размер объекта, который вы передаете unpack ?

2. @interjay, Да, я проверил, тип — «байты», размер — «2972193». Теперь я вижу свою ошибку — значение frames_count равно 743040, и формат не соответствовал буферу. Я попытался установить формат как ‘ Не могли бы вы сказать мне, пожалуйста, почему размер буфера и размер формата в данном случае не равны?

3. Этот размер для меня не имеет смысла, потому что он не делится на 2. Ошибка, которую вы получили при распаковке, предполагает, что это не фактический размер объекта bytes.

4. Извините, теперь я получил фактический размер с помощью ‘sys.getsizeof(source.readframes(frames_count))’, размер составляет 33 байта. Но в любом случае я не могу понять, какой формат мне следует использовать.

5. getsizeof почти никогда не бывает полезным. Вы можете получить фактическую длину данных с len помощью . Вам необходимо учитывать ширину выборки wav-файла (которая указывает , в каком формате использовать struct.unpack , и количество каналов (количество выборок на кадр).

Ответ №1:

Проблема в вашем коде заключается в том, что вы предоставляете struct.unpack неправильное количество байтов. Это связано с использованием wave вами модуля: каждый кадр в файле волны содержит getnchannels() образцы, поэтому при вызове readframes(n) вы получите n * getnchannels() образцы, и это номер, на который вам нужно будет перейти struct.unpack .

Чтобы сделать ваш код более надежным, вам также нужно будет изучить getsampwidth() и использовать соответствующий символ формата, но подавляющее большинство файлов wave 16-разрядные.

В комментариях вы также упомянули, что код не работал после добавления print(len(source.readframes(frames_count))) . Вы не показали полный код , но я предполагаю, что это связано с тем, что вы readframes дважды звонили без вызова rewind , поэтому во втором звонке больше не было данных для возврата. Было бы лучше сохранить результат в переменной, если вы хотите использовать его в нескольких строках.