紧急求救,程序运行一段时间后会死机.....

mdejtod 2008-06-18 10:29:05
RT...在软件中加了一个麦克风强度捕获显示的模块后,程序在有的机器上运行一段时间后会死机,但是在我的机器上一点问题都没有,以下是这个模块的代码,请各位高手帮忙看下问题有可能出现在哪里....万分感谢!!!!


unit SoundCap;

interface
uses
Windows, Messages, MMSystem, Classes, SysUtils, Math, Forms,Dialogs, Controls,ExtCtrls;
type
TData8 = array [0..127] of byte;
PData8 = ^TData8;
TData16 = array [0..127] of smallint;
PData16 = ^TData16;

TSoundCap = Class(TCustomControl)
private
protected
public
FilterValve : Integer; //音频过滤的阀值
isCapture : boolean ;
MaxValue :integer;
constructor Create(handle : THandle); //overload;
destructor Destroy; override;
procedure OpenCapture(handle : THandle);
procedure CloseCapture;
procedure OnWaveIn(var Msg: TMessage); message MM_WIM_DATA; //录音缓冲区满后,进行数据处理,将数据送到播放缓冲区
procedure StartCap;
procedure StopCap;
end;

implementation
var
WaveIn: hWaveIn;
hBuf: THandle;
BufHead: TWaveHdr;
bufsize: integer;
Bits16: boolean;
stop: boolean = false;
StartTime : DWORD ;
Count : integer = 0;
header: TWaveFormatEx;
{ TSoundCap }
//关闭音频捕捉

procedure TSoundCap.CloseCapture;
begin
if stop = false then
Exit;
stop := false;
while not stop do
Application.ProcessMessages;
stop := false;
WaveInReset(WaveIn); // 停止声音输入设备工作
WaveInUnPrepareHeader(WaveIn, addr(BufHead), sizeof(BufHead));
WaveInClose(WaveIn); //停止声音输入
GlobalUnlock(hBuf);
GlobalFree(hBuf);
end;

constructor TSoundCap.Create(handle: THandle);
begin
Inherited Create(nil);
ParentWindow := handle;
isCapture := false;
FilterValve := 3;
end;

destructor TSoundCap.Destroy;
begin
inherited;
CloseCapture;
end;
//处理Wave数据采集

procedure TSoundCap.OnWaveIn(var Msg: TMessage); //缓冲区数据已满则处理消息
var
data8 : PData8;
i, x, y : integer;
StartPos, EndPos, SCount : integer;
tmp : Integer;
begin
MaxValue := 0;
Data8 := PData8(PWaveHdr(Msg.lParam)^.lpData);
for i := 0 to BufSize - 1 do
Begin
x := i;
y := Round(abs(data8^[i] - 128) * 100 / 128); //data8^[i] 为 128 - 256 之间
tmp := Round(abs(data8^[i] - 128) * 100 / 128);
if tmp > MaxValue Then
MaxValue := tmp;
End;
if MaxValue = 1 then
MaxValue := 0;
Data8 := nil;
if stop then
WaveInAddBuffer(WaveIn, PWaveHdr(Msg.lParam),SizeOf(TWaveHdr))
else
stop := true;
end;
//打开音频捕捉

procedure TSoundCap.OpenCapture(handle: THandle);
var
BufLen: word;
buf: pointer;
begin
BufSize := 3 * 500 + 100;
Bits16 := false;
with header do
begin
wFormatTag := WAVE_FORMAT_PCM;
nChannels := 1;
nSamplesPerSec :=44100;// 22050;
wBitsPerSample := integer(Bits16) * 8 + 8;
nBlockAlign := nChannels * (wBitsPerSample div 8 );
nAvgBytesPerSec := nSamplesPerSec * nBlockAlign;
cbSize := 0;
end;
WaveInOpen(Addr(WaveIn), WAVE_MAPPER, addr(header),self.Handle , 0, CALLBACK_WINDOW);
BufLen := header.nBlockAlign * BufSize;
hBuf := GlobalAlloc(GMEM_MOVEABLE and GMEM_SHARE, BufLen); //从全局内存堆中分配一块内存(该内存可移动并且可供应用程序共享),并返回该内存块的句柄
Buf := GlobalLock(hBuf); //锁定全局内存并返回指向该内存块的指针
with BufHead do
begin
lpData := Buf;
dwBufferLength := BufLen;
dwFlags := WHDR_BEGINLOOP;
end;
WaveInPrepareHeader(WaveIn, Addr(BufHead), sizeof(BufHead)); //预备声音输入缓冲区
WaveInAddBuffer(WaveIn, addr(BufHead), sizeof(BufHead)); //向声音输入设备发送缓冲区
stop := true; // 停止声音输入设备工作
WaveInStart(WaveIn);
end;
//开始监视捕捉

