如何读取wav文件,并画成波形图。。

richarson 2004-11-18 12:39:35
如题~~~~
如何读取wav文件,并画成波形图
即画出wav 文件的频谱!!!!!!!!

...全文
2563 35 打赏 收藏 转发到动态 举报
写回复
用AI写文章
35 条回复
切换为时间正序
请发表友善的回复…
发表回复
slwang2003 2005-07-08
  • 打赏
  • 举报
回复
关注
constantine 2004-11-21
  • 打赏
  • 举报
回复
to robbyzi(红客robby) :
我的代码明显有两个地方写错,你也不告诉我,
if(NULL==Buffer)两个都要!=,我都写成==,低级错误,汗...
robbyzi 2004-11-21
  • 打赏
  • 举报
回复
好贴,,收藏。。
ahaozi 2004-11-21
  • 打赏
  • 举报
回复
好东西收藏。另外那位兄弟有在内存放音的代码呢?共享一下!
BoweirrKing 2004-11-21
  • 打赏
  • 举报
回复
这样画出的图形的意义是什么呢?
robbyzi 2004-11-21
  • 打赏
  • 举报
回复
安吉儿师兄。。。

我当时也只是在测一下哪些wav文件哪些文件不行,都没有去细看里面的代码。
初冬雪 2004-11-21
  • 打赏
  • 举报
回复
好帖子,赶快收藏!
constantine 2004-11-20
  • 打赏
  • 举报
回复
哈哈,在这里习惯了,
yuruilei 2004-11-20
  • 打赏
  • 举报
回复
我也要一份!
yuruilei@21cn.com
net205 2004-11-20
  • 打赏
  • 举报
回复
constantine(飘遥的安吉儿) :
给我也来一份
net205@126.com
robbyzi 2004-11-20
  • 打赏
  • 举报
回复
回复人: constantine(飘遥的安吉儿) ( ) 信誉:101
只要在form上放一个button,一个memo,把他们的事件对应上就可以了
我在XP+bcb6 测试通过

//----------------

不是Delphi7中通过吗????
constantine 2004-11-20
  • 打赏
  • 举报
回复
这次真的是在XP+BCB6 测试通过,
robbyzi(红客robby)的2003 系统也试过,没有问题
目前没有试过不可以的wav,
就算Form画不下全部,大家可以参考 flowercity(小唐"菜") 的方法
constantine 2004-11-20
  • 打赏
  • 举报
回复
//---------------------------------------------------------------------------

#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,不过代码还不是很完善,大家自己改
constantine 2004-11-20
  • 打赏
  • 举报
回复
//---------------------------------------------------------------------------

#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;
}
}
//---------------------------------------------------------------------------

constantine 2004-11-20
  • 打赏
  • 举报
回复
如果满意记得提交FAQ,^_^
constantine 2004-11-20
  • 打赏
  • 举报
回复
只要在form上放一个button,一个memo,把他们的事件对应上就可以了
我在XP+bcb6 测试通过
constantine 2004-11-20
  • 打赏
  • 举报
回复
代码我就不再发了,那个不是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.
flowercity 2004-11-20
  • 打赏
  • 举报
回复
记得揭帖啊。。。。。。。
我在XP+BCB6下编译通过
flowercity 2004-11-20
  • 打赏
  • 举报
回复
还是我来贴代码吧
呵呵。。。。。。。。。。。。。

//---------------------------------------------------------------------------

#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();
}
//---------------------------------------------------------------------------
robbyzi 2004-11-19
  • 打赏
  • 举报
回复
发了记得告诉我哦。。师兄。。。
加载更多回复(15)

13,826

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