php javascript wav波形绘制,PHP分析.wav文件并绘制png格式的波形图

表1 WAV文件的文件头

偏移地址

字节数

类型

内容

00H~03H

4

字符

资源交换文件标志(RIFF)注意字符大小写!

04H~07H

4

长整数

从下个地址开始到文件尾的总字节数

08H~0BH

4

字符

WAV文件标志(WAVE)注意字符大小写!

0CH~0FH

4

字符

波形格式标志(fmt)注意字符大小写!

10H~13H

4

整数

过滤字节(一般为00000010H)

14H~15H

2

整数

格式种类(值为1时,表示数据为线性PCM编码)

16H~17H

2

整数

通道数,单声道为1,双声音为2

18H~1BH

4

长整数

采样频率

1CH~1FH

4

长整数

波形数据传输速率(每秒平均字节数)

20H~21H

2

整数

数据的调整数(按字节计算)

22H~23H

2

整数

样本数据位数

表2 WAV声音文件的数据块

偏移地址

字节数

类型

内容

24H~27H

4

字符

数据标志符(data)注意字符大小写!

28H~2BH

4

长整型

采样数据总数

2CH...

...

...

采样数据

首先需要了解wav的这3个重要指标:采样率、采样位数、声道数。下面以16KHz, 16Bit, 单声道为例来说明。

采样率:(也称为采样速度或者采样频率)定义了每秒从连续信号中提取并组成离散信号的采样个数,单位用赫兹(Hz)来表示。采样频率的倒数是采样周 期(也称为采样时间),它表示采样之间的时间间隔。采样率为16KHz,表明每秒钟采样有16K次,即0.001秒内采集16个值。

采样位数:即采样值或取样值,用来衡量声音波动变化的参数,是指声卡在采集和播放声音文件时所使用数字声音信号的二进制位数。声卡的位客观地反映了数字声音信号对输入声音信号描述的准确程度。16Bit表示用计算机的16位(即2字节)来标示一个值。

声道数:是指支持能不同发声的音响的个数。常见的有单声道和双声道。

比特率:每秒传送的比特(bit)数,等于采样率*采样位数,单位为bps(Bit Per Second)。示例音频的比特率为256kbps。

了解了这些东西,我们就可以开始写代码了:

a67c3a96fd530679f48745583a6e7254.gif

function wav_graph($file,$f=0,$w=0)

{

if(!is_file($file))return 0;

$fp=fopen($file,r);

$raw=fread($fp,36);//对应36个字节的文件头,包含该文件的一些信息

$str="";

$header=unpack('A4Riff/VSize/A4Wav/A4Head/VHeadSize/vPCM/vChannels/VSampleRate/VByteRate/vBlockAlign/vSampleBits', $raw);

//print_r($header);//查看文件头

foreach($header as $k=>$v)

$str.=$k.":".$v." ";

fseek($fp,36+$header['HeadSize']-16);

$raw=fread($fp,8);

$data=unpack('A4Data/VDataSize',$raw);

foreach($data as $k=>$v)

$str.=$k.":".$v." ";

$b=$header['SampleBits'];//样本数据位数

$c=$header['Channels'];//声道数

$l=$b*$c/8;//需要用16比特的原因就在这里,16比特代表采集位数是2个字节,除于8

$s=$data['DataSize']/$l;//文件数据长度/(样本采集位数*采集频率)=歌曲时间吧

$r=$header['SampleRate'];//采集频率

if($f) $h=pow(2,$b)/$f;//设定波的高度

else {$h=200;$f=pow(2,$b-1)/$h;}

if($w==0)$w=round($r/5);//后面的5是时间,1000表示按秒为单位

header("Content-type:image/png");//查看弹出数据时需要把画图的部分隐藏掉哦

$im=@imagecreate($s/$w,$h*$c*2);

$background_color = imagecolorallocate($im, 255, 255, 255);

$text_color = imagecolorallocate($im, 233, 14, 91);

$x=0;$y=array();$yn=array();

for($i=0;$i

$n=$l*$w;

while(1)

{

if($s==0) break;

if($s

$samples=fread($fp,5*$n);//后面的5是时间,1000表示按秒为单位

if($samples==FALSE)break;

$packed=unpack('s*',$samples);

foreach($packed as $k=>$v)

{

$cnt=($k-1)%($w*$l);

if($cnt>$c-1)continue;

$yn[$cnt]=$h*$cnt+$h-$v/$f;

imageline($im,$x,$y[$cnt],$x+1,$yn[$cnt],$text_color);

$y[$cnt]=$yn[$cnt];

$x++;

}

$s-=$n;

}

/**/

imagepng($im);

imagedestroy($im);

}

wav_graph('aa.wav');

?>

a67c3a96fd530679f48745583a6e7254.gif

上传一张结果图

a461b98edeaf5181d37c9fbd55b14839.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值