2010-01-13 7 views
46

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

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

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

+12

Это действительно сбивает с толку, когда кто-то еще с моим именем задает вопрос, который я задаю, но у меня нет памяти об этом сам :) – Roman

+1

Что такое гексагональные числа? – glglgl

+1

@glglgl Вероятно, это не означает: https://en.wikipedia.org/wiki/Hexagonal_number :-) – JakeD

ответ

46

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

+0

Вы можете комбинировать это с инструментами преобразования командной строки, чтобы открыть другие форматы. – endolith

+7

Тем не менее, у него серьезно отсутствует количество каналов. Как вы должны работать со звуком, не зная количества каналов? – bastibe

+0

забрасывает некоторые странные ошибки распаковки структуры на моем компьютере. Я думаю, что вместо struct.unpack ('

1

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

+1

ОК. Я только что установил SciPy, но я не могу найти какой-либо пример использования scipy.io.wavfile. – Roman

+4

Ничто не похоже на интерактивный интерпретатор для выяснения того, как все работает! Быть амбициозным! –

44

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

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 module, вы можете взять волновые кадры (которые находятся в 2-х дополнительных двоичных файлах от -32768; 0x8000 и 32767; 0x7FFF). Это считывает файл MONO, 16-BIT, WAVE. Я нашел this webpage весьма полезным при формулировании этого.

+1

как сделать обрабатывать 24-битные стереофайлы? – Basj

+7

это дает мне ошибку: «struct.error: unpack требует строкового аргумента длины 2» – Coder404

+0

Если вы запустите этот фрагмент кода с очень большим аудиофайлом. Ваш компьютер будет умирать из-за потребности в памяти этой программы. Необходимость обработки аудиофайла по блоку для большого аудиофайла – ArthurLambert

8

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

Примечание. Я мог только заставить его работать на Ubunutu, а не на OSX.

from scikits.audiolab import wavread 

filename = "testfile.wav" 

data, sample_frequency,encoding = wavread(filename) 

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

0

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

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

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

14

Различные питон модули для чтения 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 возвращают поплавок между -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 
0

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

10

ИМХО, самый простой способ получить аудиоданные из звукового файла в массив NumPy является PySoundFile:

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

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

Существует много доступных библиотек звуковых файлов, я написал an overview, где вы можете увидеть несколько за и против. В нем также есть страница, объясняющая how to read a 24-bit wav file with the wave module.

+0

Примечание: soundfile.read() нормализуется на 2^(n_bits - 1), как в примере scipy.io.wavfile от sandoval – Quetzalcoatl

0

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

 Смежные вопросы

  • Нет связанных вопросов^_^