mirror of
https://github.com/TriM-Organization/Musicreater.git
synced 2026-08-02 00:14:28 +00:00
Maybe yes, maybe no, but 音量响度 should let to go
This commit is contained in:
+20
-3
@@ -1,6 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
音·创 v3 的功能性内容合辑
|
音·创 v3 的功能性内容合辑
|
||||||
|
此处存放无需本体类的内容
|
||||||
"""
|
"""
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@@ -35,13 +36,29 @@ def enumerated_stuffcopy_dictionary(
|
|||||||
|
|
||||||
|
|
||||||
def incremental_save_path(
|
def incremental_save_path(
|
||||||
file_name: str, suffix: str = ".file", appendix_connector: str = "-"
|
file_name: str,
|
||||||
|
suffix: str = ".file",
|
||||||
|
appendix_connector: str = "-",
|
||||||
|
parent_path: Union[Path, str] = Path.cwd(),
|
||||||
) -> Path:
|
) -> Path:
|
||||||
ss_path = Path(file_name).with_suffix(suffix)
|
"""
|
||||||
|
生成一个文件路径,该文件地址指向的文件名应为 `file_name` 添加一个后缀 `suffix`。\n
|
||||||
|
如果 `file_name` 已经存在,则添加一个后缀 `appendix_connector` 和一个数字。
|
||||||
|
此数字由 2 开始,每存在此文件,则递增 1。直到找到最后那个惟一的未被占用的文件路径。\n
|
||||||
|
例如:
|
||||||
|
- file_name = "test", suffix = ".txt", appendix_connector = "-", parent_path = "/tmp/" \n
|
||||||
|
若在 `/tmp` 中:
|
||||||
|
1. `test.txt` 不存在,则返回 Path("/tmp/test.txt")
|
||||||
|
2. 上述文件存在,且 `test-1.txt` 不存在,则返回 Path("/tmp/test-1.txt")
|
||||||
|
3. 上述文件皆存在,但 `test-2.txt` 不存在,则返回 Path("/tmp/test-2.txt")
|
||||||
|
...
|
||||||
|
"""
|
||||||
|
ss_path = parent_path / Path(file_name).with_suffix(suffix)
|
||||||
if ss_path.exists():
|
if ss_path.exists():
|
||||||
now_appendix = 2
|
now_appendix = 2
|
||||||
while (
|
while (
|
||||||
ss_path := Path(file_name + appendix_connector + str(now_appendix) + suffix)
|
ss_path := parent_path
|
||||||
|
/ Path(file_name + appendix_connector + str(now_appendix) + suffix)
|
||||||
).exists():
|
).exists():
|
||||||
now_appendix += 1
|
now_appendix += 1
|
||||||
return ss_path
|
return ss_path
|
||||||
|
|||||||
+76
-187
@@ -438,37 +438,82 @@ MC_INSTRUMENT_BLOCKS_TABLE: Dict[str, Tuple[str, ...]] = {
|
|||||||
}
|
}
|
||||||
"""MC乐器对音符盒下垫方块对照表"""
|
"""MC乐器对音符盒下垫方块对照表"""
|
||||||
|
|
||||||
MC_INSTRUMENT_VOLUME_BALANCE_TABLE: Dict[str, float] = {
|
MC_INSTRUMENT_SOUND_INFO_TABLE: Dict[str, Dict[str, float]] = {
|
||||||
"note.bass": 0.18975738,
|
"note.bass": {"C-LUFS": -1178, "MS": 532.0, "SR": 7218},
|
||||||
"note.bassattack": 0.19250469,
|
"note.bassattack": {"C-LUFS": -1188, "MS": 484.8, "SR": 7921},
|
||||||
"note.snare": 0.09636449,
|
"note.snare": {"C-LUFS": -1173, "MS": 80.0, "SR": 48000},
|
||||||
"note.hat": 0.041303635,
|
"note.hat": {"C-LUFS": -1480, "MS": 85.3, "SR": 48000},
|
||||||
"note.bd": 0.25398168,
|
"note.bd": {"C-LUFS": -957, "MS": 137.8, "SR": 29718},
|
||||||
"note.bell": 0.03190162,
|
"note.bell": {"C-LUFS": -2510, "MS": 440.7, "SR": 32531},
|
||||||
"note.flute": 0.050610494,
|
"note.flute": {"C-LUFS": -2076, "MS": 618.3, "SR": 19875},
|
||||||
"note.chime": 0.011847978,
|
"note.chime": {"C-LUFS": -2984, "MS": 1106.8, "SR": 38859},
|
||||||
"note.guitar": 0.03356794,
|
"note.guitar": {"C-LUFS": -2539, "MS": 567.8, "SR": 24796},
|
||||||
"note.xylophone": 0.025973769,
|
"note.xylophone": {"C-LUFS": -2419, "MS": 142.4, "SR": 39562},
|
||||||
"note.iron_xylophone": 0.044438824,
|
"note.iron_xylophone": {"C-LUFS": -2078, "MS": 603.8, "SR": 9328},
|
||||||
"note.cow_bell": 0.09123069,
|
"note.cow_bell": {"C-LUFS": -1427, "MS": 177.2, "SR": 33234},
|
||||||
"note.didgeridoo": 0.06332747,
|
"note.didgeridoo": {"C-LUFS": -2062, "MS": 441.5, "SR": 15656},
|
||||||
"note.bit": 0.028824601,
|
"note.bit": {"C-LUFS": -2677, "MS": 384.0, "SR": 48000},
|
||||||
"note.banjo": 0.02944984,
|
"note.banjo": {"C-LUFS": -2207, "MS": 466.5, "SR": 31828},
|
||||||
"note.pling": 0.11315284,
|
"note.pling": {"C-LUFS": -1528, "MS": 651.5, "SR": 18468},
|
||||||
"note.trumpet": 0.069420114,
|
"note.trumpet": {"C-LUFS": -1678, "MS": 277.3, "SR": 48000},
|
||||||
"note.trumpet_exposed": 0.083734825,
|
"note.trumpet_exposed": {"C-LUFS": -1682, "MS": 325.3, "SR": 48000},
|
||||||
"note.trumpet_oxidized": 0.047252066,
|
"note.trumpet_oxidized": {"C-LUFS": -2225, "MS": 314.7, "SR": 48000},
|
||||||
"note.trumpet_weathered": 0.06659823,
|
"note.trumpet_weathered": {"C-LUFS": -1875, "MS": 282.7, "SR": 48000},
|
||||||
"note.harp": 0.12101666,
|
"note.harp": {"C-LUFS": -1448, "MS": 588.7, "SR": 15656},
|
||||||
# 嗯……
|
# 嗯……
|
||||||
"fire.ignite": 0.004931174,
|
"fire.ignite": {"C-LUFS": -2788, "MS": 426.2, "SR": 40246},
|
||||||
"firework.blast": 0.015445901,
|
"firework.blast": {"C-LUFS": -2523, "MS": 1004.3, "SR": 44100},
|
||||||
"firework.twinkle": 0.032410737,
|
"firework.twinkle": {"C-LUFS": -2021, "MS": 1335.1, "SR": 44100},
|
||||||
"mob.cat.meow-2": 0.0675417,
|
"mob.cat.meow-2": {"C-LUFS": -1406, "MS": 648.1, "SR": 33182},
|
||||||
"mob.cat.meow-4": 0.05923138,
|
"mob.cat.meow-4": {"C-LUFS": -1412, "MS": 653.6, "SR": 34467},
|
||||||
"mob.zombie.wood": 0.14135803,
|
"mob.zombie.wood": {"C-LUFS": -1017, "MS": 940.4, "SR": 44100},
|
||||||
}
|
}
|
||||||
|
"""
|
||||||
|
MC 乐器对应音效信息表
|
||||||
|
C-LUFS: 响度,单位`百 LUFS`
|
||||||
|
MS: 持续时间,单位`毫秒`
|
||||||
|
SR: 采样率,单位`赫兹`
|
||||||
|
"""
|
||||||
|
|
||||||
|
# 以上的 LUFS 值可以用于计算下面这个倍率
|
||||||
|
# 我们期望所有的音效的响度都为 -20 LUFS
|
||||||
|
# 那么需要改变每一个采样的音量大小就需要
|
||||||
|
# data * (10 ** ((原响度 - 目标响度) / 20))
|
||||||
|
# 其中 10 ** ((原响度 - 目标响度) / 20) 为倍率
|
||||||
|
# 上表中的响度单位是 百 LUFS
|
||||||
|
# 因此实际计算的过程中记得把这一百除回来
|
||||||
|
# 公式就变成了:
|
||||||
|
# data * (10 ** ((C_LUFS - 2000) / 2000))
|
||||||
|
MC_INSTRUMENT_VOLUME_BALANCE_TABLE: Dict[str, float] = {
|
||||||
|
"note.bass": 0.3881503659906483,
|
||||||
|
"note.bassattack": 0.3926449353995998,
|
||||||
|
"note.snare": 0.3859224115947292,
|
||||||
|
"note.hat": 0.5495408738576245,
|
||||||
|
"note.bd": 0.3009539168873202,
|
||||||
|
"note.bell": 1.7988709151287878,
|
||||||
|
"note.flute": 1.0914403364487566,
|
||||||
|
"note.chime": 3.1045595881283554,
|
||||||
|
"note.guitar": 1.8599445632225762,
|
||||||
|
"note.xylophone": 1.6199439939036293,
|
||||||
|
"note.iron_xylophone": 1.093956366272094,
|
||||||
|
"note.cow_bell": 0.517011257968655,
|
||||||
|
"note.didgeridoo": 1.0739894123412448,
|
||||||
|
"note.bit": 2.1802183971859455,
|
||||||
|
"note.banjo": 1.2691121444451907,
|
||||||
|
"note.pling": 0.580764417521312,
|
||||||
|
"note.trumpet": 0.690239803840242,
|
||||||
|
"note.trumpet_exposed": 0.6934258060165691,
|
||||||
|
"note.trumpet_oxidized": 1.2956866975170194,
|
||||||
|
"note.trumpet_weathered": 0.8659643233600653,
|
||||||
|
"note.harp": 0.5296634438916578,
|
||||||
|
"fire.ignite": 2.4774220576332855,
|
||||||
|
"firework.blast": 1.8259967490749676,
|
||||||
|
"firework.twinkle": 1.0244717803103813,
|
||||||
|
"mob.cat.meow-2": 0.5046612975635284,
|
||||||
|
"mob.cat.meow-4": 0.5081594425605606,
|
||||||
|
"mob.zombie.wood": 0.32247793193163765,
|
||||||
|
}
|
||||||
|
"""乐器响度平衡表,倍率"""
|
||||||
|
|
||||||
MC_EILLES_RT261_INSTRUMENT_REPLACE_TABLE: Dict[str, str] = {
|
MC_EILLES_RT261_INSTRUMENT_REPLACE_TABLE: Dict[str, str] = {
|
||||||
"note.trumpet": "note.flute",
|
"note.trumpet": "note.flute",
|
||||||
@@ -519,7 +564,7 @@ MM_INSTRUMENT_RANGE_TABLE: Dict[str, Tuple[Tuple[int, int], int]] = {
|
|||||||
"note.banjo": ((42, 66), 54),
|
"note.banjo": ((42, 66), 54),
|
||||||
"note.flute": ((54, 78), 66),
|
"note.flute": ((54, 78), 66),
|
||||||
"note.bass": ((18, 42), 30),
|
"note.bass": ((18, 42), 30),
|
||||||
"note.snare": ((-1, 128), 0), # 实际上是 0~127
|
"note.snare": ((-1, 128), 0), # 实际上是 0~127,此处仅作兼容性处理
|
||||||
"note.didgeridoo": ((18, 42), 30),
|
"note.didgeridoo": ((18, 42), 30),
|
||||||
"mob.zombie.wood": ((-1, 128), 0),
|
"mob.zombie.wood": ((-1, 128), 0),
|
||||||
"note.bit": ((42, 66), 54),
|
"note.bit": ((42, 66), 54),
|
||||||
@@ -538,6 +583,7 @@ MM_INSTRUMENT_RANGE_TABLE: Dict[str, Tuple[Tuple[int, int], int]] = {
|
|||||||
"""
|
"""
|
||||||
不同乐器的音域偏离对照表
|
不同乐器的音域偏离对照表
|
||||||
元组里的是范围,后面的整数是游戏里的默认采样音高
|
元组里的是范围,后面的整数是游戏里的默认采样音高
|
||||||
|
单位是在 Midi 中的音高
|
||||||
"""
|
"""
|
||||||
|
|
||||||
MM_INSTRUMENT_DEVIATION_TABLE: Dict[str, int] = {
|
MM_INSTRUMENT_DEVIATION_TABLE: Dict[str, int] = {
|
||||||
@@ -580,164 +626,7 @@ MM_INSTRUMENT_DEVIATION_TABLE: Dict[str, int] = {
|
|||||||
# 金羿ELS 音符方块对照表
|
# 金羿ELS 音符方块对照表
|
||||||
|
|
||||||
MN_EILLES_NOTE_BLOCK_TABLE: Dict[int, str] = {
|
MN_EILLES_NOTE_BLOCK_TABLE: Dict[int, str] = {
|
||||||
0: "C",
|
|
||||||
1: "C#",
|
|
||||||
2: "D",
|
|
||||||
3: "D#",
|
|
||||||
4: "E",
|
|
||||||
5: "F",
|
|
||||||
6: "F#",
|
|
||||||
7: "G",
|
|
||||||
8: "G#",
|
|
||||||
9: "A",
|
|
||||||
10: "A#",
|
|
||||||
11: "B",
|
|
||||||
12: "C",
|
|
||||||
13: "C#",
|
|
||||||
14: "D",
|
|
||||||
15: "D#",
|
|
||||||
16: "E",
|
|
||||||
17: "F",
|
|
||||||
18: "F#",
|
|
||||||
19: "G",
|
|
||||||
20: "G#",
|
|
||||||
21: "A",
|
|
||||||
22: "A#",
|
|
||||||
23: "B",
|
|
||||||
24: "C",
|
|
||||||
25: "C#",
|
|
||||||
26: "D",
|
|
||||||
27: "D#",
|
|
||||||
28: "E",
|
|
||||||
29: "F",
|
|
||||||
30: "F#",
|
|
||||||
31: "G",
|
|
||||||
32: "G#",
|
|
||||||
33: "A",
|
|
||||||
34: "A#",
|
|
||||||
35: "B",
|
|
||||||
36: "C",
|
|
||||||
37: "C#",
|
|
||||||
38: "D",
|
|
||||||
39: "D#",
|
|
||||||
40: "E",
|
|
||||||
41: "F",
|
|
||||||
42: "F#",
|
|
||||||
43: "G",
|
|
||||||
44: "G#",
|
|
||||||
45: "A",
|
|
||||||
46: "A#",
|
|
||||||
47: "B",
|
|
||||||
48: "C",
|
|
||||||
49: "C#",
|
|
||||||
50: "D",
|
|
||||||
51: "D#",
|
|
||||||
52: "E",
|
|
||||||
53: "F",
|
|
||||||
54: "F#",
|
|
||||||
55: "G",
|
|
||||||
56: "G#",
|
|
||||||
57: "A",
|
|
||||||
58: "A#",
|
|
||||||
59: "B",
|
|
||||||
60: "C",
|
|
||||||
61: "C#",
|
|
||||||
62: "D",
|
|
||||||
63: "D#",
|
|
||||||
64: "E",
|
|
||||||
65: "F",
|
|
||||||
66: "F#",
|
|
||||||
67: "G",
|
|
||||||
68: "G#",
|
|
||||||
69: "A",
|
|
||||||
70: "A#",
|
|
||||||
71: "B",
|
|
||||||
72: "C",
|
|
||||||
73: "C#",
|
|
||||||
74: "D",
|
|
||||||
75: "D#",
|
|
||||||
76: "E",
|
|
||||||
77: "F",
|
|
||||||
78: "F#",
|
|
||||||
79: "G",
|
|
||||||
80: "G#",
|
|
||||||
81: "A",
|
|
||||||
82: "A#",
|
|
||||||
83: "B",
|
|
||||||
84: "C",
|
|
||||||
85: "C#",
|
|
||||||
86: "D",
|
|
||||||
87: "D#",
|
|
||||||
88: "E",
|
|
||||||
89: "F",
|
|
||||||
90: "F#",
|
|
||||||
91: "G",
|
|
||||||
92: "G#",
|
|
||||||
93: "A",
|
|
||||||
94: "A#",
|
|
||||||
95: "B",
|
|
||||||
96: "C",
|
|
||||||
97: "C#",
|
|
||||||
98: "D",
|
|
||||||
99: "D#",
|
|
||||||
100: "E",
|
|
||||||
101: "F",
|
|
||||||
102: "F#",
|
|
||||||
103: "G",
|
|
||||||
104: "G#",
|
|
||||||
105: "A",
|
|
||||||
106: "A#",
|
|
||||||
107: "B",
|
|
||||||
108: "C",
|
|
||||||
109: "C#",
|
|
||||||
110: "D",
|
|
||||||
111: "D#",
|
|
||||||
112: "E",
|
|
||||||
113: "F",
|
|
||||||
114: "F#",
|
|
||||||
115: "G",
|
|
||||||
116: "G#",
|
|
||||||
117: "A",
|
|
||||||
118: "A#",
|
|
||||||
119: "B",
|
|
||||||
120: "C",
|
|
||||||
121: "C#",
|
|
||||||
122: "D",
|
|
||||||
123: "D#",
|
|
||||||
124: "E",
|
|
||||||
125: "F",
|
|
||||||
126: "F#",
|
|
||||||
127: "G",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
# 即将启用
|
|
||||||
# height2note = {
|
|
||||||
# 0.5: 0,
|
|
||||||
# 0.53: 1,
|
|
||||||
# 0.56: 2,
|
|
||||||
# 0.6: 3,
|
|
||||||
# 0.63: 4,
|
|
||||||
# 0.67: 5,
|
|
||||||
# 0.7: 6,
|
|
||||||
# 0.75: 7,
|
|
||||||
# 0.8: 8,
|
|
||||||
# 0.84: 9,
|
|
||||||
# 0.9: 10,
|
|
||||||
# 0.94: 11,
|
|
||||||
# 1.0: 12,
|
|
||||||
# 1.05: 13,
|
|
||||||
# 1.12: 14,
|
|
||||||
# 1.2: 15,
|
|
||||||
# 1.25: 16,
|
|
||||||
# 1.33: 17,
|
|
||||||
# 1.4: 18,
|
|
||||||
# 1.5: 19,
|
|
||||||
# 1.6: 20,
|
|
||||||
# 1.7: 21,
|
|
||||||
# 1.8: 22,
|
|
||||||
# 1.9: 23,
|
|
||||||
# 2.0: 24,
|
|
||||||
# }
|
|
||||||
# """音高对照表\n
|
|
||||||
# MC音高:音符盒音调"""
|
|
||||||
|
|||||||
@@ -59,6 +59,13 @@
|
|||||||
"sounddevice",
|
"sounddevice",
|
||||||
"librosa",
|
"librosa",
|
||||||
]
|
]
|
||||||
|
preview-advanced = [
|
||||||
|
"numpy < 3.0",
|
||||||
|
"soundfile",
|
||||||
|
"sounddevice",
|
||||||
|
"librosa",
|
||||||
|
"pyloudnorm",
|
||||||
|
]
|
||||||
full = [
|
full = [
|
||||||
"mido >= 1.3, < 2.0",
|
"mido >= 1.3, < 2.0",
|
||||||
"numpy < 3.0",
|
"numpy < 3.0",
|
||||||
@@ -67,6 +74,7 @@
|
|||||||
"soundfile",
|
"soundfile",
|
||||||
"sounddevice",
|
"sounddevice",
|
||||||
"librosa",
|
"librosa",
|
||||||
|
"pyloudnorm",
|
||||||
]
|
]
|
||||||
dev = [
|
dev = [
|
||||||
"mido >= 1.3, < 2.0",
|
"mido >= 1.3, < 2.0",
|
||||||
@@ -76,6 +84,8 @@
|
|||||||
"soundfile",
|
"soundfile",
|
||||||
"sounddevice",
|
"sounddevice",
|
||||||
"librosa",
|
"librosa",
|
||||||
|
"pyloudnorm",
|
||||||
|
"matplotlib",
|
||||||
"dill",
|
"dill",
|
||||||
"rich",
|
"rich",
|
||||||
"pyinstaller",
|
"pyinstaller",
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
import os
|
||||||
|
import numpy as np
|
||||||
|
import soundfile as sf
|
||||||
|
import pyloudnorm as pyln
|
||||||
|
|
||||||
|
def analyze_game_sfx(wav_dir: str) -> dict:
|
||||||
|
"""
|
||||||
|
批量分析游戏音效的听感响度(LUFS)。
|
||||||
|
对于短音效,优先使用 Momentary Loudness;若文件过短则回退到 K-weighted RMS。
|
||||||
|
"""
|
||||||
|
results = {}
|
||||||
|
|
||||||
|
if not os.path.exists(wav_dir):
|
||||||
|
print(f"错误: 目录不存在 -> {wav_dir}")
|
||||||
|
return results
|
||||||
|
|
||||||
|
wav_files = [f for f in os.listdir(wav_dir) if f.lower().endswith('.wav')]
|
||||||
|
print(f"找到 {len(wav_files)} 个 WAV 文件,开始分析...\n")
|
||||||
|
|
||||||
|
for filename in sorted(wav_files):
|
||||||
|
filepath = os.path.join(wav_dir, filename)
|
||||||
|
try:
|
||||||
|
data, sr = sf.read(filepath)
|
||||||
|
|
||||||
|
# 确保为二维数组 (samples, channels)
|
||||||
|
if data.ndim == 1:
|
||||||
|
data = data.reshape(-1, 1)
|
||||||
|
|
||||||
|
duration = len(data) / sr
|
||||||
|
|
||||||
|
# --- 核心响度计算 ---
|
||||||
|
# ITU-R BS.1770 要求至少 ~400ms 才能准确计算 Integrated Loudness
|
||||||
|
# 游戏音效通常很短,我们采用以下策略:
|
||||||
|
meter = pyln.Meter(sr, block_size=duration) # 400ms block
|
||||||
|
|
||||||
|
# if duration >= 0.4:
|
||||||
|
# 使用 Momentary Loudness (无门限,适合短音效)
|
||||||
|
loudness = meter.integrated_loudness(data)
|
||||||
|
# else:
|
||||||
|
# # 极短音效:手动 K-weighting 后计算 RMS → 转为 LUFS
|
||||||
|
# # pyloudnorm 内部有 K-weight filter,这里用简化方式
|
||||||
|
# filtered = meter._filter_k_weighting(data.T).T
|
||||||
|
# rms = np.sqrt(np.mean(filtered ** 2))
|
||||||
|
# # LUFS ≈ -0.691 + 10*log10(rms^2),参考 BS.1770 公式
|
||||||
|
# loudness = -0.691 + 10 * np.log10(max(rms ** 2, 1e-12))
|
||||||
|
# method = "K-weighted RMS"
|
||||||
|
|
||||||
|
# 静音检测
|
||||||
|
if np.max(np.abs(data)) < 1e-6:
|
||||||
|
loudness = -np.inf
|
||||||
|
|
||||||
|
results[filename] = {
|
||||||
|
"loudness_lufs": round(loudness, 2),
|
||||||
|
"duration_sec": round(duration, 4),
|
||||||
|
"sample_rate": sr,
|
||||||
|
"channels": data.shape[1],
|
||||||
|
}
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
results[filename] = {"error": str(e)}
|
||||||
|
print(f" ⚠ 跳过 {filename}: {e}")
|
||||||
|
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
TARGET_DIR = "vanilla_assets/wav/"
|
||||||
|
report = analyze_game_sfx(TARGET_DIR)
|
||||||
|
|
||||||
|
# 打印结果字典
|
||||||
|
print("\n===== 分析结果 =====")
|
||||||
|
print("文件名 | 响度(LUFS) | 时长(s) | 采样率")
|
||||||
|
for name, info in report.items():
|
||||||
|
if "error" in info:
|
||||||
|
print(f"{name}: 错误 - {info['error']}")
|
||||||
|
else:
|
||||||
|
print(f"{name}: {info['loudness_lufs']:>7.2f} LUFS | "
|
||||||
|
f"{info['duration_sec']:.3f}s | {info['sample_rate']}Hz")
|
||||||
|
|
||||||
|
# 也输出原始字典方便程序化使用
|
||||||
|
print("\n===== Raw Dict =====")
|
||||||
|
print(report)
|
||||||
Reference in New Issue
Block a user