使用php实现的wav文件的相似度对比

2017-09-13 10:26:02来源:http://www.jianshu.com/p/8522ef64706c作者:御坂网络人点击

分享

此为通过对比两个文件前1秒内的声音数据来对比两个声音文件的相识性,来借此识别人们说话的内容.详细的识别方法是,首先先采集汉字的所有音素内容,包括声母和韵母,人后通过将声音文件分段,以最适合识别出单一音素内容为准,大概0.1秒左右的时长数据(以每秒22052个采样数据算的话就是每次处理2200个采样数据),每次都和所有音素对比相似度,采用最高的音素.以此循环处理完所有声音数据为一串特定字符数据(音素数据),每个音素的声音数据事先已保存为一组数值串(通过每个采样的数据转换而来的代替值-32768~32767之间).获得了音素数据之后开始转换为读音(声母+韵母的读音组合在400多个),因为采集的间隔短,所以会出现以下类似的串,如百度的声音可能会获取到EBBBXXXEEXXAAAEEEEEXDDDEEUUUXXXXXX(X为无意义串),获得有意义的BAEDEU(汉字基本都是声母+韵母格式,应该能比较容易得到对应汉字的读音的),得到了读音之后基本工作就完成了差不多了.接下来就是处理多音字问题了,这个可以通过字词间,句子前后间的内容判断出来..

===========以下内容为输出测试===========

原始文件大小:44162 byte

对比文件大小:44162 byte

文件类型:RIFF

文件大小:44154

WAVE文件格式:WAVE

fmt 波形格式标志:fmt

16 or 18PMC :18

编码方式 1为线性 大于1为压缩:1

声道数 1为单 2为双:1

采样频率:22050

byte率/每秒采样字节数:44100

块对齐/数据对齐单位,每个采样样本需要的字节数:2

每个采样需要比特数 占2字节:16

附加信息:0

fact:fact

数值 4:4

data:22052

data:data

音频数据大小:44104

相识度等于:69.059364896675 %

===========以下内容为php源码===========


$a=array();

$awj="c://1.wav";//$_POST["name"];//数据文件-------------------------------------

$bwj="c://w.wav";//$_POST["age"];//待对比文件-------------------------------------

$sh=fopen($awj,"rb");//-----------------

$head=fread($sh,filesize($awj));//      |打开数据文件

fclose($sh);         //-----------------

$zh=fopen($bwj,"rb");//-----------------

$zead=fread($zh,filesize($bwj));//      |打开待对比文件文件

fclose($zh);         //-----------------

$wjdx=44158;//filesize($awj);//用来比较的数量,以数据文件为准-------------------------------------

$arr=unpack("C$wjdx",$head);

$zrr=unpack("C$wjdx",$zead);

echo "
";

echo "原始文件大小:".filesize($awj)." byte";

echo "
";

echo "对比文件大小:".filesize($bwj)." byte";

//-----------------------------------------------------------------开始获取WAV数据-------------------

echo "
文件类型:".chr($arr[1]).chr($arr[2]).chr($arr[3]).chr($arr[4]);

echo "
文件大小:";

echo $arr[8]*16777216+$arr[7]*65536+$arr[6]*256+$arr[5];

echo "
WAVE文件格式:";

echo chr($arr[9]).chr($arr[10]).chr($arr[11]).chr($arr[12]);

echo "
fmt 波形格式标志:";

echo chr($arr[13]).chr($arr[14]).chr($arr[15]).chr($arr[16]);

echo "
16 or 18PMC :";

echo $arr[20]*16777215+$arr[19]*65536+$arr[18]*256+$arr[17];

echo "
编码方式 1为线性 大于1为压缩:";

echo $arr[22]*256+$arr[21];

echo "
声道数 1为单 2为双:";

echo $arr[24]*256+$arr[23];

echo "
采样频率:";

echo $arr[28]*16777215+$arr[27]*65536+$arr[26]*256+$arr[25];

echo "
byte率/每秒采样字节数:";

echo $arr[32]*16777215+$arr[31]*65536+$arr[30]*256+$arr[29];

echo "
块对齐/数据对齐单位,每个采样样本需要的字节数:";

echo $arr[34]*256+$arr[33];

echo "
每个采样需要比特数 占2字节:";

echo $arr[36]*256+$arr[35];

if($arr[20]*16777215+$arr[19]*65536+$arr[18]*256+$arr[17]==16)

{

echo "
fact:";

echo chr($arr[37]).chr($arr[38]).chr($arr[39]).chr($arr[40]);

echo "
数值 4:";

echo $arr[44]*16777215+$arr[43]*65536+$arr[42]*256+$arr[41];

echo "
data:";

echo $arr[48]*16777215+$arr[47]*65536+$arr[46]*256+$arr[45];

echo "
data:";

echo chr($arr[49]).chr($arr[50]).chr($arr[51]).chr($arr[52]);

echo "
音频数据大小:";

echo $arr[56]*16777215+$arr[55]*65536+$arr[54]*256+$arr[53];

}

else

{

echo "
附加信息:";

echo $arr[38]*256+$arr[37];

echo "
fact:";

echo chr($arr[39]).chr($arr[40]).chr($arr[41]).chr($arr[42]);

echo "
数值 4:";

echo $arr[46]*16777215+$arr[45]*65536+$arr[44]*256+$arr[43];

echo "
data:";

echo $arr[50]*16777215+$arr[49]*65536+$arr[48]*256+$arr[47];

echo "
data:";

echo chr($arr[51]).chr($arr[52]).chr($arr[53]).chr($arr[54]);

echo "
音频数据大小:";

echo $arr[58]*16777215+$arr[57]*65536+$arr[56]*256+$arr[55];

}

echo "
";

//print_r($arr);//此为数据数组的遍历显示

echo "
";

//print_r($zrr);//此为待比较数组的遍历显示

reset($arr);

while (list($key, $val) = each($arr))

{

if ($arr[$key]==0 and $zrr[$key]==0)

$a[]=1;

else if(($arr[$key]*$zrr[$key])==0)

$a[]=0;

else

{

if($arr[$key]>$zrr[$key])

$a[]=$zrr[$key]/$arr[$key];

else

$a[]=$arr[$key]/$zrr[$key];

}

}

echo "
相识度等于:".((array_sum($a)/$wjdx)*100)." %
";//计算所有数组的和,再除以数值的个数,得到两个数组的相识度

//print_r($a);//此为遍历显示各个数值的相似度,两数值中有一个数值为0则相识度为0.

//====================下面来说将WAV获得的数据做-2.5v到+2.5v的量化,从第59字节开始,每个采样占2字节

$wav=array();

$wavint=1;

$bianliang=59;//从这里开始

while($bianliang

{

$wav[$wavint]=($arr[$bianliang+1]*256+$arr[$bianliang])-32768;

$bianliang=$bianliang+2;

$wavint=$wavint+1;

}

//print_r($wav);//从这里结束

?>

完成,这个是自己边学php边实践的小玩意儿= =




最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台