声音的产生 :能量通过声带使其振动产生一股基声音,这个基声音通过声道 ,与声道发生相互作用产生共振声音,基声音与共振声音一起传播出去。
传感器以某种频率探测声音的振幅强度以及振动方向,所得到的一系列随时间变化的点。
传感器的探测频率,即为采样频率。根据采样定理得到采样频率。
定义:用来描述给定带宽的最高传输速率。
整数周期(eg.物体旋转后回到原状所需的时间),采样周期为整数倍的整数周期时不能检测到相位的变化。
*若为轮子转动问题:若需要同时看到旋转方向和相位变化,采样周期要小于整数周期的1/2,采样频率应大于原始频率的2倍。
➡️➡️对于模拟信号:要同时看到信号的全部特性,采样频率应大于原始模拟信号的最大频率的2倍,否则会出现混叠现象。
混叠现象
指利用 离散傅里叶变换 (DFT)对信号Z域进行频域抽样时,取样点数小于时域列长所引起的时域周期延拓序列互相交叠的现象。
分为窄带语谱图和宽带语谱图
窄带:接入速度慢,传输速率低
宽带:传输模拟信号,将信道分成多个子信道,分别传送音频、视频和数字信号,称为宽带传输。
带宽:电磁波频带的宽度,也就是信号的最高频率与最低频率的差值
时宽:脉冲宽度,是信号的结束时间减去信号的开始时间
时窗:时间间隔(time interval)
目标:找出各个频率成分的分布
傅里叶变换(FFT)操作 && 小波变换 && 全卷积时域音频分离网络——Conv-TasNet

猜测任意周期函数可以写成三角函数之和。
定义:对于θ∈R,有
虚数 i:i*i=-1
数轴上 1*(-1) [即1*i*i],线段在数轴上绕原点旋转了180°
当1*i时,线段在平面上旋转90°,即得到虚数轴(复平面)。
图源:博客园 - 韩昊 - 深入浅出的讲解傅里叶变换
是复平面上的一个夹角为
的向量

在时间轴t上,记录向量虚部(纵坐标)的值,即为
在时间轴t上,记录向量实部(横坐标)的值,即为
两种角度,一个可以观察到旋转的频率,所以称为频域;一个可以看到流逝的时间,所以称为时域。
的基(最基本单元)为:
经过点积得到:

图源:博客园 - 韩昊 - 深入浅出的讲解傅里叶变换

图源:博客园 - 韩昊 - 深入浅出的讲解傅里叶变换


