简体   繁体   English

如何从 python 中的波形文件中获取振幅值列表

[英]How to get list of amplitude values from a wave file in python

How could I get a list of the amplitudes of each frame in a wave file using python (in the dB unit)?如何使用 python(以 dB 为单位)获取波形文件中每个帧的振幅列表?

So far I have this:到目前为止我有这个:

samplerate, data = wavfile.read(patternPath)
print(max((data[:, 1]).tolist())))

but that prints out 0.7856917381286621 , which doesn't make much sense because I know that the wav file never surpasses 0 dB.但是打印出0.7856917381286621 ,这没有多大意义,因为我知道 wav 文件永远不会超过 0 dB。

Assuming you are looking for the dBFS, the simple answer would be to use the definition:假设您正在寻找 dBFS,简单的答案是使用定义:

20 log (P/P0) dB
  • P: measured power P:实测功率
  • P0: reference power P0:参考功率

In Python terms:在 Python 条款中:

import numpy as np

amps = [1, 0.1, 0.01] # that's the values you read from the file
dbs = 20 * np.log10(np.abs(amps)) # -> array([  0., -20., -40.])

The result is dBFS : Decibels relative to full scale (dBFS or dB FS) is a unit of measurement for amplitude levels in digital systems, such as pulse-code modulation (PCM), which have a defined maximum peak level.结果是dBFS相对于满刻度的分贝(dBFS 或 dB FS)是数字系统中振幅电平的测量单位,例如具有定义的最大峰值电平的脉冲编码调制 (PCM)。

Mind you, this has nothing to do with the absolute audio level, you cannot derive from it the dB SPL (Sound Pressure Level).请注意,这与绝对音频电平无关,您不能从中得出 dB SPL(声压级)。 The job of a microphone is to convert the change in air pressure (measured in dB SPL) into an analogous change in electrical voltage.麦克风的工作是将气压变化(以 dB SPL 为单位)转换为类似的电压变化。 This continuously changing voltage is sampled periodically and saved as a number (amplitude you read).这种连续变化的电压会定期采样并保存为数字(您读取的幅度)。

Since you loose the sound pressure information, to retrieve back the dB SPL you'd need to calibrate your system and know ADC range and microphone sensitivity.由于您丢失了声压信息,要恢复 dB SPL,您需要校准系统并了解 ADC 范围和麦克风灵敏度。

AES17 defines 0 dBFS as 20*log10(FS) where 1.0 FS corresponds to the RMS level of a 997 Hz sine wave whose peak value reaches the positive digital full scale. AES17 将 0 dBFS 定义为 20*log10(FS),其中 1.0 FS 对应于峰值达到正数字满刻度的 997 Hz 正弦波的 RMS 电平。 It is normally considered that positive digital full scale is 1.0.通常认为正数字满量程为1.0。 If your data is represented otherwise, you'll need to scale first.如果您的数据以其他方式表示,则需要先进行缩放。 Then it is worth nothing that the rms of a sine wave with a peak amplitude is 0.707 (sqrt(2)/2), but AES has defined this as 1.0 FS.那么一个峰值振幅的正弦波的rms是0.707(sqrt(2)/2)是没有价值的,但是AES已经将这个定义为1.0 FS。 Therefore you'll need to multiply the rms by a sqrt(2) to normalize to the AES standard.因此,您需要将 rms 乘以 sqrt(2) 以标准化为 AES 标准。

# create a 1 kHz sine wave for 100 ms.
data = np.sin(2*np.pi*np.arange(0,480)*1000/48000)

# measure the rms of the sine wave and convert to fs
# via sqrt(2)
fs = np.sqrt(2) * np.sqrt(np.mean(data*data))

# final step convert to dBFS
dbfs = 20*np.log10(fs)

Presumably, you would like periodic readings of the amplitude.据推测,您希望定期读取振幅。 To do accomplish this you need to take your signal (data) and slice it into sections at the desired rate and run this process on each section.要做到这一点,您需要获取信号(数据)并以所需的速率将其分成多个部分,然后在每个部分上运行此过程。 For a 1 second reading interval as an example, you take sample rate number of samples at a time.以 1 秒的读取间隔为例,您一次采用采样率采样数。

It's also worth understanding one of this pitfalls of this technique.了解这种技术的其中一个缺陷也很值得。 That is that chopping the signal up can result in a partial cycle of a waveform contaminating the rms computation (eg taking 1.25 ms of a 1kHz waveform).也就是说,将信号斩波会导致波形的部分周期污染均方根计算(例如,采用 1kHz 波形的 1.25 毫秒)。 Taking a longer reading will diminish the error term as a part of the whole.阅读更长的时间会减少错误项作为整体的一部分。 In effect, the lower frequency the signal, the longer your reading interval needs to be.实际上,信号频率越低,您需要的阅读间隔时间就越长。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM