声鉴

这周需要临时做一个和友商一样的声鉴 功能, 研究了一下, 顺便记录一下。

我们想要做的就是可以鉴别, 比如说 你的声音 是否够 loli,或者 大叔

那么, 解决这个问题的思路是啥?

特征

首先, 就是想办法 将 声音量化, 但是直接量化wav, 并不行, 声音太复杂了, 没发分类, 最好能只对声音的特征做量化, 便于区分。

直观来说, 人对声音的高低非常敏感, 也就是音调。

声音的高低叫做音调,频率决定音调。物体振动的快,发出声音的音调就高。振动的慢,发出声音的音调就低。

简单来说, 普通 男人 和 女人 的声音 一听就能听出来, 至少,我能非常容易的区分男女。

详细科普文 可以参考下面的 reference

量化

量化的话, 经过以前别的项目的了解, 可以使用 praat 可视化 音调数据

如图, 蓝色的就是 音调, 注意 坐标轴 在右边, 0-500hz, 可以看得出, loli 的音调 比较高, 暖男的音调 比较低。

最后就是工程化,写脚本抽取, 脚本教程

http://www.fon.hum.uva.nl/praat/manual/Scripting.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Read from file: "{path}/{name}.wav"
selectObject: "Sound {name}"
min = {pitch_min}
max = {pitch_max}
interval = 0.02
To PointProcess (periodic, cc): min, max
To PitchTier: interval
selectObject: "PitchTier {name}"
numberOfIntervals = Get number of points
resultLine$ = ""
for i to numberOfIntervals
result = Get value at index: i
result$ = string$ (result)
appendFileLine: "{csv_path}/{name}.csv", result$
endfor

计算

获得音调数据够, 如何统计?

根据上图可以看得出, 不同的人的 音调 出现的 赫兹 范围 不同,

所以, 最简单的方式,只需要 判断 他们各自的 各hz 的出现概率就行。

至于相似度的话, 则对他们的各个维度的 hz 概率百分比 求乘积, 并取sum。

sum 越大,意味着,他们有个 更相近的 音调, 也就意味着 更相近了。

reference

https://baike.baidu.com/item/%E9%9F%B3%E8%B0%83

https://www.bilibili.com/read/cv201316/

https://bideyuanli.com/p/3238

https://www.zhihu.com/question/38064124

avatar

lelouchcr's blog