图源:博客园 - 韩昊 - 深入浅出的讲解傅里叶变换
#导包 import numpy as np from scipy.io import wavfile from scipy.fftpack import dct import matplotlib.pyplot as plt #绘制时域图 def plot_time(sig, fs): time = np.arange(0,len(sig))*(1.0/fs) plt.figure(figsize = (20, 5)) plt.plot(time, sig) plt.xlabel('Time(s)') plt.ylabel('Amplitude')#振幅 plt.grid() #绘制频域图 def plot_freq(sig, sample_rate, n_fft=512): freqs = np.linspace(0, sample_rate/2, n_fft//2 + 1) xf = np.fft.rfft(sig, n_fft) / n_fft xfp = 20*np.log10(np.clip(np.abs(xf), le-20, le100))#强度 plt.figure(figsize = (20, 5)) plt.plot(freqs, xfp) plt.xlabel('Freq(hz)') plt.ylabel('dB')#强度 plt.grid() #绘制二维数组 def plot_spectrogram(spec,ylabel = 'ylabel'): fig = plt.figure(figsize = (20, 5)) heatmap = plt.pcolor(spec) fig.colorbar(mappable = heatmap) plt.xlabel('Time(s)') plt.ylabel(ylabel) plt.tight_layout() plt.show() wav_file = '文件名.wav' fs, sig = wavfile.read(wav_file) #fs是wav文件的采样率,signal是wav文件的内容,filename是要读取的音频文件的路径 sig = sig[0: int(10 *fs)] #保留前10s的数据 plot_time(sig, fs) #时域图 plot_freq(sig, fs) #频域图
时域图 源 博客园 yifanhunter
频域图 源 博客园 yifanhunter
预加重
定义:对语音的高频部分进行加重
目的:
- 平衡频谱,高频通常与低频相比具有较小的幅度,提高高频部分,使信号的频谱变得平坦,保持在低频到高频的整个频带中,能用同样的噪声比(SNR)求频谱
- 突出高频的共振峰
将语音信号通过一个高通滤波器:
![]()
(其中滤波器系数
值通常为0.95或0.97
# 代码形式 pre_emphasis = 0.97 emphasized_signal = numpy.append(signal[0], signal[1:] - pre_emphasis * signal[:-1]) # emphasized_signal为新signal效果
时域图 源 博客园 yifanhunter
频域图 源 博客园 yifanhunter
从某条曲线中去除一些特定的频率成分
基本思想:非周期性的信号可以由多个周期性的信号叠加而逼近得到。将无限长的三角函数作为基函数
傅里叶变换:将一个时域非周期的连续信号转换成一个在频域非周期的连续信号(将频域的点连接起来的图像)得到频谱和时谱

图源:博客园 - 韩昊 - 深入浅出的讲解傅里叶变换
离散谱频域:

图源:博客园 - 韩昊 - 深入浅出的讲解傅里叶变换
连续谱频域:

图源:博客园 - 韩昊 - 深入浅出的讲解傅里叶变换
解释:将语音信号截取成小段,即为分帧,每一段信号就叫做一「帧」

图源:知乎 王赟 Maigo

图源:知乎 王赟 Maigo
帧移:STRIDE,0~1/2帧长,帧与帧之间的平滑长度
def framing(frame_len_s, frame_shift_s, fs, sig):
"""
分帧,主要是计算对应下标
param frame_len_s: 帧长,s
param frame_shift_s: 帧移,s
param fs: 采样率,hz
param sig: 信号
return: 二维list,一个元素为一帧信号
"""
sig_n = len(sig)
frame_len_n, frame_shift_n = int(round(fs * frame_len_s)), int(round(fs * frame_shift_s))
num_frame = int(np.ceil(float(sig_n - frame_len_n) / frame_shift_n) + 1)
pad_num = frame_shift_n * (num_frame - 1) + frame_len_n - sig_n # 待补0的个数
pad_zero = np.zeros(int(pad_num)) # 补0
pad_sig = np.append(sig, pad_zero)
# 计算下标
# 每个帧的内部下标
frame_inner_index = np.arange(0, frame_len_n)
# 分帧后的信号每个帧的起始下标
frame_index = np.arange(0, num_frame) * frame_shift_n
# 复制每个帧的内部下标,信号有多少帧,就复制多少个,在行方向上进行复制
frame_inner_index_extend = np.tile(frame_inner_index, (num_frame, 1))
# 各帧起始下标扩展维度,便于后续相加
frame_index_extend = np.expand_dims(frame_index, 1)
# 分帧后各帧的下标,二维数组,一个元素为一帧的下标
each_frame_index = frame_inner_index_extend + frame_index_extend
each_frame_index = each_frame_index.astype(np.int, copy=False)
frame_sig = pad_sig[each_frame_index]
return frame_sig
frame_len_s = 0.025
frame_shift_s = 0.01
frame_sig = framing(frame_len_s, frame_shift_s, fs, sig)
在分帧后,要进行加窗 操作,即与一个「窗函数」相乘

图源:知乎 王赟 Maigo
确定窗函数的宽度:
对于时变的非稳态信号,高频适合小窗口,低频适合大窗口


图源:极市平台
对每一帧的信号做FFT,得到频谱

图源:知乎 王赟 Maigo

n_fft即为多少个信号点做傅里叶变换
公式:
- 某帧做STFT,得到频率组的数量 = n_fft // 2 + 1 (//表示整除
- 计算一段信号STFT能得到的帧数:已知分帧的窗长winlength,帧移长度hoplength,信号采样点个数L
- 时间帧数N = L // hoplength + 1(与窗长无关
eg:假设某信号采样率为16000,取一秒钟,也即采样点数量为16000的信号,做窗长512(512/16000*1000=32毫秒)点,帧移256(16毫秒)的STFT变换,即可得到
16000 // 256 + 1= 63帧。
import torchaudio signal = torch.rand(16000) stft = torch.stft(signal.return_complex=True,n_fft=512,hop_length=256,win_length=512) print(stft,shape)
时频分析:各个成分出现的时间、信号频率随时间变化的情况、各个时刻的瞬时频率及其幅值
傅里叶变换缺陷:只能获取一段信号总体上包括哪些频率部分,但无法获知各成分出现的时刻。➡️➡️“对于非平稳的过程,傅里叶变换有局限性” “两个时域有巨大差异的信号的频域可能高度一致”
小波变换思路:将FFT中的无限长三角函数换成了有限长的会衰减的小波基

图源:极市平台
两个变量:
得到时频谱
对于突变信号:FFT存在吉布斯效应
傅里叶变换:

图源:极市平台
对小波变换:

图源:极市平台
对一段长语音信号,分帧、加窗、在对每一帧做傅里叶变换,之后把每一帧的结果沿着另一维度堆叠,得到的图就是声谱图
图源:CSDN lvziye00lvziye文章
将声谱图通过梅尔尺度滤波器(Mel 滤波),变为梅尔频谱,得到合适大小的声音特征
图源:CSDN lvziye00lvziye文章
一种前端处理算法,以类似于人耳的方式对音频进行处理,以提高语音识别的性能。
对Fbank做离散余弦变换(DCT)即可获得MFCC特征。
MFCC:梅尔频率倒谱系数。实际就是在梅尔频谱上做倒谱分析(取对数,做DCT变换)
本文不做任何商用,仅为自我学习摘录。如有某部分侵犯了大家的利益,还望海涵,并联系删除,谢谢大家!!!
https://www.zhihu.com/question/24490634 --采样定理
https://blog.csdn.net/lzrtutu/article/details/78882715 --语谱图、基频、共振峰
https://www.zhihu.com/question/19714540/answer/334686351 --马同学(如何理解FT公式
https://mp.weixin.qq.com/s/CRqhHIlYYRjYJ64PZZnUkQ --极市平台 傅里叶变换 小波变换
https://www.cnblogs.com/h2zZhou/p/8405717.html --韩昊 博客园 深入浅出的讲解傅里叶变换
https://www.zhihu.com/question/52093104 --by 知乎 王赟 Maigo 怎样理解分帧
https://blog.csdn.net/lvziye00lvziye/article/details/100132715 --声谱图,梅尔谱图
https://www.cnblogs.com/yifanrensheng/p/13510742.html --Fbank和MFCC介绍-忆凡人生-博客园
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
我对图像处理完全陌生。我对JPEG内部是什么以及它是如何工作一无所知。我想知道,是否可以在某处找到执行以下简单操作的ruby代码:打开jpeg文件。遍历每个像素并将其颜色设置为fx绿色。将结果写入另一个文件。我对如何使用ruby-vips库实现这一点特别感兴趣https://github.com/ender672/ruby-vips我的目标-学习如何使用ruby-vips执行基本的图像处理操作(Gamma校正、亮度、色调……)任何指向比“helloworld”更复杂的工作示例的链接——比如ruby-vips的github页面上的链接,我们将不胜感激!如果有ruby-
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d
我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。
我查看了Stripedocumentationonerrors,但我仍然无法正确处理/重定向这些错误。基本上无论发生什么,我都希望他们返回到edit操作(通过edit_profile_path)并向他们显示一条消息(无论成功与否)。我在edit操作上有一个表单,它可以POST到update操作。使用有效的信用卡可以正常工作(费用在Stripe仪表板中)。我正在使用Stripe.js。classExtrasController5000,#amountincents:currency=>"usd",:card=>token,:description=>current_user.email)
当profile为nil时,总是让我感到悲伤...我该怎么办? 最佳答案 在View中使用变量之前,始终检查变量是否为nil。我确信这个问题有更优雅的解决方案,但这应该能让您入门。 关于ruby-on-rails-Rails处理.Erb与Nils,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/2709605/
写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c
目录一、inout在设计文件中的使用方法1.1、inout的第一种使用方法1.2、inout实现的第二种使用方法1.3、inout使用总结 二、inout在仿真测试中的使用方法一、inout在设计文件中的使用方法在FPGA的设计过程中,有时候会遇到双向信号(既能作为输出,也能作为输入的信号叫双向信号)。比如,IIC总线中的SDA信号就是一个双向信号,QSPIFlash的四线操作的时候四根信号线均为双向信号。在Verilog中用关键字inout定义双向信号,这里总结一下双向信号的处理方法。1.1、inout的第一种使用方法 实际上,双向信号的本质是由一个三态门组成的,三态门可以输出高电平,低电
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是