Classify WeChat Audio Messages using Speaker Recognition

Problem

微信的聊天记录导出一直是挺麻烦的事, 尤其是在iphone上. 前几天想导出一部分语音聊天记录, 就到iphone的文件系统里去找了一下, 发现微信的语音记录存放在/var/mobile/Applications/{app id}/Documents/{user id}/Audio/{friend id}/*.aud

问题是, 微信将两人互相的对话音频存在一个目录下, 不知道如何区分, 去逆向微信的聊天记录格式恐怕比较困难, 于是想到使用上学期做的说话人识别(Speaker Recognition)系统来自动处理这个问题.

Preparation

google一下发现微信所存储的音频格式为headless AMR. 因此手动为每个文件添加AMR head:

for i in *.aud; cat <(echo '#!AMR') $i > ${i%.*}.amr
rm *.aud

然后就可以将其转为正常的wav格式了:

for i in *.amr; sox $i ${i%.*}.wav
rm *.amr

手动标注一部分数据, 分别放在以两人名字命名的目录里:

$ ls /tmp/{x,y}
/tmp/x/:
1012.wav 1015.wav 943.wav

/tmp/y/:
1086.wav 1095.wav 1111.wav 1301.wav 1308.wav 1315.wav 880.wav

两人的训练数据总时间分别为21s与15s, 未消除静音部分

Classification

Speaker Recognition项目的代码放在github 上, 由于是course project而且拼的是效果, 所以我们的代码写的还挺乱的..

关于Speaker Recognition的原理, 可以看我们的 presentation slidesreport

今天为其增加了命令行工具, 方便进行训练和预测.

训练:

$ ./speaker-recognition.py -t enroll -i '/tmp/x /tmp/y' -m model.out
Label x has files /tmp/x/1015.wav,/tmp/x/1011.wav,/tmp/x/943.wav,/tmp/x/1012.wav
Label y has files /tmp/y/880.wav,/tmp/y/1315.wav,/tmp/y/1301.wav,/tmp/y/1111.wav,/tmp/y/1086.wav,/tmp/y/1095.wav,/tmp/y/1308.wav
Start training...
6.29284691811 seconds

预测:

$ ./speaker-recognition.py -t predict -i '/tmp/wechat/*.wav' -m model.out > /tmp/log

其输出的预测结果每一行形如: "/tmp/wechat/546.wav -> y" 根据输出构造shell命令, 把音频按分类结果分别放到不同目录中:

$ mkdir x y
$ cat /tmp/log | sed 's/-> //g' | awk '{print "cp " $0}' | bash

现在x与y两人的所有音频都被放到了x, y两个目录里, 为了方便人工验证正确性, 可以将一个人的所有音频合并为一个wav:

$ for i in x y; sox $i/*.wav $i.wav

结果准确率为100%..(数据比较少)

大家都去收集好(nv)友(shen)的声音吧!

Comments