use*_*664 0 python audio rms histogram amplitude
我想制作一个直方图,对音频文件的RMS 幅度进行分类。目标是显示在文件的整个持续时间内,每个幅度级别上有多少信号。有没有一个Python包有这个功能?如果不是的话,如何编码呢?
我还想设置计算分析的频率范围,例如 1 到 6 kHz 之间。
我有以下作为粗略的开始,尽管我还不明白它代表什么,而且它肯定不使用 RMS:
import numpy as np
import matplotlib.pyplot as plt
Fs, data = wavfile.read('file')
print('data =',data)
print('number of samples in data =',len(data))
subset = data[0:44100]
subset = abs(subset)
print('number of samples in subset =',len(subset))
plt.hist(subset, bins='auto')
plt.show()
Run Code Online (Sandbox Code Playgroud)
据我所知,RMS没有特殊的功能numpy,但你可以这样做
RMS = np.sqrt(np.mean(x**2))
Run Code Online (Sandbox Code Playgroud)
问题是,x您要计算哪些数据(哪些)的 RMS。例如,您可以对每个样本应用 RMS,而不是假设您的 wav 文件中只有一个通道:
length = data.shape[0] / Fs
print(f"length = {length}s")
RMS = lambda x: np.sqrt(np.mean(x**2))
sample = np.arange(int(length))
RMS_of_sample = np.zeros(sample.shape)
for ns in sample:
# here you can apply the frequency window for the sample
RMS_of_sample[ns] = RMS(data[ns*Fs:(ns+1)*Fs])
plt.hist(RMS_of_sample, label="Left channel")
plt.show()
Run Code Online (Sandbox Code Playgroud)
在这里您还可以应用一些信号窗口。这段代码给你这样的东西
对于输入信号:
添加评论中有关完整/部分频率范围的问题
如果您想分析某个频域中的完整信号,您可以对频率范围应用简单的滤波器(矩形频率窗口),如下所示[filter_freq_min, filter_freq_max]:
from scipy.fft import fft, ifft, fftfreq
filter_freq_min = 1000 # Hz
filter_freq_max = 2000 # Hz
freq = fftfreq(len(data), 1 / Fs)
data_fft = fft(data)
condition = np.logical_or(abs(freq) <= filter_freq_min, abs(freq) >= filter_freq_max)
filtered_data_fft = np.copy(data_fft)
filtered_data_fft [condition] = 0
filtered_data = np.real(ifft(filtered_data_fft ))
# show fft for incoming signal (blue) and filtered signal (orange)
plt.plot(freq, np.abs(data_fft),'.')
plt.plot(freq, np.abs(filtered_data_fft ),'.')
plt.xlim( [10, Fs/2] )
plt.xlabel( 'Frequency (Hz)' )
plt.show()
# check RMS for filtered and unfiltered signal
print(RMS(filtered_data),RMS(data))
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以在所需的频率范围之间循环。
要直接在Python中播放声音,您可以使用
import sounddevice as sd # For playing/recording audio
sd.play(data, Fs)
sd.play(filtered_data, Fs)
Run Code Online (Sandbox Code Playgroud)