Ответ 1
Per источники, scipy.io.wavfile.read(somefile)
возвращает кортеж из двух элементов: первая - частота дискретизации в выборках в секунду, вторая - a numpy
со всеми данными, считанными из файла. Выглядит довольно проста в использовании!
Мне нужно проанализировать звук, записанный в 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
В результате этого кода я ожидал увидеть звуковое давление как функцию времени. Напротив, я вижу много странных, таинственных символов (которые не являются шестнадцатеричными числами). Может ли кто-нибудь, мольбы, помочь мне с этим?
Per источники, scipy.io.wavfile.read(somefile)
возвращает кортеж из двух элементов: первая - частота дискретизации в выборках в секунду, вторая - a numpy
со всеми данными, считанными из файла. Выглядит довольно проста в использовании!
Я провел некоторое исследование этим вечером и понял это:
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]))
Надеюсь, этот фрагмент поможет кому-то. Детали: используя структурный модуль вы можете взять волновые кадры (которые находятся в 2s взаимодополняющем двоичном формате между -32768; 0x8000 и 32767; 0x7FFF). Это считывает MONO, 16-BIT, WAVE. Я нашел эту веб-страницу, весьма полезную в формулировании этого.
Различные модули python для чтения wav:
По меньшей мере эти следующие библиотеки читают звуковой файл:
Самый простой пример:
Это простой пример с Pysoundfile:
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 filetest in argv[1:]:
[x, fs, nbBits] = audiolab.wavread(filePath)
print '\nReading with scikits.audiolab.wavread: ', x
[fs, x] = wavfile.read(filetest)
print '\nReading with scipy.io.wavfile.read: ', x
Чтение с помощью scikits.audiolab.wavread: [0. 0. 0...., -0.00097656 -0.00079346 -0,00097656] Чтение с помощью scipy.io.wavfile.read: [0 0 0..., -32 -26 -32]
PySoundFile и Audiolab возвращают float между -1 и 1 (поскольку matab делает это, это соглашение для аудиосигнала). Целые числа Scipy и wave return, которые могут быть преобразованы в float в соответствии с количеством бит кодирования.
Например:
from scipy.io.wavfile import read as wavread
[samplerate, x] = wavread(audiofilename) # x is a numpy array of integer, 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.0) # samples is a numpy array of float representing the samples
IMHO, самый простой способ получить аудиоданные из звукового файла в массив NumPy - PySoundFile:
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
Если вы хотите переделать аудио блокировку, некоторые из этих решений довольно ужасны в том смысле, что они подразумевают загрузку всего аудио в память, что приводит к многочисленным промахам в кеше и замедлению работы вашей программы. python-wavefile предоставляет некоторые pythonic-конструкторы для выполнения блочной обработки NumPy с использованием эффективного и прозрачного управления блоками с помощью генераторов. Другие пифонические тонкости - это менеджер контекста для файлов, метаданных как свойств... и если вы хотите весь файловый интерфейс, потому что вы разрабатываете быстрый прототип, и вы не заботитесь об эффективности, весь файловый интерфейс все еще существует.
Простым примером обработки будет:
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
.
если его два файла и частота выборки значительно высоки, вы можете просто чередовать их.
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)
Мне нужно было прочитать 1-канальный 24-битный WAV файл. Сообщение выше Nak было очень полезно. Однако, как упоминалось выше, basj 24-бит не является простым. Я, наконец, начал работать, используя следующий фрагмент:
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. Возможно, некоторые из вас могут найти это полезное