Я провел некоторое исследование по этой теме для проекта, над которым я работаю, и столкнулся с несколькими проблемами с предоставленным решением, а именно, метод определения молчания является неправильным. «Более правильной» реализацией будет:
import struct
import wave
wave_file = wave.open("sound_file.wav", "r")
for i in range(wave_file.getnframes()):
# read a single frame and advance to next frame
current_frame = wave_file.readframes(1)
# check for silence
silent = True
# wave frame samples are stored in little endian**
# this example works for a single channel 16-bit per sample encoding
unpacked_signed_value = struct.unpack("<h", current_frame) # *
if abs(unpacked_signed_value[0]) > 500:
silent = False
if silent:
print "Frame %s is silent." % wave_file.tell()
else
print "Frame %s is not silent." % wave_file.tell()
Ссылки и полезные ссылки
*Struct Unpacking
здесь будет полезно: https://docs.python.org/2/library/struct.html
** Хорошая ссылка, которую я нашел для объяснения формата волновых файлов для работы с битовыми кодировками разного размера и несколькими каналами: http://www.piclist.com/techref/io/serial/midi/wave.html
Использование встроенной функции ord () в Python для первого элемента строкового объекта, возвращаемого методом readframes (x), будет работать некорректно.
Другим ключевым моментом является то, что многоканальное аудио чередуется, и поэтому для работы с каналами требуется немного дополнительной логики. Опять же, ссылка выше подробно описывает это.
Надеюсь, это поможет кому-то в будущем.
Вот некоторые наиболее важные моменты из ссылки и то, что я нашел полезным.
Организация данных
Все данные хранятся в 8-битных байтах в формате Intel 80x86 (т.е. с прямым порядком байтов). Байты многобайтовых значений сначала сохраняются младшими (то есть наименее значимыми) байтами. Биты данных имеют следующий вид (т. Е. Показаны с номерами бит вверху):
7 6 5 4 3 2 1 0
+-----------------------+
char: | lsb msb |
+-----------------------+
7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8
+-----------------------+-----------------------+
short: | lsb byte 0 | byte 1 msb |
+-----------------------+-----------------------+
7 6 5 4 3 2 1 0 15 14 13 12 11 10 9 8 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24
+-----------------------+-----------------------+-----------------------+-----------------------+
long: | lsb byte 0 | byte 1 | byte 2 | byte 3 msb |
+-----------------------+-----------------------+-----------------------+-----------------------+
Чередование
Для многоканальных звуков (например, стереофонического сигнала) чередуются отдельные точки выборки из каждого канала. Например, предположим стереофоническую (т.е. двухканальную) форму волны. Вместо того, чтобы сначала сохранить все точки выборки для левого канала, а затем сохранить все точки выборки для правого канала, вы «смешиваете» точки выборки двух каналов вместе. Вы бы сохранили первую точку выборки левого канала. Далее вы должны сохранить первую точку выборки правого канала. Далее вы должны сохранить вторую точку выборки левого канала. Затем вы должны сохранить вторую точку выборки правого канала и т. Д., Чередуя хранение следующей точки выборки каждого канала. Это то, что подразумевается под чередованными данными; Вы сохраняете следующую точку выборки каждого из каналов по очереди, так что точки выборки, которые должны быть «воспроизведены» (т.е. отправлены в ЦАП) одновременно, сохраняются непрерывно.