Чтение.* wav файлы в Python


Мне нужно проанализировать звук, написанный в a .WAV-файл. Для этого мне нужно преобразовать этот файл в набор чисел (массивы, например). Я думаю, что мне нужно использовать пакет wave. Однако я не знаю, как именно это работает. Например, я сделал следующее:

import wave
w = wave.open('/usr/share/sounds/ekiga/voicemail.wav', 'r')
for i in range(w.getnframes()):
    frame = w.readframes(i)
    print frame

в результате этого кода я ожидал увидеть звуковое давление как функцию времени. Напротив, я вижу много странных, таинственных символов (которые не являются шестнадцатеричными числами). Может кто-нибудь, пожалуйста, помогите мне это?

10 55

10 ответов:

на источники,scipy.io.wavfile.read(somefile) возвращает кортеж из двух элементов: первый-частота дискретизации в выборках в секунду, второй -numpy массив со всеми данными, считанными из файла. Выглядит довольно простой в использовании!

например:

from scipy.io import wavfile
fs, data = wavfile.read('./output/audio.wav')

Я сделал некоторые исследования в этот вечер, и понял это:

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]))

надеюсь, этот фрагмент поможет кому-то. Подробности: используя модуля struct, вы можете взять волновые кадры (которые находятся в 2S дополнительном двоичном между -32768; 0x8000 и 32767; 0x7FFF) это читает моно, 16-битный, волновой файл. Я нашел этот сайт весьма полезно в разработке этого.

этот фрагмент считывает 1 кадр. Для чтения более одного кадра (например, 13), используйте

waveData = waveFile.readframes(13)
data = struct.unpack("<13h", waveData)

различные модули python для чтения wav:

есть по крайней мере следующие библиотеки для чтения wave audio file:

самый простой пример:

Это простой пример с 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.аудиолаб.wavread: [ 0. 0. 0. ..., -0.00097656 -0.00079346 -0.00097656] Значение с составляющей.Ио.wavfile.читать: [ 0 0 0 ..., -32 -26 -32]

pysoundfile и Audiolab возвращают поплавок между -1 и 1 (Как matab делает, это Соглашение для звукового сигнала). Scipy и wave возвращают целые числа, которые могут быть преобразованы в 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-это контекстный менеджер для файлов, метаданные как свойства... и если вы хотите весь интерфейс файла, потому что вы разрабатываете быстрый прототип, и вы не заботитесь об эффективности, весь интерфейс файла все еще там.

простой пример обработки такой:

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.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 файл. Сообщение выше по НАК было очень полезно. Однако, как упоминалось выше 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. Может быть, кто-то из вас там может найти это полезным

u также может использовать простой import wavio библиотека u также должны иметь некоторые базовые знания о звуке.