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.
欢迎各位内存高手帮忙,.....
 

解决方案 »

  1.   

    补充一点,在定时器中调用 MaxValue  这个值,一直在调用
      

  2.   

    用MemProof检查下有没有内存泄漏
      

  3.   

    怎么检查?
    我看了下任务管理器中,这个程序的内存使用一直在往上涨...要晕了,后面改了下程序
    //处理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;
      waveInUnprepareHeader(WaveIn, Addr(BufHead), sizeof(BufHead));
      if MaxValue = 1 then
        MaxValue := 0;
      if stop then
      begin
        WaveInPrepareHeader(WaveIn, Addr(BufHead), sizeof(BufHead));
        WaveInAddBuffer(WaveIn, PWaveHdr(Msg.lParam),SizeOf(TWaveHdr));
      end
      else
        stop := true;
    end;
     好像效果差不多,只是涨得很慢,上涨的值也不多
      

  4.   

    MemProof教程,可以定为到内存泄漏的具体代码行
    http://blog.csdn.net/hero_yin/archive/2006/09/19/1246569.aspx简单点就用fastmm4,调试模式下退出会有泄漏提示,但只有泄漏的指针类型,无法定位到代码
      

  5.   

    GlobalAlloc主要是为了与16位系统兼容吧
    推荐用CreateFileMapping
      

  6.   

    内存检测的原理是,对所有分配内存的操作计数,new一个就加1,free一个就减1,在程序退出后看计数器有没有归零,没有则存在泄漏所以你必须在运行一段时间后正常退出,才能检测到泄漏....
      

  7.   

    CreateFileMapping 不是内存映射么?
    哪位帮我看下 ONWAVEIN 函数,问题在这里...
      

  8.   

    TO :skylkj 
    是在配置低一些的机器上就会S机,还有,计数器是在哪里看的?
      

  9.   

    我只是说内存泄漏检测的原理...计数器是memproof自己内置的,它就是通过这个检测是否有泄漏.所以你的程序必须正常退出. 
    运行期总不能分配个内存,memproof就报一下吧,它认为你程序退出就应该回收所有资源,所以只有到退出的时候,才去统计是否存在泄漏.你运行期间直接死机,肯定检测不到...所以你先运行一小会,尽量把各种功能都执行到,然后正常退出程序.memproof就会给出统计结果了. 或者你用aqtime,更强大,但用起来也更复杂
      

  10.   

    HEAP[SoGuaKK.exe]: 
    Invalid Address specified to RtlGetUserInfoHeap( 00060000, 17199300 )Exception 80000003 BREAKPOINT at 7C921230那些信息,看不懂,不过在调试信息中出现很多这种情况,程序是不是有问题?
      

  11.   

    程序上看不出什么问题,
    对是对些硬件的操作,是不是API本身有问题.
      

  12.   

    CSDN人才济济,竟然没人帮忙解决问题.....伤心中...
      

  13.   

    destructor TSoundCap.Destroy; 
    begin 
      inherited; 
      CloseCapture; 
    end; 
    为什么这么写 if stop = false then 
        Exit; 
      stop := false; 
      while not stop do 
      Application.ProcessMessages; 
      stop := false; 
    这里看起来也有些怪异
      

  14.   

    谢谢楼上的,以上的代码只在整个应用程序关闭时才会执行....
    为了能够响应关闭的按钮事件才这么写的..
    还有就是,我用这个单元单独做了个DEMO,怎么跑都不会S机,一集成到软件中就S了
      

  15.   

    越来越怀疑是你的代码或者内存越界了,如果单独跑没问题的话……
    多媒体方面真没接触过,唉……
    封装过没有?
    最后finally free没?
      

  16.   

    -_-
    看起来像一直在为它准备数据块,好像是越界了
    可是我封装成DLL,然后再调用,还是会S机,郁闷得不行了...