摘要:录制一段音频,分别在matlab,python两种环境下,对其作短时傅里叶变换(STFT),最终得到期望的语谱图。
1. 基础概念:
在对音频信号进行分析处理前,先简要回顾一下所用到的分析函数傅里叶变换的相关知识。
什么是傅里叶变换?
傅里叶的基本定义与性质在这里就不作赘述了,文章主要想说明它的主要应用,以助于大家对这个概念有一个更为形象的认识。(傅里叶基础概念与性质,推荐观看b站李永乐的讲解,文末附视频链接)
傅里叶变换是一种分析信号的方法,它可分析信号的成分,也可用这些成分合成信号。在分析信号时,主要应用于处理平稳信号,通过傅里叶变换可以获取一段信号总体上包含哪些频率的成分,但是对各成分出现的时刻无法得知。
因此对于非平稳信号,傅里叶变换就显示出了它的局限性,而我们日常生活中的绝大多数音频都是非平稳信号的。而解决这一问题的方法,就是采用短时傅里叶变换或者小波变换,对信号进行处理。
什么是短时傅里叶变换?
短时傅里叶变换(STFT)的核心思想:“加窗”,即把整个时域过程分解成无数个等长的小过程,每个小过程近似平稳,再对每个小过程进行傅里叶变换(FFT)。尽管STFT可以处理非平稳信号,但是它仍然有其局限性,即对窗函数的宽窄无法做到精确定义。
窗函数选择太窄,窗内的信号太短,会导致频率的分析不够精准,频率分辨率差;窗选的太宽,时域上又不够精细,时间分辨率低
什么是小波变换?
小波变换的核心思想:“把傅里叶变换的无限长三角函数的基换成有限长的会衰减的小波基”,这样不仅可以获取频率,还可以定位时间。更为详细的介绍可以参考本段末附上的参考来源,查询大佬相关阐述。
本文参考来源:
https://rf.eefocus.com/article/id-xiaobobianhuan?p=1 傅里叶–短时傅里叶–小波分析
https://blog.csdn.net/daaikuaichuan/article/details/80781505 小波与短时傅里叶的区别
https://wenku.baidu.com/view/4b9bb22c30b765ce0508763231126edb6f1a768e.html?fr=search-1_income7 短时傅里叶的概念理解
什么是语谱图?
语谱图:时间依赖于傅里叶分析的显示图形,实际上是一种动态频谱,综合了频谱图和时域波形图的优点,明显地显示出语音频谱随时间的变化情况。(其中,纵轴为频率,横着为时间,任一给定频率成分在给定时刻的强弱,用点的黑白度来表示)
2. 概念的形象化理解:
文章参考来源:
https://www.jianshu.com/p/7e160442830f 直观理解短时傅里叶变换 STFT(简书)
https://www.bilibili.com/video/BV1A4411Y7vj/?spm_id_from=333.788.videocard.1 傅里叶变换-李永乐(b站视频,讲的很好)
3. 思路流程:
编程思路:
短时傅里叶变换(STFT)就是先把一个函数和窗函数进行相乘,然后再进行一维的傅里叶变换。并通过窗函数的滑动得到一系列的傅里叶变换结果,将这些结果排开便得到一个二维的表象。具体而言,可分为如下几步(以matlab源码为例):
(1)读取音频文件。(调用audioread,处理得到一个保存音频数据的数组,和一个采样频率)
(2)确定相关参数。(如窗函数、窗长、重叠点数,重叠长度,傅里叶点数等)
(3)调用spectrogram函数,做短时傅里叶变换。(S-将输入信号做STFT处理后得到的二维含时间、频率序列的数组数据;更为详细的处理过程见spectrogram函数定义)
(4)根据处理后的时频矩阵,绘制语谱图.
文章参考来源:
https://blog.csdn.net/zhaoyinhui0802/article/details/53048362 短时傅里叶变换原理解
文章参考来源:
https://cn.office-converter.com/ 文件在线转换网址
4. 必要准备:
音频文件+python应用环境+matlab应用环境
python应用环境:
文章参考来源:
https://blog.csdn.net/Small_Yogurt/article/details/104964760 vscode安装教程
https://blog.csdn.net/qq_40197828/article/details/93468787 vscode中配置python环境(可以选择配置anaconda中的python,这样会减少后续代码实现阶段,函数库的安装,如numpy,librosa等)
https://blog.csdn.net/u010824101/article/details/85239223 Windows10中用Anaconda的conda环境和VSCode工具来编写python代码
https://blog.csdn.net/zzc15806/article/details/79603994 音频处理库—librosa的安装与使用
matlab应用环境:
如何安装以及破解matlab,请参考下方资料来源(大佬写的非常详细),这里不作赘述了。
安装前须知(提醒):
1.安装全程须断开网络,否则破解不成功;
2.解压和安装前先关闭360、腾讯管家等杀毒软件,防止误杀破解补丁,导致破解失败;
3.Matlab 2018b适用于WIN7/8/10(64位)系统,亲测可用!
4.推荐电脑最低配置:内存8G+,处理器酷睿I5+;
文章参考来源:
https://blog.csdn.net/qq_26900233/article/details/88816789 MATLAB R2018b 安装教程(含软件资源)
import librosa
import librosa.display
import matplotlib.pyplot as plt
# 读取音频文件
filepath = 'C:\\Users\\非黑不即白\\Desktop\\Audio_processing_STFT\\python_project\\data\\'
filename = filepath + 'test_digital.wav'
x, sr = librosa.load(filename, sr=None) # x--音频时间序列(一维数组) ; sr--音频的采样率
# STFT处理绘制声谱图
X = librosa.stft(x)
Xdb = librosa.amplitude_to_db(abs(X)) # X--二维数组数据
plt.figure(figsize=(14, 5))
librosa.display.specshow(Xdb, sr=sr, x_axis='time', y_axis='log')
plt.colorbar()
plt.title('STFT transform processing audio signal')
plt.show()
[X, Fs]=audioread('C:\Users\非黑不即白\Desktop\Audio_processing_STFT\matlab_project\test_digital.wav'); % Fs 采样率 48000
% audioread函数读取音频文件(X--保存音频信号的数据;Fs--音频采样率)
figure; % 绘图
win_sz = 128; % 窗函数长度设置为128
han_win = hanning(win_sz); % 选择海明窗
nfft = 2^nextpow2(length(han_win)); % DFT点数(通常取最接近信号长度的2的整数次幂,即 nfft = 2^nextpow2(length(window)) )=128=win_size
nooverlap = win_sz - 1; % 重叠长度(而随着noverlap参数的引入,增大了时间轴分辨率,即每隔(Nw - noverlap)长度进行一次频率轴的更新,随着noverlap逐渐接近Nw,图像上表现为时间轴更加“细腻”,但随之而来的肯定是计算次数的增加。)
[S, F, T, P] = spectrogram(X(:,1), window, nooverlap, nfft, Fs);
% spectrogram注释:x:输入的信号 向量;window:窗口长度 该函数默认使用海明窗;noverlap:各段之间重叠的采样点数 即两窗口相重叠的部分;nfft:对窗口下的信号做FFT的点数;fs:信号的采样率
% s:输入信号x的短时傅里叶变换。(它的每一列包含一个短期局部时间的频率成分估计,时间沿列增加,频率沿行增加。)
% F:为四舍五入的频率,其长度等于S的行数。
% T:频谱图计算的时刻点,值为窗的时刻中值。
% P:功率谱密度PSD(Power Spectral Density)
imagesc(T, F, log10(abs(S))) % 绘图函数(将矩阵S中的元素数值按大小转化为不同颜色,并在坐标轴对应位置处以这种颜色染色;T、F为其横纵坐标)
colorbar;
set(gca, 'YDir', 'normal') % 坐标轴设置(ydir表示Y轴;normal-坐标轴正序;reverse--倒序)
xlabel('Time (secs)')
ylabel('Freq (Hz)')
title('STFT transform spectrum')
[X, Fs]=audioread('C:\Users\非黑不即白\Desktop\Audio_processing_STFT\matlab_project\test_digital.wav'); % Fs 采样率 48000
% audioread函数读取音频文件(X--保存音频信号的数据;Fs--音频采样率)
wavename='cmor3-3'; % 选定小波基
totalscal=256;
Fc=centfrq(wavename); % 小波的中心频率 测得Fc = 3
c=2*Fc*totalscal; % 测得c = 1536
scals=c./(1:totalscal); % 求得尺度
f=scal2frq(scals,wavename,1/Fs); % 将尺度转换为频率 % 频率在0-500Hz取1024个点
coefs = cwt(X(:,1),scals,wavename); % 求连续小波系数
t=0:1/Fs:size(X(:,1))/Fs;
figure
imagesc(t,f,abs(coefs));
set(gca,'YDir','normal')
colorbar;
xlabel('时间 t/s');
ylabel('频率 f/Hz');
title('小波时频图')
文章参考来源:
https://blog.csdn.net/lanchunhui/article/details/72240693 matlab 时频分析(短时傅里叶变换、STFT)
https://blog.csdn.net/weixin_42765703/article/details/104871604 解析MATLAB短时傅里叶变换函数spectrogram()
https://blog.csdn.net/zb1165048017/article/details/80682473 【音频处理】短时傅里叶变换
https://blog.csdn.net/weixin_44586750/article/details/103219952 数字信号处理——时频分析(短时傅里叶变换+手动实现时频分析)
https://blog.csdn.net/qq_42815385/article/details/89095135 STFT(短时傅里叶变换)音频特征提取,用于语音识别 python
https://blog.csdn.net/Barry_J/article/details/81065932 音频特征提取——python/ librosa工具包使用
https://blog.csdn.net/qq_34218078/article/details/101255636 librosa语音信号处理
https://blog.csdn.net/yunman2012/article/details/103542690 librosa处理音频信号
文章参考来源:
https://blog.csdn.net/sinat_18131557/article/details/106440757 Python语音基础操作(对python处理语音信号的过程介绍的很详细,推荐!)