neverlib 0.2.4__py3-none-any.whl → 0.2.6__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.
- neverlib/.history/Docs/audio_aug/del_20250827162530.py +0 -0
- neverlib/.history/Docs/audio_aug/del_20250827162540.py +2 -0
- neverlib/.history/Docs/audio_aug/del_20250827162541.py +7 -0
- neverlib/.history/Docs/audio_aug/del_20250827162606.py +7 -0
- neverlib/.history/Docs/audio_aug/del_20250827162637.py +8 -0
- neverlib/.history/Docs/audio_aug/del_20250827162645.py +8 -0
- neverlib/.history/Docs/audio_aug/del_20250827162723.py +9 -0
- neverlib/.history/Docs/audio_aug/del_20250827162739.py +9 -0
- neverlib/.history/Docs/audio_aug/test_snr_20250827161751.py +55 -0
- neverlib/.history/Docs/audio_aug/test_snr_20250827161754.py +55 -0
- neverlib/.history/Docs/audio_aug/test_snr_20250827161833.py +54 -0
- neverlib/.history/Docs/audio_aug/test_snr_20250827162017.py +56 -0
- neverlib/.history/Docs/audio_aug/test_snr_20250827162021.py +57 -0
- neverlib/.history/Docs/audio_aug/test_snr_20250827162028.py +57 -0
- neverlib/.history/Docs/audio_aug_test/del_20250827162738.py +9 -0
- neverlib/.history/Docs/audio_aug_test/del_20250827162819.py +9 -0
- neverlib/.history/Docs/audio_aug_test/del_20250827162830.py +9 -0
- neverlib/.history/Docs/audio_aug_test/del_20250827162846.py +9 -0
- neverlib/.history/Docs/audio_aug_test/del_20250827162851.py +9 -0
- neverlib/.history/Docs/audio_aug_test/del_20250827162903.py +10 -0
- neverlib/.history/Docs/audio_aug_test/del_20250827162921.py +10 -0
- neverlib/.history/Docs/audio_aug_test/del_20250827162926.py +10 -0
- neverlib/.history/Docs/audio_aug_test/del_20250827163030.py +10 -0
- neverlib/.history/Docs/audio_aug_test/del_20250827163032.py +10 -0
- neverlib/.history/QA/html2markdown_20250822234112.md +0 -0
- neverlib/.history/QA/html2markdown_20250822234140.py +9 -0
- neverlib/.history/QA/html2markdown_20250822234141.md +9 -0
- neverlib/.history/QA/html2markdown_20250822234159.py +12 -0
- neverlib/.history/QA/html2markdown_20250822234200.py +17 -0
- neverlib/.history/QA/html2markdown_20250822234236.py +17 -0
- neverlib/.history/QA/html2markdown_20250822234340.py +14 -0
- neverlib/.history/QA/html2markdown_20250822234522.py +18 -0
- neverlib/.history/QA/html2markdown_20250822234601.py +20 -0
- neverlib/.history/QA/html2markdown_20250822234615.py +22 -0
- neverlib/.history/QA/html2markdown_20250822234715.py +28 -0
- neverlib/.history/QA/html2markdown_20250822234720.py +27 -0
- neverlib/.history/QA/html2markdown_20250822234903.py +27 -0
- neverlib/.history/__init___20250805234212.py +41 -0
- neverlib/.history/__init___20250904102635.py +39 -0
- neverlib/.history/__init___20250904102836.py +34 -0
- neverlib/.history/__init___20250904102838.py +39 -0
- neverlib/.history/__init___20250904102851.py +33 -0
- neverlib/.history/audio_aug/audio_aug_20250826155913.py +158 -0
- neverlib/.history/audio_aug/audio_aug_20250826164159.py +159 -0
- neverlib/.history/audio_aug/audio_aug_20250826164217.py +160 -0
- neverlib/.history/audio_aug/audio_aug_20250826164408.py +161 -0
- neverlib/.history/audio_aug/audio_aug_20250826164423.py +161 -0
- neverlib/.history/audio_aug/audio_aug_20250826164529.py +161 -0
- neverlib/.history/audio_aug/audio_aug_20250826164824.py +161 -0
- neverlib/.history/audio_aug/audio_aug_20250826164932.py +162 -0
- neverlib/.history/audio_aug/audio_aug_20250826164947.py +162 -0
- neverlib/.history/audio_aug/audio_aug_20250826165403.py +162 -0
- neverlib/.history/audio_aug/audio_aug_20250826165421.py +162 -0
- neverlib/.history/audio_aug/audio_aug_20250826165509.py +163 -0
- neverlib/.history/audio_aug/audio_aug_20250826165702.py +163 -0
- neverlib/.history/audio_aug/audio_aug_20250826165732.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826170041.py +163 -0
- neverlib/.history/audio_aug/audio_aug_20250826170105.py +164 -0
- neverlib/.history/audio_aug/audio_aug_20250826170154.py +164 -0
- neverlib/.history/audio_aug/audio_aug_20250826170220.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826170221.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826170228.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826170231.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826212001.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826220038.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826220133.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826220148.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826220154.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826220156.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826220314.py +165 -0
- neverlib/.history/audio_aug/audio_aug_20250826220343.py +184 -0
- neverlib/.history/audio_aug/audio_aug_20250826220345.py +184 -0
- neverlib/.history/audio_aug/audio_aug_20250826220349.py +184 -0
- neverlib/.history/audio_aug/audio_aug_20250826220429.py +184 -0
- neverlib/.history/audio_aug/audio_aug_20250826220447.py +184 -0
- neverlib/.history/audio_aug/audio_aug_20250826220601.py +186 -0
- neverlib/.history/audio_aug/audio_aug_20250826220638.py +186 -0
- neverlib/.history/audio_aug/audio_aug_20250826220641.py +186 -0
- neverlib/.history/audio_aug/audio_aug_20250826220647.py +186 -0
- neverlib/.history/audio_aug/audio_aug_20250826220653.py +186 -0
- neverlib/.history/audio_aug/audio_aug_20250826220655.py +186 -0
- neverlib/.history/audio_aug/audio_aug_20250826220731.py +185 -0
- neverlib/.history/audio_aug/audio_aug_20250826220739.py +185 -0
- neverlib/.history/audio_aug/audio_aug_20250826220747.py +185 -0
- neverlib/.history/audio_aug/audio_aug_20250826220801.py +186 -0
- neverlib/.history/audio_aug/audio_aug_20250826220822.py +186 -0
- neverlib/.history/audio_aug/audio_aug_20250826220901.py +186 -0
- neverlib/.history/audio_aug/audio_aug_20250826221107.py +187 -0
- neverlib/.history/audio_aug/audio_aug_20250826221310.py +188 -0
- neverlib/.history/audio_aug/audio_aug_20250826221353.py +191 -0
- neverlib/.history/audio_aug/audio_aug_20250826221821.py +191 -0
- neverlib/.history/audio_aug/audio_aug_20250826221838.py +191 -0
- neverlib/.history/audio_aug/audio_aug_20250826221906.py +191 -0
- neverlib/.history/audio_aug/audio_aug_20250826221930.py +191 -0
- neverlib/.history/audio_aug/audio_aug_20250826221939.py +191 -0
- neverlib/.history/audio_aug/audio_aug_20250826221955.py +191 -0
- neverlib/.history/audio_aug/audio_aug_20250826222008.py +197 -0
- neverlib/.history/audio_aug/audio_aug_20250826222017.py +200 -0
- neverlib/.history/audio_aug/audio_aug_20250826222046.py +203 -0
- neverlib/.history/audio_aug/audio_aug_20250826222105.py +203 -0
- neverlib/.history/audio_aug/audio_aug_20250826222206.py +203 -0
- neverlib/.history/audio_aug/audio_aug_20250826222302.py +203 -0
- neverlib/.history/audio_aug/audio_aug_20250826222336.py +203 -0
- neverlib/.history/audio_aug/audio_aug_20250826222455.py +204 -0
- neverlib/.history/audio_aug/audio_aug_20250826222526.py +204 -0
- neverlib/.history/audio_aug/audio_aug_20250826222541.py +204 -0
- neverlib/.history/audio_aug/audio_aug_20250826222624.py +202 -0
- neverlib/.history/audio_aug/audio_aug_20250826222714.py +205 -0
- neverlib/.history/audio_aug/audio_aug_20250826222820.py +205 -0
- neverlib/.history/audio_aug/audio_aug_20250826222827.py +205 -0
- neverlib/.history/audio_aug/audio_aug_20250826222927.py +232 -0
- neverlib/.history/audio_aug/audio_aug_20250826223009.py +232 -0
- neverlib/.history/audio_aug/audio_aug_20250826223054.py +232 -0
- neverlib/.history/audio_aug/audio_aug_20250826223225.py +233 -0
- neverlib/.history/audio_aug/audio_aug_20250826223344.py +236 -0
- neverlib/.history/audio_aug/audio_aug_20250826223356.py +236 -0
- neverlib/.history/audio_aug/audio_aug_20250826223955.py +242 -0
- neverlib/.history/audio_aug/audio_aug_20250826224210.py +240 -0
- neverlib/.history/audio_aug/audio_aug_20250826224250.py +242 -0
- neverlib/.history/audio_aug/audio_aug_20250826224323.py +280 -0
- neverlib/.history/audio_aug/audio_aug_20250826224452.py +263 -0
- neverlib/.history/audio_aug/audio_aug_20250826224455.py +263 -0
- neverlib/.history/audio_aug/audio_aug_20250826224502.py +263 -0
- neverlib/.history/audio_aug/audio_aug_20250826224528.py +263 -0
- neverlib/.history/audio_aug/audio_aug_20250826224658.py +263 -0
- neverlib/.history/audio_aug/audio_aug_20250826224833.py +264 -0
- neverlib/.history/audio_aug/audio_aug_20250826225013.py +269 -0
- neverlib/.history/audio_aug/audio_aug_20250826225050.py +269 -0
- neverlib/.history/audio_aug/audio_aug_20250826225241.py +268 -0
- neverlib/.history/audio_aug/audio_aug_20250826225315.py +266 -0
- neverlib/.history/audio_aug/audio_aug_20250826225404.py +266 -0
- neverlib/.history/audio_aug/audio_aug_20250826225502.py +265 -0
- neverlib/.history/audio_aug/audio_aug_20250826225950.py +267 -0
- neverlib/.history/audio_aug/audio_aug_20250826225959.py +268 -0
- neverlib/.history/audio_aug/audio_aug_20250826230222.py +271 -0
- neverlib/.history/audio_aug/audio_aug_20250826230248.py +270 -0
- neverlib/.history/audio_aug/audio_aug_20250826230638.py +266 -0
- neverlib/.history/audio_aug/audio_aug_20250826230755.py +266 -0
- neverlib/.history/audio_aug/audio_aug_20250826230941.py +265 -0
- neverlib/.history/audio_aug/audio_aug_20250826231054.py +266 -0
- neverlib/.history/audio_aug/audio_aug_20250826231117.py +266 -0
- neverlib/.history/audio_aug/audio_aug_20250826231219.py +266 -0
- neverlib/.history/audio_aug/audio_aug_20250826232330.py +266 -0
- neverlib/.history/audio_aug/audio_aug_20250826232352.py +266 -0
- neverlib/.history/audio_aug/audio_aug_20250827152748.py +268 -0
- neverlib/.history/audio_aug/audio_aug_20250827152806.py +268 -0
- neverlib/.history/audio_aug/audio_aug_20250827152808.py +268 -0
- neverlib/.history/audio_aug/audio_aug_20250827152917.py +283 -0
- neverlib/.history/audio_aug/audio_aug_20250827152929.py +281 -0
- neverlib/.history/audio_aug/audio_aug_20250827153100.py +286 -0
- neverlib/.history/audio_aug/audio_aug_20250827153102.py +286 -0
- neverlib/.history/audio_aug/audio_aug_20250827153301.py +295 -0
- neverlib/.history/audio_aug/audio_aug_20250827153331.py +298 -0
- neverlib/.history/audio_aug/audio_aug_20250827153525.py +303 -0
- neverlib/.history/audio_aug/audio_aug_20250827153533.py +304 -0
- neverlib/.history/audio_aug/audio_aug_20250827153541.py +321 -0
- neverlib/.history/audio_aug/audio_aug_20250827153805.py +322 -0
- neverlib/.history/audio_aug/audio_aug_20250827153832.py +323 -0
- neverlib/.history/audio_aug/audio_aug_20250827153836.py +324 -0
- neverlib/.history/audio_aug/audio_aug_20250827153846.py +324 -0
- neverlib/.history/audio_aug/audio_aug_20250827153859.py +325 -0
- neverlib/.history/audio_aug/audio_aug_20250827154453.py +337 -0
- neverlib/.history/audio_aug/audio_aug_20250827154513.py +355 -0
- neverlib/.history/audio_aug/audio_aug_20250827154538.py +356 -0
- neverlib/.history/audio_aug/audio_aug_20250827154541.py +357 -0
- neverlib/.history/audio_aug/audio_aug_20250827154612.py +357 -0
- neverlib/.history/audio_aug/audio_aug_20250827154657.py +360 -0
- neverlib/.history/audio_aug/audio_aug_20250827154708.py +360 -0
- neverlib/.history/audio_aug/audio_aug_20250827154728.py +366 -0
- neverlib/.history/audio_aug/audio_aug_20250827154755.py +367 -0
- neverlib/.history/audio_aug/audio_aug_20250827154800.py +367 -0
- neverlib/.history/audio_aug/audio_aug_20250827154917.py +368 -0
- neverlib/.history/audio_aug/audio_aug_20250827154928.py +369 -0
- neverlib/.history/audio_aug/audio_aug_20250827154932.py +370 -0
- neverlib/.history/audio_aug/audio_aug_20250827154947.py +372 -0
- neverlib/.history/audio_aug/audio_aug_20250827155015.py +375 -0
- neverlib/.history/audio_aug/audio_aug_20250827155106.py +375 -0
- neverlib/.history/audio_aug/audio_aug_20250827155114.py +393 -0
- neverlib/.history/audio_aug/audio_aug_20250827155207.py +415 -0
- neverlib/.history/audio_aug/audio_aug_20250827155300.py +415 -0
- neverlib/.history/audio_aug/audio_aug_20250827155321.py +471 -0
- neverlib/.history/audio_aug/audio_aug_20250827164703.py +471 -0
- neverlib/.history/audio_aug/audio_aug_20250827164749.py +471 -0
- neverlib/.history/audio_aug/audio_aug_20250827165252.py +472 -0
- neverlib/.history/audio_aug/audio_aug_20250827165334.py +472 -0
- neverlib/.history/audio_aug/audio_aug_20250827165404.py +473 -0
- neverlib/.history/audio_aug/audio_aug_20250827165610.py +473 -0
- neverlib/.history/audio_aug/audio_aug_20250827165805.py +473 -0
- neverlib/.history/audio_aug/audio_aug_20250827170056.py +473 -0
- neverlib/.history/audio_aug/audio_aug_20250827170106.py +472 -0
- neverlib/.history/audio_aug/audio_aug_20250827170143.py +472 -0
- neverlib/.history/audio_aug/audio_aug_20250827170216.py +472 -0
- neverlib/.history/audio_aug/audio_aug_20250827170218.py +472 -0
- neverlib/.history/audio_aug/audio_aug_20250827170314.py +472 -0
- neverlib/.history/audio_aug/audio_aug_20250827171500.py +471 -0
- neverlib/.history/audio_aug/audio_aug_20250827172347.py +471 -0
- neverlib/.history/audio_aug/audio_aug_20250827172558.py +470 -0
- neverlib/.history/audio_aug/audio_aug_20250827172559.py +470 -0
- neverlib/.history/audio_aug/audio_aug_20250827172801.py +470 -0
- neverlib/.history/audio_aug/audio_aug_20250827182522.py +470 -0
- neverlib/.history/audio_aug/audio_aug_20250827182526.py +470 -0
- neverlib/.history/audio_aug/audio_aug_20250827182626.py +470 -0
- neverlib/.history/audio_aug/audio_aug_20250827182715.py +470 -0
- neverlib/.history/audio_aug/audio_aug_20250904185444.py +470 -0
- neverlib/.history/audio_aug/audio_aug_20250904185538.py +445 -0
- neverlib/.history/data_analyze/__init___20250806204158.py +14 -0
- neverlib/.history/data_analyze/__init___20250827163248.py +14 -0
- neverlib/.history/filter/auto_eq/freq_eq_20250821143140.py +76 -0
- neverlib/.history/filter/auto_eq/freq_eq_20250821153208.py +76 -0
- neverlib/.history/filter/auto_eq/freq_eq_20250821153214.py +76 -0
- neverlib/.history/filter/auto_eq/ga_eq_basic_20250901110521.py +385 -0
- neverlib/.history/filter/auto_eq/ga_eq_basic_20250901110652.py +385 -0
- neverlib/.history/filter/common_20250806002134.py +37 -0
- neverlib/.history/filter/common_20250821120448.py +49 -0
- neverlib/.history/filter/common_20250821120453.py +49 -0
- neverlib/.history/metrics/snr_20250827224201.py +182 -0
- neverlib/.history/metrics/snr_20250827234019.py +186 -0
- neverlib/.history/metrics/snr_20250827234028.py +186 -0
- neverlib/.history/metrics/snr_20250827234030.py +186 -0
- neverlib/.history/utils/audio_split_20250805234209.py +268 -0
- neverlib/.history/utils/audio_split_20250904185309.py +268 -0
- neverlib/.history/utils/utils_20250813165516.py +330 -0
- neverlib/.history/utils/utils_20250904181341.py +328 -0
- neverlib/.history/utils/utils_20250904185546.py +352 -0
- neverlib/.history/utils/utils_20250904185548.py +353 -0
- neverlib/.history/utils/utils_20250904185603.py +353 -0
- neverlib/.history/utils/utils_20250904185636.py +353 -0
- neverlib/.history/utils/utils_20250904185658.py +358 -0
- neverlib/.history/utils/utils_20250904190053.py +359 -0
- neverlib/.specstory/history/2025-08-22_02-10Z-/345/256/214/345/226/204/345/207/275/346/225/260/347/232/204/345/212/237/350/203/275/345/222/214/345/217/230/351/207/217/345/220/215/345/273/272/350/256/256.md +247 -0
- neverlib/.specstory/history/2025-08-26_11-54Z-oserror-missing-shared-object-file.md +87 -0
- neverlib/.specstory/history/2025-08-27_08-07Z-/345/256/214/345/226/204/346/265/213/350/257/225/346/226/207/346/241/243/347/232/204/350/256/250/350/256/272.md +296 -0
- neverlib/.specstory/history/2025-08-27_08-29Z-delete-python-file-command.md +211 -0
- neverlib/.specstory/history/2025-08-27_09-05Z-/345/234/250jupyter/344/270/255/346/222/255/346/224/276/351/237/263/351/242/221/347/232/204/344/273/243/347/240/201/344/277/256/346/224/271.md +357 -0
- neverlib/Docs/audio_aug_test/test_snr.py +55 -0
- neverlib/Docs/audio_aug_test/test_volume.py +0 -0
- neverlib/QA/html2markdown.py +27 -0
- neverlib/__init__.py +10 -20
- neverlib/audio_aug/__init__.py +6 -1
- neverlib/audio_aug/audio_aug.py +360 -55
- neverlib/data_analyze/__init__.py +8 -2
- neverlib/data_analyze/temporal_features.py +1 -1
- neverlib/filter/__init__.py +9 -3
- neverlib/filter/auto_eq/freq_eq.py +1 -1
- neverlib/filter/auto_eq/ga_eq_basic.py +3 -3
- neverlib/filter/common.py +12 -0
- neverlib/metrics/snr.py +5 -3
- neverlib/utils/__init__.py +14 -7
- neverlib/utils/lazy_module.py +81 -0
- neverlib/utils/message.py +3 -8
- neverlib/utils/utils.py +32 -3
- neverlib/vad/__init__.py +16 -9
- neverlib/vad/utils.py +20 -6
- {neverlib-0.2.4.dist-info → neverlib-0.2.6.dist-info}/METADATA +21 -17
- neverlib-0.2.6.dist-info/RECORD +467 -0
- neverlib-0.2.4.dist-info/RECORD +0 -229
- /neverlib/{Docs/audio_aug/test_snr.py → .history/Docs/audio_aug/test_snr_20250827162033.py} +0 -0
- {neverlib-0.2.4.dist-info → neverlib-0.2.6.dist-info}/WHEEL +0 -0
- {neverlib-0.2.4.dist-info → neverlib-0.2.6.dist-info}/licenses/LICENSE +0 -0
- {neverlib-0.2.4.dist-info → neverlib-0.2.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# -*- coding:utf-8 -*-
|
|
2
|
+
# Author:凌逆战 | Never
|
|
3
|
+
# Date: 2024/9/27
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
import random
|
|
8
|
+
import numpy as np
|
|
9
|
+
import soundfile as sf
|
|
10
|
+
from scipy import signal
|
|
11
|
+
from neverlib.utils import EPS
|
|
12
|
+
from neverlib.filter import HPFilter
|
|
13
|
+
|
|
14
|
+
def volume_norm(wav):
|
|
15
|
+
"""
|
|
16
|
+
音量归一化
|
|
17
|
+
:param wav: (T,)
|
|
18
|
+
:return: (T,)
|
|
19
|
+
"""
|
|
20
|
+
wav = wav / (np.max(np.abs(wav)) + 1e-8)
|
|
21
|
+
return wav
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def add_reverb(wav, rir, ratio=1, mode="same"):
|
|
25
|
+
"""添加混响,
|
|
26
|
+
Args:
|
|
27
|
+
wav: [T, channel]
|
|
28
|
+
rir: [T, channel]
|
|
29
|
+
ratio: 0-1
|
|
30
|
+
mode: "same" for SE or "full" for kws
|
|
31
|
+
"""
|
|
32
|
+
if random.random() < ratio:
|
|
33
|
+
wav = signal.fftconvolve(wav, rir, mode=mode) # (28671, 3)
|
|
34
|
+
# note: 建议过完添加混响后再进行归一化, 否则可能会出现溢出
|
|
35
|
+
# 防止削波
|
|
36
|
+
if np.max(np.abs(wav)) > 1:
|
|
37
|
+
scale_factor = 1 / np.max(np.abs(wav))
|
|
38
|
+
wav *= scale_factor
|
|
39
|
+
return wav
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def snr_aug_changeNoise(clean, noise, target_snr, hp=False):
|
|
43
|
+
"""
|
|
44
|
+
保持语音不变, 改变噪声的幅度
|
|
45
|
+
HP: 高通滤波, 如果你的数据工频干扰较高, 建议设置为True, 否则snr会不准
|
|
46
|
+
snr = 10 * log10(signal_power / k*noise_power)
|
|
47
|
+
"""
|
|
48
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
49
|
+
if hp:
|
|
50
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
51
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
52
|
+
# 纯净语音功率, 噪声功率
|
|
53
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
54
|
+
noise_scale = np.sqrt(clean_power / (noise_power * 10 ** (target_snr / 10) + EPS))
|
|
55
|
+
noisy = clean + noise_scale * noise
|
|
56
|
+
# 防止削波
|
|
57
|
+
if np.max(np.abs(noisy)) > 1:
|
|
58
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
59
|
+
noisy *= scale_factor
|
|
60
|
+
clean *= scale_factor
|
|
61
|
+
return noisy, clean
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def snr_aug_changeNoise_dB(clean, noise, target_snr, hp=False):
|
|
65
|
+
"""
|
|
66
|
+
保持语音不变, 改变噪声的幅度
|
|
67
|
+
snr = 10 * log10(signal_power / k*noise_power)
|
|
68
|
+
"""
|
|
69
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
70
|
+
if hp:
|
|
71
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
72
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
73
|
+
# 纯净语音功率, 噪声功率
|
|
74
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
75
|
+
source_snr = 10 * np.log10(clean_power / (noise_power + EPS) + EPS)
|
|
76
|
+
noise_dB = source_snr - target_snr # 噪声还差多少dB
|
|
77
|
+
noise_gain = 10 ** (noise_dB / 20)
|
|
78
|
+
noisy = clean + noise_gain * noise
|
|
79
|
+
# 防止削波
|
|
80
|
+
if np.max(np.abs(noisy)) > 1:
|
|
81
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
82
|
+
noisy *= scale_factor
|
|
83
|
+
clean *= scale_factor
|
|
84
|
+
return noisy, clean
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def snr_aug_changeClean(clean, noise, target_snr, clip_check=True, hp=False):
|
|
89
|
+
"""
|
|
90
|
+
保持噪声不变,改变纯净语音的幅度以达到目标信噪比
|
|
91
|
+
snr = 10 * log10(k*signal_power/ noise_power)
|
|
92
|
+
"""
|
|
93
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
94
|
+
if hp:
|
|
95
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
96
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
97
|
+
# 纯净语音功率, 噪声功率
|
|
98
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
99
|
+
# 计算纯净信号需要的幅度因子
|
|
100
|
+
clean_scale = np.sqrt(noise_power * 10 ** (target_snr / 10) / (clean_power + EPS))
|
|
101
|
+
noisy = clean * clean_scale + noise
|
|
102
|
+
# 防止削波
|
|
103
|
+
if clip_check:
|
|
104
|
+
if np.max(np.abs(noisy)) > 1:
|
|
105
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
106
|
+
noisy *= scale_factor
|
|
107
|
+
clean *= (scale_factor * clean_scale)
|
|
108
|
+
return noisy, clean
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def snr_aug_changeClean_dB(clean, noise, target_snr, clip_check=True):
|
|
112
|
+
"""
|
|
113
|
+
保持噪声不变, 改变纯净语音的幅度
|
|
114
|
+
snr = 10 * log10(signal_power / k*noise_power)
|
|
115
|
+
"""
|
|
116
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
117
|
+
# 纯净语音功率, 噪声功率
|
|
118
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
119
|
+
source_snr = 10 * np.log10(clean_power / (noise_power + EPS) + EPS)
|
|
120
|
+
clean_dB = source_snr - target_snr # 纯净语音还差多少dB
|
|
121
|
+
clean_gain = 10 ** (clean_dB / 20)
|
|
122
|
+
noisy = clean_gain * clean + noise
|
|
123
|
+
# 防止削波
|
|
124
|
+
if clip_check:
|
|
125
|
+
if np.max(np.abs(noisy)) > 1:
|
|
126
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
127
|
+
noisy *= scale_factor
|
|
128
|
+
clean *= (scale_factor * clean_gain)
|
|
129
|
+
return noisy, clean
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def snr_aug_Interpolation(clean, noise, target_snr):
|
|
133
|
+
"""
|
|
134
|
+
在已知clean_len<=noise_len的情况下
|
|
135
|
+
将clean插入到noise中的snr aug方法
|
|
136
|
+
Args:
|
|
137
|
+
clean: 语音
|
|
138
|
+
noise: 噪声
|
|
139
|
+
snr: snr=random.uniform(*snr_range)
|
|
140
|
+
"""
|
|
141
|
+
clean_len, noise_len = clean.shape[0], noise.shape[0]
|
|
142
|
+
assert clean_len <= noise_len, f"clean_len must be less than noise_len."
|
|
143
|
+
noisy = noise.copy()
|
|
144
|
+
index = random.randint(0, noise_len - clean_len)
|
|
145
|
+
noise = noise[index:index + clean_len, :]
|
|
146
|
+
# 这里必须把clip_check设置为False, 否则外面的noise和里面的不一致
|
|
147
|
+
noisy_tmp, clean_tmp = snr_aug_changeClean(clean, noise, target_snr, clip_check=False)
|
|
148
|
+
noisy[index:index + clean_len, :] = noisy_tmp
|
|
149
|
+
# 防止削波
|
|
150
|
+
if np.max(np.abs(noisy)) > 1:
|
|
151
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
152
|
+
noisy *= scale_factor
|
|
153
|
+
clean_tmp *= scale_factor
|
|
154
|
+
return noisy, clean_tmp
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def get_audio_segments(wav_len, audio_path_list, sr=16000):
|
|
158
|
+
"""
|
|
159
|
+
从音频列表中随机拼接指定长度音频
|
|
160
|
+
Args:
|
|
161
|
+
wav_len: 需要返回的音频长度
|
|
162
|
+
audio_path_list: 音频路径列表
|
|
163
|
+
sr: 采样率
|
|
164
|
+
Returns:返回指定长度的音频
|
|
165
|
+
"""
|
|
166
|
+
audio_len = 0
|
|
167
|
+
wav_list = []
|
|
168
|
+
while audio_len < wav_len:
|
|
169
|
+
audio_path = random.choice(audio_path_list)
|
|
170
|
+
wav, wav_sr = sf.read(audio_path, always_2d=True, dtype='float32')
|
|
171
|
+
assert wav_sr == sr, f"音频采样率是{wav_sr}, 期望{sr}"
|
|
172
|
+
audio_len += len(wav)
|
|
173
|
+
wav_list.append(wav)
|
|
174
|
+
wav = np.concatenate(wav_list, axis=0)
|
|
175
|
+
if len(wav) > wav_len:
|
|
176
|
+
# 随机截取clean_len
|
|
177
|
+
start = random.randint(0, len(wav) - wav_len)
|
|
178
|
+
wav = wav[start:start + wav_len, :]
|
|
179
|
+
return wav
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def volume_aug(wav, range, rate, method="linmax"):
|
|
183
|
+
"""音量增强 """
|
|
184
|
+
if random.random() < rate:
|
|
185
|
+
target_level = random.uniform(range[0], range[1])
|
|
186
|
+
if method == "dbrms":
|
|
187
|
+
wav_rms = (wav ** 2).mean() ** 0.5
|
|
188
|
+
scalar = 10 ** (target_level / 20) / (np.max(wav_rms) + EPS)
|
|
189
|
+
elif method == "linmax":
|
|
190
|
+
ipt_max = np.max(np.abs(wav))
|
|
191
|
+
# wav/wav_max*target_level=target_level_wav
|
|
192
|
+
# 处理后音频的 最大值就是target_level
|
|
193
|
+
scalar = target_level / (ipt_max + EPS)
|
|
194
|
+
else:
|
|
195
|
+
raise ValueError("method must be 'dbrms' or 'linmax'")
|
|
196
|
+
wav *= scalar
|
|
197
|
+
return wav
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# -*- coding:utf-8 -*-
|
|
2
|
+
# Author:凌逆战 | Never
|
|
3
|
+
# Date: 2024/9/27
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
import random
|
|
8
|
+
import numpy as np
|
|
9
|
+
import soundfile as sf
|
|
10
|
+
from scipy import signal
|
|
11
|
+
from neverlib.utils import EPS
|
|
12
|
+
from neverlib.filter import HPFilter
|
|
13
|
+
|
|
14
|
+
def volume_norm(wav):
|
|
15
|
+
"""
|
|
16
|
+
音量归一化
|
|
17
|
+
:param wav: (T,)
|
|
18
|
+
:return: (T,)
|
|
19
|
+
"""
|
|
20
|
+
wav = wav / (np.max(np.abs(wav)) + 1e-8)
|
|
21
|
+
return wav
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def add_reverb(wav, rir, ratio=1, mode="same"):
|
|
25
|
+
"""添加混响,
|
|
26
|
+
Args:
|
|
27
|
+
wav: [T, channel]
|
|
28
|
+
rir: [T, channel]
|
|
29
|
+
ratio: 0-1
|
|
30
|
+
mode: "same" for SE or "full" for kws
|
|
31
|
+
"""
|
|
32
|
+
if random.random() < ratio:
|
|
33
|
+
wav = signal.fftconvolve(wav, rir, mode=mode) # (28671, 3)
|
|
34
|
+
# note: 建议过完添加混响后再进行归一化, 否则可能会出现溢出
|
|
35
|
+
# 防止削波
|
|
36
|
+
if np.max(np.abs(wav)) > 1:
|
|
37
|
+
scale_factor = 1 / np.max(np.abs(wav))
|
|
38
|
+
wav *= scale_factor
|
|
39
|
+
return wav
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def snr_aug_changeNoise(clean, noise, target_snr, hp=False):
|
|
43
|
+
"""
|
|
44
|
+
保持语音不变, 改变噪声的幅度
|
|
45
|
+
HP: 高通滤波, 如果你的数据工频干扰较高, 建议设置为True, 否则snr会不准
|
|
46
|
+
snr = 10 * log10(signal_power / k*noise_power)
|
|
47
|
+
"""
|
|
48
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
49
|
+
if hp:
|
|
50
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
51
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
52
|
+
# 纯净语音功率, 噪声功率
|
|
53
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
54
|
+
noise_scale = np.sqrt(clean_power / (noise_power * 10 ** (target_snr / 10) + EPS))
|
|
55
|
+
noisy = clean + noise_scale * noise
|
|
56
|
+
# 防止削波
|
|
57
|
+
if np.max(np.abs(noisy)) > 1:
|
|
58
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
59
|
+
noisy *= scale_factor
|
|
60
|
+
clean *= scale_factor
|
|
61
|
+
return noisy, clean
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def snr_aug_changeNoise_dB(clean, noise, target_snr, hp=False):
|
|
65
|
+
"""
|
|
66
|
+
保持语音不变, 改变噪声的幅度
|
|
67
|
+
snr = 10 * log10(signal_power / k*noise_power)
|
|
68
|
+
"""
|
|
69
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
70
|
+
if hp:
|
|
71
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
72
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
73
|
+
# 纯净语音功率, 噪声功率
|
|
74
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
75
|
+
source_snr = 10 * np.log10(clean_power / (noise_power + EPS) + EPS)
|
|
76
|
+
noise_dB = source_snr - target_snr # 噪声还差多少dB
|
|
77
|
+
noise_gain = 10 ** (noise_dB / 20)
|
|
78
|
+
noisy = clean + noise_gain * noise
|
|
79
|
+
# 防止削波
|
|
80
|
+
if np.max(np.abs(noisy)) > 1:
|
|
81
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
82
|
+
noisy *= scale_factor
|
|
83
|
+
clean *= scale_factor
|
|
84
|
+
return noisy, clean
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def snr_aug_changeClean(clean, noise, target_snr, clip_check=True, hp=False):
|
|
89
|
+
"""
|
|
90
|
+
保持噪声不变,改变纯净语音的幅度以达到目标信噪比
|
|
91
|
+
snr = 10 * log10(k*signal_power/ noise_power)
|
|
92
|
+
"""
|
|
93
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
94
|
+
if hp:
|
|
95
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
96
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
97
|
+
# 纯净语音功率, 噪声功率
|
|
98
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
99
|
+
# 计算纯净信号需要的幅度因子
|
|
100
|
+
clean_scale = np.sqrt(noise_power * 10 ** (target_snr / 10) / (clean_power + EPS))
|
|
101
|
+
noisy = clean * clean_scale + noise
|
|
102
|
+
# 防止削波
|
|
103
|
+
if clip_check:
|
|
104
|
+
if np.max(np.abs(noisy)) > 1:
|
|
105
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
106
|
+
noisy *= scale_factor
|
|
107
|
+
clean *= (scale_factor * clean_scale)
|
|
108
|
+
return noisy, clean
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def snr_aug_changeClean_dB(clean, noise, target_snr, clip_check=True, hp=False):
|
|
112
|
+
"""
|
|
113
|
+
保持噪声不变, 改变纯净语音的幅度
|
|
114
|
+
snr = 10 * log10(signal_power / k*noise_power)
|
|
115
|
+
"""
|
|
116
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
117
|
+
if hp:
|
|
118
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
119
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
120
|
+
# 纯净语音功率, 噪声功率
|
|
121
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
122
|
+
source_snr = 10 * np.log10(clean_power / (noise_power + EPS) + EPS)
|
|
123
|
+
clean_dB = source_snr - target_snr # 纯净语音还差多少dB
|
|
124
|
+
clean_gain = 10 ** (clean_dB / 20)
|
|
125
|
+
noisy = clean_gain * clean + noise
|
|
126
|
+
# 防止削波
|
|
127
|
+
if clip_check:
|
|
128
|
+
if np.max(np.abs(noisy)) > 1:
|
|
129
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
130
|
+
noisy *= scale_factor
|
|
131
|
+
clean *= (scale_factor * clean_gain)
|
|
132
|
+
return noisy, clean
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def snr_aug_Interpolation(clean, noise, target_snr):
|
|
136
|
+
"""
|
|
137
|
+
在已知clean_len<=noise_len的情况下
|
|
138
|
+
将clean插入到noise中的snr aug方法
|
|
139
|
+
Args:
|
|
140
|
+
clean: 语音
|
|
141
|
+
noise: 噪声
|
|
142
|
+
snr: snr=random.uniform(*snr_range)
|
|
143
|
+
"""
|
|
144
|
+
clean_len, noise_len = clean.shape[0], noise.shape[0]
|
|
145
|
+
assert clean_len <= noise_len, f"clean_len must be less than noise_len."
|
|
146
|
+
noisy = noise.copy()
|
|
147
|
+
index = random.randint(0, noise_len - clean_len)
|
|
148
|
+
noise = noise[index:index + clean_len, :]
|
|
149
|
+
# 这里必须把clip_check设置为False, 否则外面的noise和里面的不一致
|
|
150
|
+
noisy_tmp, clean_tmp = snr_aug_changeClean(clean, noise, target_snr, clip_check=False)
|
|
151
|
+
noisy[index:index + clean_len, :] = noisy_tmp
|
|
152
|
+
# 防止削波
|
|
153
|
+
if np.max(np.abs(noisy)) > 1:
|
|
154
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
155
|
+
noisy *= scale_factor
|
|
156
|
+
clean_tmp *= scale_factor
|
|
157
|
+
return noisy, clean_tmp
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def get_audio_segments(wav_len, audio_path_list, sr=16000):
|
|
161
|
+
"""
|
|
162
|
+
从音频列表中随机拼接指定长度音频
|
|
163
|
+
Args:
|
|
164
|
+
wav_len: 需要返回的音频长度
|
|
165
|
+
audio_path_list: 音频路径列表
|
|
166
|
+
sr: 采样率
|
|
167
|
+
Returns:返回指定长度的音频
|
|
168
|
+
"""
|
|
169
|
+
audio_len = 0
|
|
170
|
+
wav_list = []
|
|
171
|
+
while audio_len < wav_len:
|
|
172
|
+
audio_path = random.choice(audio_path_list)
|
|
173
|
+
wav, wav_sr = sf.read(audio_path, always_2d=True, dtype='float32')
|
|
174
|
+
assert wav_sr == sr, f"音频采样率是{wav_sr}, 期望{sr}"
|
|
175
|
+
audio_len += len(wav)
|
|
176
|
+
wav_list.append(wav)
|
|
177
|
+
wav = np.concatenate(wav_list, axis=0)
|
|
178
|
+
if len(wav) > wav_len:
|
|
179
|
+
# 随机截取clean_len
|
|
180
|
+
start = random.randint(0, len(wav) - wav_len)
|
|
181
|
+
wav = wav[start:start + wav_len, :]
|
|
182
|
+
return wav
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def volume_aug(wav, range, rate, method="linmax"):
|
|
186
|
+
"""音量增强 """
|
|
187
|
+
if random.random() < rate:
|
|
188
|
+
target_level = random.uniform(range[0], range[1])
|
|
189
|
+
if method == "dbrms":
|
|
190
|
+
wav_rms = (wav ** 2).mean() ** 0.5
|
|
191
|
+
scalar = 10 ** (target_level / 20) / (np.max(wav_rms) + EPS)
|
|
192
|
+
elif method == "linmax":
|
|
193
|
+
ipt_max = np.max(np.abs(wav))
|
|
194
|
+
# wav/wav_max*target_level=target_level_wav
|
|
195
|
+
# 处理后音频的 最大值就是target_level
|
|
196
|
+
scalar = target_level / (ipt_max + EPS)
|
|
197
|
+
else:
|
|
198
|
+
raise ValueError("method must be 'dbrms' or 'linmax'")
|
|
199
|
+
wav *= scalar
|
|
200
|
+
return wav
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# -*- coding:utf-8 -*-
|
|
2
|
+
# Author:凌逆战 | Never
|
|
3
|
+
# Date: 2024/9/27
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
import random
|
|
8
|
+
import numpy as np
|
|
9
|
+
import soundfile as sf
|
|
10
|
+
from scipy import signal
|
|
11
|
+
from neverlib.utils import EPS
|
|
12
|
+
from neverlib.filter import HPFilter
|
|
13
|
+
|
|
14
|
+
def volume_norm(wav):
|
|
15
|
+
"""
|
|
16
|
+
音量归一化
|
|
17
|
+
:param wav: (T,)
|
|
18
|
+
:return: (T,)
|
|
19
|
+
"""
|
|
20
|
+
wav = wav / (np.max(np.abs(wav)) + 1e-8)
|
|
21
|
+
return wav
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def add_reverb(wav, rir, ratio=1, mode="same"):
|
|
25
|
+
"""添加混响,
|
|
26
|
+
Args:
|
|
27
|
+
wav: [T, channel]
|
|
28
|
+
rir: [T, channel]
|
|
29
|
+
ratio: 0-1
|
|
30
|
+
mode: "same" for SE or "full" for kws
|
|
31
|
+
"""
|
|
32
|
+
if random.random() < ratio:
|
|
33
|
+
wav = signal.fftconvolve(wav, rir, mode=mode) # (28671, 3)
|
|
34
|
+
# note: 建议过完添加混响后再进行归一化, 否则可能会出现溢出
|
|
35
|
+
# 防止削波
|
|
36
|
+
if np.max(np.abs(wav)) > 1:
|
|
37
|
+
scale_factor = 1 / np.max(np.abs(wav))
|
|
38
|
+
wav *= scale_factor
|
|
39
|
+
return wav
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def snr_aug_changeNoise(clean, noise, target_snr, hp=False):
|
|
43
|
+
"""
|
|
44
|
+
保持语音不变, 改变噪声的幅度
|
|
45
|
+
HP: 高通滤波, 如果你的数据工频干扰较高, 建议设置为True, 否则snr会不准
|
|
46
|
+
snr = 10 * log10(signal_power / k*noise_power)
|
|
47
|
+
"""
|
|
48
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
49
|
+
if hp:
|
|
50
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
51
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
52
|
+
# 纯净语音功率, 噪声功率
|
|
53
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
54
|
+
noise_scale = np.sqrt(clean_power / (noise_power * 10 ** (target_snr / 10) + EPS))
|
|
55
|
+
noisy = clean + noise_scale * noise
|
|
56
|
+
# 防止削波
|
|
57
|
+
if np.max(np.abs(noisy)) > 1:
|
|
58
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
59
|
+
noisy *= scale_factor
|
|
60
|
+
clean *= scale_factor
|
|
61
|
+
return noisy, clean
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def snr_aug_changeNoise_dB(clean, noise, target_snr, hp=False):
|
|
65
|
+
"""
|
|
66
|
+
保持语音不变, 改变噪声的幅度
|
|
67
|
+
snr = 10 * log10(signal_power / k*noise_power)
|
|
68
|
+
"""
|
|
69
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
70
|
+
if hp:
|
|
71
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
72
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
73
|
+
# 纯净语音功率, 噪声功率
|
|
74
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
75
|
+
source_snr = 10 * np.log10(clean_power / (noise_power + EPS) + EPS)
|
|
76
|
+
noise_dB = source_snr - target_snr # 噪声还差多少dB
|
|
77
|
+
noise_gain = 10 ** (noise_dB / 20)
|
|
78
|
+
noisy = clean + noise_gain * noise
|
|
79
|
+
# 防止削波
|
|
80
|
+
if np.max(np.abs(noisy)) > 1:
|
|
81
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
82
|
+
noisy *= scale_factor
|
|
83
|
+
clean *= scale_factor
|
|
84
|
+
return noisy, clean
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def snr_aug_changeClean(clean, noise, target_snr, clip_check=True, hp=False):
|
|
89
|
+
"""
|
|
90
|
+
保持噪声不变,改变纯净语音的幅度以达到目标信噪比
|
|
91
|
+
snr = 10 * log10(k*signal_power/ noise_power)
|
|
92
|
+
"""
|
|
93
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
94
|
+
if hp:
|
|
95
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
96
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
97
|
+
# 纯净语音功率, 噪声功率
|
|
98
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
99
|
+
# 计算纯净信号需要的幅度因子
|
|
100
|
+
clean_scale = np.sqrt(noise_power * 10 ** (target_snr / 10) / (clean_power + EPS))
|
|
101
|
+
noisy = clean * clean_scale + noise
|
|
102
|
+
# 防止削波
|
|
103
|
+
if clip_check:
|
|
104
|
+
if np.max(np.abs(noisy)) > 1:
|
|
105
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
106
|
+
noisy *= scale_factor
|
|
107
|
+
clean *= (scale_factor * clean_scale)
|
|
108
|
+
return noisy, clean
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def snr_aug_changeClean_dB(clean, noise, target_snr, clip_check=True, hp=False):
|
|
112
|
+
"""
|
|
113
|
+
保持噪声不变, 改变纯净语音的幅度
|
|
114
|
+
snr = 10 * log10(signal_power / k*noise_power)
|
|
115
|
+
"""
|
|
116
|
+
assert clean.shape == noise.shape, "clean and noise must have the same shape"
|
|
117
|
+
if hp:
|
|
118
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
119
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
120
|
+
# 纯净语音功率, 噪声功率
|
|
121
|
+
clean_power, noise_power = np.mean(clean ** 2), np.mean(noise ** 2)
|
|
122
|
+
source_snr = 10 * np.log10(clean_power / (noise_power + EPS) + EPS)
|
|
123
|
+
clean_dB = source_snr - target_snr # 纯净语音还差多少dB
|
|
124
|
+
clean_gain = 10 ** (clean_dB / 20)
|
|
125
|
+
noisy = clean_gain * clean + noise
|
|
126
|
+
# 防止削波
|
|
127
|
+
if clip_check:
|
|
128
|
+
if np.max(np.abs(noisy)) > 1:
|
|
129
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
130
|
+
noisy *= scale_factor
|
|
131
|
+
clean *= (scale_factor * clean_gain)
|
|
132
|
+
return noisy, clean
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def snr_aug_Interpolation(clean, noise, target_snr, hp=False):
|
|
136
|
+
"""
|
|
137
|
+
在已知clean_len<=noise_len的情况下
|
|
138
|
+
将clean插入到noise中的snr aug方法
|
|
139
|
+
Args:
|
|
140
|
+
clean: 语音
|
|
141
|
+
noise: 噪声
|
|
142
|
+
snr: snr=random.uniform(*snr_range)
|
|
143
|
+
"""
|
|
144
|
+
clean_len, noise_len = clean.shape[0], noise.shape[0]
|
|
145
|
+
if hp:
|
|
146
|
+
clean = HPFilter(clean, sr=16000, order=6, cutoff=100)
|
|
147
|
+
noise = HPFilter(noise, sr=16000, order=6, cutoff=100)
|
|
148
|
+
assert clean_len <= noise_len, f"clean_len must be less than noise_len."
|
|
149
|
+
noisy = noise.copy()
|
|
150
|
+
index = random.randint(0, noise_len - clean_len)
|
|
151
|
+
noise = noise[index:index + clean_len, :]
|
|
152
|
+
# 这里必须把clip_check设置为False, 否则外面的noise和里面的不一致
|
|
153
|
+
noisy_tmp, clean_tmp = snr_aug_changeClean(clean, noise, target_snr, clip_check=False, hp=False)
|
|
154
|
+
noisy[index:index + clean_len, :] = noisy_tmp
|
|
155
|
+
# 防止削波
|
|
156
|
+
if np.max(np.abs(noisy)) > 1:
|
|
157
|
+
scale_factor = 1 / np.max(np.abs(noisy))
|
|
158
|
+
noisy *= scale_factor
|
|
159
|
+
clean_tmp *= scale_factor
|
|
160
|
+
return noisy, clean_tmp
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def get_audio_segments(wav_len, audio_path_list, sr=16000):
|
|
164
|
+
"""
|
|
165
|
+
从音频列表中随机拼接指定长度音频
|
|
166
|
+
Args:
|
|
167
|
+
wav_len: 需要返回的音频长度
|
|
168
|
+
audio_path_list: 音频路径列表
|
|
169
|
+
sr: 采样率
|
|
170
|
+
Returns:返回指定长度的音频
|
|
171
|
+
"""
|
|
172
|
+
audio_len = 0
|
|
173
|
+
wav_list = []
|
|
174
|
+
while audio_len < wav_len:
|
|
175
|
+
audio_path = random.choice(audio_path_list)
|
|
176
|
+
wav, wav_sr = sf.read(audio_path, always_2d=True, dtype='float32')
|
|
177
|
+
assert wav_sr == sr, f"音频采样率是{wav_sr}, 期望{sr}"
|
|
178
|
+
audio_len += len(wav)
|
|
179
|
+
wav_list.append(wav)
|
|
180
|
+
wav = np.concatenate(wav_list, axis=0)
|
|
181
|
+
if len(wav) > wav_len:
|
|
182
|
+
# 随机截取clean_len
|
|
183
|
+
start = random.randint(0, len(wav) - wav_len)
|
|
184
|
+
wav = wav[start:start + wav_len, :]
|
|
185
|
+
return wav
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def volume_aug(wav, range, rate, method="linmax"):
|
|
189
|
+
"""音量增强 """
|
|
190
|
+
if random.random() < rate:
|
|
191
|
+
target_level = random.uniform(range[0], range[1])
|
|
192
|
+
if method == "dbrms":
|
|
193
|
+
wav_rms = (wav ** 2).mean() ** 0.5
|
|
194
|
+
scalar = 10 ** (target_level / 20) / (np.max(wav_rms) + EPS)
|
|
195
|
+
elif method == "linmax":
|
|
196
|
+
ipt_max = np.max(np.abs(wav))
|
|
197
|
+
# wav/wav_max*target_level=target_level_wav
|
|
198
|
+
# 处理后音频的 最大值就是target_level
|
|
199
|
+
scalar = target_level / (ipt_max + EPS)
|
|
200
|
+
else:
|
|
201
|
+
raise ValueError("method must be 'dbrms' or 'linmax'")
|
|
202
|
+
wav *= scalar
|
|
203
|
+
return wav
|