neverlib 0.2.2__py3-none-any.whl → 0.2.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. neverlib/.history/Docs/audio_aug/test_snr_20250806011311.py +0 -0
  2. neverlib/.history/Docs/audio_aug/test_snr_20250806011331.py +75 -0
  3. neverlib/.history/Docs/audio_aug/test_snr_20250806011342.py +57 -0
  4. neverlib/.history/Docs/audio_aug/test_snr_20250806011352.py +57 -0
  5. neverlib/.history/Docs/audio_aug/test_snr_20250806011403.py +57 -0
  6. neverlib/.history/Docs/audio_aug/test_snr_20250806011413.py +57 -0
  7. neverlib/.history/Docs/audio_aug/test_snr_20250806011435.py +55 -0
  8. neverlib/.history/Docs/vad/1_20250810032405.py +0 -0
  9. neverlib/.history/Docs/vad/1_20250810032417.py +39 -0
  10. neverlib/.history/audio_aug/audio_aug_20250806010451.py +125 -0
  11. neverlib/.history/audio_aug/audio_aug_20250806010750.py +138 -0
  12. neverlib/.history/audio_aug/audio_aug_20250806010759.py +140 -0
  13. neverlib/.history/audio_aug/audio_aug_20250806010803.py +140 -0
  14. neverlib/.history/audio_aug/audio_aug_20250806010809.py +140 -0
  15. neverlib/.history/audio_aug/audio_aug_20250806011108.py +140 -0
  16. neverlib/.history/dataAnalyze/__init___20250805234204.py +87 -0
  17. neverlib/.history/dataAnalyze/__init___20250806204125.py +14 -0
  18. neverlib/.history/dataAnalyze/__init___20250806204139.py +14 -0
  19. neverlib/.history/dataAnalyze/__init___20250806204159.py +14 -0
  20. neverlib/.history/filter/__init___20250820103351.py +70 -0
  21. neverlib/.history/filter/__init___20250821102348.py +70 -0
  22. neverlib/.history/filter/__init___20250821102405.py +14 -0
  23. neverlib/.history/filter/auto_eq/__init___20250819213121.py +36 -0
  24. neverlib/.history/filter/auto_eq/__init___20250821102241.py +36 -0
  25. neverlib/.history/filter/auto_eq/__init___20250821102259.py +36 -0
  26. neverlib/.history/filter/auto_eq/__init___20250821102307.py +36 -0
  27. neverlib/.history/filter/auto_eq/__init___20250821102310.py +36 -0
  28. neverlib/.history/filter/auto_eq/__init___20250821102318.py +36 -0
  29. neverlib/.history/filter/auto_eq/__init___20250821102507.py +36 -0
  30. neverlib/.history/filter/auto_eq/de_eq_20250820103848.py +361 -0
  31. neverlib/.history/filter/auto_eq/de_eq_20250821102422.py +360 -0
  32. neverlib/.history/filter/auto_eq/freq_eq_20250805234206.py +75 -0
  33. neverlib/.history/filter/auto_eq/freq_eq_20250820140732.py +75 -0
  34. neverlib/.history/filter/auto_eq/freq_eq_20250820140745.py +75 -0
  35. neverlib/.history/filter/auto_eq/freq_eq_20250820140816.py +75 -0
  36. neverlib/.history/filter/auto_eq/freq_eq_20250820140938.py +77 -0
  37. neverlib/.history/filter/auto_eq/freq_eq_20250820141003.py +77 -0
  38. neverlib/.history/filter/auto_eq/freq_eq_20250820141006.py +77 -0
  39. neverlib/.history/filter/auto_eq/freq_eq_20250820141019.py +77 -0
  40. neverlib/.history/filter/auto_eq/freq_eq_20250820141049.py +77 -0
  41. neverlib/.history/filter/auto_eq/freq_eq_20250820141211.py +77 -0
  42. neverlib/.history/filter/auto_eq/freq_eq_20250820141227.py +77 -0
  43. neverlib/.history/filter/auto_eq/freq_eq_20250820141311.py +78 -0
  44. neverlib/.history/filter/auto_eq/freq_eq_20250820141340.py +78 -0
  45. neverlib/.history/filter/auto_eq/freq_eq_20250820141712.py +78 -0
  46. neverlib/.history/filter/auto_eq/freq_eq_20250820141733.py +78 -0
  47. neverlib/.history/filter/auto_eq/freq_eq_20250820141755.py +78 -0
  48. neverlib/.history/filter/auto_eq/freq_eq_20250821102434.py +76 -0
  49. neverlib/.history/filter/auto_eq/freq_eq_20250821102500.py +76 -0
  50. neverlib/.history/filter/auto_eq/freq_eq_20250821102502.py +76 -0
  51. neverlib/.history/filter/auto_eq/ga_eq_basic_20250820102957.py +380 -0
  52. neverlib/.history/filter/auto_eq/ga_eq_basic_20250820113054.py +380 -0
  53. neverlib/.history/filter/auto_eq/ga_eq_basic_20250820113150.py +380 -0
  54. neverlib/.history/filter/auto_eq/ga_eq_basic_20250820113520.py +385 -0
  55. neverlib/.history/filter/auto_eq/ga_eq_basic_20250820113525.py +385 -0
  56. neverlib/.history/filter/auto_eq/ga_eq_basic_20250821102212.py +385 -0
  57. neverlib/.history/metrics/dnsmos_20250806001612.py +160 -0
  58. neverlib/.history/metrics/dnsmos_20250815180659.py +160 -0
  59. neverlib/.history/metrics/dnsmos_20250815180701.py +158 -0
  60. neverlib/.history/metrics/dnsmos_20250815181321.py +154 -0
  61. neverlib/.history/metrics/dnsmos_20250815181327.py +154 -0
  62. neverlib/.history/metrics/dnsmos_20250815181331.py +154 -0
  63. neverlib/.history/metrics/dnsmos_20250815181620.py +154 -0
  64. neverlib/.history/metrics/dnsmos_20250815181631.py +154 -0
  65. neverlib/.history/metrics/dnsmos_20250815181742.py +154 -0
  66. neverlib/.history/metrics/dnsmos_20250815181824.py +153 -0
  67. neverlib/.history/metrics/dnsmos_20250815181834.py +153 -0
  68. neverlib/.history/metrics/dnsmos_20250815181922.py +153 -0
  69. neverlib/.history/metrics/dnsmos_20250815182011.py +147 -0
  70. neverlib/.history/metrics/dnsmos_20250815182036.py +144 -0
  71. neverlib/.history/metrics/dnsmos_20250815182936.py +143 -0
  72. neverlib/.history/metrics/dnsmos_20250815182942.py +143 -0
  73. neverlib/.history/metrics/dnsmos_20250815183032.py +137 -0
  74. neverlib/.history/metrics/dnsmos_20250815183101.py +144 -0
  75. neverlib/.history/metrics/dnsmos_20250815183121.py +144 -0
  76. neverlib/.history/metrics/dnsmos_20250815183123.py +143 -0
  77. neverlib/.history/metrics/dnsmos_20250815183214.py +143 -0
  78. neverlib/.history/metrics/dnsmos_20250815183240.py +143 -0
  79. neverlib/.history/metrics/dnsmos_20250815183248.py +144 -0
  80. neverlib/.history/metrics/dnsmos_20250815183407.py +142 -0
  81. neverlib/.history/metrics/dnsmos_20250815183409.py +142 -0
  82. neverlib/.history/metrics/dnsmos_20250815183431.py +142 -0
  83. neverlib/.history/metrics/dnsmos_20250815183507.py +140 -0
  84. neverlib/.history/metrics/dnsmos_20250815183513.py +139 -0
  85. neverlib/.history/metrics/dnsmos_20250815183618.py +139 -0
  86. neverlib/.history/metrics/dnsmos_20250815183709.py +140 -0
  87. neverlib/.history/metrics/dnsmos_20250815183756.py +137 -0
  88. neverlib/.history/metrics/dnsmos_20250815183815.py +128 -0
  89. neverlib/.history/metrics/dnsmos_20250815183827.py +129 -0
  90. neverlib/.history/metrics/dnsmos_20250815183913.py +117 -0
  91. neverlib/.history/metrics/dnsmos_20250815183914.py +117 -0
  92. neverlib/.history/metrics/dnsmos_20250815184003.py +118 -0
  93. neverlib/.history/metrics/dnsmos_20250815184040.py +118 -0
  94. neverlib/.history/metrics/dnsmos_20250815184049.py +118 -0
  95. neverlib/.history/metrics/dnsmos_20250815184104.py +117 -0
  96. neverlib/.history/metrics/dnsmos_20250815184200.py +117 -0
  97. neverlib/.history/metrics/lpc_lsp_metric_20250816015944.py +128 -0
  98. neverlib/.history/metrics/lpc_lsp_metric_20250816020142.py +128 -0
  99. neverlib/.history/metrics/lpc_lsp_metric_20250816020156.py +128 -0
  100. neverlib/.history/metrics/lpc_lsp_metric_20250816020554.py +130 -0
  101. neverlib/.history/metrics/lpc_lsp_metric_20250816020600.py +125 -0
  102. neverlib/.history/metrics/lpc_lsp_metric_20250816020631.py +120 -0
  103. neverlib/.history/metrics/lpc_lsp_metric_20250816020746.py +118 -0
  104. neverlib/.history/metrics/lpc_me_20250816013111.py +0 -0
  105. neverlib/.history/metrics/lpc_me_20250816013129.py +121 -0
  106. neverlib/.history/metrics/lpc_me_20250816015430.py +103 -0
  107. neverlib/.history/metrics/lpc_me_20250816015535.py +96 -0
  108. neverlib/.history/metrics/lpc_me_20250816015542.py +96 -0
  109. neverlib/.history/metrics/lpc_me_20250816015636.py +97 -0
  110. neverlib/.history/metrics/lpc_me_20250816015658.py +104 -0
  111. neverlib/.history/metrics/lpc_me_20250816015703.py +100 -0
  112. neverlib/.history/metrics/lpc_me_20250816015945.py +128 -0
  113. neverlib/.history/metrics/snr_20250806010538.py +177 -0
  114. neverlib/.history/metrics/snr_20250806211634.py +184 -0
  115. neverlib/.history/metrics/spec_20250805234209.py +45 -0
  116. neverlib/.history/metrics/spec_20250816135530.py +11 -0
  117. neverlib/.history/metrics/spec_20250816135654.py +16 -0
  118. neverlib/.history/metrics/spec_20250816135736.py +68 -0
  119. neverlib/.history/metrics/spec_20250816135904.py +75 -0
  120. neverlib/.history/metrics/spec_20250816135921.py +82 -0
  121. neverlib/.history/metrics/spec_20250816140111.py +82 -0
  122. neverlib/.history/metrics/spec_20250816140543.py +136 -0
  123. neverlib/.history/metrics/spec_20250816140559.py +172 -0
  124. neverlib/.history/metrics/spec_20250816140602.py +172 -0
  125. neverlib/.history/metrics/spec_20250816140608.py +172 -0
  126. neverlib/.history/metrics/spec_20250816140654.py +148 -0
  127. neverlib/.history/metrics/spec_20250816140705.py +144 -0
  128. neverlib/.history/metrics/spec_20250816140755.py +138 -0
  129. neverlib/.history/metrics/spec_20250816140823.py +170 -0
  130. neverlib/.history/metrics/spec_20250816140832.py +170 -0
  131. neverlib/.history/metrics/spec_20250816140833.py +170 -0
  132. neverlib/.history/metrics/spec_20250816140922.py +147 -0
  133. neverlib/.history/metrics/spec_20250816141148.py +107 -0
  134. neverlib/.history/metrics/spec_20250816141219.py +123 -0
  135. neverlib/.history/metrics/spec_20250816141732.py +178 -0
  136. neverlib/.history/metrics/spec_20250816141740.py +178 -0
  137. neverlib/.history/metrics/spec_20250816142030.py +178 -0
  138. neverlib/.history/metrics/spec_20250816142107.py +135 -0
  139. neverlib/.history/metrics/spec_20250816142126.py +135 -0
  140. neverlib/.history/metrics/spec_20250816142410.py +135 -0
  141. neverlib/.history/metrics/spec_20250816142415.py +136 -0
  142. neverlib/.history/metrics/spec_metric_20250816135156.py +0 -0
  143. neverlib/.history/metrics/spec_metric_20250816135226.py +5 -0
  144. neverlib/.history/metrics/spec_metric_20250816135227.py +10 -0
  145. neverlib/.history/metrics/spec_metric_20250816135306.py +15 -0
  146. neverlib/.history/metrics/spec_metric_20250816135442.py +31 -0
  147. neverlib/.history/metrics/spec_metric_20250816135448.py +31 -0
  148. neverlib/.history/metrics/spec_metric_20250816135520.py +29 -0
  149. neverlib/.history/metrics/spec_metric_20250816135537.py +63 -0
  150. neverlib/.history/metrics/spec_metric_20250816135653.py +65 -0
  151. neverlib/.history/vad/PreProcess_20250805234211.py +63 -0
  152. neverlib/.history/vad/PreProcess_20250809232455.py +63 -0
  153. neverlib/.history/vad/PreProcess_20250816020725.py +66 -0
  154. neverlib/.history/vad/VAD_Silero_20250805234211.py +50 -0
  155. neverlib/.history/vad/VAD_Silero_20250809232456.py +50 -0
  156. neverlib/.history/vad/VAD_WebRTC_20250805234211.py +61 -0
  157. neverlib/.history/vad/VAD_WebRTC_20250809232456.py +61 -0
  158. neverlib/.history/vad/VAD_funasr_20250805234211.py +54 -0
  159. neverlib/.history/vad/VAD_funasr_20250809232456.py +54 -0
  160. neverlib/.history/vad/VAD_vadlib_20250805234211.py +70 -0
  161. neverlib/.history/vad/VAD_vadlib_20250809232455.py +70 -0
  162. neverlib/.history/vad/VAD_whisper_20250805234211.py +55 -0
  163. neverlib/.history/vad/VAD_whisper_20250809232456.py +55 -0
  164. neverlib/.specstory/.what-is-this.md +69 -0
  165. neverlib/.specstory/history/2025-08-05_17-06Z-/350/277/231/344/270/200/346/255/245/347/232/204/347/233/256/347/232/204/346/230/257/344/273/200/344/271/210.md +424 -0
  166. neverlib/Docs/audio_aug/test_snr.py +55 -0
  167. neverlib/__init__.py +2 -2
  168. neverlib/audio_aug/HarmonicDistortion.py +79 -0
  169. neverlib/audio_aug/TFDrop.py +41 -0
  170. neverlib/audio_aug/TFMask.py +56 -0
  171. neverlib/audio_aug/__init__.py +1 -1
  172. neverlib/audio_aug/audio_aug.py +19 -5
  173. neverlib/audio_aug/clip_aug.py +41 -0
  174. neverlib/audio_aug/coder_aug.py +209 -0
  175. neverlib/audio_aug/coder_aug2.py +118 -0
  176. neverlib/audio_aug/loss_packet_aug.py +103 -0
  177. neverlib/audio_aug/quant_aug.py +78 -0
  178. neverlib/data_analyze/README.md +234 -0
  179. neverlib/data_analyze/__init__.py +14 -0
  180. neverlib/data_analyze/dataset_analyzer.py +590 -0
  181. neverlib/data_analyze/quality_metrics.py +364 -0
  182. neverlib/data_analyze/rms_distrubution.py +62 -0
  183. neverlib/data_analyze/spectral_analysis.py +218 -0
  184. neverlib/data_analyze/statistics.py +406 -0
  185. neverlib/data_analyze/temporal_features.py +126 -0
  186. neverlib/data_analyze/visualization.py +468 -0
  187. neverlib/filter/README.md +101 -0
  188. neverlib/filter/__init__.py +7 -0
  189. neverlib/filter/auto_eq/README.md +165 -0
  190. neverlib/filter/auto_eq/__init__.py +36 -0
  191. neverlib/filter/auto_eq/de_eq.py +360 -0
  192. neverlib/filter/auto_eq/freq_eq.py +76 -0
  193. neverlib/filter/auto_eq/ga_eq_advanced.py +577 -0
  194. neverlib/filter/auto_eq/ga_eq_basic.py +385 -0
  195. neverlib/filter/biquad.py +45 -0
  196. neverlib/filter/common.py +5 -6
  197. neverlib/filter/core.py +339 -0
  198. neverlib/metrics/dnsmos.py +117 -0
  199. neverlib/metrics/lpc_lsp.py +118 -0
  200. neverlib/metrics/snr.py +184 -0
  201. neverlib/metrics/spec.py +136 -0
  202. neverlib/metrics/test_pesq.py +35 -0
  203. neverlib/metrics/time.py +68 -0
  204. neverlib/tests/test_vad.py +21 -0
  205. neverlib/utils/audio_split.py +2 -1
  206. neverlib/utils/message.py +4 -4
  207. neverlib/utils/utils.py +36 -16
  208. neverlib/vad/PreProcess.py +6 -3
  209. neverlib/vad/README.md +10 -10
  210. neverlib/vad/VAD_Energy.py +1 -1
  211. neverlib/vad/VAD_Silero.py +2 -2
  212. neverlib/vad/VAD_WebRTC.py +2 -2
  213. neverlib/vad/VAD_funasr.py +2 -2
  214. neverlib/vad/VAD_statistics.py +3 -3
  215. neverlib/vad/VAD_vadlib.py +3 -3
  216. neverlib/vad/VAD_whisper.py +2 -2
  217. neverlib/vad/__init__.py +1 -1
  218. neverlib/vad/class_get_speech.py +4 -4
  219. neverlib/vad/class_vad.py +1 -1
  220. neverlib/vad/utils.py +47 -5
  221. {neverlib-0.2.2.dist-info → neverlib-0.2.4.dist-info}/METADATA +120 -120
  222. neverlib-0.2.4.dist-info/RECORD +229 -0
  223. {neverlib-0.2.2.dist-info → neverlib-0.2.4.dist-info}/WHEEL +1 -1
  224. neverlib/Documents/vad/VAD_Energy.ipynb +0 -159
  225. neverlib/Documents/vad/VAD_Silero.ipynb +0 -305
  226. neverlib/Documents/vad/VAD_WebRTC.ipynb +0 -183
  227. neverlib/Documents/vad/VAD_funasr.ipynb +0 -179
  228. neverlib/Documents/vad/VAD_ppasr.ipynb +0 -175
  229. neverlib/Documents/vad/VAD_statistics.ipynb +0 -522
  230. neverlib/Documents/vad/VAD_vadlib.ipynb +0 -184
  231. neverlib/Documents/vad/VAD_whisper.ipynb +0 -430
  232. neverlib/utils/waveform_analyzer.py +0 -51
  233. neverlib/wav_data/000_short.wav +0 -0
  234. neverlib-0.2.2.dist-info/RECORD +0 -40
  235. {neverlib-0.2.2.dist-info → neverlib-0.2.4.dist-info}/licenses/LICENSE +0 -0
  236. {neverlib-0.2.2.dist-info → neverlib-0.2.4.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,339 @@
1
+ '''
2
+ Author: 凌逆战 | Never
3
+ Date: 2025-08-04 16:25:00
4
+ Description: EQ滤波器
5
+ type(fc, gain, Q)
6
+
7
+ enum IIR_BIQUARD_TYPE {
8
+ IIR_BIQUARD_PASS = 0, // pass through
9
+ IIR_BIQUARD_RAW, // raw filter
10
+ IIR_BIQUARD_LPF, // 低通滤波器 low pass filter
11
+ IIR_BIQUARD_HPF, // 高通滤波器 high pass filter
12
+ IIR_BIQUARD_BPF0, // 带通滤波器 band pass filter, constant skirt gain, peak gain = Q
13
+ IIR_BIQUARD_BPF1, // 带通滤波器 band pass filter, const 0 dB peak gain
14
+ IIR_BIQUARD_NOTCH, // 陷波滤波器 notch filter
15
+ IIR_BIQUARD_APF, // 全通滤波器 allpass filter
16
+ IIR_BIQUARD_PEAKINGEQ, // 峰值滤波器 peakingEQ
17
+ IIR_BIQUARD_LOWSHELF, // 低切滤波器 low shelf filter
18
+ IIR_BIQUARD_HIGHSHELF, // 高切滤波器 high shelf filter
19
+ IIR_BIQUARD_QTY // number of biquard types
20
+ };
21
+ '''
22
+ import random
23
+ import numpy as np
24
+ from scipy import signal
25
+
26
+
27
+ class EQFilter():
28
+ def __init__(self, fs=16000):
29
+ self.fs = fs
30
+
31
+ def LowpassFilter(self, fc, Q=1 / np.sqrt(2.0)):
32
+ """ 低通滤波器(Low Pass Filter)
33
+ LPF: H(s) = 1 / (s^2 + s/Q + 1)
34
+
35
+ b0 = (1 - cos(w0))/2;
36
+ b1 = 1 - cos(w0);
37
+ b2 = (1 - cos(w0))/2;
38
+ a0 = 1 + alpha;
39
+ a1 = -2*cos(w0);
40
+ a2 = 1 - alpha;
41
+ """
42
+ # 中间变量
43
+ w0 = 2.0 * np.pi * fc / self.fs # 角频率
44
+ cos_w0 = np.cos(w0) # cos(w0)
45
+ sin_w0 = np.sin(w0) # sin(w0)
46
+ alpha = sin_w0 / (2.0 * Q) # alpha
47
+ # ---------------------------------------------
48
+ b0 = (1.0 - cos_w0) / 2.0
49
+ b1 = 1.0 - cos_w0
50
+ b2 = (1.0 - cos_w0) / 2.0
51
+ a0 = 1.0 + alpha
52
+ a1 = -2.0 * cos_w0
53
+ a2 = 1.0 - alpha
54
+ numerator_B = np.array([b0, b1, b2], dtype=np.float32)
55
+ denominator_A = np.array([a0, a1, a2], dtype=np.float32)
56
+ return numerator_B / a0, denominator_A / a0
57
+
58
+ def HighpassFilter(self, fc, Q=1 / np.sqrt(2)):
59
+ """ 高通滤波器(High Pass Filter)
60
+ HPF: $H(s)=\frac{s^2}{s^2 + s/Q + 1}$
61
+ b0 = (1 + cos(w0))/2
62
+ b1 = -(1 + cos(w0))
63
+ b2 = (1 + cos(w0))/2
64
+ a0 = 1 + alpha
65
+ a1 = -2*cos(w0)
66
+ a2 = 1 - alpha
67
+ """
68
+ # 中间变量
69
+ w0 = 2.0 * np.pi * fc / self.fs # 角频率
70
+ cos_w0 = np.cos(w0) # cos(w0)
71
+ sin_w0 = np.sin(w0) # sin(w0)
72
+ alpha = sin_w0 / (2.0 * Q) # alpha
73
+ # ---------------------------------------------
74
+ b0 = (1.0 + cos_w0) / 2.0
75
+ b1 = -(1.0 + cos_w0)
76
+ b2 = (1.0 + cos_w0) / 2.0
77
+ a0 = 1.0 + alpha
78
+ a1 = -2.0 * cos_w0
79
+ a2 = 1.0 - alpha
80
+ numerator_B = np.array([b0, b1, b2], dtype=np.float32)
81
+ denominator_A = np.array([a0, a1, a2], dtype=np.float32)
82
+ return numerator_B / a0, denominator_A / a0
83
+
84
+ def BandpassFilter_Q(self, fc, Q):
85
+ """带通 Band Pass Filter (增益 = Q)
86
+ BPF: H(s) = s / (s^2 + s/Q + 1) (constant skirt gain, peak gain = Q)
87
+ b0 = sin(w0)/2 = Q*alpha
88
+ b1 = 0
89
+ b2 = -sin(w0)/2 = -Q*alpha
90
+ a0 = 1 + alpha
91
+ a1 = -2*cos(w0)
92
+ a2 = 1 - alpha
93
+ """
94
+ # 中间变量
95
+ w0 = 2.0 * np.pi * fc / self.fs # 角频率
96
+ cos_w0 = np.cos(w0) # cos(w0)
97
+ sin_w0 = np.sin(w0) # sin(w0)
98
+ alpha = sin_w0 / (2.0 * Q) # alpha
99
+ # ---------------------------------------------
100
+ b0 = sin_w0 / 2.0 # Q*alpha
101
+ b1 = 0.0
102
+ b2 = -sin_w0 / 2.0 # -Q*alpha
103
+ a0 = 1.0 + alpha
104
+ a1 = -2.0 * cos_w0
105
+ a2 = 1.0 - alpha
106
+ numerator_B = np.array([b0, b1, b2], dtype=np.float32)
107
+ denominator_A = np.array([a0, a1, a2], dtype=np.float32)
108
+ return numerator_B / a0, denominator_A / a0
109
+
110
+ def BandpassFilter_0dB(self, fc, Q=1 / np.sqrt(2)):
111
+ """带通 Band Pass Filter(0 db增益)
112
+ BPF: H(s) = (s/Q) / (s^2 + s/Q + 1) (constant 0 dB peak gain)
113
+ b0 = alpha
114
+ b1 = 0
115
+ b2 = -alpha
116
+ a0 = 1 + alpha
117
+ a1 = -2*cos(w0)
118
+ a2 = 1 - alpha
119
+ """
120
+ # 中间变量
121
+ w0 = 2.0 * np.pi * fc / self.fs # 角频率
122
+ cos_w0 = np.cos(w0) # cos(w0)
123
+ sin_w0 = np.sin(w0) # sin(w0)
124
+ alpha = sin_w0 / (2.0 * Q) # alpha
125
+ # ---------------------------------------------
126
+ b0 = alpha
127
+ b1 = 0.0
128
+ b2 = -alpha
129
+ a0 = 1.0 + alpha
130
+ a1 = -2.0 * cos_w0
131
+ a2 = 1.0 - alpha
132
+ numerator_B = np.array([b0, b1, b2], dtype=np.float32)
133
+ denominator_A = np.array([a0, a1, a2], dtype=np.float32)
134
+ return numerator_B / a0, denominator_A / a0
135
+
136
+ def NotchFilter(self, fc, Q=1 / np.sqrt(2)):
137
+ """Notch滤波器
138
+ notch: H(s) = (s^2 + 1) / (s^2 + s/Q + 1)$
139
+ b0 = 1
140
+ b1 = -2*cos(w0)
141
+ b2 = 1
142
+ a0 = 1 + alpha
143
+ a1 = -2*cos(w0)
144
+ a2 = 1 - alpha
145
+ """
146
+ # 中间变量
147
+ w0 = 2.0 * np.pi * fc / self.fs # 角频率
148
+ cos_w0 = np.cos(w0) # cos(w0)
149
+ sin_w0 = np.sin(w0) # sin(w0)
150
+ alpha = sin_w0 / (2.0 * Q) # alpha
151
+ # ---------------------------------------------
152
+ b0 = 1.0
153
+ b1 = -2.0 * cos_w0
154
+ b2 = 1.0
155
+ a0 = 1.0 + alpha
156
+ a1 = -2.0 * cos_w0
157
+ a2 = 1.0 - alpha
158
+ numerator_B = np.array([b0, b1, b2], dtype=np.float32)
159
+ denominator_A = np.array([a0, a1, a2], dtype=np.float32)
160
+ return numerator_B / a0, denominator_A / a0
161
+
162
+ def AllpassFilter(self, fc, Q=1 / np.sqrt(2)):
163
+ """全通 All Pass Filter
164
+ APF: H(s) = (s^2 - s/Q + 1) / (s^2 + s/Q + 1)$
165
+ b0 = 1 - alpha
166
+ b1 = -2*cos(w0)
167
+ b2 = 1 + alpha
168
+ a0 = 1 + alpha
169
+ a1 = -2*cos(w0)
170
+ a2 = 1 - alpha
171
+ """
172
+ # 中间变量
173
+ w0 = 2.0 * np.pi * fc / self.fs # 角频率
174
+ cos_w0 = np.cos(w0) # cos(w0)
175
+ sin_w0 = np.sin(w0) # sin(w0)
176
+ alpha = sin_w0 / (2.0 * Q) # alpha
177
+ # ---------------------------------------------
178
+ b0 = 1.0 - alpha
179
+ b1 = -2.0 * cos_w0
180
+ b2 = 1.0 + alpha
181
+ a0 = 1.0 + alpha
182
+ a1 = -2.0 * cos_w0
183
+ a2 = 1.0 - alpha
184
+ numerator_B = np.array([b0, b1, b2], dtype=np.float32)
185
+ denominator_A = np.array([a0, a1, a2], dtype=np.float32)
186
+ return numerator_B / a0, denominator_A / a0
187
+
188
+ def PeakingFilter(self, fc, dBgain, Q=1 / np.sqrt(2)):
189
+ """峰值滤波器
190
+ peakingEQ: H(s) = (s^2 + s*(A/Q) + 1) / (s^2 + s/(A*Q) + 1)
191
+ b0 = 1 + alpha*A
192
+ b1 = -2*cos(w0)
193
+ b2 = 1 - alpha*A
194
+ a0 = 1 + alpha/A
195
+ a1 = -2*cos(w0)
196
+ a2 = 1 - alpha/A
197
+ """
198
+ # 中间变量
199
+ w0 = 2.0 * np.pi * fc / self.fs # 角频率
200
+ # cos_w0 = np.cos(w0) # cos(w0)
201
+ sin_w0 = np.sin(w0) # sin(w0)
202
+ alpha = sin_w0 / (2.0 * Q) # alpha
203
+ # gain、A 仅用于峰值和shelf滤波器
204
+ dBgain = round(float(dBgain), 3)
205
+ A = 10 ** (dBgain / 40)
206
+ # ---------------------------------------------
207
+ b0 = 1 + alpha * A
208
+ b1 = -2 * np.cos(w0)
209
+ b2 = 1 - alpha * A
210
+ a0 = 1 + alpha / A
211
+ a1 = -2 * np.cos(w0)
212
+ a2 = 1 - alpha / A
213
+ numerator_B = np.array([b0, b1, b2], dtype=np.float32)
214
+ denominator_A = np.array([a0, a1, a2], dtype=np.float32)
215
+ return numerator_B / a0, denominator_A / a0
216
+
217
+ def LowshelfFilter(self, fc, dBgain, Q=1 / np.sqrt(2)):
218
+ """低切滤波器
219
+ lowShelf: H(s) = A * (s^2 + (sqrt(A)/Q)*s + A)/(A*s^2 + (sqrt(A)/Q)*s + 1)
220
+ b0 = A*( (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha )
221
+ b1 = 2*A*( (A-1) - (A+1)*cos(w0) )
222
+ b2 = A*( (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha )
223
+ a0 = (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha
224
+ a1 = -2*( (A-1) + (A+1)*cos(w0) )
225
+ a2 = (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha
226
+ """
227
+ # 中间变量
228
+ w0 = 2.0 * np.pi * fc / self.fs # 角频率
229
+ cos_w0 = np.cos(w0) # cos(w0)
230
+ sin_w0 = np.sin(w0) # sin(w0)
231
+ alpha = sin_w0 / (2.0 * Q) # alpha
232
+ # gain、A 仅用于峰值和shelf滤波器
233
+ dBgain = round(float(dBgain), 3)
234
+ A = 10.0 ** (dBgain / 40.0)
235
+ # ---------------------------------------------
236
+ b0 = A * ((A + 1) - (A - 1) * cos_w0 + 2 * np.sqrt(A) * alpha)
237
+ b1 = 2 * A * ((A - 1) - (A + 1) * cos_w0)
238
+ b2 = A * ((A + 1) - (A - 1) * cos_w0 - 2 * np.sqrt(A) * alpha)
239
+ a0 = (A + 1) + (A - 1) * cos_w0 + 2 * np.sqrt(A) * alpha
240
+ a1 = -2 * ((A - 1) + (A + 1) * cos_w0)
241
+ a2 = (A + 1) + (A - 1) * cos_w0 - 2 * np.sqrt(A) * alpha
242
+ numerator_B = np.array([b0, b1, b2], dtype=np.float32)
243
+ denominator_A = np.array([a0, a1, a2], dtype=np.float32)
244
+ return numerator_B / a0, denominator_A / a0
245
+
246
+ def HighshelfFilter(self, fc, dBgain, Q=1 / np.sqrt(2)):
247
+ """高切滤波器
248
+ highShelf: H(s) = A * (A*s^2 + (sqrt(A)/Q)*s + 1)/(s^2 + (sqrt(A)/Q)*s + A)
249
+ b0 = A*( (A+1) + (A-1)*cos(w0) + 2*sqrt(A)*alpha )
250
+ b1 = -2*A*( (A-1) + (A+1)*cos(w0) )
251
+ b2 = A*( (A+1) + (A-1)*cos(w0) - 2*sqrt(A)*alpha )
252
+ a0 = (A+1) - (A-1)*cos(w0) + 2*sqrt(A)*alpha
253
+ a1 = 2*( (A-1) - (A+1)*cos(w0) )
254
+ a2 = (A+1) - (A-1)*cos(w0) - 2*sqrt(A)*alpha
255
+ """
256
+ # 中间变量
257
+ w0 = 2.0 * np.pi * fc / self.fs # 角频率
258
+ cos_w0 = np.cos(w0) # cos(w0)
259
+ sin_w0 = np.sin(w0) # sin(w0)
260
+ alpha = sin_w0 / (2.0 * Q) # alpha
261
+ # gain、A 仅用于峰值和shelf滤波器
262
+ dBgain = round(float(dBgain), 3)
263
+ A = 10.0 ** (dBgain / 40.0)
264
+ # ---------------------------------------------
265
+ b0 = A * ((A + 1) + (A - 1) * cos_w0 + 2 * np.sqrt(A) * alpha)
266
+ b1 = -2 * A * ((A - 1) + (A + 1) * cos_w0)
267
+ b2 = A * ((A + 1) + (A - 1) * cos_w0 - 2 * np.sqrt(A) * alpha)
268
+ a0 = (A + 1) - (A - 1) * cos_w0 + 2 * np.sqrt(A) * alpha
269
+ a1 = 2 * ((A - 1) - (A + 1) * cos_w0)
270
+ a2 = (A + 1) - (A - 1) * cos_w0 - 2 * np.sqrt(A) * alpha
271
+ numerator_B = np.array([b0, b1, b2], dtype=np.float32)
272
+ denominator_A = np.array([a0, a1, a2], dtype=np.float32)
273
+ return numerator_B / a0, denominator_A / a0
274
+
275
+
276
+ def eq_process(sig, b_list, a_list, ratio):
277
+ """ psap eq增强
278
+ :param sig: input signal with size [T] or [T, C]
279
+ :param b_list: 滤波器系数列表
280
+ :param a_list: 滤波器系数列表
281
+ :param ratio: 0-1, processing ratio
282
+ :return: [T] when ipt.shape is [T]; [T, C] when ipt.shape is [T, C]
283
+ """
284
+ if len(sig.shape) == 1:
285
+ sig.shape = -1, 1
286
+ assert len(sig.shape) == 2, f"input signal's shape must be 2, but {sig.shape} now!"
287
+ sig_eq = sig.copy()
288
+ if random.random() < ratio:
289
+ # 逐个应用滤波器
290
+ for b, a in zip(b_list, a_list):
291
+ sig_eq = signal.lfilter(b, a, sig_eq, axis=0)
292
+ return sig_eq
293
+
294
+
295
+ def eq_process_test():
296
+ import soundfile as sf
297
+
298
+ EQ_Coef = [
299
+ ([1.5023072, -1.0912886, 0.1981803], [1., -1.3417218, 0.4500543]), # f0 = 80, gain = -20, q = 1
300
+ ([1.2288871, -1.173879, 0.18292512], [1., -1.173879, 0.4118123]), # f0 = 100, gain = -10, q = 1
301
+ ]
302
+
303
+ wav, wav_sr = sf.read("./white.wav", dtype="float32", always_2d=True)
304
+
305
+ wav = eq_process(wav, EQ_Coef, ratio=1)
306
+
307
+ sf.write("./white_eq.wav", wav, wav_sr)
308
+
309
+
310
+ def EQ_test():
311
+ """
312
+ lowshelf滤波器 freq=1.5kHz, gain=15dB, Q=0.5
313
+ b: [ 1.5023072 -1.0912886 0.1981803]
314
+ a: [ 1. -1.3417218 0.4500543]
315
+
316
+ peak freq=1.5kHz, gain=5dB, Q=0.5
317
+ b: [ 1.2288871 -1.173879 0.18292512]
318
+ a: [ 1. -1.173879 0.4118123]
319
+ """
320
+ import numpy as np
321
+ import matplotlib.pyplot as plt
322
+ from scipy import signal
323
+
324
+ fs = 16000
325
+
326
+ # b, a = LowshelfFilter(1500, 15, Q=0.5)
327
+ b, a = PeakingFilter(1500, 5, Q=0.5)
328
+ print(b)
329
+ print(a)
330
+
331
+ w, h = signal.freqz(b, a) # 根据系数计算滤波器的频率响应, w是角频率, h是频率响应
332
+ plt.plot(0.5 * fs * w / np.pi, 20 * np.log10(h)) # 0.5*fs*w/np.pi 为频率
333
+ plt.title('Butterworth filter frequency response')
334
+ plt.xlabel('Frequency [Hz]')
335
+ plt.ylabel('Amplitude [dB]')
336
+ plt.grid(which='both', axis='both') # 显示网格
337
+ # 画红色的垂直线, 标记截止频率
338
+ plt.xscale('log') # x轴对数化
339
+ plt.show()
@@ -0,0 +1,117 @@
1
+ '''
2
+ Author: 凌逆战 | Never
3
+ Date: 2025-08-06 10:00:00
4
+ Description:
5
+ 要计算个性化 MOS 分数(干扰说话者受到惩罚),请提供“-p”参数,例如:python dnsmos.py -t ./SampleClips -o sample.csv -p
6
+ 要计算常规 MOS 分数,请省略“-p”参数。例如:python dnsmos.py -t ./SampleClips -o sample.csv
7
+ '''
8
+ import argparse
9
+ import concurrent.futures
10
+ import glob
11
+ import os
12
+ import librosa
13
+ import numpy as np
14
+ import onnxruntime as ort
15
+ import pandas as pd
16
+ import soundfile as sf
17
+ from tqdm import tqdm
18
+ from neverlib.utils import get_path_list
19
+
20
+
21
+ class ComputeScore:
22
+ def __init__(self, is_personalized_MOS, sr, input_length) -> None:
23
+ self.sr = sr
24
+ self.input_length = input_length
25
+ self.is_personalized_MOS = is_personalized_MOS
26
+ p808_model_path = "./DNSMOS/model_v8.onnx"
27
+ if is_personalized_MOS:
28
+ primary_model_path = "./pDNSMOS/sig_bak_ovr.onnx"
29
+ else:
30
+ primary_model_path = "./DNSMOS/sig_bak_ovr.onnx"
31
+
32
+ self.onnx_sess = ort.InferenceSession(primary_model_path)
33
+ self.p808_onnx_sess = ort.InferenceSession(p808_model_path)
34
+
35
+ def audio_melspec(self, audio, n_mels=120, frame_size=320, hop_length=160, to_db=True):
36
+ mel_spec = librosa.feature.melspectrogram(y=audio, sr=self.sr, n_fft=frame_size + 1, hop_length=hop_length, n_mels=n_mels)
37
+ if to_db:
38
+ mel_spec = (librosa.power_to_db(mel_spec, ref=np.max) + 40) / 40
39
+ return mel_spec.T
40
+
41
+ def get_polyfit_val(self, sig, bak, ovr):
42
+ if self.is_personalized_MOS:
43
+ p_ovr = np.poly1d([-0.00533021, 0.005101, 1.18058466, -0.11236046])
44
+ p_sig = np.poly1d([-0.01019296, 0.02751166, 1.19576786, -0.24348726])
45
+ p_bak = np.poly1d([-0.04976499, 0.44276479, -0.1644611, 0.96883132])
46
+ else:
47
+ p_ovr = np.poly1d([-0.06766283, 1.11546468, 0.04602535])
48
+ p_sig = np.poly1d([-0.08397278, 1.22083953, 0.0052439])
49
+ p_bak = np.poly1d([-0.13166888, 1.60915514, -0.39604546])
50
+
51
+ sig_poly, bak_poly, ovr_poly = p_sig(sig), p_bak(bak), p_ovr(ovr)
52
+
53
+ return sig_poly, bak_poly, ovr_poly
54
+
55
+ def __call__(self, wav_path):
56
+ wav, wav_sr = sf.read(wav_path, dtype='float32')
57
+ if wav_sr != self.sr:
58
+ wav = librosa.resample(wav, wav_sr, self.sr)
59
+ else:
60
+ wav = wav
61
+ len_samples = int(self.input_length * self.sr)
62
+ while len(wav) < len_samples:
63
+ wav = np.append(wav, wav)
64
+
65
+ num_hops = int(np.floor(len(wav) / self.sr) - self.input_length) + 1
66
+ hop_len_samples = self.sr
67
+ predicted_mos_sig_seg_raw = []
68
+ predicted_mos_bak_seg_raw = []
69
+ predicted_mos_ovr_seg_raw = []
70
+ predicted_mos_sig_seg = []
71
+ predicted_mos_bak_seg = []
72
+ predicted_mos_ovr_seg = []
73
+ predicted_p808_mos = []
74
+
75
+ for idx in range(num_hops):
76
+ wav_seg = wav[int(idx * hop_len_samples): int((idx + self.input_length) * hop_len_samples)]
77
+ if len(wav_seg) < len_samples:
78
+ continue
79
+
80
+ input_features = np.array(wav_seg)[np.newaxis, :]
81
+ p808_input_features = np.array(self.audio_melspec(audio=wav_seg[:-160]))[np.newaxis, :, :]
82
+ oi = {'input_1': input_features}
83
+ p808_oi = {'input_1': p808_input_features}
84
+ p808_mos = self.p808_onnx_sess.run(None, p808_oi)[0][0][0]
85
+ mos_sig_raw, mos_bak_raw, mos_ovr_raw = self.onnx_sess.run(None, oi)[0][0]
86
+ mos_sig, mos_bak, mos_ovr = self.get_polyfit_val(mos_sig_raw, mos_bak_raw, mos_ovr_raw)
87
+ predicted_mos_sig_seg_raw.append(mos_sig_raw)
88
+ predicted_mos_bak_seg_raw.append(mos_bak_raw)
89
+ predicted_mos_ovr_seg_raw.append(mos_ovr_raw)
90
+ predicted_mos_sig_seg.append(mos_sig)
91
+ predicted_mos_bak_seg.append(mos_bak)
92
+ predicted_mos_ovr_seg.append(mos_ovr)
93
+ predicted_p808_mos.append(p808_mos)
94
+ out_dict = {}
95
+ out_dict['OVRL_raw'] = np.mean(predicted_mos_ovr_seg_raw)
96
+ out_dict['SIG_raw'] = np.mean(predicted_mos_sig_seg_raw)
97
+ out_dict['BAK_raw'] = np.mean(predicted_mos_bak_seg_raw)
98
+ out_dict['OVRL'] = np.mean(predicted_mos_ovr_seg)
99
+ out_dict['SIG'] = np.mean(predicted_mos_sig_seg)
100
+ out_dict['BAK'] = np.mean(predicted_mos_bak_seg)
101
+ out_dict['P808_MOS'] = np.mean(predicted_p808_mos)
102
+ return out_dict
103
+
104
+
105
+ def main():
106
+ SAMPLING_RATE = 16000
107
+ INPUT_LENGTH = 9.01
108
+ is_personalized_MOS = False
109
+ testset_dir = "../data/vad_example.wav"
110
+
111
+ compute_score = ComputeScore(is_personalized_MOS, SAMPLING_RATE, INPUT_LENGTH)
112
+ data = compute_score(testset_dir)
113
+ print(data)
114
+
115
+
116
+ if __name__ == "__main__":
117
+ main()
@@ -0,0 +1,118 @@
1
+ '''
2
+ 功能描述
3
+
4
+ 计算参考语音和测试语音之间的线性预测编码-线谱对(LPC-LSP)参
5
+ 数失真度
6
+
7
+ 主要组件
8
+
9
+ 预处理函数:
10
+ - pre_emphasis(): 预加重滤波,增强高频成分
11
+ - framing(): 分帧处理并应用汉明窗
12
+
13
+ LPC分析:
14
+ - lpc_analysis(): 使用librosa.lpc进行线性预测分析
15
+ - lpc_to_lsp(): LPC系数转换为线谱对参数
16
+
17
+ 距离计算:
18
+ - lsp_mse(): 计算LSP向量间的均方误差
19
+ - lpc_lsp_distance(): 主函数,返回平均失真度和逐帧失真列表
20
+
21
+ 技术特点
22
+
23
+ - 使用soundfile读取音频(支持多种格式)
24
+ - librosa进行LPC分析(替代了自定义算法)
25
+ - 基于LSP的频域失真测量,对量化误差敏感度更低
26
+ - 逐帧分析捕捉语音时变特性
27
+
28
+ 应用场景
29
+
30
+ 语音编码器质量评估、语音增强效果测量、语音合成质量分析
31
+ '''
32
+ import numpy as np
33
+ import librosa
34
+ import soundfile as sf
35
+ from neverlib.vad.PreProcess import pre_emphasis
36
+
37
+
38
+ def framing(signal, frame_size, frame_stride, fs):
39
+ """分帧 + 汉明窗"""
40
+ frame_length = int(round(frame_size * fs))
41
+ frame_step = int(round(frame_stride * fs))
42
+
43
+ # 使用 librosa 进行分帧
44
+ frames = librosa.util.frame(signal, frame_length=frame_length, hop_length=frame_step, axis=0)
45
+
46
+ # frames的形状是(num_frames, frame_length)
47
+ hamming_window = np.hamming(frame_length)
48
+ frames = frames * hamming_window # 直接广播
49
+
50
+ return frames
51
+
52
+
53
+ def lpc_to_lsp(a, num_points=512):
54
+ """
55
+ LPC -> LSP 转换(简易近似版,零点搜索法)
56
+ """
57
+ p = len(a) - 1
58
+ a = np.array(a)
59
+ # 构造P(z) Q(z)
60
+ P = np.zeros(p+1)
61
+ Q = np.zeros(p+1)
62
+ for i in range(p+1):
63
+ if i == 0:
64
+ P[i] = 1 + a[i]
65
+ Q[i] = 1 - a[i]
66
+ else:
67
+ P[i] = a[i] + a[p - i]
68
+ Q[i] = a[i] - a[p - i]
69
+ # 频域采样找过零点
70
+ w = np.linspace(0, np.pi, num_points)
71
+ Pw = np.polyval(P[::-1], np.cos(w))
72
+ Qw = np.polyval(Q[::-1], np.cos(w))
73
+
74
+ # 找零点近似位置
75
+ roots_P = w[np.where(np.diff(np.sign(Pw)) != 0)]
76
+ roots_Q = w[np.where(np.diff(np.sign(Qw)) != 0)]
77
+ lsp = np.sort(np.concatenate([roots_P, roots_Q]))
78
+ return lsp
79
+
80
+
81
+ def lpc_lsp_distance(ref_wav, test_wav, frame_size=0.025, frame_stride=0.01, order=12):
82
+ """主函数:计算 LPC-LSP 参数失真"""
83
+ ref_sig, fs_r = sf.read(ref_wav, dtype='float32')
84
+ test_sig, fs_t = sf.read(test_wav, dtype='float32')
85
+
86
+ # 预加重
87
+ ref_sig = pre_emphasis(ref_sig)
88
+ test_sig = pre_emphasis(test_sig)
89
+
90
+ # 分帧
91
+ ref_frames = framing(ref_sig, frame_size, frame_stride, fs_r)
92
+ test_frames = framing(test_sig, frame_size, frame_stride, fs_t)
93
+
94
+ # 对齐帧数(简单切到最短)
95
+ num_frames = min(len(ref_frames), len(test_frames))
96
+ ref_frames = ref_frames[:num_frames]
97
+ test_frames = test_frames[:num_frames]
98
+
99
+ distances = []
100
+ for i in range(num_frames):
101
+ a_ref = librosa.lpc(ref_frames[i], order=order)
102
+ a_test = librosa.lpc(test_frames[i], order=order)
103
+ lsp_ref = lpc_to_lsp(a_ref)
104
+ lsp_test = lpc_to_lsp(a_test)
105
+ # 对齐长度(简单裁切)
106
+ min_len = min(len(lsp_ref), len(lsp_test))
107
+ # 计算两个 LSP 向量的均方差
108
+ dist = np.mean((lsp_ref[:min_len] - lsp_test[:min_len]) ** 2)
109
+ distances.append(dist)
110
+
111
+ return np.mean(distances), distances
112
+
113
+ if __name__ == "__main__":
114
+ ref_file = "../data/vad_example.wav" # 参考语音文件路径
115
+ test_file = "../data/vad_example.wav" # 测试语音文件路径
116
+
117
+ avg_dist, dist_list = lpc_lsp_distance(ref_file, test_file)
118
+ print(f"平均 LSP MSE 失真: {avg_dist}")