procedure TSoundCap.StartCap;
begin
isCapture := true;
StartTime := GetTickCount;
end;
//停止监视音频捕捉

procedure TSoundCap.StopCap;
begin
isCapture := false;
end;

end.


欢迎各位内存高手帮忙,.....
...全文
674 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
TRUE 2009-11-26
  • 打赏
  • 举报
回复
你的程序是频繁的创建内存和释放内存,应该是这样的,造成了没有内存释放
smartbear_2008 2009-02-07
  • 打赏
  • 举报
回复
我也遇到类似的问题,期待高人解决。
seawen 2008-07-31
  • 打赏
  • 举报
回复
这样的问题要如何查?因为代码太多,不知道如何下手。请高手指点迷津。。。
seawen 2008-07-21
  • 打赏
  • 举报
回复
在网上找了很久。。。最有可能的估计就是内存使用不当引起的。如使用了未初始化的内存、内存溢出了
seawen 2008-07-21
  • 打赏
  • 举报
回复
我也遇到了同样的问题,期待高人的出现。。。
无条件为你 2008-06-23
  • 打赏
  • 举报
回复
帮你顶下贴子,关注你的问题。
mdejtod 2008-06-23
  • 打赏
  • 举报
回复
顶起来...
我靠,顶自己的贴还内容太短.....
mdejtod 2008-06-23
  • 打赏
  • 举报
回复
-_-
看起来像一直在为它准备数据块,好像是越界了
可是我封装成DLL,然后再调用,还是会S机,郁闷得不行了...
gyk120 2008-06-23
  • 打赏
  • 举报
回复
越来越怀疑是你的代码或者内存越界了,如果单独跑没问题的话……
多媒体方面真没接触过,唉……
封装过没有?
最后finally free没?
mdejtod 2008-06-23
  • 打赏
  • 举报
回复
谢谢楼上的,以上的代码只在整个应用程序关闭时才会执行....
为了能够响应关闭的按钮事件才这么写的..
还有就是,我用这个单元单独做了个DEMO,怎么跑都不会S机,一集成到软件中就S了
coffeemay 2008-06-23
  • 打赏
  • 举报
回复
destructor TSoundCap.Destroy;
begin
inherited;
CloseCapture;
end;
为什么这么写

if stop = false then
Exit;
stop := false;
while not stop do
Application.ProcessMessages;
stop := false;
这里看起来也有些怪异
mdejtod 2008-06-20
  • 打赏
  • 举报
回复
CSDN人才济济,竟然没人帮忙解决问题.....伤心中...
zdlou 2008-06-19
  • 打赏
  • 举报
回复
帮顶的.....................
mdejtod 2008-06-19
  • 打赏
  • 举报
回复
我也不太清楚了,如果说在函数中一直准备内存,但是现在也有进行释放.可还是死机
oushengfen 2008-06-19
  • 打赏
  • 举报
回复
程序上看不出什么问题,
对是对些硬件的操作,是不是API本身有问题.
mdejtod 2008-06-19
  • 打赏
  • 举报
回复
HEAP[SoGuaKK.exe]:
Invalid Address specified to RtlGetUserInfoHeap( 00060000, 17199300 )

Exception 80000003 BREAKPOINT at 7C921230

那些信息,看不懂,不过在调试信息中出现很多这种情况,程序是不是有问题?
skylkj 2008-06-19
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 mdejtod 的回复:]
TO :skylkj
是在配置低一些的机器上就会S机,还有,计数器是在哪里看的?
[/Quote]
我只是说内存泄漏检测的原理...计数器是memproof自己内置的,它就是通过这个检测是否有泄漏.所以你的程序必须正常退出.
运行期总不能分配个内存,memproof就报一下吧,它认为你程序退出就应该回收所有资源,所以只有到退出的时候,才去统计是否存在泄漏.你运行期间直接死机,肯定检测不到...

所以你先运行一小会,尽量把各种功能都执行到,然后正常退出程序.memproof就会给出统计结果了. 或者你用aqtime,更强大,但用起来也更复杂
mdejtod 2008-06-19
  • 打赏
  • 举报
回复
TO :skylkj
是在配置低一些的机器上就会S机,还有,计数器是在哪里看的?
mdejtod 2008-06-19
  • 打赏
  • 举报
回复
CreateFileMapping 不是内存映射么?
哪位帮我看下 ONWAVEIN 函数,问题在这里...
skylkj 2008-06-19
  • 打赏
  • 举报
回复
还有,如果是在"有的机器"上会死机的话,最好重装个最新的声卡驱动,也可能是硬件驱动的问题
加载更多回复(11)

16,749

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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