Подтвердить что ты не робот

Как построить wav файл

Я только что прочитал wav файл с scipy, и теперь я хочу сделать график файла, используя matplotlib, в шкале "y", я хочу видеть амплитуду и по шкале "x", я хочу видеть количество кадров! Любая помощь, как я могу это сделать? Спасибо!

from scipy.io.wavfile import read
import numpy as np
from numpy import*
import matplotlib.pyplot as plt
a=read("C:/Users/Martinez/Desktop/impulso.wav")
print a
4b9b3361

Ответ 1

Вы можете вызвать wave lib для чтения аудиофайла.

Чтобы построить форму волны, используйте функцию "plot" из matplotlib

import matplotlib.pyplot as plt
import numpy as np
import wave
import sys


spf = wave.open('wavfile.wav','r')

#Extract Raw Audio from Wav File
signal = spf.readframes(-1)
signal = np.fromstring(signal, 'Int16')


#If Stereo
if spf.getnchannels() == 2:
    print 'Just mono files'
    sys.exit(0)

plt.figure(1)
plt.title('Signal Wave...')
plt.plot(signal)
plt.show()

у вас будет что-то вроде: enter image description here

Чтобы выстроить ось x в секундах, вам нужно получить частоту кадров и разделить по размеру вашего сигнала, вы можете использовать функцию linspace из numpy, чтобы создать временной вектор, линейно распределенный с размером аудиофайла, и, наконец, вы можете снова используйте график, например plt.plot(Time,signal)

import matplotlib.pyplot as plt
import numpy as np
import wave
import sys


spf = wave.open('Animal_cut.wav','r')

#Extract Raw Audio from Wav File
signal = spf.readframes(-1)
signal = np.fromstring(signal, 'Int16')
fs = spf.getframerate()

#If Stereo
if spf.getnchannels() == 2:
    print 'Just mono files'
    sys.exit(0)


Time=np.linspace(0, len(signal)/fs, num=len(signal))

plt.figure(1)
plt.title('Signal Wave...')
plt.plot(Time,signal)
plt.show()

Новая ось графика x в секундах:

enter image description here

Ответ 2

В качестве альтернативы, если вы хотите использовать SciPy, вы также можете сделать следующее:

from scipy.io.wavfile import read
import matplotlib.pyplot as plt

# read audio samples
input_data = read("Sample.wav")
audio = input_data[1]
# plot the first 1024 samples
plt.plot(audio[0:1024])
# label the axes
plt.ylabel("Amplitude")
plt.xlabel("Time")
# set the title  
plt.title("Sample Wav")
# display the plot
plt.show()

Ответ 3

Вот версия, которая также будет обрабатывать стереовходы, основываясь на ответе @ederwander

import matplotlib.pyplot as plt
import numpy as np
import wave

file = 'test.wav'

with wave.open(file,'r') as wav_file:
    #Extract Raw Audio from Wav File
    signal = wav_file.readframes(-1)
    signal = np.fromstring(signal, 'Int16')

    #Split the data into channels 
    channels = [[] for channel in range(wav_file.getnchannels())]
    for index, datum in enumerate(signal):
        channels[index%len(channels)].append(datum)

    #Get time from indices
    fs = wav_file.getframerate()
    Time=np.linspace(0, len(signal)/len(channels)/fs, num=len(signal)/len(channels))

    #Plot
    plt.figure(1)
    plt.title('Signal Wave...')
    for channel in channels:
        plt.plot(Time,channel)
    plt.show()

enter image description here

Ответ 4

Просто наблюдение (я не могу добавить комментарий).

Вы получите следующее сообщение:

Предупреждение об устаревании: коды типов в числовом формате устарели и в будущем приведут к ошибке.

Не используйте np.fromstring с двоичными файлами. Вместо signal = np.fromstring(signal, 'Int16') предпочтительнее использовать signal = np.frombuffer(signal, dtype='int16').

Ответ 5

Вот версия, которая обрабатывает моно/стерео и 8-бит/16-бит PCM.

import matplotlib.pyplot as plt
import numpy as np
import wave

