网页js版音频数字信号处理:H5录音+特定频率信号的特征分析和识别提取
音频数字信号处理 Audio DSP (Digital Signal Processing) 是一个复杂又专业的话题,本文介绍的是如何从音频中实时分析和识别出特定频率信号的一种方法,对应的代码为可运行在浏览器中的html5网页版(可移植);可用于识别环境中特定频率的声音、或噪声、乐器弹奏的音调。
在线测试:FFT频域分析ECharts频谱曲线图
900Hz频率的摩尔斯电码声音频谱曲线,为本文的主要分析对象,请见文末生成LOVE对应的电码音频文件,然后把文件拖入上面的这个在线测试页面,即可得到此图: 
吉他6根空弦音频谱曲线: 
一、网页中的音频数据源
H5网页中获取音频数据的方法至少有三种:
- 通过网络请求下载得到音频文件二进制内容(
xhr、fetch) - 通过
input[type=file]选择文件,在用FileReader读取获得二进制内容 - 通过浏览器的
getUserMedia接口访问设备的麦克风,录制得到音频二进制内容
不同音频格式有不同的压缩编码方法,为了得到文件内的音频数据,我们需要解码音频文件,得到音频的采样数据(PCM)才好进行下一步处理;.wav格式的文件解码简单,它是一般是由wav头+pcm数据组合而成的,直接去掉wav头即完成解码,其他文件可通过AudioContext的decodeAudioData方法直接解码成32位pcm再转成16位pcm。
得益于现代浏览器的WebRTC功能加持,网页也能实现丰富的音视频交互,可以实现网页录音,实时采集环境中的声音得到pcm数据,GitHub Recorder是一个功能丰富的H5网页录音开源库,可以方便的进行实时处理录音数据。
二、FFT:时域转频域
我们得到音频的采样数据(PCM)后,可以将此数据按值的大小直接绘制出来,即可得到一个声音的波形,此波形为音频的时域波形:横坐标是时间,纵坐标是采样值的大小,比如在Audition中显示如下图所示(生成此音频文件请见文末)。

在时域波形上,我们能直观的知道在某个时间点是否有声音,和声音的大小,但不知道这个声音是否是我们需要的信号,还是其他杂音;数字信号分析的重头戏出场了:FFT,快速傅里叶变换。
通过FFT可以将单个时域波形分解成N个不同频率的波形,即时域信号变换成频域信号,N取决于fftSize的大小,比如fftSize=1024,将得到512个频率分量;在Audition中可以非常直观的感受到频域信号的强度分布,如下图所示,900Hz的信号非常亮(生成此音频文件请见文末)。

H5 js版的FFT的实现有很多开源代码可以参考,或者直接使用浏览器提供的AudioContext的createAnalyser接口来进行频域数据变换;Recorder库中的提供了2个FFT实现可以使用:extensions/lib.fft.js、dsp.lib.fft_exact.js,到上文中的在线测试中可以看到这两文件。
js版的FFT变换操作也比较简单,Audition中用到的这个音频文件,在网页中通过变换后得到的频域数据,叠加绘制到一起即得到了文章开头的第一张摩尔斯电码声音频谱曲线图,信号非常明显。
三、信号的特征分析
以文章开头的“900Hz频率的摩尔斯电码声音频谱曲线图”为例,我们通过频谱分析,可以直观的看到信号最强的频率波峰,能量非常集中,频率值分散在900Hz附近,也就是说这段音频中信号的主要频率为900Hz左右,和实际生成此摩尔斯电码所使用的900Hz频率一致。
分析得到了主要频率,我们只关注这个主要频率的波形曲线,也能直观的看出和摩尔斯电码规律一致的特征:持续时间短的是滴(.),持续时间长的是嗒(-),嗒的长度是滴的3倍,滴嗒之间间隔1个滴的长度,字符之间间隔3个滴的长度(单词之间间隔7个滴以上的长度)。

