unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,MMsystem;
type
//定义一个Wave文件头
TWaveHeader=record
rId:longint; //固定标记,值为"RIFF"
rLen:longint; //随后的字节数,值为(wSampleLength+36)
wId:longint; //固定标记,值为"WAVE"
fId:longint; //ckID值为"fmt "
fLen:longint; //nChunkSize Wave文件块的大小 16
wFormatTag:word; //音频数据的编码方式,此值为1,标书PCM方式
nChannels:word; //声道数
nSamplesPerSec:longint; //采样频率
nAvgBytesPerSec:longint; //每秒字节数
nBlockAlign:word; //一次输出的字节数 值为采样位数×声道数/8
wBitsPerSample:word; //采样位数,一般为16和8位
dId:longint; //固定标记,值位"data"
wSampleLength:longint; //采样数据长度,值为文件大小-文件头大小(44)
end;
TRecorder = class
private
{ Private declarations }
public
{ Public declarations }
FWaveFmt:TWaveFormatEx;//指向PCMWAVEFORMAT数据结构的指针,重新封装后包括PCMWAVEFORMAT和WAVEFORMAT
WaveHandle:HWaveIn;//设备句柄
WaveHdr1:PWAVEHDR; // 为采样数据分配缓冲空间 1
WaveHdr2:PWAVEHDR; // 为采样数据分配缓冲空间 2
WaveBuffer1:lpstr; //数据缓冲1
WaveBuffer2:lpstr; //数据缓冲2
Procedure CallBack(uMsg,dwInstance,dwParam1,dwParam2:DWORD);stdcall;
end;
TForm1 = class(TForm)
initial: TButton;
start: TButton;
stop: TButton;
close: TButton;
Label1: TLabel;
procedure startClick(Sender: TObject);
procedure stopClick(Sender: TObject);
procedure initialClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
//channelse为声道数,resolution为采样位数,rate为采样频率,fn为对应的文件名称
procedure CreateWave(channels:word;resolution:word;rate:longint;fn:string);
procedure closeClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Recorder:TRecorder;
//定义一个缓冲控制变量
flag:integer;
implementation
{$R *.dfm}
Procedure TRecorder.CallBack(uMsg,dwInstance,dwParam1,dwParam2:DWORD);stdcall;//回调函数声明
var
i,k:integer; //循环变量
SPByte:^Byte; //假设在打开设备时采用8位量化
SingleData:Integer;
fd:TFileStream; //保存结果
f:textfile;
begin
//******************************************//
case uMsg of //
MM_WIM_OPEN : //波形输入设备成功打开发回的消息
begin
application.MessageBox('波形输入设备成功打开','ok',mb_OK);
end;
//感觉是以下部分出了错[/b]
MM_WIM_DATA : //一个缓冲区已满发回的消息处理,此处需要修改
begin
if(flag=0) then
begin
form1.Label1.caption:='ok1';
WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,sizeof(TWAVEHDR));
WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
flag:=1;
end
else
begin
form1.Label1.caption:='ok2';
WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,sizeof(TWAVEHDR));
WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));
WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));
flag:=0;
end;
SPByte:=Pointer(dwParam1);
//////////////////////////////////////////////////
fd:=TFileStream.Create('C:\test.wav',fmCreate);
for i:=0 to 1023 do // Recorder.DataLength-1
begin
SingleData:=SPByte^;//通过SPByte来访问缓冲区的数据
//application.MessageBox(StrtoInt(SingleData),'');
/////////////////此处有内容省略
fd.read(SingleData,sizeof(SingleData));
write('C:\test.wav', SingleData);
Inc(SPByte);//Increments an ordinal value by one or N.
end;
fd.Free; //closefile(f);
if(flag=1) then
begin
//dispose(Recorder.WaveHdr1.lpData);
//dispose(Recorder.WaveHdr1);
end
else
begin
//dispose(Recorder.WaveHdr2.lpData);
//dispose(Recorder.WaveHdr2);
end;
end;
MM_WIM_CLOSE : //波形输入设备关闭成功发回的消息
//释放内存
begin;
WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,sizeof(TWAVEHDR));//解除置换保护
WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,sizeof(TWAVEHDR));
GlobalFreePtr(Recorder.WaveBuffer1); //释放分配的内存
GlobalFreePtr(Recorder.WaveBuffer2); //释放分配的内存
application.MessageBox('录音设备已经关闭','Congratuations!',mb_OK);
end;
end;
end;
procedure TForm1.CreateWave(channels:word;resolution:word;rate:longint;fn:string);
var
wf : file of TWaveHeader;
wh : TWaveHeader;
begin
wh.rId := $46464952;
wh.rLen:= 36;
wh.wId := $45564157;
wh.fId := $20746d66;
wh.fLen:= 16;
wh.wFormatTag:= 1;
wh.nChannels := channels;
wh.nSamplesPerSec:= rate;
wh.nAvgBytesPerSec := channels*rate*(resolution div 8);
wh.nBlockAlign:= channels*(resolution div 8);
wh.wBitsPerSample:= resolution;
wh.dId := $61746164;
wh.wSampleLength:= 0;
assignfile(wf,fn); {打开对应文件 }
rewrite(wf); {移动指针到文件头}
write(wf,wh);{写进文件头}
closefile(wf);{关闭文件}
end;
procedure TForm1.startClick(Sender: TObject);
begin
//开始录音
//检验
WaveInStart(Recorder.WaveHandle);
if(WaveInStart(Recorder.WaveHandle)<>0) then application.MessageBox('Strart error/启动波形输入设备错误','Error',mb_OK);
initial.Enabled:=FALSE;
//stop.Enabled:=TRUE;
end;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,MMsystem;
type
//定义一个Wave文件头
TWaveHeader=record
rId:longint; //固定标记,值为"RIFF"
rLen:longint; //随后的字节数,值为(wSampleLength+36)
wId:longint; //固定标记,值为"WAVE"
fId:longint; //ckID值为"fmt "
fLen:longint; //nChunkSize Wave文件块的大小 16
wFormatTag:word; //音频数据的编码方式,此值为1,标书PCM方式
nChannels:word; //声道数
nSamplesPerSec:longint; //采样频率
nAvgBytesPerSec:longint; //每秒字节数
nBlockAlign:word; //一次输出的字节数 值为采样位数×声道数/8
wBitsPerSample:word; //采样位数,一般为16和8位
dId:longint; //固定标记,值位"data"
wSampleLength:longint; //采样数据长度,值为文件大小-文件头大小(44)
end;
TRecorder = class
private
{ Private declarations }
public
{ Public declarations }
FWaveFmt:TWaveFormatEx;//指向PCMWAVEFORMAT数据结构的指针,重新封装后包括PCMWAVEFORMAT和WAVEFORMAT
WaveHandle:HWaveIn;//设备句柄
WaveHdr1:PWAVEHDR; // 为采样数据分配缓冲空间 1
WaveHdr2:PWAVEHDR; // 为采样数据分配缓冲空间 2
WaveBuffer1:lpstr; //数据缓冲1
WaveBuffer2:lpstr; //数据缓冲2
Procedure CallBack(uMsg,dwInstance,dwParam1,dwParam2:DWORD);stdcall;
end;
TForm1 = class(TForm)
initial: TButton;
start: TButton;
stop: TButton;
close: TButton;
Label1: TLabel;
procedure startClick(Sender: TObject);
procedure stopClick(Sender: TObject);
procedure initialClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
//channelse为声道数,resolution为采样位数,rate为采样频率,fn为对应的文件名称
procedure CreateWave(channels:word;resolution:word;rate:longint;fn:string);
procedure closeClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Recorder:TRecorder;
//定义一个缓冲控制变量
flag:integer;
implementation
{$R *.dfm}
Procedure TRecorder.CallBack(uMsg,dwInstance,dwParam1,dwParam2:DWORD);stdcall;//回调函数声明
var
i,k:integer; //循环变量
SPByte:^Byte; //假设在打开设备时采用8位量化
SingleData:Integer;
fd:TFileStream; //保存结果
f:textfile;
begin
//******************************************//
case uMsg of //
MM_WIM_OPEN : //波形输入设备成功打开发回的消息
begin
application.MessageBox('波形输入设备成功打开','ok',mb_OK);
end;
//感觉是以下部分出了错[/b]
MM_WIM_DATA : //一个缓冲区已满发回的消息处理,此处需要修改
begin
if(flag=0) then
begin
form1.Label1.caption:='ok1';
WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,sizeof(TWAVEHDR));
WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
flag:=1;
end
else
begin
form1.Label1.caption:='ok2';
WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,sizeof(TWAVEHDR));
WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));
WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));
flag:=0;
end;
SPByte:=Pointer(dwParam1);
//////////////////////////////////////////////////
fd:=TFileStream.Create('C:\test.wav',fmCreate);
for i:=0 to 1023 do // Recorder.DataLength-1
begin
SingleData:=SPByte^;//通过SPByte来访问缓冲区的数据
//application.MessageBox(StrtoInt(SingleData),'');
/////////////////此处有内容省略
fd.read(SingleData,sizeof(SingleData));
write('C:\test.wav', SingleData);
Inc(SPByte);//Increments an ordinal value by one or N.
end;
fd.Free; //closefile(f);
if(flag=1) then
begin
//dispose(Recorder.WaveHdr1.lpData);
//dispose(Recorder.WaveHdr1);
end
else
begin
//dispose(Recorder.WaveHdr2.lpData);
//dispose(Recorder.WaveHdr2);
end;
end;
MM_WIM_CLOSE : //波形输入设备关闭成功发回的消息
//释放内存
begin;
WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,sizeof(TWAVEHDR));//解除置换保护
WaveInUnprepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,sizeof(TWAVEHDR));
GlobalFreePtr(Recorder.WaveBuffer1); //释放分配的内存
GlobalFreePtr(Recorder.WaveBuffer2); //释放分配的内存
application.MessageBox('录音设备已经关闭','Congratuations!',mb_OK);
end;
end;
end;
procedure TForm1.CreateWave(channels:word;resolution:word;rate:longint;fn:string);
var
wf : file of TWaveHeader;
wh : TWaveHeader;
begin
wh.rId := $46464952;
wh.rLen:= 36;
wh.wId := $45564157;
wh.fId := $20746d66;
wh.fLen:= 16;
wh.wFormatTag:= 1;
wh.nChannels := channels;
wh.nSamplesPerSec:= rate;
wh.nAvgBytesPerSec := channels*rate*(resolution div 8);
wh.nBlockAlign:= channels*(resolution div 8);
wh.wBitsPerSample:= resolution;
wh.dId := $61746164;
wh.wSampleLength:= 0;
assignfile(wf,fn); {打开对应文件 }
rewrite(wf); {移动指针到文件头}
write(wf,wh);{写进文件头}
closefile(wf);{关闭文件}
end;
procedure TForm1.startClick(Sender: TObject);
begin
//开始录音
//检验
WaveInStart(Recorder.WaveHandle);
if(WaveInStart(Recorder.WaveHandle)<>0) then application.MessageBox('Strart error/启动波形输入设备错误','Error',mb_OK);
initial.Enabled:=FALSE;
//stop.Enabled:=TRUE;
end;
解决方案 »
- 有做物流业ERP的吗?
- delphi 5 不能进行单步调试了
- 扩展的Comobox控件,为什么鼠标在下拉框的子项间移动时会有一连串的虚线
- guolvguolv(guolvguolv)请来拿分(100)_2!(版主请等他拿了分再删)
- 关于DBGrid的字段和下标显示的问题,比较难,在线等待答案
- 谁有ADO数据库例子(添加,插入,删除等)送100分。
- 请问窗体的onhelp事件
- 寻求有CkeckBox 的树形控件,如杀毒软件中选择路径的控件。
- 请教:memo中对字体的设置.
- 关于报表生成及打印的小问题,高分相赠!
- 用with写法,设断点调度时 怎么取对象的值?
- delphi 中 怎样在d:\下创建一个名为 xx.txt的文本文件呢 ?
procedure TForm1.stopClick(Sender: TObject);
begin
WaveInStop(Recorder.WaveHandle); //停止录音
WaveInReset(Recorder.WaveHandle); // 重置语音射入设备
WaveInClose(Recorder.WaveHandle); // 关闭语音射入设备
application.MessageBox('关闭录音设备','Congratuations!',mb_OK);
initial.Enabled:=TRUE;
//start.Enabled:=TRUE;
//stop.Enabled:=FALSE;
//close.Enabled:=TRUE;
end;
procedure TForm1.initialClick(Sender: TObject);
begin
CreateWave(1,8,11025,'d:\test.wav');// 创建文件头 flag:=0;
//设置我们需要的格式
Recorder:=TRecorder.Create;
Recorder.FWaveFmt.wFormatTag:=WAVE_FORMAT_PCM;
Recorder.FWaveFmt.nChannels:=1;
Recorder.FWaveFmt.wBitsPerSample:=8;
Recorder.FWaveFmt.nSamplesPerSec:=11025;
Recorder.FWaveFmt.nAvgBytesPerSec:=11025;
Recorder.FWaveFmt.nBlockAlign:=2;
WaveInOpen(@Recorder.WaveHandle,Wave_Mapper,(@Recorder.FWaveFmt),DWORD(@TRecorder.CallBack),DWORD(@Recorder),CALLBACK_FUNCTION + WAVE_ALLOWSYNC); //打开波形输入设备//*********************//
//为采样分配缓冲空间
Recorder.WaveHdr1:=GlobalAllocPtr(GHND or GMEM_SHARE,Sizeof(TWAVEHDR));//开辟一段内存空间
Recorder.WaveBuffer1:=GlobalAllocPtr(GHND or GMEM_SHARE,1024); //为Buffer1分配内存空间
Recorder.WaveHdr1.lpData:=Recorder.WaveBuffer1;
Recorder.WaveHdr1.dwBufferLength:=1024;
Recorder.WaveHdr2:=GlobalAllocPtr(GHND or GMEM_SHARE,Sizeof(TWAVEHDR));//开辟一段内存空间
Recorder.WaveBuffer2:=GlobalAllocPtr(GHND or GMEM_SHARE,1024);//为Buffer2分配内存空间
Recorder.WaveHdr2.lpData:=Recorder.WaveBuffer2;//
Recorder.WaveHdr2.dwBufferLength:=1024;
WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));
WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));//将缓冲区送往波形输入设备
WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
//start.Enabled:=TRUE;end;procedure TForm1.FormCreate(Sender: TObject);
begin
//判断是否有声卡
if (WaveInGetNumDevs()=0) then
application.MessageBox('There is no recording sound cadd in your computer!','Error',mb_OK)
else
application.MessageBox('There is a recording sound cadd in your computer!','ok',mb_OK)
end;
procedure TForm1.closeClick(Sender: TObject);
begin
waveInStop(Recorder.WaveHandle);
waveInClose(Recorder.WaveHandle);
end;
end.
procedure TForm1.stopClick(Sender: TObject);
begin
WaveInStop(Recorder.WaveHandle); //停止录音
WaveInReset(Recorder.WaveHandle); // 重置语音射入设备
WaveInClose(Recorder.WaveHandle); // 关闭语音射入设备
application.MessageBox('关闭录音设备','Congratuations!',mb_OK);
initial.Enabled:=TRUE;
//start.Enabled:=TRUE;
//stop.Enabled:=FALSE;
//close.Enabled:=TRUE;
end;
procedure TForm1.initialClick(Sender: TObject);
begin
CreateWave(1,8,11025,'d:\test.wav');// 创建文件头 flag:=0;
//设置我们需要的格式
Recorder:=TRecorder.Create;
Recorder.FWaveFmt.wFormatTag:=WAVE_FORMAT_PCM;
Recorder.FWaveFmt.nChannels:=1;
Recorder.FWaveFmt.wBitsPerSample:=8;
Recorder.FWaveFmt.nSamplesPerSec:=11025;
Recorder.FWaveFmt.nAvgBytesPerSec:=11025;
Recorder.FWaveFmt.nBlockAlign:=2;
WaveInOpen(@Recorder.WaveHandle,Wave_Mapper,(@Recorder.FWaveFmt),DWORD(@TRecorder.CallBack),DWORD(@Recorder),CALLBACK_FUNCTION + WAVE_ALLOWSYNC); //打开波形输入设备//*********************//
//为采样分配缓冲空间
Recorder.WaveHdr1:=GlobalAllocPtr(GHND or GMEM_SHARE,Sizeof(TWAVEHDR));//开辟一段内存空间
Recorder.WaveBuffer1:=GlobalAllocPtr(GHND or GMEM_SHARE,1024); //为Buffer1分配内存空间
Recorder.WaveHdr1.lpData:=Recorder.WaveBuffer1;
Recorder.WaveHdr1.dwBufferLength:=1024;
Recorder.WaveHdr2:=GlobalAllocPtr(GHND or GMEM_SHARE,Sizeof(TWAVEHDR));//开辟一段内存空间
Recorder.WaveBuffer2:=GlobalAllocPtr(GHND or GMEM_SHARE,1024);//为Buffer2分配内存空间
Recorder.WaveHdr2.lpData:=Recorder.WaveBuffer2;//
Recorder.WaveHdr2.dwBufferLength:=1024;
WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));
WaveInPrepareHeader(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr1,Sizeof(WAVEHDR));//将缓冲区送往波形输入设备
WaveInAddBuffer(Recorder.WaveHandle,Recorder.WaveHdr2,Sizeof(WAVEHDR));
//start.Enabled:=TRUE;end;procedure TForm1.FormCreate(Sender: TObject);
begin
//判断是否有声卡
if (WaveInGetNumDevs()=0) then
application.MessageBox('There is no recording sound cadd in your computer!','Error',mb_OK)
else
application.MessageBox('There is a recording sound cadd in your computer!','ok',mb_OK)
end;
procedure TForm1.closeClick(Sender: TObject);
begin
waveInStop(Recorder.WaveHandle);
waveInClose(Recorder.WaveHandle);
end;
end.