file = 'test.wav'

wav_file = wave.open(file,'r')

#Extract Raw Audio from Wav File
signal = wav_file.readframes(-1)
if wav_file.getsampwidth() == 1:
    signal = np.array(np.frombuffer(signal, dtype='UInt8')-128, dtype='Int8')
elif wav_file.getsampwidth() == 2:
    signal = np.frombuffer(signal, dtype='Int16')
else:
    raise RuntimeError("Unsupported sample width")

# http://schlameel.com/2017/06/09/interleaving-and-de-interleaving-data-with-python/
deinterleaved = [signal[idx::wav_file.getnchannels()] for idx in range(wav_file.getnchannels())]

#Get time from indices
fs = wav_file.getframerate()
Time=np.linspace(0, len(signal)/wav_file.getnchannels()/fs, num=len(signal)/wav_file.getnchannels())

#Plot
plt.figure(1)
plt.title('Signal Wave...')
for channel in deinterleaved:
    plt.plot(Time,channel)
plt.show()

Ответ 6

Вот код для рисования файла волновой волны и спектра сигнала

import wave

from scipy import signal

import numpy as np

import matplotlib.pyplot as plt

signal_wave = wave.open('voice.wav', 'r')

sample_frequency = 16000

data = np.fromstring(signal_wave.readframes(sample_frequency), dtype=np.int16)

sig = signal_wave.readframes(-1)

sig = np.fromstring(sig, 'Int16')

Для волнового файла

sig = sig[:]

Для некоторого сегмента волнового файла

sig = sig[25000:32000]

left, right = data[0::2], da[1::2]

lf, rf = abs(np.fft.rfft(left)), abs(np.fft.rfft(right))

Для построения графика волны и спектра файла волновой волны

plt.figure(1)

a = plt.subplot(211)

a.set_xlabel('time [s]')

a.set_ylabel('sample value [-]')

plt.plot(sig)

c = plt.subplot(212)

Pxx, freqs, bins, im = c.specgram(sig, NFFT=1024, Fs=16000, noverlap=900)

c.set_xlabel('Time')

c.set_ylabel('Frequency')

plt.show() wave signal and spectrogram of the signal

Ответ 7

Полагаю, я мог бы поместить это в комментарии, но, опираясь немного на ответы как @ederwander, так и @TimSC, я хотел сделать что-то более прекрасное (как подробно) и эстетически приятное. Приведенный ниже код создает то, что я считаю очень хорошей формой волны стереофонического или моноволнового файла (мне не нужен заголовок, поэтому я просто закомментировал это, и при этом мне не понадобился метод show - просто нужно было сохранить файл изображения).

Вот пример стерео wav рендеринга: enter image description here

И код с упомянутыми мною различиями:

import matplotlib.pyplot as plt
import numpy as np
import wave

file = '/Path/to/my/audio/file/DeadMenTellNoTales.wav'

wav_file = wave.open(file,'r')

#Extract Raw Audio from Wav File
signal = wav_file.readframes(-1)
if wav_file.getsampwidth() == 1:
    signal = np.array(np.frombuffer(signal, dtype='UInt8')-128, dtype='Int8')
elif wav_file.getsampwidth() == 2:
    signal = np.frombuffer(signal, dtype='Int16')
else:
    raise RuntimeError("Unsupported sample width")

# http://schlameel.com/2017/06/09/interleaving-and-de-interleaving-data-with-python/
deinterleaved = [signal[idx::wav_file.getnchannels()] for idx in range(wav_file.getnchannels())]

#Get time from indices
fs = wav_file.getframerate()
Time=np.linspace(0, len(signal)/wav_file.getnchannels()/fs, num=len(signal)/wav_file.getnchannels())
plt.figure(figsize=(50,3))
#Plot
plt.figure(1)
#don't care for title
#plt.title('Signal Wave...')
for channel in deinterleaved:
    plt.plot(Time,channel, linewidth=.125)
#don't need to show, just save
#plt.show()
plt.savefig('/testing_folder/deadmentellnotales2d.png', dpi=72)