声音响度、声压级加权(A B C)的实现
最编程
2024-03-21 19:54:21
...
声压 sound pressure
声压就是大气压受到声波扰动后产生的变化,即为大气压强的余压,它相当于在大气压强上的叠加一个声波扰动引起的压强变化。由于声压的测量比较容易实现,通过声压的测量也可以间接求得质点速度等其它物理量,所以声学中常用这个物理量来描述声波
我们知道大气压强单位 1Pa = 1 pascal = 1N/m
实际计算可以参考http://www.sengpielaudio.com/calculator-soundlevel.htm
由于人对不同的声音频段 听感大小不一致,所以要对声音进行计权处理
如下实现 A B C 计权的实现,计权的实现参考标准,用于逼近实际的等响度曲线
ISO 226-2003标准
A、B、C三种计权网络特性,分别对应于倒置的40、70、100Phon等响曲线(1000Hz归一化到0dB),其作用是分别反应人耳对低、中、高声压级的响度感觉。A计权被证实是人耳对声压级主观反应的极好校正。对由A计权测量的声级称为A声级,记作LPA 或dB(A)。近来B计权、C计权已很少采用。
-
A计权:40Phon等响曲线的翻转,模拟55dB以下低强度噪声特性。
-
B计权:70Phon等响曲线的翻转,模拟55~85dB中等强度噪声特性。
-
C计权:100Phon等响曲线的翻转,模拟高强度噪声特性。
-
D计权:专用于飞机噪声的测量。
target_folder='audio/'
audio_targets = '.wav'
spl_folder = '/c_audio'
from librosa import load
from os import listdir,path
from scipy.signal import lfilter,bilinear
from numpy import pi, convolve,log10,sqrt,sum,power
from csv import writer
def a_weighting_coeffs_design(sample_rate):
"""Returns b and a coeff of a A-weighting filter.
Parameters
----------
sample_rate : scalar
Sample rate of the signals that well be filtered.
Returns
-------
b, a : ndarray
Filter coefficients for a digital weighting filter.
Examples
--------
>>> b, a = a_weighting_coeff_design(sample_rate)
To Filter a signal use scipy lfilter:
>>> from scipy.signal import lfilter
>>> y = lfilter(b, a, x)
See Also
--------
b_weighting_coeffs_design : B-Weighting coefficients.
c_weighting_coeffs_design : C-Weighting coefficients.
weight_signal : Apply a weighting filter to a signal.
scipy.lfilter : Filtering signal with `b` and `a` coefficients.
"""
f1 = 20.598997
f2 = 107.65265
f3 = 737.86223
f4 = 12194.217
A1000 = 1.9997
numerators = [(2 * pi * f4)**2 * (10**(A1000 / 20.0)), 0., 0., 0., 0.]
denominators = convolve([1., +4 * pi * f4, (2 * pi * f4)**2],
[1., +4 * pi * f1, (2 * pi * f1)**2])
denominators = convolve(convolve(denominators, [1., 2 * pi * f3]),
[1., 2 * pi * f2])
return bilinear(numerators, denominators, sample_rate)
def b_weighting_coeffs_design(sample_rate):
"""Returns `b` and `a` coeff of a B-weighting filter.
B-Weighting is no longer described in DIN61672.
Parameters
----------
sample_rate : scalar
Sample rate of the signals that well be filtered.
Returns
-------
b, a : ndarray
Filter coefficients for a digital weighting filter.
Examples
--------
>>> b, a = b_weighting_coeff_design(sample_rate)
To Filter a signal use :function: scipy.lfilter:
>>> from scipy.signal import lfilter
>>> y = lfilter(b, a, x)
See Also
--------
a_weighting_coeffs_design : A-Weighting coefficients.
c_weighting_coeffs_design : C-Weighting coefficients.
weight_signal : Apply a weighting filter to a signal.
"""
f1 = 20.598997
f2 = 158.5
f4 = 12194.217
B1000 = 0.17
numerators = [(2 * pi * f4)**2 * (10**(B1000 / 20)), 0, 0, 0]
denominators = convolve([1, +4 * pi * f4, (2 * pi * f4)**2],
[1, +4 * pi * f1, (2 * pi * f1)**2])
denominators = convolve(denominators, [1, 2 * pi * f2])
return bilinear(numerators, denominators, sample_rate)
def c_weighting_coeffs_design(sample_rate):
"""Returns b and a coeff of a C-weighting filter.
Parameters
----------
sample_rate : scalar
Sample rate of the signals that well be filtered.
Returns
-------
b, a : ndarray
Filter coefficients for a digital weighting filter.
Examples
--------
b, a = c_weighting_coeffs_design(sample_rate)
To Filter a signal use scipy lfilter:
from scipy.signal import lfilter
y = lfilter(b, a, x)
See Also
--------
a_weighting_coeffs_design : A-Weighting coefficients.
b_weighting_coeffs_design : B-Weighting coefficients.
weight_signal : Apply a weighting filter to a signal.
"""
f1 = 20.598997
f4 = 12194.217
C1000 = 0.0619
numerators = [(2 * pi * f4)**2 * (10**(C1000 / 20)), 0, 0]
denominators = convolve([1, +4 * pi * f4, (2 * pi * f4)**2],
[1, +4 * pi * f1, (2 * pi * f1)**2])
return bilinear(numerators, denominators, sample_rate)
def SPLCal(x):
Leng = len(x)
pa = sqrt(sum(power(x, 2))/Leng)
p0 = 2e-5
spl = 20 * log10(pa / p0)
return spl
def preprocess_spl(name,spl):
"""Main logic for SPL weighting"""
n = 1
##at = find_recordings(target_folder, audio_targets)
at =listdir(target_folder)
for f in at:
filename = path.join(target_folder, f)
x, Fs = load(filename)
b, a = c_weighting_coeffs_design(Fs)
y = lfilter(b, a, x)
out = SPLCal(y)
spl.append(out)
name.append(f[:-4])
print(filename[6:-4]+" spl:"+str(out))
'''print("--- Preprocessing SPLs: " + str(round(n / len(at) * 100, 2)) +
"% done. ---\t\t",
end='\r\r\r\n\n')'''
n += 1
if __name__ == '__main__':
name =[]
spl= []
preprocess_spl(name,spl)
header =['name', 'spl(dbc)']
with open('save.csv', 'w') as file:
# 2. Create a CSV writer
mywrite = writer(file)
# 3. Write data to the file
mywrite.writerow(header)
tmp = zip(name,spl)
mywrite.writerows(tmp)
file.close()
推荐阅读
-
正负偏差变量 即 d2+、d2- 分别表示决策值中超出和未达到目标值的部分。而 di+、di- 均大于 0 刚性约束和目标约束(柔性目标约束有偏差) 在多目标规划中,>=/<= 在刚性约束中保持不变。当需要将约束条件转换为柔性约束条件时,需要将 >=/<= 更改为 =(因为已经有 d2+、d2- 用来表示正负偏差),并附加上 (+dii-di+) 注意这里是 +di、-di+!之所以是 +di,-di+,是因为需要将目标还原为最接近的原始刚性约束条件 优先级因素和权重因素 对多个目标进行优先排序和优先排序 目标规划的目标函数 是所有偏差变量的加权和。值得注意的是,这个加权和都取最小值。而 di+ 和 dii- 并不一定要出现在每个不同的需求层次中。具体分析需要具体问题具体分析 下面是一个例子: 题目中说设备 B 既要求充分利用,又要求尽可能不加班,那么列出的时间计量表达式即为:min z = P3 (d3- + d3 +) 使用 + 而不是 -d3 + 的原因是:正负偏差不可能同时存在,必须有 di+di=0 (因为判定值不可能同时大于目标值和小于目标值),而前面是 min,所以只要取 + 并让 di+ 和 dii- 都为正值即可。因此,得出以下规则: 最后,给出示例和相应的解法: 问题:某企业生产 A 和 B 两种产品,需要使用 A、B、C 三种设备。下表显示了与工时和设备使用限制有关的产品利润率。问该企业应如何组织生产以实现下列目标? (1) 力争利润目标不低于 1 500 美元; (2) 考虑到市场需求,A、B 两种产品的生产比例应尽量保持在 1:2; (3)设备 A 是贵重设备,严禁超时使用; (4)设备 C 可以适当加班,但要控制;设备 B 要求充分利用,但尽量不加班。 从重要性来看,设备 B 的重要性是设备 C 的三倍。 建立相应的目标规划模型并求解。 解:设企业生产 A、B 两种产品的件数分别为 x1、x2,并建立相应的目标计划模型: 以下为顺序求解法,利用 LINGO 求解: 1 级目标: 模型。 设置。 variable/1..2/:x;! s_con_num/1...4/:g,dplus,dminus;!所需软约束数量(g=dplus=dminus 数量)及相关参数; s_con(s_con_num);! s_con(s_con_num,variable):c;!软约束系数; 结束集 数据。 g=1500 0 16 15. c=200 300 2 -1 4 0 0 5; 结束数据 min=dminus(1);!第一个目标函数;!对应于 min=z 的第一小部分;! 2*x(1)+2*x(2)<12;!硬约束 @for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i)); !使用设置完成的数据构建软约束表达式; ! !软约束表达式 @for(variable:@gin(x)); !将变量约束为整数; ! 结束 此时,第一级目标的最优值为 0,第一级偏差为 0: 第二级目标: !求 dminus(1)=0,然后求解第二级目标。 模型。 设置。 变量/1..2/:x;!设置:变量/1..2/:x; ! s_con_num/1...4/:g,dplus,dminus;!软约束数量及相关参数; s_con(s_con_num(s_con_num));! s_con(s_con_num,variable):c;! 软约束系数; s_con(s_con_num,variable):c;! 结束集 数据。 g=1500 0 16 15; c=200 300 2 -1 4 0 0 5; 结束数据 min=dminus(2)+dplus(2);!第二个目标函数 2*x(1)+2*x(2)<12;!硬约束 @for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i)); ! 软约束表达式;! dminus(1)=0; !第一个目标结果 @for(variable:@gin(x)); ! 结束 此时,第二个目标的最优值为 0,偏差为 0: 第三目标 !求 dminus(2)=0,然后求解第三个目标。 模型。 设置。 变量/1..2/:x;!设置:变量/1..2/:x; ! s_con_num/1...4/:g,dplus,dminus;!软约束数量及相关参数; s_con(s_con_num(s_con_num));! s_con(s_con_num,variable):c;! 软约束系数; s_con(s_con_num,variable):c;! 结束集 数据。 g=1500 0 16 15; c=200 300 2 -1 4 0 0 5; 结束数据 min=3*dminus(3)+3*dplus(3)+dminus(4);!第三个目标函数。 2*x(1)+2*x(2)<12;!硬约束 @for(s_con_num(i):@sum(variable(j):c(i,j)*x(j))+dminus(i)-dplus(i)=g(i)); ! 软约束表达式;! dminus(1)=0; !第一个目标约束条件; ! dminus(2)+dplus(2)=0; !第二个目标约束条件 @for(variable:@gin(x));! 结束 最终结果为 x1=2,x2=4,dplus(1)=100,最优利润为
-
声音响度、声压级加权(A B C)的实现