You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

音频合成归一化后调用Spectrogram报错:TypeError: 'int'对象不可调用

问题分析与解决

问题概述

尝试合成三个numpy格式音频数据并执行max-min归一化后,在spec = spectrogram(sig)行触发TypeError: 'int' object is not callable,报错栈指向waveform.size()调用失败。

错误原因

  1. 输入类型不匹配:torchaudio.transforms.Spectrogram要求输入为torch.Tensor,但代码中传入的sig是numpy数组。numpy数组的size是整数属性,而非可调用方法,内部代码调用.size()时触发类型错误。
  2. 维度不符合要求:合成后的sig是一维数组,而torchaudio的频谱变换期望输入至少是二维(通道×时间)的张量结构。

修复方案

关键修改点

  • 将归一化后的numpy数组转换为torch张量。
  • 为张量添加通道维度,满足输入格式要求。
  • 简化音频合成的补零逻辑,使用numpy原生pad函数替代手动循环。

修复后的完整代码

import torch
import torchaudio
import torchaudio.transforms as T
import os
import numpy as np
import librosa
import matplotlib.pyplot as plt

# 音声の保存
_SAMPLE_DIR = "_sample_data"
SAMPLE_WAV_URL = "https://pytorch-tutorial-assets.s3.amazonaws.com/VOiCES_devkit/source-16k/train/sp0307/Lab41-SRI-VOiCES-src-sp0307-ch127535-sg0042.wav"
SAMPLE_WAV_PATH = os.path.join(_SAMPLE_DIR, "speech.wav")

def plot_spectrogram(spec, title=None, ylabel="freq_bin", aspect="auto", xmax=None):
    fig, axs = plt.subplots(1, 1)
    axs.set_title(title or "Spectrogram (db)")
    axs.set_ylabel(ylabel)
    axs.set_xlabel("frame")
    im = axs.imshow(librosa.power_to_db(spec), origin="lower", aspect=aspect)
    if xmax:
        axs.set_xlim((0, xmax))
    fig.colorbar(im, ax=axs)
    plt.show(block=False)

def synthesis(sigList):
    maxLength = max(len(data) for data in sigList)
    tmpArray = []
    # 使用numpy.pad简化补零逻辑
    for i in sigList:
        padded = np.pad(i, (0, maxLength - len(i)), mode='constant')
        tmpArray.append(padded)
    # 合成三个音频
    sig = tmpArray[0] + tmpArray[1] + tmpArray[2]
    return sig

def min_max(x, axis=None):
    min_val = x.min(axis=axis, keepdims=True)
    max_val = x.max(axis=axis, keepdims=True)
    try:
        z = (x - min_val) / (max_val - min_val)
    except ZeroDivisionError:
        z = (x - min_val) / min_val
    return z

# 加载音频
waveform, sample_rate = torchaudio.load(filepath=SAMPLE_WAV_URL)

n_fft = 1024
win_length = None
hop_length = 512
window_fn = torch.hann_window

# 生成三个音频数据
waveforms = waveform.numpy()
k = waveforms
for i in range(2):
    waveforms = np.concatenate([waveforms, k], 0)

# 初始化频谱变换
spectrogram_transform = T.Spectrogram(
    n_fft=n_fft,
    win_length=win_length,
    hop_length=hop_length,
    window_fn=window_fn,
    power=2.0,
)

# 合成、归一化、转换为张量并添加通道维度
sig = min_max(synthesis(waveforms))
sig_tensor = torch.tensor(sig).unsqueeze(0)  # 添加通道维度,变为(1, time)

# 生成频谱
spec = spectrogram_transform(sig_tensor)
plot_spectrogram(spec[0], title='torchaudio')

修改说明

  1. 变量名优化:将原spectrogram变量改为spectrogram_transform,提升代码可读性。
  2. 类型转换:使用torch.tensor(sig)将numpy数组转换为torch张量,匹配频谱变换的输入要求。
  3. 维度调整:用.unsqueeze(0)为张量添加通道维度,使输入形状符合(channel, time)的规范。
  4. 补零逻辑简化:使用np.pad替代手动循环补零,代码更简洁高效。

内容的提问来源于stack exchange,提问作者assa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 20:20:31