关于信号处理方法的两个小问题
profthecopyright opened this issue · 3 comments
1. Recorder.SampleData()
(1) 命名建议:这个方法的功能相当于是重采样,而且本质上只会降低采样率,建议改名为ResampleData/DownsampleData更合适。
(2) 现在的的降低采样率实现方式只是按比例舍弃采样(decimation),但是从信号处理的角度,单纯这样做的话会有aliasing effect(混叠),引起严重失真(注意,此现象并非由于采样点减少本身导致的音质变差)。标准的降低采样率方式应当在处理之前加入低通滤波过程。如采样比非整数,则应先提高采样率再降低采样率。参见https://zh.wikipedia.org/zh-my/%E9%99%8D%E9%87%87%E6%A0%B7
2. pcmAbsSum
目前音量显示用信号绝对值之和的平均值,此方法据我所知并非标准做法,而且不反映能量/功率(power)。常规处理方式是用信号平方和的平均值(或者最后开个平方得到方均根RMS,与最大值的比值就是平均振幅百分比)来表示能量(与感知的音量直接相关,与标准值作比再取对数就可以得到分贝值)。如果此操作不是特别占用计算能力,建议考虑适当修改。
1.1 命名是一件掉头发的事,保护我方为数不多的头发😂 不单单这个名字很奇怪,还有几个我自己都看的别扭的名字,在相关性不是偏的离谱的前提下,不会增加新命名
1.2 当前的降低采样率的算法已经是采用的比较优秀的一个了,相对于录音音质,此算法并不会对音质产生多少影响(其实低采样率导致的音质变差在专业软件里面也是一样的变的很差);算法中的采样比例是浮点数;如果要在重采样过程中先一步过滤掉低频率下不包含的高频部分(为避免高频信号降频到低频从而混合到了低频率中 就是维基上说的混叠),得引入fft时域转成频域,去掉多余的高频信号,再逆fft变回时域,这个计算量将变得很大也太难了,对于录音来讲,有点得不偿失
- 目前PowerLevel里面的算法(计算的是一个百分比,近似相当于音量),是先取的平均值,将这个平均值当做当前的采样信号数据,然后再进行和音量类似的计算。算法特意优化过了,对小的音量也能比较灵敏的检测到,大的音量适当进行了削弱
对于1.2的计算量问题,一般有两种方式解决。
- 直接打表hard code低通滤波器在时域上对应的sinc function,然后直接计算时域上的卷积,不必做FFT。
- 可以将lib-fft.js这种基础算法库用C/Rust之类的底层语言写,编译成WebAssembly再用js引入(如wasm-pack),这种方法可以对性能有明显提升(https://github.com/AWSM-WASM/PulseFFT)
1.2 今天更新的版本:84167ba ,已经增加了一个滤波函数 Recorder.IIRFilter,函数的代码量30行不到,已经在SampleData里面使用上了低通滤波,48k转成8k采样率时效果很明显,以前版本8k采样率的音频基本杂音占一大半,现在滤波后就没有多少杂音了 人声很清晰😁