如何读取wav文件,并画成波形图
即画出wav 文件的频谱!!!!!!!!
35 个解决方案
#1
MMTools控件是不是能支持啊!
#2
先熟悉Wave文件格式,如Wave文件头格式、声音数据格式等
然后以时间作为横坐标,采样点作为纵坐标,然后画点连线。
可以参考《Programming Windows,Fifth Edition,Charles Petzold 》第22章 声音与音乐
需要注意的是Wave文件格式有很多种,可以在网上查找相关资料。
然后以时间作为横坐标,采样点作为纵坐标,然后画点连线。
可以参考《Programming Windows,Fifth Edition,Charles Petzold 》第22章 声音与音乐
需要注意的是Wave文件格式有很多种,可以在网上查找相关资料。
#3
gz
#4
wav文件是属于RIFF文件结构的。
RIFF文件结构和WAVE文件格式
Windows支持两种RIFF(Resource Interchange File Format,"资源交互文件格式")格式的音频文件:MIDI的RMID文件和波形音频文件格式WAVE文件,其中在计算机领域最常用的数字化声音文件格式是后者,它是微软专门为Windows系统定义的波形文件格式(Waveform Audio),由于其扩展名为"*.wav",因而该类文件也被称为WAVE文件。为了突出重点,有的放矢,本文涉及到的声音文件所指的就是WAVE文件。常见的WAVE语音文件主要有两种,分别对应于单声道(11.025KHz采样率、8Bit的采样值)和双声道(44.1KHz采样率、16Bit的采样值)。这里的采样率是指声音信号在进行"模→数"转换过程中单位时间内采样的次数。采样值是指每一次采样周期内声音模拟信号的积分值。对于单声道声音文件,采样数据为八位的短整数(short int 00H-FFH);而对于双声道立体声声音文件,每次采样数据为一个16位的整数(int),高八位和低八位分别代表左右两个声道。WAVE文件数据块包含以脉冲编码调制(PCM)格式表示的样本。在进行声音编程处理以前,首先让我们来了解一下RIFF文件和WAVE文件格式。
RIFF文件结构可以看作是树状结构,其基本构成是称为"块"(Chunk)的单元,每个块有"标志符"、"数据大小"及"数据"所组成,块的结构如图1所示:
块的标志符(4BYTES)
数据大小 (4BYTES)
数据
图一、 块的结构示意图
从上图可以看出,其中"标志符"为4个字符所组成的代码,如"RIFF","LIST"等,指定块的标志ID;数据大小用来指定块的数据域大小,它的尺寸也为4个字符;数据用来描述具体的声音信号,它可以由若干个子块构成,一般情况下块与块是平行的,不能相互嵌套,但是有两种类型的块可以嵌套子块,他们是"RIFF"或"LIST"标志的块,其中RIFF块的级别最高,它可以包括LIST块。另外,RIFF块和LIST块与其他块不同,RIFF块的数据总是以一个指定文件中数据存储格式的四个字符码(称为格式类型)开始,如WAVE文件有一个"WAVE"的格式类型。LIST块的数据总是以一个指定列表内容的4个字符码(称为列表类型)开始,例如扩展名为".AVI"的视频文件就有一个"strl"的列表类型。RIFF和LIST的块结构如下:
RIFF/LIST标志符
数据1大小
数据1 格式/列表类型
数据
图二、RIFF/LIST块结构
WAVE文件是非常简单的一种RIFF文件,它的格式类型为"WAVE"。RIFF块包含两个子块,这两个子块的ID分别是"fmt"和"data",其中"fmt"子块由结构PCMWAVEFORMAT所组成,其子块的大小就是sizeofof(PCMWAVEFORMAT),数据组成就是PCMWAVEFORMAT结构中的数据。WAVE文件的结构如下图三所示:
标志符(RIFF)
数据大小
格式类型("WAVE")
"fmt"
Sizeof(PCMWAVEFORMAT)
PCMWAVEFORMAT
"data"
声音数据大小
声音数据
图三、WAVE文件结构
PCMWAVEFORMAT结构定义如下:
Typedef struct
{
WAVEFORMAT wf;//波形格式;
WORD wBitsPerSample;//WAVE文件的采样大小;
}PCMWAVEFORMAT;
WAVEFORMAT结构定义如下:
typedef struct
{
WORD wFormatag;//编码格式,包括WAVE_FORMAT_PCM,WAVEFORMAT_ADPCM等
WORD nChannls;//声道数,单声道为1,双声道为2;
DWORD nSamplesPerSec;//采样频率;
DWORD nAvgBytesperSec;//每秒的数据量;
WORD nBlockAlign;//块对齐;
}WAVEFORMAT;
"data"子块包含WAVE文件的数字化波形声音数据,其存放格式依赖于"fmt"子块中wFormatTag成员指定的格式种类,在多声道WAVE文件中,样本是交替出现的。如16bit的单声道WAVE文件和双声道WAVE文件的数据采样格式分别如图四所示:
16位单声道:
采样一 采样二 ……
低字节 高字节 低字节 高字节 ……
16位双声道:
采样一 ……
左声道 右声道 ……
低字节 高字节 低字节 高字节 ……
图四、WAVE文件数据采样格式
RIFF文件结构和WAVE文件格式
Windows支持两种RIFF(Resource Interchange File Format,"资源交互文件格式")格式的音频文件:MIDI的RMID文件和波形音频文件格式WAVE文件,其中在计算机领域最常用的数字化声音文件格式是后者,它是微软专门为Windows系统定义的波形文件格式(Waveform Audio),由于其扩展名为"*.wav",因而该类文件也被称为WAVE文件。为了突出重点,有的放矢,本文涉及到的声音文件所指的就是WAVE文件。常见的WAVE语音文件主要有两种,分别对应于单声道(11.025KHz采样率、8Bit的采样值)和双声道(44.1KHz采样率、16Bit的采样值)。这里的采样率是指声音信号在进行"模→数"转换过程中单位时间内采样的次数。采样值是指每一次采样周期内声音模拟信号的积分值。对于单声道声音文件,采样数据为八位的短整数(short int 00H-FFH);而对于双声道立体声声音文件,每次采样数据为一个16位的整数(int),高八位和低八位分别代表左右两个声道。WAVE文件数据块包含以脉冲编码调制(PCM)格式表示的样本。在进行声音编程处理以前,首先让我们来了解一下RIFF文件和WAVE文件格式。
RIFF文件结构可以看作是树状结构,其基本构成是称为"块"(Chunk)的单元,每个块有"标志符"、"数据大小"及"数据"所组成,块的结构如图1所示:
块的标志符(4BYTES)
数据大小 (4BYTES)
数据
图一、 块的结构示意图
从上图可以看出,其中"标志符"为4个字符所组成的代码,如"RIFF","LIST"等,指定块的标志ID;数据大小用来指定块的数据域大小,它的尺寸也为4个字符;数据用来描述具体的声音信号,它可以由若干个子块构成,一般情况下块与块是平行的,不能相互嵌套,但是有两种类型的块可以嵌套子块,他们是"RIFF"或"LIST"标志的块,其中RIFF块的级别最高,它可以包括LIST块。另外,RIFF块和LIST块与其他块不同,RIFF块的数据总是以一个指定文件中数据存储格式的四个字符码(称为格式类型)开始,如WAVE文件有一个"WAVE"的格式类型。LIST块的数据总是以一个指定列表内容的4个字符码(称为列表类型)开始,例如扩展名为".AVI"的视频文件就有一个"strl"的列表类型。RIFF和LIST的块结构如下:
RIFF/LIST标志符
数据1大小
数据1 格式/列表类型
数据
图二、RIFF/LIST块结构
WAVE文件是非常简单的一种RIFF文件,它的格式类型为"WAVE"。RIFF块包含两个子块,这两个子块的ID分别是"fmt"和"data",其中"fmt"子块由结构PCMWAVEFORMAT所组成,其子块的大小就是sizeofof(PCMWAVEFORMAT),数据组成就是PCMWAVEFORMAT结构中的数据。WAVE文件的结构如下图三所示:
标志符(RIFF)
数据大小
格式类型("WAVE")
"fmt"
Sizeof(PCMWAVEFORMAT)
PCMWAVEFORMAT
"data"
声音数据大小
声音数据
图三、WAVE文件结构
PCMWAVEFORMAT结构定义如下:
Typedef struct
{
WAVEFORMAT wf;//波形格式;
WORD wBitsPerSample;//WAVE文件的采样大小;
}PCMWAVEFORMAT;
WAVEFORMAT结构定义如下:
typedef struct
{
WORD wFormatag;//编码格式,包括WAVE_FORMAT_PCM,WAVEFORMAT_ADPCM等
WORD nChannls;//声道数,单声道为1,双声道为2;
DWORD nSamplesPerSec;//采样频率;
DWORD nAvgBytesperSec;//每秒的数据量;
WORD nBlockAlign;//块对齐;
}WAVEFORMAT;
"data"子块包含WAVE文件的数字化波形声音数据,其存放格式依赖于"fmt"子块中wFormatTag成员指定的格式种类,在多声道WAVE文件中,样本是交替出现的。如16bit的单声道WAVE文件和双声道WAVE文件的数据采样格式分别如图四所示:
16位单声道:
采样一 采样二 ……
低字节 高字节 低字节 高字节 ……
16位双声道:
采样一 ……
左声道 右声道 ……
低字节 高字节 低字节 高字节 ……
图四、WAVE文件数据采样格式
#5
偶比较关心:谁有代码哈?
#6
我有点资料,显示系统声音的波形图,
如果你认为对你帮助留个email
wav的我也想知道,没有接触过
如果你认为对你帮助留个email
wav的我也想知道,没有接触过
#7
richarsun@163.com
如果是程序那就最好了。。呵呵。
如果是程序那就最好了。。呵呵。
#8
发了记得告诉我哦。。师兄。。。
#9
没有问题,等一下我就发给你,是代码来的,可惜不是读wav的
#10
我发了,你去收了
#11
想读WAV的文件
先知道RIFF的文件格式
然后用API的mmioOpen,mmioRead,mmioSeek,mmioWrite,等
函数来操作
有个例子你看一下 不过例子不全对里面有错误
BYTE * GetData(Cstring *pString)
//获取声音文件数据的函数,pString参数指向要打开的声音文件;
{
if (pString==NULL)
return NULL;
HMMIO file1;//定义HMMIO文件句柄;
file1=mmioOpen((LPSTR)pString,NULL,MMIO_READWRITE);//以读写模式打开所给的WAVE文件;
if(file1==NULL)
{
MessageBox("WAVE文件打开失败!");
Return NULL;
}
char style[4];//定义一个四字节的数据,用来存放文件的类型;
mmioSeek(file1,8,SEEK_SET);//定位到WAVE文件的类型位置
mmioRead(file1,style,4);
if(style[0]!=’W’||style[1]!=’A’||style[2]!=’V’||style[3]!=’E’)//判断该文件是否为"WAVE"文件格式
{
MessageBox("该文件不是WAVE格式的文件!");
Return NULL;
}
PCMWAVEFORMAT format; //定义PCMWAVEFORMAT结构对象,用来判断WAVE文件格式;
mmioSeek(file1,20,SEEK_SET);
//对打开的文件进行定位,此时指向WAVE文件的PCMWAVEFORMAT结构的数据;
mmioRead(file1,(char*)&format,sizeof(PCMWAVEFORMAT));//获取该结构的数据;
if(format.wf.nChannels!=2)//判断是否是立体声声音;
{
MessageBox("该声音文件不是双通道立体声文件");
return NULL;
}
mmioSeek(file1,24+sizeof(PCMWAVEFORMAT),SEEK_SET);
//获取WAVE文件的声音数据的大小;
long size;
mmioRead(file1,(char*)&size,4);
BYTE *pData;
pData=(BYTE*)new char[size];//根据数据的大小申请缓冲区;
mmioSeek(file1,28+sizeof(PCMWAVEFORMAT),SEEK_SET);//对文件重新定位;
mmioRead(file1,(char*)pData,size);//读取声音数据;
mmioClose(file1, MMIO_FHOPEN);//关闭WAVE文件;
return pData;
}
先知道RIFF的文件格式
然后用API的mmioOpen,mmioRead,mmioSeek,mmioWrite,等
函数来操作
有个例子你看一下 不过例子不全对里面有错误
BYTE * GetData(Cstring *pString)
//获取声音文件数据的函数,pString参数指向要打开的声音文件;
{
if (pString==NULL)
return NULL;
HMMIO file1;//定义HMMIO文件句柄;
file1=mmioOpen((LPSTR)pString,NULL,MMIO_READWRITE);//以读写模式打开所给的WAVE文件;
if(file1==NULL)
{
MessageBox("WAVE文件打开失败!");
Return NULL;
}
char style[4];//定义一个四字节的数据,用来存放文件的类型;
mmioSeek(file1,8,SEEK_SET);//定位到WAVE文件的类型位置
mmioRead(file1,style,4);
if(style[0]!=’W’||style[1]!=’A’||style[2]!=’V’||style[3]!=’E’)//判断该文件是否为"WAVE"文件格式
{
MessageBox("该文件不是WAVE格式的文件!");
Return NULL;
}
PCMWAVEFORMAT format; //定义PCMWAVEFORMAT结构对象,用来判断WAVE文件格式;
mmioSeek(file1,20,SEEK_SET);
//对打开的文件进行定位,此时指向WAVE文件的PCMWAVEFORMAT结构的数据;
mmioRead(file1,(char*)&format,sizeof(PCMWAVEFORMAT));//获取该结构的数据;
if(format.wf.nChannels!=2)//判断是否是立体声声音;
{
MessageBox("该声音文件不是双通道立体声文件");
return NULL;
}
mmioSeek(file1,24+sizeof(PCMWAVEFORMAT),SEEK_SET);
//获取WAVE文件的声音数据的大小;
long size;
mmioRead(file1,(char*)&size,4);
BYTE *pData;
pData=(BYTE*)new char[size];//根据数据的大小申请缓冲区;
mmioSeek(file1,28+sizeof(PCMWAVEFORMAT),SEEK_SET);//对文件重新定位;
mmioRead(file1,(char*)pData,size);//读取声音数据;
mmioClose(file1, MMIO_FHOPEN);//关闭WAVE文件;
return pData;
}
#12
支持
#13
回复人: constantine(飘遥的安吉儿)
我要。。
richarson_001@163.com
TO:红客robby。。我才是楼主。。-_-###
我要。。
richarson_001@163.com
TO:红客robby。。我才是楼主。。-_-###
#14
发了
#15
c++builder程序设计经典
这本书上有代码
这本书上有代码
#16
顶,顶。。。
#17
constantine(飘遥的安吉儿) :
给我也来一份
net205@126.com
给我也来一份
net205@126.com
#18
我也要一份!
yuruilei@21cn.com
yuruilei@21cn.com
#19
代码我就不再发了,那个不是wave的,下面我给大家贴个是的,并画出图来,不过是delphi的
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TPCMWaveHeader = record
rID: array[0..3] of char; // 'RIFF' 标志
rLen: longint; // 文件长度
wID: array[0..3] of char; // 'WAVE' 标志
fId: array[0..3] of char; // 'fmt '标志 以空格结束(fID[3]:=Chr($20);)
fLen: longint; // 过度字节(不定)
wFormatTag: word; // 格式字节(过度字节为PCM形式的声音数据)
nChannels: word; // 通道数 单声道=1, 双声道=2 }
nSamplesPerSec: longint; // 采样频率 (每秒样本数),表示每个通道的播放速度
nAvgBytesPerSec: longint; // 波形音频数据传送速度(值:通道数X每秒数据位数X每
// 样本的数据位数/8。播放软件利用根据此值估计缓
// 冲区的大小)
nBlockAlign: word; // 数据块的调整数(按字节计算),值为通道数*没样本的数据位值/8。
// 播放软件需要一次处理多个该值大小的字节数据,以便
// 将其值用于缓冲区的调整。
nBitsPerSample: word; // 每样本数据位数,表示每个声道中各个样本的数据位
// 数。如果有多个声道,对每个声道而言,样本大
// 小都一样 8 or 16
dId: array[0..3] of char; // 'data' 标志
dLen: longint; // 语音数据长度
end;
TForm1 = class(TForm)
Button2: TButton;
Memo1: TMemo;
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
filename: string;
pcm: TPCMWaveHeader;
Data: array[0..80 * 10240] of Byte;
procedure PrintPcm;
procedure PrintData;
public
{ Public declarations }
end;
var
Form1 : TForm1;
implementation
{$R *.DFM}
procedure TForm1.PrintPcm;
begin
// memo1.lines.add('FileName:' + Filename);
memo1.lines.add('RIFF:' + pcm.rID);
memo1.lines.add('RLEN:' + inttostr(pcm.rLen));
memo1.lines.add('WAVE:' + pcm.wID);
memo1.lines.add('fmt:' + pcm.fId);
memo1.lines.add('Fixed:' + inttostr(pcm.fLen));
memo1.lines.add('wFormatTag:' + inttostr(pcm.wFormatTag));
memo1.lines.add('nChannels:' + inttostr(pcm.nChannels));
memo1.lines.add('nSamplesPerSec:' + inttostr(pcm.nSamplesPerSec));
memo1.lines.add('nAvgBytesPerSec:' + inttostr(pcm.nAvgBytesPerSec));
memo1.lines.add('nBlockAlign:' + inttostr(pcm.nBlockAlign));
memo1.lines.add('nBitsPerSample:' + inttostr(pcm.nBitsPerSample));
memo1.lines.add('dLen:' + inttostr(pcm.dLen));
end;
procedure TForm1.Button2Click(Sender: TObject);
var
iFileHandle : Integer;
iFileLength : Integer;
iBytesRead : Integer;
Buffer : PChar;
//i, Size : Integer;
begin
iFileHandle := FileOpen(filename, fmOpenRead);
iFileLength := FileSeek(iFileHandle, 0, 2) - FileSeek(iFileHandle, 0, 0);
GetMem(Buffer, iFileLength + 1);
iBytesRead := FileRead(iFileHandle, Buffer^, iFileLength); //把文件读到buffer
FileClose(iFileHandle);
Move((Buffer)^, pcm, sizeof(pcm));
Move((Buffer)^, Data, pcm.dLen);
printpcm; //显示头信息
printData; //画波形图
FreeMem(Buffer);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
filename := 'C:\Windows XP 登录音.wav';
end;
procedure TForm1.PrintData;
var
i : Integer;
begin
for i := 0 to pcm.dLen - 1 do
begin
//memo1.lines.add(inttostr(Data[i]));
Canvas.LineTo(i, Data[i])
end;
end;
end.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TPCMWaveHeader = record
rID: array[0..3] of char; // 'RIFF' 标志
rLen: longint; // 文件长度
wID: array[0..3] of char; // 'WAVE' 标志
fId: array[0..3] of char; // 'fmt '标志 以空格结束(fID[3]:=Chr($20);)
fLen: longint; // 过度字节(不定)
wFormatTag: word; // 格式字节(过度字节为PCM形式的声音数据)
nChannels: word; // 通道数 单声道=1, 双声道=2 }
nSamplesPerSec: longint; // 采样频率 (每秒样本数),表示每个通道的播放速度
nAvgBytesPerSec: longint; // 波形音频数据传送速度(值:通道数X每秒数据位数X每
// 样本的数据位数/8。播放软件利用根据此值估计缓
// 冲区的大小)
nBlockAlign: word; // 数据块的调整数(按字节计算),值为通道数*没样本的数据位值/8。
// 播放软件需要一次处理多个该值大小的字节数据,以便
// 将其值用于缓冲区的调整。
nBitsPerSample: word; // 每样本数据位数,表示每个声道中各个样本的数据位
// 数。如果有多个声道,对每个声道而言,样本大
// 小都一样 8 or 16
dId: array[0..3] of char; // 'data' 标志
dLen: longint; // 语音数据长度
end;
TForm1 = class(TForm)
Button2: TButton;
Memo1: TMemo;
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
filename: string;
pcm: TPCMWaveHeader;
Data: array[0..80 * 10240] of Byte;
procedure PrintPcm;
procedure PrintData;
public
{ Public declarations }
end;
var
Form1 : TForm1;
implementation
{$R *.DFM}
procedure TForm1.PrintPcm;
begin
// memo1.lines.add('FileName:' + Filename);
memo1.lines.add('RIFF:' + pcm.rID);
memo1.lines.add('RLEN:' + inttostr(pcm.rLen));
memo1.lines.add('WAVE:' + pcm.wID);
memo1.lines.add('fmt:' + pcm.fId);
memo1.lines.add('Fixed:' + inttostr(pcm.fLen));
memo1.lines.add('wFormatTag:' + inttostr(pcm.wFormatTag));
memo1.lines.add('nChannels:' + inttostr(pcm.nChannels));
memo1.lines.add('nSamplesPerSec:' + inttostr(pcm.nSamplesPerSec));
memo1.lines.add('nAvgBytesPerSec:' + inttostr(pcm.nAvgBytesPerSec));
memo1.lines.add('nBlockAlign:' + inttostr(pcm.nBlockAlign));
memo1.lines.add('nBitsPerSample:' + inttostr(pcm.nBitsPerSample));
memo1.lines.add('dLen:' + inttostr(pcm.dLen));
end;
procedure TForm1.Button2Click(Sender: TObject);
var
iFileHandle : Integer;
iFileLength : Integer;
iBytesRead : Integer;
Buffer : PChar;
//i, Size : Integer;
begin
iFileHandle := FileOpen(filename, fmOpenRead);
iFileLength := FileSeek(iFileHandle, 0, 2) - FileSeek(iFileHandle, 0, 0);
GetMem(Buffer, iFileLength + 1);
iBytesRead := FileRead(iFileHandle, Buffer^, iFileLength); //把文件读到buffer
FileClose(iFileHandle);
Move((Buffer)^, pcm, sizeof(pcm));
Move((Buffer)^, Data, pcm.dLen);
printpcm; //显示头信息
printData; //画波形图
FreeMem(Buffer);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
filename := 'C:\Windows XP 登录音.wav';
end;
procedure TForm1.PrintData;
var
i : Integer;
begin
for i := 0 to pcm.dLen - 1 do
begin
//memo1.lines.add(inttostr(Data[i]));
Canvas.LineTo(i, Data[i])
end;
end;
end.
#20
只要在form上放一个button,一个memo,把他们的事件对应上就可以了
我在XP+bcb6 测试通过
我在XP+bcb6 测试通过
#21
如果满意记得提交FAQ,^_^
#22
回复人: constantine(飘遥的安吉儿) ( ) 信誉:101
只要在form上放一个button,一个memo,把他们的事件对应上就可以了
我在XP+bcb6 测试通过
//----------------
不是Delphi7中通过吗????
只要在form上放一个button,一个memo,把他们的事件对应上就可以了
我在XP+bcb6 测试通过
//----------------
不是Delphi7中通过吗????
#23
哈哈,在这里习惯了,
#24
还是我来贴代码吧
呵呵。。。。。。。。。。。。。
//---------------------------------------------------------------------------
#ifndef U14_4_2H
#define U14_4_2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <MPlayer.hpp>
//---------------------------------------------------------------------------
class Tf14_4_2 : public TForm
{
__published: // IDE-managed Components
TLabel *Label1;
TLabel *Label2;
TButton *btnEnd;
TButton *btnShowWave;
TScrollBar *Srb;
TEdit *Edit1;
TEdit *Edit2;
TMediaPlayer *MediaPlayer1;
void __fastcall FormCreate(TObject *Sender);
void __fastcall MediaPlayer1Click(TObject *Sender,
TMPBtnType Button, bool &DoDefault);
void __fastcall btnShowWaveClick(TObject *Sender);
void __fastcall SrbChange(TObject *Sender);
void __fastcall Edit1Change(TObject *Sender);
void __fastcall Edit2Change(TObject *Sender);
void __fastcall btnEndClick(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall Tf14_4_2(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE Tf14_4_2 *f14_4_2;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "U14_4_2.h"
#include <stdio.h>
#include<io.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
int FileLen,dx=0,dy=200,dd=44;
int divx,divy;
char* file_name="test.WAV";
short *data;
FILE *inf;
Tf14_4_2 *f14_4_2;
//---------------------------------------------------------------------------
__fastcall Tf14_4_2::Tf14_4_2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void show(void)
{
f14_4_2->Refresh();
f14_4_2->Canvas->TextOut(10,400,IntToStr(f14_4_2->Srb->Position) );
divx=StrToInt(f14_4_2->Edit1->Text);
divy=StrToInt(f14_4_2->Edit2->Text);
f14_4_2->Canvas->MoveTo(0+dx,-data[0]/divy+dy);
f14_4_2->Canvas->Pen->Color=clBlue;
for(int i=1;(i<f14_4_2->Width*divx)&&(i<(FileLen-dd)/2-1);i++)
f14_4_2->Canvas->LineTo(i/divx+dx,-data[i+f14_4_2->Srb->Position]/divy+dy);
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::FormCreate(TObject *Sender)
{
bool open_flag;
int handle;
if(open_flag==true)
{
fclose(inf);
}
inf=fopen(file_name,"r");
open_flag=true;
handle=fileno(inf);
FileLen= filelength(handle);
if(feof(inf))
{
fclose(inf);
open_flag=false;
}
data = new short[(FileLen-dd)/2];
fseek(inf,dd,SEEK_SET);
fread(data,sizeof(short),(FileLen-dd)/2,inf);
MediaPlayer1->VisibleButtons=Mplayer::TButtonSet()<<btPlay<<btStop<<btPause;
MediaPlayer1->DeviceType=dtWaveAudio;
MediaPlayer1->FileName=file_name;
MediaPlayer1->Display=f14_4_2;
MediaPlayer1->Open();
if((FileLen-dd)-f14_4_2->Width*divx<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::MediaPlayer1Click(TObject *Sender,
TMPBtnType Button, bool &DoDefault)
{
if(!MediaPlayer1->AutoOpen)
MediaPlayer1->Play();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::btnShowWaveClick(TObject *Sender)
{
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::SrbChange(TObject *Sender)
{
if(((FileLen-dd)/2-f14_4_2->Width*divx)<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::Edit1Change(TObject *Sender)
{
if(((FileLen-dd)/2-f14_4_2->Width*divx)<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
f14_4_2->Srb->Position=0;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::Edit2Change(TObject *Sender)
{
f14_4_2->Srb->Position=0;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::btnEndClick(TObject *Sender)
{
delete data;
fclose(inf);
Close();
}
//---------------------------------------------------------------------------
呵呵。。。。。。。。。。。。。
//---------------------------------------------------------------------------
#ifndef U14_4_2H
#define U14_4_2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <MPlayer.hpp>
//---------------------------------------------------------------------------
class Tf14_4_2 : public TForm
{
__published: // IDE-managed Components
TLabel *Label1;
TLabel *Label2;
TButton *btnEnd;
TButton *btnShowWave;
TScrollBar *Srb;
TEdit *Edit1;
TEdit *Edit2;
TMediaPlayer *MediaPlayer1;
void __fastcall FormCreate(TObject *Sender);
void __fastcall MediaPlayer1Click(TObject *Sender,
TMPBtnType Button, bool &DoDefault);
void __fastcall btnShowWaveClick(TObject *Sender);
void __fastcall SrbChange(TObject *Sender);
void __fastcall Edit1Change(TObject *Sender);
void __fastcall Edit2Change(TObject *Sender);
void __fastcall btnEndClick(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall Tf14_4_2(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE Tf14_4_2 *f14_4_2;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "U14_4_2.h"
#include <stdio.h>
#include<io.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
int FileLen,dx=0,dy=200,dd=44;
int divx,divy;
char* file_name="test.WAV";
short *data;
FILE *inf;
Tf14_4_2 *f14_4_2;
//---------------------------------------------------------------------------
__fastcall Tf14_4_2::Tf14_4_2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void show(void)
{
f14_4_2->Refresh();
f14_4_2->Canvas->TextOut(10,400,IntToStr(f14_4_2->Srb->Position) );
divx=StrToInt(f14_4_2->Edit1->Text);
divy=StrToInt(f14_4_2->Edit2->Text);
f14_4_2->Canvas->MoveTo(0+dx,-data[0]/divy+dy);
f14_4_2->Canvas->Pen->Color=clBlue;
for(int i=1;(i<f14_4_2->Width*divx)&&(i<(FileLen-dd)/2-1);i++)
f14_4_2->Canvas->LineTo(i/divx+dx,-data[i+f14_4_2->Srb->Position]/divy+dy);
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::FormCreate(TObject *Sender)
{
bool open_flag;
int handle;
if(open_flag==true)
{
fclose(inf);
}
inf=fopen(file_name,"r");
open_flag=true;
handle=fileno(inf);
FileLen= filelength(handle);
if(feof(inf))
{
fclose(inf);
open_flag=false;
}
data = new short[(FileLen-dd)/2];
fseek(inf,dd,SEEK_SET);
fread(data,sizeof(short),(FileLen-dd)/2,inf);
MediaPlayer1->VisibleButtons=Mplayer::TButtonSet()<<btPlay<<btStop<<btPause;
MediaPlayer1->DeviceType=dtWaveAudio;
MediaPlayer1->FileName=file_name;
MediaPlayer1->Display=f14_4_2;
MediaPlayer1->Open();
if((FileLen-dd)-f14_4_2->Width*divx<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::MediaPlayer1Click(TObject *Sender,
TMPBtnType Button, bool &DoDefault)
{
if(!MediaPlayer1->AutoOpen)
MediaPlayer1->Play();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::btnShowWaveClick(TObject *Sender)
{
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::SrbChange(TObject *Sender)
{
if(((FileLen-dd)/2-f14_4_2->Width*divx)<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::Edit1Change(TObject *Sender)
{
if(((FileLen-dd)/2-f14_4_2->Width*divx)<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
f14_4_2->Srb->Position=0;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::Edit2Change(TObject *Sender)
{
f14_4_2->Srb->Position=0;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::btnEndClick(TObject *Sender)
{
delete data;
fclose(inf);
Close();
}
//---------------------------------------------------------------------------
#25
记得揭帖啊。。。。。。。
我在XP+BCB6下编译通过
我在XP+BCB6下编译通过
#26
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if(OpenDialog1->Execute())
mFileName=OpenDialog1->FileName;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TPCMWaveHeader pcm;
int iFileHandle,iFileLength,iBytesRead;
iFileHandle = FileOpen(mFileName, fmOpenRead);
iFileLength = FileSeek(iFileHandle, 0, 2) - FileSeek(iFileHandle, 0, 0);
Buffer = new char[iFileLength + 1];
FileRead(iFileHandle, Buffer, iFileLength); //把文件读到buffer
FileClose(iFileHandle);
Move(Buffer, &pcm, sizeof(pcm)); //copy buffer to pcm
Data = new BYTE[pcm.dLen];
setmem(Data, pcm.dLen, 0);
Move(Buffer, Data, pcm.dLen);
//显示头信息
Memo1->Lines->Clear();
Memo1->Lines->Add("FileName:" + mFileName);
Memo1->Lines->Add("RIFF:"+AnsiString(pcm.rID));
Memo1->Lines->Add("RLEN:"+IntToStr(pcm.rLen));
Memo1->Lines->Add("WAVE:"+AnsiString(pcm.wID));
Memo1->Lines->Add("fmt:"+AnsiString(pcm.fID));
Memo1->Lines->Add("Fixed:" + IntToStr(pcm.fLen));
Memo1->Lines->Add("wFormatTag:" + IntToStr(pcm.wFormatTag));
Memo1->Lines->Add("nChannels:" + IntToStr(pcm.nChannels));
Memo1->Lines->Add("nSamplesPerSec:" + IntToStr(pcm.nSamplesPerSec));
Memo1->Lines->Add("nAvgBytesPerSec:" + IntToStr(pcm.nAvgBytesPerSec));
Memo1->Lines->Add("nBlockAlign:" + IntToStr(pcm.nBlockAlign));
Memo1->Lines->Add("nBitsPerSample:" + IntToStr(pcm.nBitsPerSample));
Memo1->Lines->Add("dLen:" + IntToStr(pcm.dLen));
PaintBox1->Canvas->FillRect(PaintBox1->ClientRect);
for (int i=0;i<pcm.dLen;i++)
{
PaintBox1->Canvas->MoveTo(i,128);
PaintBox1->Canvas->LineTo(i, 256-Data[i]);
}
//画波形图
delete[] Buffer;
delete[] Data;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if(NULL==Buffer)
{
delete[] Buffer;
Buffer=NULL;
}
if(NULL==Data)
{
delete[] Data;
Data=NULL;
}
}
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if(OpenDialog1->Execute())
mFileName=OpenDialog1->FileName;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TPCMWaveHeader pcm;
int iFileHandle,iFileLength,iBytesRead;
iFileHandle = FileOpen(mFileName, fmOpenRead);
iFileLength = FileSeek(iFileHandle, 0, 2) - FileSeek(iFileHandle, 0, 0);
Buffer = new char[iFileLength + 1];
FileRead(iFileHandle, Buffer, iFileLength); //把文件读到buffer
FileClose(iFileHandle);
Move(Buffer, &pcm, sizeof(pcm)); //copy buffer to pcm
Data = new BYTE[pcm.dLen];
setmem(Data, pcm.dLen, 0);
Move(Buffer, Data, pcm.dLen);
//显示头信息
Memo1->Lines->Clear();
Memo1->Lines->Add("FileName:" + mFileName);
Memo1->Lines->Add("RIFF:"+AnsiString(pcm.rID));
Memo1->Lines->Add("RLEN:"+IntToStr(pcm.rLen));
Memo1->Lines->Add("WAVE:"+AnsiString(pcm.wID));
Memo1->Lines->Add("fmt:"+AnsiString(pcm.fID));
Memo1->Lines->Add("Fixed:" + IntToStr(pcm.fLen));
Memo1->Lines->Add("wFormatTag:" + IntToStr(pcm.wFormatTag));
Memo1->Lines->Add("nChannels:" + IntToStr(pcm.nChannels));
Memo1->Lines->Add("nSamplesPerSec:" + IntToStr(pcm.nSamplesPerSec));
Memo1->Lines->Add("nAvgBytesPerSec:" + IntToStr(pcm.nAvgBytesPerSec));
Memo1->Lines->Add("nBlockAlign:" + IntToStr(pcm.nBlockAlign));
Memo1->Lines->Add("nBitsPerSample:" + IntToStr(pcm.nBitsPerSample));
Memo1->Lines->Add("dLen:" + IntToStr(pcm.dLen));
PaintBox1->Canvas->FillRect(PaintBox1->ClientRect);
for (int i=0;i<pcm.dLen;i++)
{
PaintBox1->Canvas->MoveTo(i,128);
PaintBox1->Canvas->LineTo(i, 256-Data[i]);
}
//画波形图
delete[] Buffer;
delete[] Data;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if(NULL==Buffer)
{
delete[] Buffer;
Buffer=NULL;
}
if(NULL==Data)
{
delete[] Data;
Data=NULL;
}
}
//---------------------------------------------------------------------------
#27
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
struct TPCMWaveHeader{
// 'RIFF' 标志
char rID[4];
// 文件长度
long int rLen;
// 'WAVE' 标志
char wID[4];
// 'fmt '标志 以空格结束(fID[3]:=Chr($20);)
char fID[4];
// 过度字节(不定)
long int fLen;
// 格式字节(过度字节为PCM形式的声音数据)
WORD wFormatTag;
// 通道数 单声道=1, 双声道=2 }
WORD nChannels;
// 采样频率 (每秒样本数),表示每个通道的播放速度
long int nSamplesPerSec;
// 波形音频数据传送速度(值:通道数X每秒数据位数X每
// 样本的数据位数/8。播放软件利用根据此值估计缓
// 冲区的大小)
long int nAvgBytesPerSec;
// 数据块的调整数(按字节计算),值为通道数*没样本的数据位值/8。
// 播放软件需要一次处理多个该值大小的字节数据,以便
// 将其值用于缓冲区的调整。
WORD nBlockAlign;
// 每样本数据位数,表示每个声道中各个样本的数据位
// 数。如果有多个声道,对每个声道而言,样本大
// 小都一样 8 or 16
WORD nBitsPerSample;
// 'data' 标志
char dId[4];
// 语音数据长度
long int dLen;
} ;
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TPaintBox *PaintBox1;
TMemo *Memo1;
TButton *Button2;
TButton *Button3;
TOpenDialog *OpenDialog1;
void __fastcall Button2Click(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button3Click(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
private: // User declarations
AnsiString mFileName;
char *Buffer;
BYTE *Data;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
我改成了BCB的,去掉了一些BUG,不过代码还不是很完善,大家自己改
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
struct TPCMWaveHeader{
// 'RIFF' 标志
char rID[4];
// 文件长度
long int rLen;
// 'WAVE' 标志
char wID[4];
// 'fmt '标志 以空格结束(fID[3]:=Chr($20);)
char fID[4];
// 过度字节(不定)
long int fLen;
// 格式字节(过度字节为PCM形式的声音数据)
WORD wFormatTag;
// 通道数 单声道=1, 双声道=2 }
WORD nChannels;
// 采样频率 (每秒样本数),表示每个通道的播放速度
long int nSamplesPerSec;
// 波形音频数据传送速度(值:通道数X每秒数据位数X每
// 样本的数据位数/8。播放软件利用根据此值估计缓
// 冲区的大小)
long int nAvgBytesPerSec;
// 数据块的调整数(按字节计算),值为通道数*没样本的数据位值/8。
// 播放软件需要一次处理多个该值大小的字节数据,以便
// 将其值用于缓冲区的调整。
WORD nBlockAlign;
// 每样本数据位数,表示每个声道中各个样本的数据位
// 数。如果有多个声道,对每个声道而言,样本大
// 小都一样 8 or 16
WORD nBitsPerSample;
// 'data' 标志
char dId[4];
// 语音数据长度
long int dLen;
} ;
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TPaintBox *PaintBox1;
TMemo *Memo1;
TButton *Button2;
TButton *Button3;
TOpenDialog *OpenDialog1;
void __fastcall Button2Click(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button3Click(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
private: // User declarations
AnsiString mFileName;
char *Buffer;
BYTE *Data;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
我改成了BCB的,去掉了一些BUG,不过代码还不是很完善,大家自己改
#28
这次真的是在XP+BCB6 测试通过,
robbyzi(红客robby)的2003 系统也试过,没有问题
目前没有试过不可以的wav,
就算Form画不下全部,大家可以参考 flowercity(小唐"菜") 的方法
robbyzi(红客robby)的2003 系统也试过,没有问题
目前没有试过不可以的wav,
就算Form画不下全部,大家可以参考 flowercity(小唐"菜") 的方法
#29
好贴,,收藏。。
#30
to robbyzi(红客robby) :
我的代码明显有两个地方写错,你也不告诉我,
if(NULL==Buffer)两个都要!=,我都写成==,低级错误,汗...
我的代码明显有两个地方写错,你也不告诉我,
if(NULL==Buffer)两个都要!=,我都写成==,低级错误,汗...
#31
好东西收藏。另外那位兄弟有在内存放音的代码呢?共享一下!
#32
好帖子,赶快收藏!
#33
安吉儿师兄。。。
我当时也只是在测一下哪些wav文件哪些文件不行,都没有去细看里面的代码。
我当时也只是在测一下哪些wav文件哪些文件不行,都没有去细看里面的代码。
#34
这样画出的图形的意义是什么呢?
#35
关注
#1
MMTools控件是不是能支持啊!
#2
先熟悉Wave文件格式,如Wave文件头格式、声音数据格式等
然后以时间作为横坐标,采样点作为纵坐标,然后画点连线。
可以参考《Programming Windows,Fifth Edition,Charles Petzold 》第22章 声音与音乐
需要注意的是Wave文件格式有很多种,可以在网上查找相关资料。
然后以时间作为横坐标,采样点作为纵坐标,然后画点连线。
可以参考《Programming Windows,Fifth Edition,Charles Petzold 》第22章 声音与音乐
需要注意的是Wave文件格式有很多种,可以在网上查找相关资料。
#3
gz
#4
wav文件是属于RIFF文件结构的。
RIFF文件结构和WAVE文件格式
Windows支持两种RIFF(Resource Interchange File Format,"资源交互文件格式")格式的音频文件:MIDI的RMID文件和波形音频文件格式WAVE文件,其中在计算机领域最常用的数字化声音文件格式是后者,它是微软专门为Windows系统定义的波形文件格式(Waveform Audio),由于其扩展名为"*.wav",因而该类文件也被称为WAVE文件。为了突出重点,有的放矢,本文涉及到的声音文件所指的就是WAVE文件。常见的WAVE语音文件主要有两种,分别对应于单声道(11.025KHz采样率、8Bit的采样值)和双声道(44.1KHz采样率、16Bit的采样值)。这里的采样率是指声音信号在进行"模→数"转换过程中单位时间内采样的次数。采样值是指每一次采样周期内声音模拟信号的积分值。对于单声道声音文件,采样数据为八位的短整数(short int 00H-FFH);而对于双声道立体声声音文件,每次采样数据为一个16位的整数(int),高八位和低八位分别代表左右两个声道。WAVE文件数据块包含以脉冲编码调制(PCM)格式表示的样本。在进行声音编程处理以前,首先让我们来了解一下RIFF文件和WAVE文件格式。
RIFF文件结构可以看作是树状结构,其基本构成是称为"块"(Chunk)的单元,每个块有"标志符"、"数据大小"及"数据"所组成,块的结构如图1所示:
块的标志符(4BYTES)
数据大小 (4BYTES)
数据
图一、 块的结构示意图
从上图可以看出,其中"标志符"为4个字符所组成的代码,如"RIFF","LIST"等,指定块的标志ID;数据大小用来指定块的数据域大小,它的尺寸也为4个字符;数据用来描述具体的声音信号,它可以由若干个子块构成,一般情况下块与块是平行的,不能相互嵌套,但是有两种类型的块可以嵌套子块,他们是"RIFF"或"LIST"标志的块,其中RIFF块的级别最高,它可以包括LIST块。另外,RIFF块和LIST块与其他块不同,RIFF块的数据总是以一个指定文件中数据存储格式的四个字符码(称为格式类型)开始,如WAVE文件有一个"WAVE"的格式类型。LIST块的数据总是以一个指定列表内容的4个字符码(称为列表类型)开始,例如扩展名为".AVI"的视频文件就有一个"strl"的列表类型。RIFF和LIST的块结构如下:
RIFF/LIST标志符
数据1大小
数据1 格式/列表类型
数据
图二、RIFF/LIST块结构
WAVE文件是非常简单的一种RIFF文件,它的格式类型为"WAVE"。RIFF块包含两个子块,这两个子块的ID分别是"fmt"和"data",其中"fmt"子块由结构PCMWAVEFORMAT所组成,其子块的大小就是sizeofof(PCMWAVEFORMAT),数据组成就是PCMWAVEFORMAT结构中的数据。WAVE文件的结构如下图三所示:
标志符(RIFF)
数据大小
格式类型("WAVE")
"fmt"
Sizeof(PCMWAVEFORMAT)
PCMWAVEFORMAT
"data"
声音数据大小
声音数据
图三、WAVE文件结构
PCMWAVEFORMAT结构定义如下:
Typedef struct
{
WAVEFORMAT wf;//波形格式;
WORD wBitsPerSample;//WAVE文件的采样大小;
}PCMWAVEFORMAT;
WAVEFORMAT结构定义如下:
typedef struct
{
WORD wFormatag;//编码格式,包括WAVE_FORMAT_PCM,WAVEFORMAT_ADPCM等
WORD nChannls;//声道数,单声道为1,双声道为2;
DWORD nSamplesPerSec;//采样频率;
DWORD nAvgBytesperSec;//每秒的数据量;
WORD nBlockAlign;//块对齐;
}WAVEFORMAT;
"data"子块包含WAVE文件的数字化波形声音数据,其存放格式依赖于"fmt"子块中wFormatTag成员指定的格式种类,在多声道WAVE文件中,样本是交替出现的。如16bit的单声道WAVE文件和双声道WAVE文件的数据采样格式分别如图四所示:
16位单声道:
采样一 采样二 ……
低字节 高字节 低字节 高字节 ……
16位双声道:
采样一 ……
左声道 右声道 ……
低字节 高字节 低字节 高字节 ……
图四、WAVE文件数据采样格式
RIFF文件结构和WAVE文件格式
Windows支持两种RIFF(Resource Interchange File Format,"资源交互文件格式")格式的音频文件:MIDI的RMID文件和波形音频文件格式WAVE文件,其中在计算机领域最常用的数字化声音文件格式是后者,它是微软专门为Windows系统定义的波形文件格式(Waveform Audio),由于其扩展名为"*.wav",因而该类文件也被称为WAVE文件。为了突出重点,有的放矢,本文涉及到的声音文件所指的就是WAVE文件。常见的WAVE语音文件主要有两种,分别对应于单声道(11.025KHz采样率、8Bit的采样值)和双声道(44.1KHz采样率、16Bit的采样值)。这里的采样率是指声音信号在进行"模→数"转换过程中单位时间内采样的次数。采样值是指每一次采样周期内声音模拟信号的积分值。对于单声道声音文件,采样数据为八位的短整数(short int 00H-FFH);而对于双声道立体声声音文件,每次采样数据为一个16位的整数(int),高八位和低八位分别代表左右两个声道。WAVE文件数据块包含以脉冲编码调制(PCM)格式表示的样本。在进行声音编程处理以前,首先让我们来了解一下RIFF文件和WAVE文件格式。
RIFF文件结构可以看作是树状结构,其基本构成是称为"块"(Chunk)的单元,每个块有"标志符"、"数据大小"及"数据"所组成,块的结构如图1所示:
块的标志符(4BYTES)
数据大小 (4BYTES)
数据
图一、 块的结构示意图
从上图可以看出,其中"标志符"为4个字符所组成的代码,如"RIFF","LIST"等,指定块的标志ID;数据大小用来指定块的数据域大小,它的尺寸也为4个字符;数据用来描述具体的声音信号,它可以由若干个子块构成,一般情况下块与块是平行的,不能相互嵌套,但是有两种类型的块可以嵌套子块,他们是"RIFF"或"LIST"标志的块,其中RIFF块的级别最高,它可以包括LIST块。另外,RIFF块和LIST块与其他块不同,RIFF块的数据总是以一个指定文件中数据存储格式的四个字符码(称为格式类型)开始,如WAVE文件有一个"WAVE"的格式类型。LIST块的数据总是以一个指定列表内容的4个字符码(称为列表类型)开始,例如扩展名为".AVI"的视频文件就有一个"strl"的列表类型。RIFF和LIST的块结构如下:
RIFF/LIST标志符
数据1大小
数据1 格式/列表类型
数据
图二、RIFF/LIST块结构
WAVE文件是非常简单的一种RIFF文件,它的格式类型为"WAVE"。RIFF块包含两个子块,这两个子块的ID分别是"fmt"和"data",其中"fmt"子块由结构PCMWAVEFORMAT所组成,其子块的大小就是sizeofof(PCMWAVEFORMAT),数据组成就是PCMWAVEFORMAT结构中的数据。WAVE文件的结构如下图三所示:
标志符(RIFF)
数据大小
格式类型("WAVE")
"fmt"
Sizeof(PCMWAVEFORMAT)
PCMWAVEFORMAT
"data"
声音数据大小
声音数据
图三、WAVE文件结构
PCMWAVEFORMAT结构定义如下:
Typedef struct
{
WAVEFORMAT wf;//波形格式;
WORD wBitsPerSample;//WAVE文件的采样大小;
}PCMWAVEFORMAT;
WAVEFORMAT结构定义如下:
typedef struct
{
WORD wFormatag;//编码格式,包括WAVE_FORMAT_PCM,WAVEFORMAT_ADPCM等
WORD nChannls;//声道数,单声道为1,双声道为2;
DWORD nSamplesPerSec;//采样频率;
DWORD nAvgBytesperSec;//每秒的数据量;
WORD nBlockAlign;//块对齐;
}WAVEFORMAT;
"data"子块包含WAVE文件的数字化波形声音数据,其存放格式依赖于"fmt"子块中wFormatTag成员指定的格式种类,在多声道WAVE文件中,样本是交替出现的。如16bit的单声道WAVE文件和双声道WAVE文件的数据采样格式分别如图四所示:
16位单声道:
采样一 采样二 ……
低字节 高字节 低字节 高字节 ……
16位双声道:
采样一 ……
左声道 右声道 ……
低字节 高字节 低字节 高字节 ……
图四、WAVE文件数据采样格式
#5
偶比较关心:谁有代码哈?
#6
我有点资料,显示系统声音的波形图,
如果你认为对你帮助留个email
wav的我也想知道,没有接触过
如果你认为对你帮助留个email
wav的我也想知道,没有接触过
#7
richarsun@163.com
如果是程序那就最好了。。呵呵。
如果是程序那就最好了。。呵呵。
#8
发了记得告诉我哦。。师兄。。。
#9
没有问题,等一下我就发给你,是代码来的,可惜不是读wav的
#10
我发了,你去收了
#11
想读WAV的文件
先知道RIFF的文件格式
然后用API的mmioOpen,mmioRead,mmioSeek,mmioWrite,等
函数来操作
有个例子你看一下 不过例子不全对里面有错误
BYTE * GetData(Cstring *pString)
//获取声音文件数据的函数,pString参数指向要打开的声音文件;
{
if (pString==NULL)
return NULL;
HMMIO file1;//定义HMMIO文件句柄;
file1=mmioOpen((LPSTR)pString,NULL,MMIO_READWRITE);//以读写模式打开所给的WAVE文件;
if(file1==NULL)
{
MessageBox("WAVE文件打开失败!");
Return NULL;
}
char style[4];//定义一个四字节的数据,用来存放文件的类型;
mmioSeek(file1,8,SEEK_SET);//定位到WAVE文件的类型位置
mmioRead(file1,style,4);
if(style[0]!=’W’||style[1]!=’A’||style[2]!=’V’||style[3]!=’E’)//判断该文件是否为"WAVE"文件格式
{
MessageBox("该文件不是WAVE格式的文件!");
Return NULL;
}
PCMWAVEFORMAT format; //定义PCMWAVEFORMAT结构对象,用来判断WAVE文件格式;
mmioSeek(file1,20,SEEK_SET);
//对打开的文件进行定位,此时指向WAVE文件的PCMWAVEFORMAT结构的数据;
mmioRead(file1,(char*)&format,sizeof(PCMWAVEFORMAT));//获取该结构的数据;
if(format.wf.nChannels!=2)//判断是否是立体声声音;
{
MessageBox("该声音文件不是双通道立体声文件");
return NULL;
}
mmioSeek(file1,24+sizeof(PCMWAVEFORMAT),SEEK_SET);
//获取WAVE文件的声音数据的大小;
long size;
mmioRead(file1,(char*)&size,4);
BYTE *pData;
pData=(BYTE*)new char[size];//根据数据的大小申请缓冲区;
mmioSeek(file1,28+sizeof(PCMWAVEFORMAT),SEEK_SET);//对文件重新定位;
mmioRead(file1,(char*)pData,size);//读取声音数据;
mmioClose(file1, MMIO_FHOPEN);//关闭WAVE文件;
return pData;
}
先知道RIFF的文件格式
然后用API的mmioOpen,mmioRead,mmioSeek,mmioWrite,等
函数来操作
有个例子你看一下 不过例子不全对里面有错误
BYTE * GetData(Cstring *pString)
//获取声音文件数据的函数,pString参数指向要打开的声音文件;
{
if (pString==NULL)
return NULL;
HMMIO file1;//定义HMMIO文件句柄;
file1=mmioOpen((LPSTR)pString,NULL,MMIO_READWRITE);//以读写模式打开所给的WAVE文件;
if(file1==NULL)
{
MessageBox("WAVE文件打开失败!");
Return NULL;
}
char style[4];//定义一个四字节的数据,用来存放文件的类型;
mmioSeek(file1,8,SEEK_SET);//定位到WAVE文件的类型位置
mmioRead(file1,style,4);
if(style[0]!=’W’||style[1]!=’A’||style[2]!=’V’||style[3]!=’E’)//判断该文件是否为"WAVE"文件格式
{
MessageBox("该文件不是WAVE格式的文件!");
Return NULL;
}
PCMWAVEFORMAT format; //定义PCMWAVEFORMAT结构对象,用来判断WAVE文件格式;
mmioSeek(file1,20,SEEK_SET);
//对打开的文件进行定位,此时指向WAVE文件的PCMWAVEFORMAT结构的数据;
mmioRead(file1,(char*)&format,sizeof(PCMWAVEFORMAT));//获取该结构的数据;
if(format.wf.nChannels!=2)//判断是否是立体声声音;
{
MessageBox("该声音文件不是双通道立体声文件");
return NULL;
}
mmioSeek(file1,24+sizeof(PCMWAVEFORMAT),SEEK_SET);
//获取WAVE文件的声音数据的大小;
long size;
mmioRead(file1,(char*)&size,4);
BYTE *pData;
pData=(BYTE*)new char[size];//根据数据的大小申请缓冲区;
mmioSeek(file1,28+sizeof(PCMWAVEFORMAT),SEEK_SET);//对文件重新定位;
mmioRead(file1,(char*)pData,size);//读取声音数据;
mmioClose(file1, MMIO_FHOPEN);//关闭WAVE文件;
return pData;
}
#12
支持
#13
回复人: constantine(飘遥的安吉儿)
我要。。
richarson_001@163.com
TO:红客robby。。我才是楼主。。-_-###
我要。。
richarson_001@163.com
TO:红客robby。。我才是楼主。。-_-###
#14
发了
#15
c++builder程序设计经典
这本书上有代码
这本书上有代码
#16
顶,顶。。。
#17
constantine(飘遥的安吉儿) :
给我也来一份
net205@126.com
给我也来一份
net205@126.com
#18
我也要一份!
yuruilei@21cn.com
yuruilei@21cn.com
#19
代码我就不再发了,那个不是wave的,下面我给大家贴个是的,并画出图来,不过是delphi的
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TPCMWaveHeader = record
rID: array[0..3] of char; // 'RIFF' 标志
rLen: longint; // 文件长度
wID: array[0..3] of char; // 'WAVE' 标志
fId: array[0..3] of char; // 'fmt '标志 以空格结束(fID[3]:=Chr($20);)
fLen: longint; // 过度字节(不定)
wFormatTag: word; // 格式字节(过度字节为PCM形式的声音数据)
nChannels: word; // 通道数 单声道=1, 双声道=2 }
nSamplesPerSec: longint; // 采样频率 (每秒样本数),表示每个通道的播放速度
nAvgBytesPerSec: longint; // 波形音频数据传送速度(值:通道数X每秒数据位数X每
// 样本的数据位数/8。播放软件利用根据此值估计缓
// 冲区的大小)
nBlockAlign: word; // 数据块的调整数(按字节计算),值为通道数*没样本的数据位值/8。
// 播放软件需要一次处理多个该值大小的字节数据,以便
// 将其值用于缓冲区的调整。
nBitsPerSample: word; // 每样本数据位数,表示每个声道中各个样本的数据位
// 数。如果有多个声道,对每个声道而言,样本大
// 小都一样 8 or 16
dId: array[0..3] of char; // 'data' 标志
dLen: longint; // 语音数据长度
end;
TForm1 = class(TForm)
Button2: TButton;
Memo1: TMemo;
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
filename: string;
pcm: TPCMWaveHeader;
Data: array[0..80 * 10240] of Byte;
procedure PrintPcm;
procedure PrintData;
public
{ Public declarations }
end;
var
Form1 : TForm1;
implementation
{$R *.DFM}
procedure TForm1.PrintPcm;
begin
// memo1.lines.add('FileName:' + Filename);
memo1.lines.add('RIFF:' + pcm.rID);
memo1.lines.add('RLEN:' + inttostr(pcm.rLen));
memo1.lines.add('WAVE:' + pcm.wID);
memo1.lines.add('fmt:' + pcm.fId);
memo1.lines.add('Fixed:' + inttostr(pcm.fLen));
memo1.lines.add('wFormatTag:' + inttostr(pcm.wFormatTag));
memo1.lines.add('nChannels:' + inttostr(pcm.nChannels));
memo1.lines.add('nSamplesPerSec:' + inttostr(pcm.nSamplesPerSec));
memo1.lines.add('nAvgBytesPerSec:' + inttostr(pcm.nAvgBytesPerSec));
memo1.lines.add('nBlockAlign:' + inttostr(pcm.nBlockAlign));
memo1.lines.add('nBitsPerSample:' + inttostr(pcm.nBitsPerSample));
memo1.lines.add('dLen:' + inttostr(pcm.dLen));
end;
procedure TForm1.Button2Click(Sender: TObject);
var
iFileHandle : Integer;
iFileLength : Integer;
iBytesRead : Integer;
Buffer : PChar;
//i, Size : Integer;
begin
iFileHandle := FileOpen(filename, fmOpenRead);
iFileLength := FileSeek(iFileHandle, 0, 2) - FileSeek(iFileHandle, 0, 0);
GetMem(Buffer, iFileLength + 1);
iBytesRead := FileRead(iFileHandle, Buffer^, iFileLength); //把文件读到buffer
FileClose(iFileHandle);
Move((Buffer)^, pcm, sizeof(pcm));
Move((Buffer)^, Data, pcm.dLen);
printpcm; //显示头信息
printData; //画波形图
FreeMem(Buffer);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
filename := 'C:\Windows XP 登录音.wav';
end;
procedure TForm1.PrintData;
var
i : Integer;
begin
for i := 0 to pcm.dLen - 1 do
begin
//memo1.lines.add(inttostr(Data[i]));
Canvas.LineTo(i, Data[i])
end;
end;
end.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls;
type
TPCMWaveHeader = record
rID: array[0..3] of char; // 'RIFF' 标志
rLen: longint; // 文件长度
wID: array[0..3] of char; // 'WAVE' 标志
fId: array[0..3] of char; // 'fmt '标志 以空格结束(fID[3]:=Chr($20);)
fLen: longint; // 过度字节(不定)
wFormatTag: word; // 格式字节(过度字节为PCM形式的声音数据)
nChannels: word; // 通道数 单声道=1, 双声道=2 }
nSamplesPerSec: longint; // 采样频率 (每秒样本数),表示每个通道的播放速度
nAvgBytesPerSec: longint; // 波形音频数据传送速度(值:通道数X每秒数据位数X每
// 样本的数据位数/8。播放软件利用根据此值估计缓
// 冲区的大小)
nBlockAlign: word; // 数据块的调整数(按字节计算),值为通道数*没样本的数据位值/8。
// 播放软件需要一次处理多个该值大小的字节数据,以便
// 将其值用于缓冲区的调整。
nBitsPerSample: word; // 每样本数据位数,表示每个声道中各个样本的数据位
// 数。如果有多个声道,对每个声道而言,样本大
// 小都一样 8 or 16
dId: array[0..3] of char; // 'data' 标志
dLen: longint; // 语音数据长度
end;
TForm1 = class(TForm)
Button2: TButton;
Memo1: TMemo;
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
filename: string;
pcm: TPCMWaveHeader;
Data: array[0..80 * 10240] of Byte;
procedure PrintPcm;
procedure PrintData;
public
{ Public declarations }
end;
var
Form1 : TForm1;
implementation
{$R *.DFM}
procedure TForm1.PrintPcm;
begin
// memo1.lines.add('FileName:' + Filename);
memo1.lines.add('RIFF:' + pcm.rID);
memo1.lines.add('RLEN:' + inttostr(pcm.rLen));
memo1.lines.add('WAVE:' + pcm.wID);
memo1.lines.add('fmt:' + pcm.fId);
memo1.lines.add('Fixed:' + inttostr(pcm.fLen));
memo1.lines.add('wFormatTag:' + inttostr(pcm.wFormatTag));
memo1.lines.add('nChannels:' + inttostr(pcm.nChannels));
memo1.lines.add('nSamplesPerSec:' + inttostr(pcm.nSamplesPerSec));
memo1.lines.add('nAvgBytesPerSec:' + inttostr(pcm.nAvgBytesPerSec));
memo1.lines.add('nBlockAlign:' + inttostr(pcm.nBlockAlign));
memo1.lines.add('nBitsPerSample:' + inttostr(pcm.nBitsPerSample));
memo1.lines.add('dLen:' + inttostr(pcm.dLen));
end;
procedure TForm1.Button2Click(Sender: TObject);
var
iFileHandle : Integer;
iFileLength : Integer;
iBytesRead : Integer;
Buffer : PChar;
//i, Size : Integer;
begin
iFileHandle := FileOpen(filename, fmOpenRead);
iFileLength := FileSeek(iFileHandle, 0, 2) - FileSeek(iFileHandle, 0, 0);
GetMem(Buffer, iFileLength + 1);
iBytesRead := FileRead(iFileHandle, Buffer^, iFileLength); //把文件读到buffer
FileClose(iFileHandle);
Move((Buffer)^, pcm, sizeof(pcm));
Move((Buffer)^, Data, pcm.dLen);
printpcm; //显示头信息
printData; //画波形图
FreeMem(Buffer);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
filename := 'C:\Windows XP 登录音.wav';
end;
procedure TForm1.PrintData;
var
i : Integer;
begin
for i := 0 to pcm.dLen - 1 do
begin
//memo1.lines.add(inttostr(Data[i]));
Canvas.LineTo(i, Data[i])
end;
end;
end.
#20
只要在form上放一个button,一个memo,把他们的事件对应上就可以了
我在XP+bcb6 测试通过
我在XP+bcb6 测试通过
#21
如果满意记得提交FAQ,^_^
#22
回复人: constantine(飘遥的安吉儿) ( ) 信誉:101
只要在form上放一个button,一个memo,把他们的事件对应上就可以了
我在XP+bcb6 测试通过
//----------------
不是Delphi7中通过吗????
只要在form上放一个button,一个memo,把他们的事件对应上就可以了
我在XP+bcb6 测试通过
//----------------
不是Delphi7中通过吗????
#23
哈哈,在这里习惯了,
#24
还是我来贴代码吧
呵呵。。。。。。。。。。。。。
//---------------------------------------------------------------------------
#ifndef U14_4_2H
#define U14_4_2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <MPlayer.hpp>
//---------------------------------------------------------------------------
class Tf14_4_2 : public TForm
{
__published: // IDE-managed Components
TLabel *Label1;
TLabel *Label2;
TButton *btnEnd;
TButton *btnShowWave;
TScrollBar *Srb;
TEdit *Edit1;
TEdit *Edit2;
TMediaPlayer *MediaPlayer1;
void __fastcall FormCreate(TObject *Sender);
void __fastcall MediaPlayer1Click(TObject *Sender,
TMPBtnType Button, bool &DoDefault);
void __fastcall btnShowWaveClick(TObject *Sender);
void __fastcall SrbChange(TObject *Sender);
void __fastcall Edit1Change(TObject *Sender);
void __fastcall Edit2Change(TObject *Sender);
void __fastcall btnEndClick(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall Tf14_4_2(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE Tf14_4_2 *f14_4_2;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "U14_4_2.h"
#include <stdio.h>
#include<io.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
int FileLen,dx=0,dy=200,dd=44;
int divx,divy;
char* file_name="test.WAV";
short *data;
FILE *inf;
Tf14_4_2 *f14_4_2;
//---------------------------------------------------------------------------
__fastcall Tf14_4_2::Tf14_4_2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void show(void)
{
f14_4_2->Refresh();
f14_4_2->Canvas->TextOut(10,400,IntToStr(f14_4_2->Srb->Position) );
divx=StrToInt(f14_4_2->Edit1->Text);
divy=StrToInt(f14_4_2->Edit2->Text);
f14_4_2->Canvas->MoveTo(0+dx,-data[0]/divy+dy);
f14_4_2->Canvas->Pen->Color=clBlue;
for(int i=1;(i<f14_4_2->Width*divx)&&(i<(FileLen-dd)/2-1);i++)
f14_4_2->Canvas->LineTo(i/divx+dx,-data[i+f14_4_2->Srb->Position]/divy+dy);
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::FormCreate(TObject *Sender)
{
bool open_flag;
int handle;
if(open_flag==true)
{
fclose(inf);
}
inf=fopen(file_name,"r");
open_flag=true;
handle=fileno(inf);
FileLen= filelength(handle);
if(feof(inf))
{
fclose(inf);
open_flag=false;
}
data = new short[(FileLen-dd)/2];
fseek(inf,dd,SEEK_SET);
fread(data,sizeof(short),(FileLen-dd)/2,inf);
MediaPlayer1->VisibleButtons=Mplayer::TButtonSet()<<btPlay<<btStop<<btPause;
MediaPlayer1->DeviceType=dtWaveAudio;
MediaPlayer1->FileName=file_name;
MediaPlayer1->Display=f14_4_2;
MediaPlayer1->Open();
if((FileLen-dd)-f14_4_2->Width*divx<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::MediaPlayer1Click(TObject *Sender,
TMPBtnType Button, bool &DoDefault)
{
if(!MediaPlayer1->AutoOpen)
MediaPlayer1->Play();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::btnShowWaveClick(TObject *Sender)
{
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::SrbChange(TObject *Sender)
{
if(((FileLen-dd)/2-f14_4_2->Width*divx)<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::Edit1Change(TObject *Sender)
{
if(((FileLen-dd)/2-f14_4_2->Width*divx)<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
f14_4_2->Srb->Position=0;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::Edit2Change(TObject *Sender)
{
f14_4_2->Srb->Position=0;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::btnEndClick(TObject *Sender)
{
delete data;
fclose(inf);
Close();
}
//---------------------------------------------------------------------------
呵呵。。。。。。。。。。。。。
//---------------------------------------------------------------------------
#ifndef U14_4_2H
#define U14_4_2H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <MPlayer.hpp>
//---------------------------------------------------------------------------
class Tf14_4_2 : public TForm
{
__published: // IDE-managed Components
TLabel *Label1;
TLabel *Label2;
TButton *btnEnd;
TButton *btnShowWave;
TScrollBar *Srb;
TEdit *Edit1;
TEdit *Edit2;
TMediaPlayer *MediaPlayer1;
void __fastcall FormCreate(TObject *Sender);
void __fastcall MediaPlayer1Click(TObject *Sender,
TMPBtnType Button, bool &DoDefault);
void __fastcall btnShowWaveClick(TObject *Sender);
void __fastcall SrbChange(TObject *Sender);
void __fastcall Edit1Change(TObject *Sender);
void __fastcall Edit2Change(TObject *Sender);
void __fastcall btnEndClick(TObject *Sender);
private: // User declarations
public: // User declarations
__fastcall Tf14_4_2(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE Tf14_4_2 *f14_4_2;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "U14_4_2.h"
#include <stdio.h>
#include<io.h>
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
int FileLen,dx=0,dy=200,dd=44;
int divx,divy;
char* file_name="test.WAV";
short *data;
FILE *inf;
Tf14_4_2 *f14_4_2;
//---------------------------------------------------------------------------
__fastcall Tf14_4_2::Tf14_4_2(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void show(void)
{
f14_4_2->Refresh();
f14_4_2->Canvas->TextOut(10,400,IntToStr(f14_4_2->Srb->Position) );
divx=StrToInt(f14_4_2->Edit1->Text);
divy=StrToInt(f14_4_2->Edit2->Text);
f14_4_2->Canvas->MoveTo(0+dx,-data[0]/divy+dy);
f14_4_2->Canvas->Pen->Color=clBlue;
for(int i=1;(i<f14_4_2->Width*divx)&&(i<(FileLen-dd)/2-1);i++)
f14_4_2->Canvas->LineTo(i/divx+dx,-data[i+f14_4_2->Srb->Position]/divy+dy);
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::FormCreate(TObject *Sender)
{
bool open_flag;
int handle;
if(open_flag==true)
{
fclose(inf);
}
inf=fopen(file_name,"r");
open_flag=true;
handle=fileno(inf);
FileLen= filelength(handle);
if(feof(inf))
{
fclose(inf);
open_flag=false;
}
data = new short[(FileLen-dd)/2];
fseek(inf,dd,SEEK_SET);
fread(data,sizeof(short),(FileLen-dd)/2,inf);
MediaPlayer1->VisibleButtons=Mplayer::TButtonSet()<<btPlay<<btStop<<btPause;
MediaPlayer1->DeviceType=dtWaveAudio;
MediaPlayer1->FileName=file_name;
MediaPlayer1->Display=f14_4_2;
MediaPlayer1->Open();
if((FileLen-dd)-f14_4_2->Width*divx<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::MediaPlayer1Click(TObject *Sender,
TMPBtnType Button, bool &DoDefault)
{
if(!MediaPlayer1->AutoOpen)
MediaPlayer1->Play();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::btnShowWaveClick(TObject *Sender)
{
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::SrbChange(TObject *Sender)
{
if(((FileLen-dd)/2-f14_4_2->Width*divx)<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::Edit1Change(TObject *Sender)
{
if(((FileLen-dd)/2-f14_4_2->Width*divx)<0)
Srb->Max=0;
else
Srb->Max=(FileLen-dd)/2-f14_4_2->Width*divx;
f14_4_2->Srb->Position=0;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::Edit2Change(TObject *Sender)
{
f14_4_2->Srb->Position=0;
show();
}
//---------------------------------------------------------------------------
void __fastcall Tf14_4_2::btnEndClick(TObject *Sender)
{
delete data;
fclose(inf);
Close();
}
//---------------------------------------------------------------------------
#25
记得揭帖啊。。。。。。。
我在XP+BCB6下编译通过
我在XP+BCB6下编译通过
#26
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if(OpenDialog1->Execute())
mFileName=OpenDialog1->FileName;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TPCMWaveHeader pcm;
int iFileHandle,iFileLength,iBytesRead;
iFileHandle = FileOpen(mFileName, fmOpenRead);
iFileLength = FileSeek(iFileHandle, 0, 2) - FileSeek(iFileHandle, 0, 0);
Buffer = new char[iFileLength + 1];
FileRead(iFileHandle, Buffer, iFileLength); //把文件读到buffer
FileClose(iFileHandle);
Move(Buffer, &pcm, sizeof(pcm)); //copy buffer to pcm
Data = new BYTE[pcm.dLen];
setmem(Data, pcm.dLen, 0);
Move(Buffer, Data, pcm.dLen);
//显示头信息
Memo1->Lines->Clear();
Memo1->Lines->Add("FileName:" + mFileName);
Memo1->Lines->Add("RIFF:"+AnsiString(pcm.rID));
Memo1->Lines->Add("RLEN:"+IntToStr(pcm.rLen));
Memo1->Lines->Add("WAVE:"+AnsiString(pcm.wID));
Memo1->Lines->Add("fmt:"+AnsiString(pcm.fID));
Memo1->Lines->Add("Fixed:" + IntToStr(pcm.fLen));
Memo1->Lines->Add("wFormatTag:" + IntToStr(pcm.wFormatTag));
Memo1->Lines->Add("nChannels:" + IntToStr(pcm.nChannels));
Memo1->Lines->Add("nSamplesPerSec:" + IntToStr(pcm.nSamplesPerSec));
Memo1->Lines->Add("nAvgBytesPerSec:" + IntToStr(pcm.nAvgBytesPerSec));
Memo1->Lines->Add("nBlockAlign:" + IntToStr(pcm.nBlockAlign));
Memo1->Lines->Add("nBitsPerSample:" + IntToStr(pcm.nBitsPerSample));
Memo1->Lines->Add("dLen:" + IntToStr(pcm.dLen));
PaintBox1->Canvas->FillRect(PaintBox1->ClientRect);
for (int i=0;i<pcm.dLen;i++)
{
PaintBox1->Canvas->MoveTo(i,128);
PaintBox1->Canvas->LineTo(i, 256-Data[i]);
}
//画波形图
delete[] Buffer;
delete[] Data;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if(NULL==Buffer)
{
delete[] Buffer;
Buffer=NULL;
}
if(NULL==Data)
{
delete[] Data;
Data=NULL;
}
}
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
if(OpenDialog1->Execute())
mFileName=OpenDialog1->FileName;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
TPCMWaveHeader pcm;
int iFileHandle,iFileLength,iBytesRead;
iFileHandle = FileOpen(mFileName, fmOpenRead);
iFileLength = FileSeek(iFileHandle, 0, 2) - FileSeek(iFileHandle, 0, 0);
Buffer = new char[iFileLength + 1];
FileRead(iFileHandle, Buffer, iFileLength); //把文件读到buffer
FileClose(iFileHandle);
Move(Buffer, &pcm, sizeof(pcm)); //copy buffer to pcm
Data = new BYTE[pcm.dLen];
setmem(Data, pcm.dLen, 0);
Move(Buffer, Data, pcm.dLen);
//显示头信息
Memo1->Lines->Clear();
Memo1->Lines->Add("FileName:" + mFileName);
Memo1->Lines->Add("RIFF:"+AnsiString(pcm.rID));
Memo1->Lines->Add("RLEN:"+IntToStr(pcm.rLen));
Memo1->Lines->Add("WAVE:"+AnsiString(pcm.wID));
Memo1->Lines->Add("fmt:"+AnsiString(pcm.fID));
Memo1->Lines->Add("Fixed:" + IntToStr(pcm.fLen));
Memo1->Lines->Add("wFormatTag:" + IntToStr(pcm.wFormatTag));
Memo1->Lines->Add("nChannels:" + IntToStr(pcm.nChannels));
Memo1->Lines->Add("nSamplesPerSec:" + IntToStr(pcm.nSamplesPerSec));
Memo1->Lines->Add("nAvgBytesPerSec:" + IntToStr(pcm.nAvgBytesPerSec));
Memo1->Lines->Add("nBlockAlign:" + IntToStr(pcm.nBlockAlign));
Memo1->Lines->Add("nBitsPerSample:" + IntToStr(pcm.nBitsPerSample));
Memo1->Lines->Add("dLen:" + IntToStr(pcm.dLen));
PaintBox1->Canvas->FillRect(PaintBox1->ClientRect);
for (int i=0;i<pcm.dLen;i++)
{
PaintBox1->Canvas->MoveTo(i,128);
PaintBox1->Canvas->LineTo(i, 256-Data[i]);
}
//画波形图
delete[] Buffer;
delete[] Data;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
if(NULL==Buffer)
{
delete[] Buffer;
Buffer=NULL;
}
if(NULL==Data)
{
delete[] Data;
Data=NULL;
}
}
//---------------------------------------------------------------------------
#27
//---------------------------------------------------------------------------
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
struct TPCMWaveHeader{
// 'RIFF' 标志
char rID[4];
// 文件长度
long int rLen;
// 'WAVE' 标志
char wID[4];
// 'fmt '标志 以空格结束(fID[3]:=Chr($20);)
char fID[4];
// 过度字节(不定)
long int fLen;
// 格式字节(过度字节为PCM形式的声音数据)
WORD wFormatTag;
// 通道数 单声道=1, 双声道=2 }
WORD nChannels;
// 采样频率 (每秒样本数),表示每个通道的播放速度
long int nSamplesPerSec;
// 波形音频数据传送速度(值:通道数X每秒数据位数X每
// 样本的数据位数/8。播放软件利用根据此值估计缓
// 冲区的大小)
long int nAvgBytesPerSec;
// 数据块的调整数(按字节计算),值为通道数*没样本的数据位值/8。
// 播放软件需要一次处理多个该值大小的字节数据,以便
// 将其值用于缓冲区的调整。
WORD nBlockAlign;
// 每样本数据位数,表示每个声道中各个样本的数据位
// 数。如果有多个声道,对每个声道而言,样本大
// 小都一样 8 or 16
WORD nBitsPerSample;
// 'data' 标志
char dId[4];
// 语音数据长度
long int dLen;
} ;
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TPaintBox *PaintBox1;
TMemo *Memo1;
TButton *Button2;
TButton *Button3;
TOpenDialog *OpenDialog1;
void __fastcall Button2Click(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button3Click(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
private: // User declarations
AnsiString mFileName;
char *Buffer;
BYTE *Data;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
我改成了BCB的,去掉了一些BUG,不过代码还不是很完善,大家自己改
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Dialogs.hpp>
#include <ExtCtrls.hpp>
//---------------------------------------------------------------------------
struct TPCMWaveHeader{
// 'RIFF' 标志
char rID[4];
// 文件长度
long int rLen;
// 'WAVE' 标志
char wID[4];
// 'fmt '标志 以空格结束(fID[3]:=Chr($20);)
char fID[4];
// 过度字节(不定)
long int fLen;
// 格式字节(过度字节为PCM形式的声音数据)
WORD wFormatTag;
// 通道数 单声道=1, 双声道=2 }
WORD nChannels;
// 采样频率 (每秒样本数),表示每个通道的播放速度
long int nSamplesPerSec;
// 波形音频数据传送速度(值:通道数X每秒数据位数X每
// 样本的数据位数/8。播放软件利用根据此值估计缓
// 冲区的大小)
long int nAvgBytesPerSec;
// 数据块的调整数(按字节计算),值为通道数*没样本的数据位值/8。
// 播放软件需要一次处理多个该值大小的字节数据,以便
// 将其值用于缓冲区的调整。
WORD nBlockAlign;
// 每样本数据位数,表示每个声道中各个样本的数据位
// 数。如果有多个声道,对每个声道而言,样本大
// 小都一样 8 or 16
WORD nBitsPerSample;
// 'data' 标志
char dId[4];
// 语音数据长度
long int dLen;
} ;
class TForm1 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
TPaintBox *PaintBox1;
TMemo *Memo1;
TButton *Button2;
TButton *Button3;
TOpenDialog *OpenDialog1;
void __fastcall Button2Click(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
void __fastcall Button3Click(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
private: // User declarations
AnsiString mFileName;
char *Buffer;
BYTE *Data;
public: // User declarations
__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
我改成了BCB的,去掉了一些BUG,不过代码还不是很完善,大家自己改
#28
这次真的是在XP+BCB6 测试通过,
robbyzi(红客robby)的2003 系统也试过,没有问题
目前没有试过不可以的wav,
就算Form画不下全部,大家可以参考 flowercity(小唐"菜") 的方法
robbyzi(红客robby)的2003 系统也试过,没有问题
目前没有试过不可以的wav,
就算Form画不下全部,大家可以参考 flowercity(小唐"菜") 的方法
#29
好贴,,收藏。。
#30
to robbyzi(红客robby) :
我的代码明显有两个地方写错,你也不告诉我,
if(NULL==Buffer)两个都要!=,我都写成==,低级错误,汗...
我的代码明显有两个地方写错,你也不告诉我,
if(NULL==Buffer)两个都要!=,我都写成==,低级错误,汗...
#31
好东西收藏。另外那位兄弟有在内存放音的代码呢?共享一下!
#32
好帖子,赶快收藏!
#33
安吉儿师兄。。。
我当时也只是在测一下哪些wav文件哪些文件不行,都没有去细看里面的代码。
我当时也只是在测一下哪些wav文件哪些文件不行,都没有去细看里面的代码。
#34
这样画出的图形的意义是什么呢?
#35
关注