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

将音频信号转换为时序频率与音量列表的最简实现方法

问题描述

我有一组音频信号数据,格式如下:

input = [0, 0.1, 0.5, 2, 3, 4, 2, 0, ...]

需要将其转换成随时间变化的频率列表与对应音量列表的结构,示例输出如下:

output = [..., [[50, 100, 325, 950, 4000, ...], [0.1, 0.9, 4, 2, 0.3, ...]], ...]

之前试过signal.spectrogram()方法,但它返回的是按时间周期计算的频率平均值,不符合需求——我要的是每个时间点上频率和音量的明确映射关系。

解决方案

要实现逐时间点的频率-音量映射,你可以用希尔伯特变换计算瞬时频率,这能直接得到每个采样点对应的瞬时频率,搭配原信号的幅值作为音量,完全满足你的需求。

具体步骤与代码实现

  1. 用希尔伯特变换生成解析信号,提取瞬时相位
  2. 对相位做解缠绕处理,避免相位跳变导致的频率计算错误
  3. 对解缠绕后的相位求导,得到瞬时频率(需按采样率换算成实际赫兹值)
  4. 原信号的幅值(或做dB转换、平方处理)作为对应时间点的音量
import numpy as np
from scipy.signal import hilbert

# 假设音频参数:采样率sr,输入信号x
sr = 44100  # 示例采样率,根据你的实际数据调整
x = np.array([0, 0.1, 0.5, 2, 3, 4, 2, 0, ...])

# 计算解析信号
analytic_signal = hilbert(x)
# 提取瞬时幅值(即音量)
instantaneous_amplitude = np.abs(analytic_signal)
# 提取瞬时相位并解缠绕
instantaneous_phase = np.unwrap(np.angle(analytic_signal))
# 计算瞬时频率(弧度/秒转赫兹)
instantaneous_frequency = (np.diff(instantaneous_phase) / (2.0 * np.pi)) * sr

# 处理diff后频率数组长度短1的问题,这里补全第一个值做对齐
aligned_frequency = np.concatenate([[instantaneous_frequency[0]], instantaneous_frequency])
# 生成目标输出结构
output = [[aligned_frequency.tolist(), instantaneous_amplitude.tolist()]]

补充说明

  • 如果你的信号是多成分的(同时包含多个频率),希尔伯特变换只能提取主导频率,这种情况可以用**变分模态分解(VMD)或者经验模态分解(EMD)**先把信号分解成单成分IMF,再对每个IMF计算瞬时频率和幅值,最后合并成多频率-音量的映射。
  • 瞬时频率对噪声比较敏感,如果信号有噪声,建议先做低通滤波处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:40:22