librosa.get_duration() 是一个无参函数(不接受音频数据作为位置参数),必须显式通过关键字参数 y 和 sr 传入音频数组与采样率,否则会报错“takes 0 positional arguments but 1 was given”。
librosa.get_duration() 是一个无参函数(不接受音频数据作为位置参数),必须显式通过关键字参数 `y` 和 `sr` 传入音频数组与采样率,否则会报错“takes 0 positional arguments but 1 was given”。
在使用 librosa.get_duration() 时,一个常见误区是将其误当作接收音频数组的位置参数函数调用(如 lb.get_duration(swap_ad[1]))。实际上,该函数自 librosa 0.8.0 起已改为纯关键字参数接口,不再支持位置参数传入音频数据 —— 它的签名是 get_duration(*, y=None, sr=22050, duration=None, hop_length=512, n_fft=2048),其中 * 表示所有参数必须以关键字形式传入。
因此,原代码中:
duration = lb.get_duration(swap_ad[1])
会直接触发 TypeError,因为 swap_ad[1] 被当作第一个位置参数传递,而函数根本不接受任何位置参数。
✅ 正确做法是显式指定 y(单声道音频时间序列)和 sr(采样率):
duration = lb.get_duration(y=swap_ad[1][:, 0], sr=sr)
这里额外注意两点:
- swap_ad[1] 是形状为 (n_samples, n_channels) 的二维数组(例如立体声为 (T, 2)),而 librosa.get_duration() 要求 y 是一维数组(单声道)。因此需选取某一声道,如 [:, 0] 获取左声道。
- sr 必须与实际加载的采样率一致(本例中 sp.read_stems(..., sample_rate=22050) 明确设为 22050),不可省略或错用默认值。
? 完整修正后的函数如下:
import numpy as np
import librosa as lb
import soundfile as sp
def decoding_stems(file_name):
audio, sr = sp.read_stems(file_name, sample_rate=22050)
swap_ad = np.swapaxes(audio, 1, 2) # shape: (n_samples, n_channels)
# ✅ 关键修复:显式传入 y(单声道)和 sr
duration = lb.get_duration(y=swap_ad[1][:, 0], sr=sr)
# ✅ 向下取整到最接近 0.6 秒的整数倍(单位:秒),再换算为帧数(每段 6 帧)
duration_length = int((duration // 0.6) * 6)
return stft_frame(file_name, duration_length, 6)
⚠️ 注意事项:
- 若音频为单声道,swap_ad[1] 可能已是 1D,但仍建议统一用 [:, 0] 保证健壮性;
- stft_frame() 函数需确保能处理 duration_length 为整数且非零(建议添加 if duration_length
- soundfile 的 read_stems 并非标准 API(可能是自定义或来自 stempeg),请确认其返回结构与假设一致(即 audio.shape == (n_sources, n_channels, n_samples))。
此修复同时适用于训练与测试流程,可彻底消除 TypeError,确保音频时长计算逻辑稳定可靠。










