python - 如何使用python获取声音包络

标签 python audio scipy signal-processing

你好,我是 python 的新手,也是声音信号分析的新手。我想弄到一首诞生之歌(斑胸草雀)的信封。它的信号波动非常快,我尝试了不同的方法。例如,我尝试绘制信号并根据我发现的其他示例使用以下代码获取包络(我在代码上添加了注释以理解它):

#Import the libraries
from pylab import *
import numpy
import scipy.signal.signaltools as sigtool
import scipy, pylab
from scipy.io import wavfile
import wave, struct
import scipy.signal as signal

#Open the txt file and read the wave file (also save it as txt file)

f_out = open('mike_1_44100_.txt', 'w')
w     = scipy.io.wavfile.read("mike_1_44100_.wav") #here your sound file

a=w[1]
f_out.write('#time #z' + '\n')

#I print to check
print 'vector w'
print w[0],w[1]
print w

i=w[1].size
p=numpy.arange(i)*0.0000226 #to properly define the time signal with    the sample rate

print 'vector p:'
print p 

x=numpy.dstack([p,a])

print 'vector x:'
print x[0]

#saving file
numpy.savetxt('mike_1_44100_.txt',x[0])

f_out.close()
print 'i:'
print i

# num is the number of samples in the resampled signal.
num= np.ceil(float(i*0.0000226)/0.0015)
print num

y_resample, x_resample = scipy.signal.resample(numpy.abs(a),num, p,axis=0, window=('gaussian',150))

#y_resample, x_resample = scipy.signal.resample(numpy.abs(a), num, p,axis=-1, window=0)

#Aplaying a filter 

W1=float(5000)/(float(44100)/2) #the frequency  for the cut over the sample frequency

(b, a1) = signal.butter(4, W1, btype='lowpass')
aaa=a
slp =1* signal.filtfilt(b, a1, aaa)

#Taking the abs value of the signal the resample and finaly aplying the hilbert transform

y_resample2 =numpy.sqrt(numpy.abs(np.imag(sigtool.hilbert(slp, axis=-1)))**2+numpy.abs(np.real(sigtool.hilbert(slp, axis=-1)))**2)

print 'x sampled'
#print x_resample
print 'y sampled'
#print  y_resample

xx=x_resample #[0]
yy=y_resample #[1]

#ploting with some style

plot(p,a,label='Time Signal') #to plot amplitud vs time
#plot(p,numpy.abs(a),label='Time signal')
plot(xx,yy,label='Resampled time signal Fourier technique Gauss window 1.5 ms ', linewidth=3)
#plot(ww,label='Window', linewidth=3)
#plot(p,y_resample2,label='Hilbert transformed sime signal', linewidth=3)

grid(True)
pylab.xlabel("time [s]")
pylab.ylabel("Amplitde")

legend()
show()

在这里我尝试了两件事,第一是使用 scipy 的重采样函数来获取包络,但是我对信号幅度有一些问题我还不明白(我上传了用傅立叶技术获得的图像但是系统不允许我):

第二种是用hilbert变换得到包络(现在我又上传了hilbert变换的图片系统不允许)可以运行我的代码得到两张图片。但是我会用这个链接 http://ceciliajarne.web.unq.edu.ar/?page_id=92&preview=true

现在“信封”又失败了。我尝试像在某些示例中看到的那样过滤信号,但我的信号被衰减了,我无法获得包络。 任何人都可以帮助我编写代码或获得信封的更好主意吗?可以使用任何鸟鸣作为示例(我可以给你我的),但我需要看看会发生什么复杂的声音不是简单的信号,因为它非常不同(对于简单的声音,两种技术都可以)。

我还尝试修改我在以下位置找到的代码:http://nipy.org/nitime/examples/mtm_baseband_power.html

但我无法为我的信号获得正确的参数,而且我不了解调制部分。我已经问过代码开发人员,等待答案。

最佳答案

可以使用相应的 analytic signal 的绝对值计算信号的包络. Scipy 实现函数 scipy.signal.hilbert计算解析信号。

来自其文档:

我们创建了一个频率从 20 Hz 增加到 100 Hz 的线性调频信号,并应用幅度调制。

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import hilbert, chirp

duration = 1.0
fs = 400.0
samples = int(fs*duration)
t = np.arange(samples) / fs

signal = chirp(t, 20.0, t[-1], 100.0)
signal *= (1.0 + 0.5 * np.sin(2.0*np.pi*3.0*t))

幅度包络由分析信号的幅度给出。

analytic_signal = hilbert(signal)
amplitude_envelope = np.abs(analytic_signal)

看起来像

plt.plot(t, signal, label='signal')
plt.plot(t, amplitude_envelope, label='envelope')
plt.show()

Plot of signal and envelope

它也可用于计算瞬时频率(参见文档)。

关于python - 如何使用python获取声音包络,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30889748/

相关文章:

python - 在 django admin 中对模型中的自定义字段进行排序

javascript - 从频谱功率电平(FFT 输出)中恢复 RMS 和/或峰值

python - 以 png 格式保存图像的 2 channel 像素

python - 将 scipy.optimize.curve_fit 与权重一起使用

python - 如何在 python 3 中禁用 SSL 身份验证

python - 为什么 Django 网址以斜线结尾?

python - Google App Engine 上论坛应用程序的数据建模建议

audio - ASCII码转音频

iphone - 一个应用程序中可以有AVFramework和AudioToolbox框架吗?

python - 如何在python中拟合三个高斯峰?