Мне нужно проанализировать звук, записанный в файле .wav. Для этого мне нужно преобразовать этот файл в набор чисел (например, в массивы). Думаю, мне нужно использовать волновой пакет. Однако я не знаю, как именно это работает. Например, я сделал следующее:
import wave
w = wave.open('/usr/share/sounds/ekiga/voicemail.wav', 'r')
for i in range(w.getnframes()):
frame = w.readframes(i)
print frame
В результате этого кода я ожидал увидеть звуковое давление как функцию времени. Напротив, я вижу много странных, загадочных символов (которые не являются шестнадцатеричными числами). Кто-нибудь может мне с этим помочь?
data
является NumPy массив 2-D так ,data.shape
возвращает кортеж (num_samples, num_channels)Используя
struct
модуль , вы можете взять кадры волны (которые находятся в дополнительном двоичном коде 2 между -32768 и 32767 (т.е.0x8000
и0x7FFF
). Он читает файл MONO, 16-BIT, WAVE. Я нашел эту веб-страницу весьма полезной для формулировки этого:import wave, struct wavefile = wave.open('sine.wav', 'r') length = wavefile.getnframes() for i in range(0, length): wavedata = wavefile.readframes(1) data = struct.unpack("<h", wavedata) print(int(data[0]))
Этот фрагмент читает 1 кадр. Чтобы прочитать более одного кадра (например, 13), используйте
wavedata = wavefile.readframes(13) data = struct.unpack("<13h", wavedata)
источник
Различные модули Python для чтения wav:
Для чтения аудиофайлов в формате wave есть как минимум следующие библиотеки:
Самый простой пример:
Это простой пример с SoundFile:
import soundfile as sf data, samplerate = sf.read('existing_file.wav')
Формат вывода:
Предупреждение, данные не всегда в одном и том же формате, это зависит от библиотеки. Например:
from scikits import audiolab from scipy.io import wavfile from sys import argv for filepath in argv[1:]: x, fs, nb_bits = audiolab.wavread(filepath) print('Reading with scikits.audiolab.wavread:', x) fs, x = wavfile.read(filepath) print('Reading with scipy.io.wavfile.read:', x)
Выход:
Reading with scikits.audiolab.wavread: [ 0. 0. 0. ..., -0.00097656 -0.00079346 -0.00097656] Reading with scipy.io.wavfile.read: [ 0 0 0 ..., -32 -26 -32]
SoundFile и Audiolab возвращают значения с плавающей запятой между -1 и 1 (как и matab, это соглашение для аудиосигналов). Scipy и wave возвращают целые числа, которые вы можете преобразовать в числа с плавающей запятой в соответствии с количеством бит кодирования, например:
from scipy.io.wavfile import read as wavread samplerate, x = wavread(audiofilename) # x is a numpy array of integers, representing the samples # scale to -1.0 -- 1.0 if x.dtype == 'int16': nb_bits = 16 # -> 16-bit wav files elif x.dtype == 'int32': nb_bits = 32 # -> 32-bit wav files max_nb_bit = float(2 ** (nb_bits - 1)) samples = x / (max_nb_bit + 1) # samples is a numpy array of floats representing the samples
источник
IMHO, самый простой способ получить аудиоданные из звукового файла в массив NumPy - это SoundFile :
import soundfile as sf data, fs = sf.read('/usr/share/sounds/ekiga/voicemail.wav')
Это также поддерживает 24-битные файлы из коробки.
Доступно множество библиотек звуковых файлов, я написал обзор, в котором вы можете увидеть несколько плюсов и минусов. На нем также есть страница, объясняющая, как читать 24-битный файл WAV с помощью
wave
модуля .источник
Вы можете сделать это с помощью модуля scikits.audiolab . Для работы требуется NumPy и SciPy, а также libsndfile.
Обратите внимание, мне удалось заставить его работать только на Ubunutu, но не на OSX.
from scikits.audiolab import wavread filename = "testfile.wav" data, sample_frequency,encoding = wavread(filename)
Теперь у вас есть данные wav
источник
scikits.audiolab
не обновлялся с 2010 года и, вероятно, это только Python 2.Если вы хотите обрабатывать аудио блок за блоком, некоторые из данных решений довольно ужасны в том смысле, что они подразумевают загрузку всего аудио в память, вызывая множество промахов кеша и замедляя вашу программу. python-wavefile предоставляет некоторые питонические конструкции для поблочной обработки NumPy с использованием эффективного и прозрачного управления блоками с помощью генераторов. Другие тонкости Python - это менеджер контекста для файлов, метаданные как свойства ... и если вам нужен весь файловый интерфейс, потому что вы разрабатываете быстрый прототип и вам не важна эффективность, весь файловый интерфейс все еще существует.
Простой пример обработки:
import sys from wavefile import WaveReader, WaveWriter with WaveReader(sys.argv[1]) as r : with WaveWriter( 'output.wav', channels=r.channels, samplerate=r.samplerate, ) as w : # Just to set the metadata w.metadata.title = r.metadata.title + " II" w.metadata.artist = r.metadata.artist # This is the prodessing loop for data in r.read_iter(size=512) : data[1] *= .8 # lower volume on the second channel w.write(data)
В примере повторно используется один и тот же блок для чтения всего файла, даже если последний блок обычно меньше требуемого размера. В этом случае вы получите кусок блока. Так что доверяйте возвращенной длине блока вместо использования жестко запрограммированного размера 512 для дальнейшей обработки.
источник
Если вы собираетесь выполнять передачу данных формы сигнала, возможно, вам следует использовать SciPy , в частности
scipy.io.wavfile
.источник
Мне нужно было прочитать 1-канальный 24-битный WAV файл. Сообщение Нака выше было очень полезным. Однако, как упоминалось выше, с помощью basj 24-bit не так просто. Наконец-то я заставил его работать, используя следующий фрагмент:
from scipy.io import wavfile TheFile = 'example24bit1channelFile.wav' [fs, x] = wavfile.read(TheFile) # convert the loaded data into a 24bit signal nx = len(x) ny = nx/3*4 # four 3-byte samples are contained in three int32 words y = np.zeros((ny,), dtype=np.int32) # initialise array # build the data left aligned in order to keep the sign bit operational. # result will be factor 256 too high y[0:ny:4] = ((x[0:nx:3] & 0x000000FF) << 8) | \ ((x[0:nx:3] & 0x0000FF00) << 8) | ((x[0:nx:3] & 0x00FF0000) << 8) y[1:ny:4] = ((x[0:nx:3] & 0xFF000000) >> 16) | \ ((x[1:nx:3] & 0x000000FF) << 16) | ((x[1:nx:3] & 0x0000FF00) << 16) y[2:ny:4] = ((x[1:nx:3] & 0x00FF0000) >> 8) | \ ((x[1:nx:3] & 0xFF000000) >> 8) | ((x[2:nx:3] & 0x000000FF) << 24) y[3:ny:4] = (x[2:nx:3] & 0x0000FF00) | \ (x[2:nx:3] & 0x00FF0000) | (x[2:nx:3] & 0xFF000000) y = y/256 # correct for building 24 bit data left aligned in 32bit words
Некоторое дополнительное масштабирование требуется, если вам нужны результаты от -1 до +1. Возможно, некоторые из вас найдут это полезным
источник
если это всего два файла и частота дискретизации значительно высока, вы можете просто чередовать их.
from scipy.io import wavfile rate1,dat1 = wavfile.read(File1) rate2,dat2 = wavfile.read(File2) if len(dat2) > len(dat1):#swap shortest temp = dat2 dat2 = dat1 dat1 = temp output = dat1 for i in range(len(dat2)/2): output[i*2]=dat2[i*2] wavfile.write(OUTPUT,rate,dat)
источник
Вы также можете использовать простую
import wavio
библиотеку. Вам также необходимо иметь некоторые базовые знания о звуке.источник
PyDub ( http://pydub.com/ ) не упоминается, и это следует исправить. ИМО, это самая полная библиотека для чтения аудиофайлов на Python прямо сейчас, хотя и не без недостатков. Чтение wav файла:
from pydub import AudioSegment audio_file = AudioSegment.from_wav('path_to.wav') # or audio_file = AudioSegment.from_file('path_to.wav') # do whatever you want with the audio, change bitrate, export, convert, read info, etc. # Check out the API docs http://pydub.com/
PS. Пример касается чтения файла wav, но PyDub может обрабатывать множество различных форматов из коробки. Предостережение заключается в том, что он основан как на собственной поддержке wav Python, так и на ffmpeg, поэтому вам необходимо установить ffmpeg, а многие возможности pydub полагаются на версию ffmpeg. Обычно, если это умеет ffmpeg, то может и pydub (который довольно мощный).
Отсутствие отказа от ответственности: я не имею отношения к проекту, но я активный пользователь.
источник