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.
Files changed (260) hide show
  1. neverlib/.history/Docs/audio_aug/del_20250827162530.py +0 -0
  2. neverlib/.history/Docs/audio_aug/del_20250827162540.py +2 -0
  3. neverlib/.history/Docs/audio_aug/del_20250827162541.py +7 -0
  4. neverlib/.history/Docs/audio_aug/del_20250827162606.py +7 -0
  5. neverlib/.history/Docs/audio_aug/del_20250827162637.py +8 -0
  6. neverlib/.history/Docs/audio_aug/del_20250827162645.py +8 -0
  7. neverlib/.history/Docs/audio_aug/del_20250827162723.py +9 -0
  8. neverlib/.history/Docs/audio_aug/del_20250827162739.py +9 -0
  9. neverlib/.history/Docs/audio_aug/test_snr_20250827161751.py +55 -0
  10. neverlib/.history/Docs/audio_aug/test_snr_20250827161754.py +55 -0
  11. neverlib/.history/Docs/audio_aug/test_snr_20250827161833.py +54 -0
  12. neverlib/.history/Docs/audio_aug/test_snr_20250827162017.py +56 -0
  13. neverlib/.history/Docs/audio_aug/test_snr_20250827162021.py +57 -0
  14. neverlib/.history/Docs/audio_aug/test_snr_20250827162028.py +57 -0
  15. neverlib/.history/Docs/audio_aug_test/del_20250827162738.py +9 -0
  16. neverlib/.history/Docs/audio_aug_test/del_20250827162819.py +9 -0
  17. neverlib/.history/Docs/audio_aug_test/del_20250827162830.py +9 -0
  18. neverlib/.history/Docs/audio_aug_test/del_20250827162846.py +9 -0
  19. neverlib/.history/Docs/audio_aug_test/del_20250827162851.py +9 -0
  20. neverlib/.history/Docs/audio_aug_test/del_20250827162903.py +10 -0
  21. neverlib/.history/Docs/audio_aug_test/del_20250827162921.py +10 -0
  22. neverlib/.history/Docs/audio_aug_test/del_20250827162926.py +10 -0
  23. neverlib/.history/Docs/audio_aug_test/del_20250827163030.py +10 -0
  24. neverlib/.history/Docs/audio_aug_test/del_20250827163032.py +10 -0
  25. neverlib/.history/QA/html2markdown_20250822234112.md +0 -0
  26. neverlib/.history/QA/html2markdown_20250822234140.py +9 -0
  27. neverlib/.history/QA/html2markdown_20250822234141.md +9 -0
  28. neverlib/.history/QA/html2markdown_20250822234159.py +12 -0
  29. neverlib/.history/QA/html2markdown_20250822234200.py +17 -0
  30. neverlib/.history/QA/html2markdown_20250822234236.py +17 -0
  31. neverlib/.history/QA/html2markdown_20250822234340.py +14 -0
  32. neverlib/.history/QA/html2markdown_20250822234522.py +18 -0
  33. neverlib/.history/QA/html2markdown_20250822234601.py +20 -0
  34. neverlib/.history/QA/html2markdown_20250822234615.py +22 -0
  35. neverlib/.history/QA/html2markdown_20250822234715.py +28 -0
  36. neverlib/.history/QA/html2markdown_20250822234720.py +27 -0
  37. neverlib/.history/QA/html2markdown_20250822234903.py +27 -0
  38. neverlib/.history/__init___20250805234212.py +41 -0
  39. neverlib/.history/__init___20250904102635.py +39 -0
  40. neverlib/.history/__init___20250904102836.py +34 -0
  41. neverlib/.history/__init___20250904102838.py +39 -0
  42. neverlib/.history/__init___20250904102851.py +33 -0
  43. neverlib/.history/audio_aug/audio_aug_20250826155913.py +158 -0
  44. neverlib/.history/audio_aug/audio_aug_20250826164159.py +159 -0
  45. neverlib/.history/audio_aug/audio_aug_20250826164217.py +160 -0
  46. neverlib/.history/audio_aug/audio_aug_20250826164408.py +161 -0
  47. neverlib/.history/audio_aug/audio_aug_20250826164423.py +161 -0
  48. neverlib/.history/audio_aug/audio_aug_20250826164529.py +161 -0
  49. neverlib/.history/audio_aug/audio_aug_20250826164824.py +161 -0
  50. neverlib/.history/audio_aug/audio_aug_20250826164932.py +162 -0
  51. neverlib/.history/audio_aug/audio_aug_20250826164947.py +162 -0
  52. neverlib/.history/audio_aug/audio_aug_20250826165403.py +162 -0
  53. neverlib/.history/audio_aug/audio_aug_20250826165421.py +162 -0
  54. neverlib/.history/audio_aug/audio_aug_20250826165509.py +163 -0
  55. neverlib/.history/audio_aug/audio_aug_20250826165702.py +163 -0
  56. neverlib/.history/audio_aug/audio_aug_20250826165732.py +165 -0
  57. neverlib/.history/audio_aug/audio_aug_20250826170041.py +163 -0
  58. neverlib/.history/audio_aug/audio_aug_20250826170105.py +164 -0
  59. neverlib/.history/audio_aug/audio_aug_20250826170154.py +164 -0
  60. neverlib/.history/audio_aug/audio_aug_20250826170220.py +165 -0
  61. neverlib/.history/audio_aug/audio_aug_20250826170221.py +165 -0
  62. neverlib/.history/audio_aug/audio_aug_20250826170228.py +165 -0
  63. neverlib/.history/audio_aug/audio_aug_20250826170231.py +165 -0
  64. neverlib/.history/audio_aug/audio_aug_20250826212001.py +165 -0
  65. neverlib/.history/audio_aug/audio_aug_20250826220038.py +165 -0
  66. neverlib/.history/audio_aug/audio_aug_20250826220133.py +165 -0
  67. neverlib/.history/audio_aug/audio_aug_20250826220148.py +165 -0
  68. neverlib/.history/audio_aug/audio_aug_20250826220154.py +165 -0
  69. neverlib/.history/audio_aug/audio_aug_20250826220156.py +165 -0
  70. neverlib/.history/audio_aug/audio_aug_20250826220314.py +165 -0
  71. neverlib/.history/audio_aug/audio_aug_20250826220343.py +184 -0
  72. neverlib/.history/audio_aug/audio_aug_20250826220345.py +184 -0
  73. neverlib/.history/audio_aug/audio_aug_20250826220349.py +184 -0
  74. neverlib/.history/audio_aug/audio_aug_20250826220429.py +184 -0
  75. neverlib/.history/audio_aug/audio_aug_20250826220447.py +184 -0
  76. neverlib/.history/audio_aug/audio_aug_20250826220601.py +186 -0
  77. neverlib/.history/audio_aug/audio_aug_20250826220638.py +186 -0
  78. neverlib/.history/audio_aug/audio_aug_20250826220641.py +186 -0
  79. neverlib/.history/audio_aug/audio_aug_20250826220647.py +186 -0
  80. neverlib/.history/audio_aug/audio_aug_20250826220653.py +186 -0
  81. neverlib/.history/audio_aug/audio_aug_20250826220655.py +186 -0
  82. neverlib/.history/audio_aug/audio_aug_20250826220731.py +185 -0
  83. neverlib/.history/audio_aug/audio_aug_20250826220739.py +185 -0
  84. neverlib/.history/audio_aug/audio_aug_20250826220747.py +185 -0
  85. neverlib/.history/audio_aug/audio_aug_20250826220801.py +186 -0
  86. neverlib/.history/audio_aug/audio_aug_20250826220822.py +186 -0
  87. neverlib/.history/audio_aug/audio_aug_20250826220901.py +186 -0
  88. neverlib/.history/audio_aug/audio_aug_20250826221107.py +187 -0
  89. neverlib/.history/audio_aug/audio_aug_20250826221310.py +188 -0
  90. neverlib/.history/audio_aug/audio_aug_20250826221353.py +191 -0
  91. neverlib/.history/audio_aug/audio_aug_20250826221821.py +191 -0
  92. neverlib/.history/audio_aug/audio_aug_20250826221838.py +191 -0
  93. neverlib/.history/audio_aug/audio_aug_20250826221906.py +191 -0
  94. neverlib/.history/audio_aug/audio_aug_20250826221930.py +191 -0
  95. neverlib/.history/audio_aug/audio_aug_20250826221939.py +191 -0
  96. neverlib/.history/audio_aug/audio_aug_20250826221955.py +191 -0
  97. neverlib/.history/audio_aug/audio_aug_20250826222008.py +197 -0
  98. neverlib/.history/audio_aug/audio_aug_20250826222017.py +200 -0
  99. neverlib/.history/audio_aug/audio_aug_20250826222046.py +203 -0
  100. neverlib/.history/audio_aug/audio_aug_20250826222105.py +203 -0
  101. neverlib/.history/audio_aug/audio_aug_20250826222206.py +203 -0
  102. neverlib/.history/audio_aug/audio_aug_20250826222302.py +203 -0
  103. neverlib/.history/audio_aug/audio_aug_20250826222336.py +203 -0
  104. neverlib/.history/audio_aug/audio_aug_20250826222455.py +204 -0
  105. neverlib/.history/audio_aug/audio_aug_20250826222526.py +204 -0
  106. neverlib/.history/audio_aug/audio_aug_20250826222541.py +204 -0
  107. neverlib/.history/audio_aug/audio_aug_20250826222624.py +202 -0
  108. neverlib/.history/audio_aug/audio_aug_20250826222714.py +205 -0
  109. neverlib/.history/audio_aug/audio_aug_20250826222820.py +205 -0
  110. neverlib/.history/audio_aug/audio_aug_20250826222827.py +205 -0
  111. neverlib/.history/audio_aug/audio_aug_20250826222927.py +232 -0
  112. neverlib/.history/audio_aug/audio_aug_20250826223009.py +232 -0
  113. neverlib/.history/audio_aug/audio_aug_20250826223054.py +232 -0
  114. neverlib/.history/audio_aug/audio_aug_20250826223225.py +233 -0
  115. neverlib/.history/audio_aug/audio_aug_20250826223344.py +236 -0
  116. neverlib/.history/audio_aug/audio_aug_20250826223356.py +236 -0
  117. neverlib/.history/audio_aug/audio_aug_20250826223955.py +242 -0
  118. neverlib/.history/audio_aug/audio_aug_20250826224210.py +240 -0
  119. neverlib/.history/audio_aug/audio_aug_20250826224250.py +242 -0
  120. neverlib/.history/audio_aug/audio_aug_20250826224323.py +280 -0
  121. neverlib/.history/audio_aug/audio_aug_20250826224452.py +263 -0
  122. neverlib/.history/audio_aug/audio_aug_20250826224455.py +263 -0
  123. neverlib/.history/audio_aug/audio_aug_20250826224502.py +263 -0
  124. neverlib/.history/audio_aug/audio_aug_20250826224528.py +263 -0
  125. neverlib/.history/audio_aug/audio_aug_20250826224658.py +263 -0
  126. neverlib/.history/audio_aug/audio_aug_20250826224833.py +264 -0
  127. neverlib/.history/audio_aug/audio_aug_20250826225013.py +269 -0
  128. neverlib/.history/audio_aug/audio_aug_20250826225050.py +269 -0
  129. neverlib/.history/audio_aug/audio_aug_20250826225241.py +268 -0
  130. neverlib/.history/audio_aug/audio_aug_20250826225315.py +266 -0
  131. neverlib/.history/audio_aug/audio_aug_20250826225404.py +266 -0
  132. neverlib/.history/audio_aug/audio_aug_20250826225502.py +265 -0
  133. neverlib/.history/audio_aug/audio_aug_20250826225950.py +267 -0
  134. neverlib/.history/audio_aug/audio_aug_20250826225959.py +268 -0
  135. neverlib/.history/audio_aug/audio_aug_20250826230222.py +271 -0
  136. neverlib/.history/audio_aug/audio_aug_20250826230248.py +270 -0
  137. neverlib/.history/audio_aug/audio_aug_20250826230638.py +266 -0
  138. neverlib/.history/audio_aug/audio_aug_20250826230755.py +266 -0
  139. neverlib/.history/audio_aug/audio_aug_20250826230941.py +265 -0
  140. neverlib/.history/audio_aug/audio_aug_20250826231054.py +266 -0
  141. neverlib/.history/audio_aug/audio_aug_20250826231117.py +266 -0
  142. neverlib/.history/audio_aug/audio_aug_20250826231219.py +266 -0
  143. neverlib/.history/audio_aug/audio_aug_20250826232330.py +266 -0
  144. neverlib/.history/audio_aug/audio_aug_20250826232352.py +266 -0
  145. neverlib/.history/audio_aug/audio_aug_20250827152748.py +268 -0
  146. neverlib/.history/audio_aug/audio_aug_20250827152806.py +268 -0
  147. neverlib/.history/audio_aug/audio_aug_20250827152808.py +268 -0
  148. neverlib/.history/audio_aug/audio_aug_20250827152917.py +283 -0
  149. neverlib/.history/audio_aug/audio_aug_20250827152929.py +281 -0
  150. neverlib/.history/audio_aug/audio_aug_20250827153100.py +286 -0
  151. neverlib/.history/audio_aug/audio_aug_20250827153102.py +286 -0
  152. neverlib/.history/audio_aug/audio_aug_20250827153301.py +295 -0
  153. neverlib/.history/audio_aug/audio_aug_20250827153331.py +298 -0
  154. neverlib/.history/audio_aug/audio_aug_20250827153525.py +303 -0
  155. neverlib/.history/audio_aug/audio_aug_20250827153533.py +304 -0
  156. neverlib/.history/audio_aug/audio_aug_20250827153541.py +321 -0
  157. neverlib/.history/audio_aug/audio_aug_20250827153805.py +322 -0
  158. neverlib/.history/audio_aug/audio_aug_20250827153832.py +323 -0
  159. neverlib/.history/audio_aug/audio_aug_20250827153836.py +324 -0
  160. neverlib/.history/audio_aug/audio_aug_20250827153846.py +324 -0
  161. neverlib/.history/audio_aug/audio_aug_20250827153859.py +325 -0
  162. neverlib/.history/audio_aug/audio_aug_20250827154453.py +337 -0
  163. neverlib/.history/audio_aug/audio_aug_20250827154513.py +355 -0
  164. neverlib/.history/audio_aug/audio_aug_20250827154538.py +356 -0
  165. neverlib/.history/audio_aug/audio_aug_20250827154541.py +357 -0
  166. neverlib/.history/audio_aug/audio_aug_20250827154612.py +357 -0
  167. neverlib/.history/audio_aug/audio_aug_20250827154657.py +360 -0
  168. neverlib/.history/audio_aug/audio_aug_20250827154708.py +360 -0
  169. neverlib/.history/audio_aug/audio_aug_20250827154728.py +366 -0
  170. neverlib/.history/audio_aug/audio_aug_20250827154755.py +367 -0
  171. neverlib/.history/audio_aug/audio_aug_20250827154800.py +367 -0
  172. neverlib/.history/audio_aug/audio_aug_20250827154917.py +368 -0
  173. neverlib/.history/audio_aug/audio_aug_20250827154928.py +369 -0
  174. neverlib/.history/audio_aug/audio_aug_20250827154932.py +370 -0
  175. neverlib/.history/audio_aug/audio_aug_20250827154947.py +372 -0
  176. neverlib/.history/audio_aug/audio_aug_20250827155015.py +375 -0
  177. neverlib/.history/audio_aug/audio_aug_20250827155106.py +375 -0
  178. neverlib/.history/audio_aug/audio_aug_20250827155114.py +393 -0
  179. neverlib/.history/audio_aug/audio_aug_20250827155207.py +415 -0
  180. neverlib/.history/audio_aug/audio_aug_20250827155300.py +415 -0
  181. neverlib/.history/audio_aug/audio_aug_20250827155321.py +471 -0
  182. neverlib/.history/audio_aug/audio_aug_20250827164703.py +471 -0
  183. neverlib/.history/audio_aug/audio_aug_20250827164749.py +471 -0
  184. neverlib/.history/audio_aug/audio_aug_20250827165252.py +472 -0
  185. neverlib/.history/audio_aug/audio_aug_20250827165334.py +472 -0
  186. neverlib/.history/audio_aug/audio_aug_20250827165404.py +473 -0
  187. neverlib/.history/audio_aug/audio_aug_20250827165610.py +473 -0
  188. neverlib/.history/audio_aug/audio_aug_20250827165805.py +473 -0
  189. neverlib/.history/audio_aug/audio_aug_20250827170056.py +473 -0
  190. neverlib/.history/audio_aug/audio_aug_20250827170106.py +472 -0
  191. neverlib/.history/audio_aug/audio_aug_20250827170143.py +472 -0
  192. neverlib/.history/audio_aug/audio_aug_20250827170216.py +472 -0
  193. neverlib/.history/audio_aug/audio_aug_20250827170218.py +472 -0
  194. neverlib/.history/audio_aug/audio_aug_20250827170314.py +472 -0
  195. neverlib/.history/audio_aug/audio_aug_20250827171500.py +471 -0
  196. neverlib/.history/audio_aug/audio_aug_20250827172347.py +471 -0
  197. neverlib/.history/audio_aug/audio_aug_20250827172558.py +470 -0
  198. neverlib/.history/audio_aug/audio_aug_20250827172559.py +470 -0
  199. neverlib/.history/audio_aug/audio_aug_20250827172801.py +470 -0
  200. neverlib/.history/audio_aug/audio_aug_20250827182522.py +470 -0
  201. neverlib/.history/audio_aug/audio_aug_20250827182526.py +470 -0
  202. neverlib/.history/audio_aug/audio_aug_20250827182626.py +470 -0
  203. neverlib/.history/audio_aug/audio_aug_20250827182715.py +470 -0
  204. neverlib/.history/audio_aug/audio_aug_20250904185444.py +470 -0
  205. neverlib/.history/audio_aug/audio_aug_20250904185538.py +445 -0
  206. neverlib/.history/data_analyze/__init___20250806204158.py +14 -0
  207. neverlib/.history/data_analyze/__init___20250827163248.py +14 -0
  208. neverlib/.history/filter/auto_eq/freq_eq_20250821143140.py +76 -0
  209. neverlib/.history/filter/auto_eq/freq_eq_20250821153208.py +76 -0
  210. neverlib/.history/filter/auto_eq/freq_eq_20250821153214.py +76 -0
  211. neverlib/.history/filter/auto_eq/ga_eq_basic_20250901110521.py +385 -0
  212. neverlib/.history/filter/auto_eq/ga_eq_basic_20250901110652.py +385 -0
  213. neverlib/.history/filter/common_20250806002134.py +37 -0
  214. neverlib/.history/filter/common_20250821120448.py +49 -0
  215. neverlib/.history/filter/common_20250821120453.py +49 -0
  216. neverlib/.history/metrics/snr_20250827224201.py +182 -0
  217. neverlib/.history/metrics/snr_20250827234019.py +186 -0
  218. neverlib/.history/metrics/snr_20250827234028.py +186 -0
  219. neverlib/.history/metrics/snr_20250827234030.py +186 -0
  220. neverlib/.history/utils/audio_split_20250805234209.py +268 -0
  221. neverlib/.history/utils/audio_split_20250904185309.py +268 -0
  222. neverlib/.history/utils/utils_20250813165516.py +330 -0
  223. neverlib/.history/utils/utils_20250904181341.py +328 -0
  224. neverlib/.history/utils/utils_20250904185546.py +352 -0
  225. neverlib/.history/utils/utils_20250904185548.py +353 -0
  226. neverlib/.history/utils/utils_20250904185603.py +353 -0
  227. neverlib/.history/utils/utils_20250904185636.py +353 -0
  228. neverlib/.history/utils/utils_20250904185658.py +358 -0
  229. neverlib/.history/utils/utils_20250904190053.py +359 -0
  230. 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
  231. neverlib/.specstory/history/2025-08-26_11-54Z-oserror-missing-shared-object-file.md +87 -0
  232. 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
  233. neverlib/.specstory/history/2025-08-27_08-29Z-delete-python-file-command.md +211 -0
  234. 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
  235. neverlib/Docs/audio_aug_test/test_snr.py +55 -0
  236. neverlib/Docs/audio_aug_test/test_volume.py +0 -0
  237. neverlib/QA/html2markdown.py +27 -0
  238. neverlib/__init__.py +10 -20
  239. neverlib/audio_aug/__init__.py +6 -1
  240. neverlib/audio_aug/audio_aug.py +360 -55
  241. neverlib/data_analyze/__init__.py +8 -2
  242. neverlib/data_analyze/temporal_features.py +1 -1
  243. neverlib/filter/__init__.py +9 -3
  244. neverlib/filter/auto_eq/freq_eq.py +1 -1
  245. neverlib/filter/auto_eq/ga_eq_basic.py +3 -3
  246. neverlib/filter/common.py +12 -0
  247. neverlib/metrics/snr.py +5 -3
  248. neverlib/utils/__init__.py +14 -7
  249. neverlib/utils/lazy_module.py +81 -0
  250. neverlib/utils/message.py +3 -8
  251. neverlib/utils/utils.py +32 -3
  252. neverlib/vad/__init__.py +16 -9
  253. neverlib/vad/utils.py +20 -6
  254. {neverlib-0.2.4.dist-info → neverlib-0.2.6.dist-info}/METADATA +21 -17
  255. neverlib-0.2.6.dist-info/RECORD +467 -0
  256. neverlib-0.2.4.dist-info/RECORD +0 -229
  257. /neverlib/{Docs/audio_aug/test_snr.py → .history/Docs/audio_aug/test_snr_20250827162033.py} +0 -0
  258. {neverlib-0.2.4.dist-info → neverlib-0.2.6.dist-info}/WHEEL +0 -0
  259. {neverlib-0.2.4.dist-info → neverlib-0.2.6.dist-info}/licenses/LICENSE +0 -0
  260. {neverlib-0.2.4.dist-info → neverlib-0.2.6.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,328 @@
1
+ # -*- coding:utf-8 -*-
2
+ # Author:凌逆战 | Never
3
+ # Date: 2023/9/25
4
+ """
5
+ folder处理
6
+ """
7
+ import os
8
+ import random
9
+ import shutil
10
+ import fnmatch
11
+ from tqdm import tqdm
12
+ from datetime import datetime
13
+ import soundfile as sf
14
+ import numpy as np
15
+ EPS = np.finfo(float).eps
16
+
17
+
18
+ def get_path_list(source_path, end="*.wav", shuffle=False):
19
+ wav_list = []
20
+ for root, dirnames, filenames in os.walk(source_path):
21
+ # 实现列表特殊字符的过滤或筛选,返回符合匹配“.wav”字符列表
22
+ for filename in fnmatch.filter(filenames, end):
23
+ wav_list.append(os.path.join(root, filename))
24
+ if os.environ.get("LOCAL_RANK", "0") == "0":
25
+ print(source_path, len(wav_list))
26
+ if shuffle:
27
+ random.shuffle(wav_list)
28
+ return wav_list
29
+
30
+
31
+ def rename_files_and_folders(directory, replace='_-', replacement='_'):
32
+ # 将路径的指定字符替换为指定字符
33
+ for root, dirs, files in os.walk(directory):
34
+ for filename in files:
35
+ if replace in filename:
36
+ new_filename = filename.replace(replace, replacement)
37
+ old_path = os.path.join(root, filename)
38
+ new_path = os.path.join(root, new_filename)
39
+ os.rename(old_path, new_path)
40
+ print(f'Renamed file: {old_path} -> {new_path}')
41
+
42
+ for folder in dirs:
43
+ if replace in folder:
44
+ new_folder = folder.replace(replace, replacement)
45
+ old_path = os.path.join(root, folder)
46
+ new_path = os.path.join(root, new_folder)
47
+ os.rename(old_path, new_path)
48
+ print(f'Renamed folder: {old_path} -> {new_path}')
49
+
50
+
51
+ def get_file_time(file_path):
52
+ # 获取最后修改时间
53
+ mod_time = os.path.getmtime(file_path)
54
+ # 转为data_time格式: 年-月-日-时-分-秒
55
+ datetime_dt = datetime.fromtimestamp(mod_time)
56
+
57
+ # 如果时间早于2024-09-04 02:00:00, 则删除
58
+ # if datetime_dt < datetime(2024, 9, 4, 2, 0, 0):
59
+ # print(file_path)
60
+ return datetime_dt
61
+
62
+
63
+ def TrainValSplit(dataset_dir, train_dir, val_dir, percentage=0.9):
64
+ """ 分割数据集为训练集和验证集
65
+ :param dataset_dir: 源数据集地址
66
+ :param train_dir: 训练集地址
67
+ :param val_dir: 验证集地址
68
+ :param percentage: 分割百分比
69
+ """
70
+ wav_path_list = get_path_list(dataset_dir, end="*.wav", shuffle=True)
71
+ total_wav_num = len(wav_path_list)
72
+ # 计算训练集和验证集的分割点
73
+ split_idx = int(total_wav_num * percentage)
74
+ train_path_list, val_path_list = wav_path_list[:split_idx], wav_path_list[split_idx:]
75
+
76
+ for train_wavpath in tqdm(train_path_list, desc="Copying train wav"):
77
+ target_path = train_wavpath.replace(dataset_dir, train_dir)
78
+ if not os.path.exists(os.path.split(target_path)[0]):
79
+ os.makedirs(os.path.split(target_path)[0])
80
+ shutil.copy(train_wavpath, target_path)
81
+
82
+ for val_wavpath in tqdm(val_path_list, desc="Copying val wav"):
83
+ target_path = val_wavpath.replace(dataset_dir, val_dir)
84
+ if not os.path.exists(os.path.split(target_path)[0]):
85
+ os.makedirs(os.path.split(target_path)[0])
86
+ shutil.copy(val_wavpath, target_path)
87
+
88
+ print("Done!")
89
+
90
+
91
+ def TrainValTestSplit(dataset_dir, train_dir, val_dir, test_dir, percentage=[0.8, 0.1, 0.1]):
92
+ """ 分割数据集为训练集、验证集和测试集
93
+ :param dataset_dir: 源数据集地址
94
+ :param train_dir: 训练集地址
95
+ :param val_dir: 验证集地址
96
+ :param test_dir: 测试集地址
97
+ :param percentage: 分割百分比
98
+ """
99
+ assert sum(percentage) == 1.0, "百分比总和必须等于1.0"
100
+
101
+ wav_path_list = sorted(get_path_list(dataset_dir, end="*.wav"))
102
+ random.seed(10086)
103
+ random.shuffle(wav_path_list) # 打乱列表的顺序
104
+ total_wav_num = len(wav_path_list)
105
+
106
+ # 计算训练集、验证集和测试集的分割点
107
+ train_split_idx = int(total_wav_num * percentage[0])
108
+ val_split_idx = train_split_idx + int(total_wav_num * percentage[1])
109
+
110
+ train_path_list = wav_path_list[:train_split_idx]
111
+ val_path_list = wav_path_list[train_split_idx:val_split_idx]
112
+ test_path_list = wav_path_list[val_split_idx:]
113
+
114
+ for train_wavpath in tqdm(train_path_list, desc="复制训练集音频"):
115
+ target_path = train_wavpath.replace(dataset_dir, train_dir)
116
+ if not os.path.exists(os.path.split(target_path)[0]):
117
+ os.makedirs(os.path.split(target_path)[0])
118
+ shutil.copy(train_wavpath, target_path)
119
+
120
+ for val_wavpath in tqdm(val_path_list, desc="复制验证集音频"):
121
+ target_path = val_wavpath.replace(dataset_dir, val_dir)
122
+ if not os.path.exists(os.path.split(target_path)[0]):
123
+ os.makedirs(os.path.split(target_path)[0])
124
+ shutil.copy(val_wavpath, target_path)
125
+
126
+ for test_wavpath in tqdm(test_path_list, desc="复制测试集音频"):
127
+ target_path = test_wavpath.replace(dataset_dir, test_dir)
128
+ if not os.path.exists(os.path.split(target_path)[0]):
129
+ os.makedirs(os.path.split(target_path)[0])
130
+ shutil.copy(test_wavpath, target_path)
131
+
132
+ print(f"完成! 训练集: {len(train_path_list)}个文件, 验证集: {len(val_path_list)}个文件, 测试集: {len(test_path_list)}个文件")
133
+
134
+
135
+ def get_leaf_folders(directory):
136
+ # 获取最底层的文件夹路径
137
+ leaf_folders = []
138
+ for root, dirs, _ in os.walk(directory):
139
+ if not dirs: # 如果当前文件夹没有子文件夹
140
+ leaf_folders.append(root)
141
+ return leaf_folders
142
+
143
+
144
+ def del_empty_folders(path):
145
+ """递归删除空文件夹(先删除子文件夹, 再删除父文件夹)"""
146
+ if not os.path.isdir(path):
147
+ return
148
+
149
+ # 获取子文件夹
150
+ subfolders = [os.path.join(path, d) for d in os.listdir(path) if os.path.isdir(os.path.join(path, d))]
151
+
152
+ # 递归处理子文件夹
153
+ for subfolder in subfolders:
154
+ del_empty_folders(subfolder)
155
+
156
+ # 如果文件夹为空,则删除
157
+ if not os.listdir(path):
158
+ os.rmdir(path)
159
+ print(f"删除空文件夹: {path}")
160
+
161
+
162
+ def DatasetSubfloderSplit(source_dir, split_dirs, percentage=None):
163
+ """
164
+ 将一个数据集按照子文件夹数量分割成train/val/test数据集
165
+ Args:
166
+ source_dir (str): 源数据集目录
167
+ split_dirs (list): 目标目录列表, 如 [train_dir, val_dir] 或 [train_dir, val_dir, test_dir]
168
+ percentage (list, optional): 分割比例, 如 [0.9, 0.1] 或 [0.8, 0.1, 0.1]。默认为 None, 此时:
169
+ - 如果是两路分割, 默认为 [0.9, 0.1]
170
+ - 如果是三路分割, 默认为 [0.8, 0.1, 0.1]
171
+ Example:
172
+ # 两路分割示例
173
+ DatasetSplit(
174
+ source_dir=source_dataset_path,
175
+ split_dirs=[target_train_path, target_val_path],
176
+ percentage=[0.9, 0.1]
177
+ )
178
+
179
+ # 三路分割示例
180
+ DatasetSplit(
181
+ source_dir=source_dataset_path,
182
+ split_dirs=[target_train_path, target_val_path, target_test_path],
183
+ percentage=[0.8, 0.1, 0.1]
184
+ )
185
+
186
+ # 使用默认比例的两路分割
187
+ DatasetSplit(
188
+ source_dir=source_dataset_path,
189
+ split_dirs=[target_train_path, target_val_path]
190
+ )
191
+ """
192
+ if percentage is None:
193
+ percentage = [0.9, 0.1] if len(split_dirs) == 2 else [0.8, 0.1, 0.1]
194
+
195
+ # 验证输入参数
196
+ if len(split_dirs) not in [2, 3]:
197
+ raise ValueError("只支持2路或3路分割(训练集/验证集 或 训练集/验证集/测试集)")
198
+ if len(percentage) != len(split_dirs):
199
+ raise ValueError("分割比例数量必须与目标目录数量相同")
200
+ if sum(percentage) != 1.0:
201
+ raise ValueError("分割比例之和必须等于1.0")
202
+
203
+ # 获取并打乱文件夹列表
204
+ leaf_folder_list = sorted(get_leaf_folders(source_dir))
205
+ random.seed(10086)
206
+ random.shuffle(leaf_folder_list)
207
+ total_folder_num = len(leaf_folder_list)
208
+
209
+ # 计算分割点
210
+ split_indices = []
211
+ acc_percentage = 0
212
+ for p in percentage[:-1]: # 最后一个比例不需要计算
213
+ acc_percentage += p
214
+ split_indices.append(int(total_folder_num * acc_percentage))
215
+
216
+ # 分割文件夹列表
217
+ split_folder_lists = []
218
+ start_idx = 0
219
+ for end_idx in split_indices:
220
+ split_folder_lists.append(leaf_folder_list[start_idx:end_idx])
221
+ start_idx = end_idx
222
+ split_folder_lists.append(leaf_folder_list[start_idx:]) # 添加最后一部分
223
+
224
+ # 复制文件夹
225
+ split_names = ['train', 'val', 'test']
226
+ for folders, target_dir, split_name in zip(split_folder_lists, split_dirs, split_names[:len(split_dirs)]):
227
+ for folder in tqdm(folders, desc=f"Copying {split_name} folders"):
228
+ target_folder = folder.replace(source_dir, target_dir)
229
+ os.makedirs(os.path.dirname(target_folder), exist_ok=True)
230
+ shutil.copytree(folder, target_folder)
231
+
232
+ # 打印统计信息
233
+ print(f"Total folders: {total_folder_num}")
234
+ for folders, split_name in zip(split_folder_lists, split_names[:len(split_dirs)]):
235
+ print(f"{split_name.capitalize()} folders: {len(folders)}")
236
+
237
+
238
+ def pcm2wav(pcm_path, wav_path, sr=16000, channels=1, subtype='PCM_16'):
239
+ """
240
+ 将pcm文件转换为wav文件
241
+ :param pcm_path: pcm文件路径
242
+ :param wav_path: wav文件路径
243
+ :param sr: 采样率
244
+ :param channels: 声道数
245
+ :param subtype: 子类型
246
+ """
247
+ pcm_data = np.fromfile(pcm_path, dtype=np.int16)
248
+ pcm_data = pcm_data.reshape(-1, channels) # 支持多通道
249
+ sf.write(wav_path, pcm_data, sr, subtype=subtype)
250
+
251
+
252
+ def wav2pcm(wav_path, pcm_path):
253
+ """
254
+ 将wav文件转换为pcm文件
255
+ :param wav_path: wav文件路径
256
+ :param pcm_path: pcm文件路径
257
+ """
258
+ data, _ = sf.read(wav_path, dtype='int16')
259
+ data.tofile(pcm_path)
260
+
261
+
262
+ def save_weight_histogram(model, save_dir, mode=["params", "buffers"], ignore_name=["scale", "bias"], bins=100):
263
+ """
264
+ 保存模型权重分布直方图
265
+ Args:
266
+ model: PyTorch模型
267
+ save_dir: 保存路径
268
+ mode: 保存模式, 可选值为["params", "buffers"]
269
+ bins: 直方图bin数量
270
+ """
271
+ import matplotlib.pyplot as plt
272
+ # 如果路径存在, 则删除
273
+ if os.path.exists(save_dir):
274
+ shutil.rmtree(save_dir)
275
+
276
+ if "params" in mode:
277
+ os.makedirs(os.path.join(save_dir, "param"), exist_ok=True)
278
+ for name, param in model.named_parameters():
279
+ if any(ignore in name for ignore in ignore_name):
280
+ continue
281
+ param = param.cpu().data.flatten().numpy()
282
+ param_min = param.min()
283
+ param_max = param.max()
284
+ param_mean = param.mean()
285
+ param_std = param.std()
286
+
287
+ # 保存模型参数到地址
288
+ # 绘制直方图
289
+ plt.title(name)
290
+ plt.xlabel("value")
291
+ plt.ylabel("count")
292
+ plt.grid(alpha=0.5)
293
+ # 在右上角添加统计信息
294
+ plt.text(1, 1, f"max: {param_max:.2f}\n \
295
+ min: {param_min:.2f}\n \
296
+ mean: {param_mean:.2f}\n \
297
+ std: {param_std:.2f}",
298
+ ha='right', va='top', transform=plt.gca().transAxes)
299
+ plt.hist(param, bins=bins)
300
+ plt.savefig(os.path.join(save_dir, "param", f"{name}.png"))
301
+ plt.close()
302
+ if "buffers" in mode:
303
+ os.makedirs(os.path.join(save_dir, "buffer"), exist_ok=True)
304
+ for name, buffer in model.named_buffers():
305
+ if "running_mean" not in name and "running_var" not in name:
306
+ continue
307
+ buffer = buffer.cpu().data.flatten().numpy()
308
+
309
+ # 计算统计数据
310
+ buffer_min = buffer.min()
311
+ buffer_max = buffer.max()
312
+ buffer_mean = buffer.mean()
313
+ buffer_std = buffer.std()
314
+
315
+ # 绘制直方图
316
+ plt.title(name)
317
+ plt.xlabel("value")
318
+ plt.ylabel("count")
319
+ plt.grid(alpha=0.5)
320
+ # 在右上角添加统计信息
321
+ plt.text(1, 1, f"max: {buffer_max:.2f}\n \
322
+ min: {buffer_min:.2f}\n \
323
+ mean: {buffer_mean:.2f}\n \
324
+ std: {buffer_std:.2f}",
325
+ ha='right', va='top', transform=plt.gca().transAxes)
326
+ plt.hist(buffer, bins=bins)
327
+ plt.savefig(os.path.join(save_dir, "buffer", f"{name}.png"))
328
+ plt.close()
@@ -0,0 +1,352 @@
1
+ # -*- coding:utf-8 -*-
2
+ # Author:凌逆战 | Never
3
+ # Date: 2023/9/25
4
+ """
5
+ folder处理
6
+ """
7
+ import os
8
+ import random
9
+ import shutil
10
+ import fnmatch
11
+ from tqdm import tqdm
12
+ from datetime import datetime
13
+ import soundfile as sf
14
+ import numpy as np
15
+ EPS = np.finfo(float).eps
16
+
17
+
18
+ def get_path_list(source_path, end="*.wav", shuffle=False):
19
+ wav_list = []
20
+ for root, dirnames, filenames in os.walk(source_path):
21
+ # 实现列表特殊字符的过滤或筛选,返回符合匹配“.wav”字符列表
22
+ for filename in fnmatch.filter(filenames, end):
23
+ wav_list.append(os.path.join(root, filename))
24
+ if os.environ.get("LOCAL_RANK", "0") == "0":
25
+ print(source_path, len(wav_list))
26
+ if shuffle:
27
+ random.shuffle(wav_list)
28
+ return wav_list
29
+
30
+ def get_audio_segments(wav_len, audio_path_list, sr=16000):
31
+ """
32
+ 从音频列表中随机拼接指定长度音频
33
+ Args:
34
+ wav_len: 需要返回的音频长度
35
+ audio_path_list: 音频路径列表
36
+ sr: 采样率
37
+ Returns:返回指定长度的音频
38
+ """
39
+ audio_len = 0
40
+ wav_list = []
41
+ while audio_len < wav_len:
42
+ audio_path = random.choice(audio_path_list)
43
+ wav, wav_sr = sf.read(audio_path, always_2d=True, dtype='float32')
44
+ assert wav_sr == sr, f"音频采样率是{wav_sr}, 期望{sr}"
45
+ audio_len += len(wav)
46
+ wav_list.append(wav)
47
+ wav = np.concatenate(wav_list, axis=0)
48
+ if len(wav) > wav_len:
49
+ # 随机截取clean_len
50
+ start = random.randint(0, len(wav) - wav_len)
51
+ wav = wav[start:start + wav_len, :]
52
+ return wav
53
+
54
+
55
+ def rename_files_and_folders(directory, replace='_-', replacement='_'):
56
+ # 将路径的指定字符替换为指定字符
57
+ for root, dirs, files in os.walk(directory):
58
+ for filename in files:
59
+ if replace in filename:
60
+ new_filename = filename.replace(replace, replacement)
61
+ old_path = os.path.join(root, filename)
62
+ new_path = os.path.join(root, new_filename)
63
+ os.rename(old_path, new_path)
64
+ print(f'Renamed file: {old_path} -> {new_path}')
65
+
66
+ for folder in dirs:
67
+ if replace in folder:
68
+ new_folder = folder.replace(replace, replacement)
69
+ old_path = os.path.join(root, folder)
70
+ new_path = os.path.join(root, new_folder)
71
+ os.rename(old_path, new_path)
72
+ print(f'Renamed folder: {old_path} -> {new_path}')
73
+
74
+
75
+ def get_file_time(file_path):
76
+ # 获取最后修改时间
77
+ mod_time = os.path.getmtime(file_path)
78
+ # 转为data_time格式: 年-月-日-时-分-秒
79
+ datetime_dt = datetime.fromtimestamp(mod_time)
80
+
81
+ # 如果时间早于2024-09-04 02:00:00, 则删除
82
+ # if datetime_dt < datetime(2024, 9, 4, 2, 0, 0):
83
+ # print(file_path)
84
+ return datetime_dt
85
+
86
+
87
+ def TrainValSplit(dataset_dir, train_dir, val_dir, percentage=0.9):
88
+ """ 分割数据集为训练集和验证集
89
+ :param dataset_dir: 源数据集地址
90
+ :param train_dir: 训练集地址
91
+ :param val_dir: 验证集地址
92
+ :param percentage: 分割百分比
93
+ """
94
+ wav_path_list = get_path_list(dataset_dir, end="*.wav", shuffle=True)
95
+ total_wav_num = len(wav_path_list)
96
+ # 计算训练集和验证集的分割点
97
+ split_idx = int(total_wav_num * percentage)
98
+ train_path_list, val_path_list = wav_path_list[:split_idx], wav_path_list[split_idx:]
99
+
100
+ for train_wavpath in tqdm(train_path_list, desc="Copying train wav"):
101
+ target_path = train_wavpath.replace(dataset_dir, train_dir)
102
+ if not os.path.exists(os.path.split(target_path)[0]):
103
+ os.makedirs(os.path.split(target_path)[0])
104
+ shutil.copy(train_wavpath, target_path)
105
+
106
+ for val_wavpath in tqdm(val_path_list, desc="Copying val wav"):
107
+ target_path = val_wavpath.replace(dataset_dir, val_dir)
108
+ if not os.path.exists(os.path.split(target_path)[0]):
109
+ os.makedirs(os.path.split(target_path)[0])
110
+ shutil.copy(val_wavpath, target_path)
111
+
112
+ print("Done!")
113
+
114
+
115
+ def TrainValTestSplit(dataset_dir, train_dir, val_dir, test_dir, percentage=[0.8, 0.1, 0.1]):
116
+ """ 分割数据集为训练集、验证集和测试集
117
+ :param dataset_dir: 源数据集地址
118
+ :param train_dir: 训练集地址
119
+ :param val_dir: 验证集地址
120
+ :param test_dir: 测试集地址
121
+ :param percentage: 分割百分比
122
+ """
123
+ assert sum(percentage) == 1.0, "百分比总和必须等于1.0"
124
+
125
+ wav_path_list = sorted(get_path_list(dataset_dir, end="*.wav"))
126
+ random.seed(10086)
127
+ random.shuffle(wav_path_list) # 打乱列表的顺序
128
+ total_wav_num = len(wav_path_list)
129
+
130
+ # 计算训练集、验证集和测试集的分割点
131
+ train_split_idx = int(total_wav_num * percentage[0])
132
+ val_split_idx = train_split_idx + int(total_wav_num * percentage[1])
133
+
134
+ train_path_list = wav_path_list[:train_split_idx]
135
+ val_path_list = wav_path_list[train_split_idx:val_split_idx]
136
+ test_path_list = wav_path_list[val_split_idx:]
137
+
138
+ for train_wavpath in tqdm(train_path_list, desc="复制训练集音频"):
139
+ target_path = train_wavpath.replace(dataset_dir, train_dir)
140
+ if not os.path.exists(os.path.split(target_path)[0]):
141
+ os.makedirs(os.path.split(target_path)[0])
142
+ shutil.copy(train_wavpath, target_path)
143
+
144
+ for val_wavpath in tqdm(val_path_list, desc="复制验证集音频"):
145
+ target_path = val_wavpath.replace(dataset_dir, val_dir)
146
+ if not os.path.exists(os.path.split(target_path)[0]):
147
+ os.makedirs(os.path.split(target_path)[0])
148
+ shutil.copy(val_wavpath, target_path)
149
+
150
+ for test_wavpath in tqdm(test_path_list, desc="复制测试集音频"):
151
+ target_path = test_wavpath.replace(dataset_dir, test_dir)
152
+ if not os.path.exists(os.path.split(target_path)[0]):
153
+ os.makedirs(os.path.split(target_path)[0])
154
+ shutil.copy(test_wavpath, target_path)
155
+
156
+ print(f"完成! 训练集: {len(train_path_list)}个文件, 验证集: {len(val_path_list)}个文件, 测试集: {len(test_path_list)}个文件")
157
+
158
+
159
+ def get_leaf_folders(directory):
160
+ # 获取最底层的文件夹路径
161
+ leaf_folders = []
162
+ for root, dirs, _ in os.walk(directory):
163
+ if not dirs: # 如果当前文件夹没有子文件夹
164
+ leaf_folders.append(root)
165
+ return leaf_folders
166
+
167
+
168
+ def del_empty_folders(path):
169
+ """递归删除空文件夹(先删除子文件夹, 再删除父文件夹)"""
170
+ if not os.path.isdir(path):
171
+ return
172
+
173
+ # 获取子文件夹
174
+ subfolders = [os.path.join(path, d) for d in os.listdir(path) if os.path.isdir(os.path.join(path, d))]
175
+
176
+ # 递归处理子文件夹
177
+ for subfolder in subfolders:
178
+ del_empty_folders(subfolder)
179
+
180
+ # 如果文件夹为空,则删除
181
+ if not os.listdir(path):
182
+ os.rmdir(path)
183
+ print(f"删除空文件夹: {path}")
184
+
185
+
186
+ def DatasetSubfloderSplit(source_dir, split_dirs, percentage=None):
187
+ """
188
+ 将一个数据集按照子文件夹数量分割成train/val/test数据集
189
+ Args:
190
+ source_dir (str): 源数据集目录
191
+ split_dirs (list): 目标目录列表, 如 [train_dir, val_dir] 或 [train_dir, val_dir, test_dir]
192
+ percentage (list, optional): 分割比例, 如 [0.9, 0.1] 或 [0.8, 0.1, 0.1]。默认为 None, 此时:
193
+ - 如果是两路分割, 默认为 [0.9, 0.1]
194
+ - 如果是三路分割, 默认为 [0.8, 0.1, 0.1]
195
+ Example:
196
+ # 两路分割示例
197
+ DatasetSplit(
198
+ source_dir=source_dataset_path,
199
+ split_dirs=[target_train_path, target_val_path],
200
+ percentage=[0.9, 0.1]
201
+ )
202
+
203
+ # 三路分割示例
204
+ DatasetSplit(
205
+ source_dir=source_dataset_path,
206
+ split_dirs=[target_train_path, target_val_path, target_test_path],
207
+ percentage=[0.8, 0.1, 0.1]
208
+ )
209
+
210
+ # 使用默认比例的两路分割
211
+ DatasetSplit(
212
+ source_dir=source_dataset_path,
213
+ split_dirs=[target_train_path, target_val_path]
214
+ )
215
+ """
216
+ if percentage is None:
217
+ percentage = [0.9, 0.1] if len(split_dirs) == 2 else [0.8, 0.1, 0.1]
218
+
219
+ # 验证输入参数
220
+ if len(split_dirs) not in [2, 3]:
221
+ raise ValueError("只支持2路或3路分割(训练集/验证集 或 训练集/验证集/测试集)")
222
+ if len(percentage) != len(split_dirs):
223
+ raise ValueError("分割比例数量必须与目标目录数量相同")
224
+ if sum(percentage) != 1.0:
225
+ raise ValueError("分割比例之和必须等于1.0")
226
+
227
+ # 获取并打乱文件夹列表
228
+ leaf_folder_list = sorted(get_leaf_folders(source_dir))
229
+ random.seed(10086)
230
+ random.shuffle(leaf_folder_list)
231
+ total_folder_num = len(leaf_folder_list)
232
+
233
+ # 计算分割点
234
+ split_indices = []
235
+ acc_percentage = 0
236
+ for p in percentage[:-1]: # 最后一个比例不需要计算
237
+ acc_percentage += p
238
+ split_indices.append(int(total_folder_num * acc_percentage))
239
+
240
+ # 分割文件夹列表
241
+ split_folder_lists = []
242
+ start_idx = 0
243
+ for end_idx in split_indices:
244
+ split_folder_lists.append(leaf_folder_list[start_idx:end_idx])
245
+ start_idx = end_idx
246
+ split_folder_lists.append(leaf_folder_list[start_idx:]) # 添加最后一部分
247
+
248
+ # 复制文件夹
249
+ split_names = ['train', 'val', 'test']
250
+ for folders, target_dir, split_name in zip(split_folder_lists, split_dirs, split_names[:len(split_dirs)]):
251
+ for folder in tqdm(folders, desc=f"Copying {split_name} folders"):
252
+ target_folder = folder.replace(source_dir, target_dir)
253
+ os.makedirs(os.path.dirname(target_folder), exist_ok=True)
254
+ shutil.copytree(folder, target_folder)
255
+
256
+ # 打印统计信息
257
+ print(f"Total folders: {total_folder_num}")
258
+ for folders, split_name in zip(split_folder_lists, split_names[:len(split_dirs)]):
259
+ print(f"{split_name.capitalize()} folders: {len(folders)}")
260
+
261
+
262
+ def pcm2wav(pcm_path, wav_path, sr=16000, channels=1, subtype='PCM_16'):
263
+ """
264
+ 将pcm文件转换为wav文件
265
+ :param pcm_path: pcm文件路径
266
+ :param wav_path: wav文件路径
267
+ :param sr: 采样率
268
+ :param channels: 声道数
269
+ :param subtype: 子类型
270
+ """
271
+ pcm_data = np.fromfile(pcm_path, dtype=np.int16)
272
+ pcm_data = pcm_data.reshape(-1, channels) # 支持多通道
273
+ sf.write(wav_path, pcm_data, sr, subtype=subtype)
274
+
275
+
276
+ def wav2pcm(wav_path, pcm_path):
277
+ """
278
+ 将wav文件转换为pcm文件
279
+ :param wav_path: wav文件路径
280
+ :param pcm_path: pcm文件路径
281
+ """
282
+ data, _ = sf.read(wav_path, dtype='int16')
283
+ data.tofile(pcm_path)
284
+
285
+
286
+ def save_weight_histogram(model, save_dir, mode=["params", "buffers"], ignore_name=["scale", "bias"], bins=100):
287
+ """
288
+ 保存模型权重分布直方图
289
+ Args:
290
+ model: PyTorch模型
291
+ save_dir: 保存路径
292
+ mode: 保存模式, 可选值为["params", "buffers"]
293
+ bins: 直方图bin数量
294
+ """
295
+ import matplotlib.pyplot as plt
296
+ # 如果路径存在, 则删除
297
+ if os.path.exists(save_dir):
298
+ shutil.rmtree(save_dir)
299
+
300
+ if "params" in mode:
301
+ os.makedirs(os.path.join(save_dir, "param"), exist_ok=True)
302
+ for name, param in model.named_parameters():
303
+ if any(ignore in name for ignore in ignore_name):
304
+ continue
305
+ param = param.cpu().data.flatten().numpy()
306
+ param_min = param.min()
307
+ param_max = param.max()
308
+ param_mean = param.mean()
309
+ param_std = param.std()
310
+
311
+ # 保存模型参数到地址
312
+ # 绘制直方图
313
+ plt.title(name)
314
+ plt.xlabel("value")
315
+ plt.ylabel("count")
316
+ plt.grid(alpha=0.5)
317
+ # 在右上角添加统计信息
318
+ plt.text(1, 1, f"max: {param_max:.2f}\n \
319
+ min: {param_min:.2f}\n \
320
+ mean: {param_mean:.2f}\n \
321
+ std: {param_std:.2f}",
322
+ ha='right', va='top', transform=plt.gca().transAxes)
323
+ plt.hist(param, bins=bins)
324
+ plt.savefig(os.path.join(save_dir, "param", f"{name}.png"))
325
+ plt.close()
326
+ if "buffers" in mode:
327
+ os.makedirs(os.path.join(save_dir, "buffer"), exist_ok=True)
328
+ for name, buffer in model.named_buffers():
329
+ if "running_mean" not in name and "running_var" not in name:
330
+ continue
331
+ buffer = buffer.cpu().data.flatten().numpy()
332
+
333
+ # 计算统计数据
334
+ buffer_min = buffer.min()
335
+ buffer_max = buffer.max()
336
+ buffer_mean = buffer.mean()
337
+ buffer_std = buffer.std()
338
+
339
+ # 绘制直方图
340
+ plt.title(name)
341
+ plt.xlabel("value")
342
+ plt.ylabel("count")
343
+ plt.grid(alpha=0.5)
344
+ # 在右上角添加统计信息
345
+ plt.text(1, 1, f"max: {buffer_max:.2f}\n \
346
+ min: {buffer_min:.2f}\n \
347
+ mean: {buffer_mean:.2f}\n \
348
+ std: {buffer_std:.2f}",
349
+ ha='right', va='top', transform=plt.gca().transAxes)
350
+ plt.hist(buffer, bins=bins)
351
+ plt.savefig(os.path.join(save_dir, "buffer", f"{name}.png"))
352
+ plt.close()