我刚刚读了一个带有scipy的wav文件,现在我想使用matplotlib制作文件的图,在“y scale”上我希望看到aplitude和“x scale”我希望看到帧数! 任何帮助我该怎么办? 谢谢!
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
答案 0 :(得分:55)
您可以调用wave lib来读取音频文件。
要绘制波形,请使用matplotlib中的“plot”功能
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()
您将拥有类似:
的内容要以秒为单位绘制x轴,你需要获得帧率并除以信号的大小,你可以使用numpy的linspace函数创建一个与音频文件大小线性间隔的时间向量,最后你可以再次使用情节,如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轴:
答案 1 :(得分:16)
或者,如果您想使用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()
答案 2 :(得分:7)
根据@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()
答案 3 :(得分:3)
只是一个观察(我不能添加评论)。
您将收到以下消息:
DeprecationWarning:不推荐使用数字样式代码 导致将来出错。
不要将np.fromstring与二进制文件一起使用。它不是signal = np.fromstring(signal, 'Int16')
,而是首选使用signal = np.frombuffer(signal, dtype='int16')
。
答案 4 :(得分:2)
这是绘制信号波文件和信号频谱的代码
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')
用于wave文件
sig = sig[:]
对于wave文件的某些段
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()
答案 5 :(得分:1)
这是处理单声道/立体声和8位/ 16位PCM的版本。
{{1}}
答案 6 :(得分:0)
我想我可以对此发表评论,但是在@ederwander和@TimSC的回答略有基础上,我想做些更精致的事情(如详细说明),并在美学上令人愉悦。下面的代码创建了我认为是立体声或单声道文件的非常不错的波形(我不需要标题,因此我只是将其注释掉,也不需要show方法-只需要保存图像文件)
代码,以及我提到的区别:
1
答案 7 :(得分:0)
我想出了一个更灵活,更高效的解决方案:
import matplotlib.pyplot as plt
import numpy as np
import wave
import math
file = 'audiofile.wav'
with wave.open(file,'r') as wav_file:
num_channels = wav_file.getnchannels()
frame_rate = wav_file.getframerate()
downsample = math.ceil(frame_rate * num_channels / 2) # Get two samples per second!
process_chunk_size = 600000 - (600000 % frame_rate)
signal = None
waveform = np.array([])
while signal is None or signal.size > 0:
signal = np.frombuffer(wav_file.readframes(process_chunk_size), dtype='int16')
# Take mean of absolute values per 0.5 seconds
sub_waveform = np.nanmean(
np.pad(np.absolute(signal), (0, ((downsample - (signal.size % downsample)) % downsample)), mode='constant', constant_values=np.NaN).reshape(-1, downsample),
axis=1
)
waveform = np.concatenate((waveform, sub_waveform))
#Plot
plt.figure(1)
plt.title('Waveform')
plt.plot(waveform)
plt.show()