Чтение *.wav файлов в Python - программирование
Подтвердить что ты не робот

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

Мне нужно проанализировать звук, записанный в 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

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

4b9b3361

Ответ 1

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

Ответ 2

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

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. Я нашел эту веб-страницу, весьма полезную в формулировании этого.

Ответ 3

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

По меньшей мере эти следующие библиотеки читают звуковой файл:

  • PySoundFile
  • scipy.io.wavfile (из scipy)
  • wave (для чтения потоков. Включено в python 2 и 3)
  • scikits.audiolab (кажется, не поддерживается)
  • sounddevice (воспроизведение и запись звуков, хороших для потоков и в режиме реального времени)
  • pyglet

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

Это простой пример с 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 

Ответ 4

IMHO, самый простой способ получить аудиоданные из звукового файла в массив NumPy - PySoundFile:

import soundfile as sf
data, fs = sf.read('/usr/share/sounds/ekiga/voicemail.wav')

Это также поддерживает 24-битные файлы из коробки.

Имеется много доступных звуковых файлов, я написал обзор, где вы можете увидеть несколько плюсов и минусов. В нем также есть страница, объясняющая как читать 24-битный wav файл с модулем wave.

Ответ 5

Вы можете выполнить это, используя модуль scikits.audiolab. Он требует функции NumPy и SciPy, а также libsndfile.

Заметьте, мне удалось заставить его работать на Ubunutu, а не на OSX.

from scikits.audiolab import wavread

filename = "testfile.wav"

data, sample_frequency,encoding = wavread(filename)

Теперь у вас есть данные wav

Ответ 6

Если вы хотите переделать аудио блокировку, некоторые из этих решений довольно ужасны в том смысле, что они подразумевают загрузку всего аудио в память, что приводит к многочисленным промахам в кеше и замедлению работы вашей программы. 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 для любой последующей обработки.

Ответ 7

Если вы собираетесь выполнять переводы по данным осциллограммы, то, возможно, вам следует использовать SciPy, в частности scipy.io.wavfile.

Ответ 8

если его два файла и частота выборки значительно высоки, вы можете просто чередовать их.

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)

Ответ 9

Мне нужно было прочитать 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. Возможно, некоторые из вас могут найти это полезное