# 东西多了点..

Posted by Honey on August 09, 1998 at 16:46:41:

In Reply to: 教教我吧！要如何绘出声音的波形？ posted by Bomber on August 07, 1998 at 17:27:58:

我是没听过有那种能绘出波形的函式 不过可以自己写喔
嗯~废话少说 首先提供你一些声音档(Wav档)的一些必要资料

$每个声音档都有 44 bytes 的档头
1~20 bytes 的部分储存的是 声档格式
21~22 bytes 的部分储存的是 压缩格式
23~24 bytes 的部分储存的是 声道数
25~28 bytes 的部分储存的是 每秒取样量
29~32 bytes 的部分储存的是 每秒资料量
33~34 bytes 的部分储存的是 ~我忘了 但是并不重要
35~36 bytes 的部分储存的是 位元数
37~40 bytes 的部分储存的是 data 字串
41~44 bytes 的部分储存的是 实际声档大小
45 bytes 以后是储存的才是实际声档内容

$ Wav 档是以二进位(随机档)模式储存
8位元的音档每笔资料长度是 8 Bit(1 Bytes)
储存数值有 2^8个 范围在0~255
16位元的音档每笔资料长度是 16 Bit(2 Bytes)
储存数值有 2^16个 范围在-32768~32767

$绘制波形前 得先取得音档 位元数 才能判断每笔资
料长度 通常是用以下程式码取得

Dim StrFileName As String '储存档名
Dim IntCost As Integer '储存 位元数
StrFileName="C:\windows\media\ding.wav"
'设定要读取的档案
open StrfileName For Random As #1 _
Len = 2 '设定每笔资料长度为 2 bytes
get #1,18,IntCost '取得第18笔资料 _
即档头35~36 bytes位置的"位元数"

'注:如果每笔资料长度为 2 bytes _
储存变数需为Integer型态
如果每笔资料长度为 1 bytes _
储存变数需为byte型态 _
如果每笔资料长度为 N bytes _
储存变数可宣告为String*N
close #1

$如果IntCost=16 通常是用以下程式码读取
并绘制图形
dim StrFileName as String '储存档名
dim DblSize as double '储存实际声档大小
dim Int16BitPoint() as integer
dim LngVariable_K as long
dim LngVariable_I as long
StrFileName="C:\windows\media\hoversel.wav" _
'设定要读取的档案

'#以下部分是将实际声档资料读入阵列#
open StrfileName for random as #2 _
len = 2'每笔资料位元组数
DblSize = lof(2)-44
'实际档案大小(Bytes) _
前44Bytes是档头*/

LngVariable_K = DblSize/2'总资料笔数
redim Int16BitPoint(LngVariable_K)
'/*定义阵列大小*/
LngVariable_I = 1
for LngVariable_I = 1 to LngVariable_K
get #2, LngVariable_I + 22, Int16BitPoint( _
LngVariable_I)'/*从45bytte开始取样*/
doevents
next
close #2

'#以下是绘图的部分#

picture1.scale(0,-32768)-(DblSize,32767)
'先定义画布座标 通常用物件Picture

picture1.Line (0,0)-(LngVariable_K,0), _
rgb(0, 0, 0) '画中线
for LngVariable_I = 1 to LngVariable_K - 1
picture1.line (LngVariable_I, -(Int16BitPoint( _
LngVariable_I) + 1))-(LngVariable_I + 1, -(Int16BitPoint( _
LngVariable_I + 1) + 1)), RGB(0, 0, 0)
next
$如果IntCost=8 通常是用以下程式码读取
并绘制图形
dim StrFileName as string '储存档名
dim DblSize as double '储存实际声档大小
dim Byt8BitPoint() as byte
dim LngVariable_K as long
dim LngVariable_I as long
StrFileName="C:\windows\media\ding.wav" _
'设定要读取的档案

'#以下部分是将实际声档资料读入阵列#
open StrfileName for random as #2 _
len = 1'每笔资料位元组数
DblSize = lof(2) - 44
'实际档案大小(Bytes) _
前44Bytes是档头*/

LngVariable_K = DblSize'总资料笔数
redim Byt8BitPoint(LngVariable_K)
'/*定义阵列大小*/
LngVariable_I = 1
for LngVariable_I = 1 to LngVariable_K
get #2, LngVariable_I + 44, Byt8BitPoint( _
LngVariable_I)'/*从45bytte开始取样*/
doevents
next
close #2

'#以下是绘图的部分#

picture1.scale(0,0)-(DblSize,255)
'先定义画布座标 通常用物件Picture

picture1.line (0,128)-(DblSize,128), _
rgb(0, 0, 0) '画中线
for LngVariable_I=1 to LngVariable_K-1
picture1.line(LngVariable_I,-(Byt8BitPoint( _
LngVariable_I)-255))-(LngVariable_I+1,-(Byt8BitPoint( _
LngVariable_I+1)-255)),rgb(0,0,0)
next

$表单中最少要放上一个Picture物件

$波形外的其他资讯可以从档头中读取

$当然在资料读取方面还有更快的方法
像记忆体映射档之类的东东
用Get读入阵列 执行效率很低
如果...对于这方面有所了解的话
拜托到"如何更快速读取资料"的
讨论区提供点资料喔 thanks
: 　　像播放mp3的WinampC中的音波分析器，录音程式中的声音波形
: ，到底是要用什么函数来描绘呢？
: 　　　　　　　　　　　　　　　　　恳请赐教，谢谢！

Follow Ups: