当前位置: 首页 > news >正文

为什么我画的频谱图和audacity、audition不一样?

文章目录

  • 系列文章目录

    目录

    文章目录

    前言

    一、问题引入

    二、使用步骤

    三、分析和改进

    总结


前言

我们知道audacity和audition都有频谱分析这个窗口,一般过程肯定是分帧加窗,fft变换然后呈现,

大体这个过程是没问题的,但为什么我画出来的频谱图和它们的不一样?本篇文章就来分析这个


一、问题引入

一个典型的wav(一个底噪)的波形频谱,在audition里面展示如下:

fft频谱分析如下:

注意三个要素,window窗长,选取整个wav数据范围,采用hanning窗

二、使用步骤

根据上面的分析,我们自己写了一个频谱分析的spectrum【AI写的,我哪有那么厉害】

clear all
close all
clc[x,fs] = audioread('4-OK.wav');% 1. 分帧处理(假设信号长度是帧长的整数倍)
N = length(x);
signal = x;
winLen =2048;
numFrames = floor(N/winLen);
frames = reshape(signal(1:numFrames*winLen), winLen, numFrames);% 2. 加Hanning窗
window = hann(winLen);logMagAll = zeros(winLen/2+1, 1);
for i = 1:numFramesframe = frames(:,i) .* window;mag = abs(fft(frame, winLen));logMagAll = logMagAll + 10*log10(mag(1:winLen/2+1).^2 + 1e-16);
endlogMag = logMagAll/numFrames ;% 5. 绘图
freq = (0:winLen/2)/winLen * fs; % 频率轴
figure;
semilogx(freq(2:end), logMag(2:end)); % 对数频率轴,跳过DC
xlabel('Frequency (Hz)');
ylabel('Magnitude (dB)');
title('Power Spectrum (Hanning window)');
grid on;

核心过程就是 分帧,加窗,先求 log对数,然后算完之后求平均

 

频谱形状是对的,但发现底噪和整体幅度有差别

底噪是-60,audition显示底噪是-100多呢,这个地方肯定有问题,但俩形状相似,很可能是增益导致,差了倍数。

倍数差在边度呢?

三、分析和改进

audition的源代码肯定是没有,人商业软件,被adobe买了,别想了。我们可以参考audacity 的, 先看看audacity分析的频谱如何

低频底噪太低,没显示全,但是没关系,鼠标可以放到低频,给出信息,大概-100多dB,那和audition的一样,audacity的源代码可是有的哦,马上参考它的代码;

 经过一系列的分析,我们知道这个函数是画频谱的地方【具体怎么分析得到的的可以参考韦神解五次方程的过程,就是题感!

关键是这个地方

方框部分,有个时域加权,对窗口系数的加权!

能量谱没有什么特殊的,就是普通的fft计算 

回到   SpectrumAnalyst::Calculate 函数,这个地方 by每帧会 直接求和

也就是 应该先 求能量谱的总和,不着急求 log,

​​​​​​

等出每一帧的while循环之后呢

能量谱求 20倍log,幅度谱求10倍log

再乘以scale,scale里面有对每一帧的平均,194行

到这里就明白了,注意要点有两个

1、注意要乘窗口归一化权重 wss

2、注意先求 幅度谱加和,再平均,然后上对数,而不是先对数,再加和平均,经常玩log的都知道,说白了其实一个是算术平均,一个是几何平均

行了,道理都清楚了,代码的事情让deepseek 出!嗷嗷的来吧你就

clear all
close all
clc[x,fs] = audioread('4-OK.wav');% 1. 分帧处理(假设信号长度是帧长的整数倍)
N = length(x);
signal = x;
winLen =2048;
numFrames = floor(N/winLen);
frames = reshape(signal(1:numFrames*winLen), winLen, numFrames);% 2. 加Hanning窗
window = hann(winLen);
wss = sum(window); % 窗谱和
if wss > 0wss = 4.0 / (wss^2); % 窗谱平方和归一化因子
elsewss = 1.0;
end% 3. 计算每帧幅度谱平方和
MagAll = zeros(winLen/2+1, 1);
for i = 1:numFramesframe = frames(:,i) .* window;mag = abs(fft(frame, winLen));MagAll = MagAll + mag(1:winLen/2+1).^2;
end% 4. 计算对数幅度谱
scale = wss / numFrames;
logMag = 10 * log10(MagAll * scale);% 5. 绘图
freq = (0:winLen/2)/winLen * fs; % 频率轴
figure;
semilogx(freq(2:end), logMag(2:end)); % 对数频率轴,跳过DC
xlabel('Frequency (Hz)');
ylabel('Magnitude (dB)');
title('Power Spectrum (Hanning window)');
grid on;

再看频谱图

行了,应该对上了,齐刷的!


总结

1、要会发现问题,别总以为自己的代码最牛逼,实际根本不符合规律,-30dB底噪那么大,可能么?

2、要利用互联网资源,能开源的为毛不用,deepseek自己写也不一定你给正确代码,还得靠自己分析

3、要会用deepseek,巧用ai,不受制于ai,才不会被ai卷死

http://www.dtcms.com/a/265123.html

相关文章:

  • containerd 项目主要目录简要说明
  • Flink-1.19.0源码详解-番外补充3-StreamGraph图
  • 精准定义 RediSearch 索引 Schema
  • LeetCode Hot 100 哈希【Java和Golang解法】
  • 无人机状态识别研究梳理2025.7.2
  • 欧拉角、四元数和旋转矩阵的变换关系以及无人机的坐标变换
  • 在服务器中下载 HuggingFace 模型:终极指南
  • Java的SpringAI+Deepseek大模型实战-会话记忆【三】
  • 深度学习入门day4--手写数字识别初探
  • Cloudflare大动作
  • 大语言模型:是逐字生成还是一次多词?
  • Ubuntu22.04搭建基于GPU的Yolov8环境
  • 昇腾NPU节点软件版本检查与升级方法
  • iOS 集成RN Installing glog (0.3.5)报错的解决方案
  • 深度解析Linux内核IPv4设备管理:net/ipv4/devinet.c
  • 单片机学习笔记.10.串口UART
  • Excel 如何让某些符合特定条件的数据自动变色,以作警示?
  • SSL/TLS协议信息泄露漏洞(CVE-2016-2183)、SSL/TLS RC4 信息泄露漏洞(CVE-2013-2566)修复方法
  • Tomcat10.0以上版本编译成功但报错HTTP状态 404
  • MVI+Compose架构实战
  • 解释LLM怎么预测下一个词语的
  • Go语言动态数据访问实战
  • windows安装maven环境
  • vscode vim配置
  • ElementUI el-select多选下拉框,回显数据后无法重新选择和修改
  • vue中的torefs
  • 自定义注解的使用
  • 玄机——某学校系统中挖矿病毒应急排查
  • Redis 常用五大数据类型
  • 【大模型学习 | MINIGPT-4原理】