四、信号的识别提取
分析出信号的特征后,就有办法通过编写代码来进行信号的识别和提取,依旧是以上图为例,我们来提取出里面包含的摩尔斯电码。
(1)过滤掉其他能量低的值,中只保留能量集中的几个频率 
(2)程序代码中对这几个频率进行综合分析判断,每个波峰取和前面频率相差不大的频率当做有效波峰(这样可有效排除掉杂波干扰),得到一条曲线 
(3)根据曲线中的值的大小,较小的值全部当做0,高的保留,最终转换得到断断续续的矩形波,有波峰的地方即为有信号,得到每个波峰的持续时间,即可识别出滴(.)嗒(-),即为摩尔斯电码 
Q: 为啥不用PCM的音量大小来直接判断信号?
A: 最后的矩形波看起来和时域的波形包络没有多大区别,这是因为录制的样本中没有比较大的背景杂音干扰;在没有杂音干扰的情况下,直接用PCM的采样值(或音量)来提取信号也是可行的;但在有比较大的干扰的情况下(末尾那段杂音),时域就很难区分出是否是正确的信号,频域中分离出来的波形更能反映出原本的信号。
如果是要根据声音的频率来判断是什么信号,那就必须转到频域来识别处理,比如乐器的音调,时域是完全无法识别出是哪个调的。
附录
- Recorder用于html5录音:https://github.com/xiangyuecn/Recorder,网页中实时录制获得音频数据。
- 趣味摩尔斯电码:小程序,微信版和字节抖音版,将文本
LOVE转换成摩斯码并播放,录制得到上文中使用的摩尔斯电码音频;内置电码翻译功能,可以实时录制音频并解析出电码,本文所总结的内容即为其音频识别成电码所使用的原理。
【完】
网页js版音频数字信号处理:H5录音+特定频率信号的特征分析和识别提取的更多相关文章
- h5 录音 自动生成proto Js语句 UglifyJS-- 对你的js做了什么 【原码笔记】-- protobuf.js 与 Long.js 【微信开发】-- 发送模板消息 能编程与会编程 vue2入坑随记(二) -- 自定义动态组件 微信上传图片
得益于前辈的分享,做了一个h5录音的demo.效果图如下: 点击开始录音会先弹出确认框: 首次确认允许后,再次录音不需要再确认,但如果用户点击禁止,则无法录音: 点击发送 将录音内容发送到对话框中.点 ...
- H5录音音频可视化-实时波形频谱绘制、频率直方图
这段时间给GitHub Recorder开源库添加了两个新的音频可视化功能,比以前单一的动态波形显示丰富了好多(下图后两行是不是比第一行看起来丰满些):趁热打铁写了一个音频可视化相关扩展测试代码,下面 ...
- 数字信号处理与音频处理(使用Audition)
前一阵子由于考博学习须要,看了<数字信号处理>,之前一直不清除这门课的理论在哪里应用比較广泛. 这次正巧用Audition处理了一段音频,猛然发现<数字信号处理>这门课还是很实 ...
- 优化Recorder H5录音:可边录边转码上传服务器,支持微信提供Android IOS Hybrid App源码
Recorder H5 GitHub开源库随着支持功能的增多,音频转码处理效率渐渐的跟不上需求了,近期抽时间对音频转码部分进行了升级优化,以支持更多实用的功能. 另外IOS的Hybrid App也完成 ...
- JS控制音频顺序播放
做一项目,用到“叫号功能”,网页上有一“叫号”按钮,点击后就读数据库中存的号码,如123号, 然后就发声音出来, 思路是网上下载0123456789的叫号声音,然后按钮点击事件里就在JS里写用那个HT ...
- 常见排序算法(JS版)
常见排序算法(JS版)包括: 内置排序,冒泡排序,选择排序,插入排序,希尔排序,快速排序(递归 & 堆栈),归并排序,堆排序,以及分析每种排序算法的执行时间. index.html <! ...
- h5 录音
得益于前辈的分享,做了一个h5录音的demo.效果图如下: 点击开始录音会先弹出确认框: 首次确认允许后,再次录音不需要再确认,但如果用户点击禁止,则无法录音: 点击发送 将录音内容发送到对话框中.点 ...
- js版贪吃蛇
之前没有写博客的习惯,这是我的第一个博客,有些的不好的地方,希望大家多多提意见 js版的贪吃蛇相对比较简单,废话不多说直接上代码,有需要注意的地方我会标红,github源码地址https://gith ...
- FPGA与数字信号处理
过去十几年,通信与多媒体技术的快速发展极大地扩展了数字信号处理(DSP)的应用范围.眼下正在发生的是,以更高的速度和更低的成本实现越来越复杂的算法,这是针对高级信息服更高带宽以及增强的多媒体处理能力等 ...
- 原生js版分页插件
之前我在自己的博客里发表了一篇用angularJs自定义指令实现的分页插件,今天简单改造了一下,改成了原生JavaScript版本的分页插件,可以自定义一些简单配置,特此记录下来.如有不足之处,欢迎指 ...
随机推荐
- [信息抽取]基于ERNIE3.0的多对多信息抽取算法:属性关系抽取
[信息抽取]基于ERNIE3.0的多对多信息抽取算法:属性关系抽取 实体关系,实体属性抽取是信息抽取的关键任务:实体关系抽取是指从一段文本中抽取关系三元组,实体属性抽取是指从一段文本中抽取属性三元组: ...
- JavaScript:this指针
this指针,存储的是一个内存地址,如同变量一样,指向一块内存区域: 而这个内存区域,保存的就是一个对象的数据,那么这个对象是什么呢? 通常来说,this指针,主要是用在方法(函数)中,用来指向调用方 ...
- linux系统中安装虚拟机
在linux系统中,利用图形化界面安装虚拟机.首先启动 virt-manager,当然没有安装 virt-manager需要先安装好. 1 $ apt-get install virt-manager ...
- Atcoder Beginner Contest ABC 284 Ex Count Unlabeled Graphs 题解 (Polya定理)
题目链接 弱化版(其实完全一样) u1s1,洛谷上这题的第一个题解写得很不错,可以参考 直接边讲Polya定理边做这题 问题引入:n颗珠子组成的手串,每颗珠子有两种不同的颜色, 如果两个手串能够在旋转 ...
- 如何在mac电脑上配置命令行工具
Hi,欢迎大家在有空的时候做客[江涛学编程],这里是2023年的第7篇原创文章,今天我们来聊一聊如何在mac电脑上配置命令行工具 老规矩,拍拍手,上菜. 同学,打开你的mac电脑,按住键盘上的&quo ...
- solidity 内存(memory) 可变数组的增删改查 操作
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; library Array { function push(uint256[] memo ...
- 安装pytorch-gpu的经验与教训
首先说明 本文并不是安装教程,网上有很多,这里只是自己遇到的一些问题 我是以前安装的tensorflow-gpu的,但是发现现在的学术论文大部分都是用pytorch复现的,因此才去安装的pytorch ...
- ZROI3
题解 ZROI3 T1 与<滑动窗口>类似,用单调队列维护 #include <queue> #include <cstdio> #include <cstr ...
- ng + zorro angular表格横纵向合并,横向目前是手动,纵向是自动合并,微调后可适配三大框架使用
表格横纵向合并,可以看一下代码编写之前和之后的样式,先上图~~ 表格页面文件.html <h1>正常表格</h1> <nz-table #colSpanTable [nz ...
- echart大坑总结~~echarts呈现的数据刷新不完全/echarts画图时tooltip不会更新
谨以此文记录在使用echarts中遇到的各种大坑或者小坑,陆续更新加入新坑 欢迎朋友们一起提坑,我们势必绕过它们,愿我们永不再入坑~ 坑一:echarts图表重新赋值数据,图表显示会存在一部分原来的数 ...