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.
欢迎各位内存高手帮忙,.....
31 个解决方案
#1
先顶一下,明天睡醒后看看
#2
补充一点,在定时器中调用 MaxValue 这个值,一直在调用
#3
用MemProof检查下有没有内存泄漏
#4
怎么检查?
我看了下任务管理器中,这个程序的内存使用一直在往上涨...要晕了,后面改了下程序
//处理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;
好像效果差不多,只是涨得很慢,上涨的值也不多
我看了下任务管理器中,这个程序的内存使用一直在往上涨...要晕了,后面改了下程序
//处理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;
好像效果差不多,只是涨得很慢,上涨的值也不多
#5
MemProof教程,可以定为到内存泄漏的具体代码行
http://blog.csdn.net/hero_yin/archive/2006/09/19/1246569.aspx
简单点就用fastmm4,调试模式下退出会有泄漏提示,但只有泄漏的指针类型,无法定位到代码
http://blog.csdn.net/hero_yin/archive/2006/09/19/1246569.aspx
简单点就用fastmm4,调试模式下退出会有泄漏提示,但只有泄漏的指针类型,无法定位到代码
#6
检测不到内存泄漏,直接死机了,各位有什么好的办法?
#7
GlobalAlloc主要是为了与16位系统兼容吧
推荐用CreateFileMapping
推荐用CreateFileMapping
#8
内存检测的原理是,对所有分配内存的操作计数,new一个就加1,free一个就减1,在程序 退出后看计数器有没有归零,没有则存在泄漏
所以你必须在运行一段时间后 正常退出,才能检测到泄漏....
#9
还有,如果是在"有的机器"上会死机的话,最好重装个最新的声卡驱动,也可能是硬件驱动的问题
#10
CreateFileMapping 不是内存映射么?
哪位帮我看下 ONWAVEIN 函数,问题在这里...
哪位帮我看下 ONWAVEIN 函数,问题在这里...
#11
TO :skylkj
是在配置低一些的机器上就会S机,还有,计数器是在哪里看的?
是在配置低一些的机器上就会S机,还有,计数器是在哪里看的?
#12
我只是说内存泄漏检测的原理...计数器是memproof自己内置的,它就是通过这个检测是否有泄漏.所以你的程序必须正常退出.
运行期总不能分配个内存,memproof就报一下吧,它认为你程序退出就应该回收所有资源,所以只有到退出的时候,才去统计是否存在泄漏.你运行期间直接死机,肯定检测不到...
所以你先运行一小会,尽量把各种功能都执行到,然后正常退出程序.memproof就会给出统计结果了. 或者你用aqtime,更强大,但用起来也更复杂
#13
HEAP[SoGuaKK.exe]:
Invalid Address specified to RtlGetUserInfoHeap( 00060000, 17199300 )
Exception 80000003 BREAKPOINT at 7C921230
那些信息,看不懂,不过在调试信息中出现很多这种情况,程序是不是有问题?
Invalid Address specified to RtlGetUserInfoHeap( 00060000, 17199300 )
Exception 80000003 BREAKPOINT at 7C921230
那些信息,看不懂,不过在调试信息中出现很多这种情况,程序是不是有问题?
#14
程序上看不出什么问题,
对是对些硬件的操作,是不是API本身有问题.
对是对些硬件的操作,是不是API本身有问题.
#15
我也不太清楚了,如果说在函数中一直准备内存,但是现在也有进行释放.可还是死机
#16
帮顶的.....................
#17
高人呢?
大家都很忙??
大家都很忙??
#18
要疯了,怎么还没高人帮忙?????
顶起来..
顶起来..
#19
这里暂时没高人,就一堆菜鸟而已
看样子似乎是代码越界了
看样子似乎是代码越界了
#20
CSDN人才济济,竟然没人帮忙解决问题.....伤心中...
#21
顶起来...
我靠,顶自己的贴还内容太短.....
我靠,顶自己的贴还内容太短.....
#22
帮你顶下贴子,关注你的问题。
#23
destructor TSoundCap.Destroy;
begin
inherited;
CloseCapture;
end;
为什么这么写
if stop = false then
Exit;
stop := false;
while not stop do
Application.ProcessMessages;
stop := false;
这里看起来也有些怪异
begin
inherited;
CloseCapture;
end;
为什么这么写
if stop = false then
Exit;
stop := false;
while not stop do
Application.ProcessMessages;
stop := false;
这里看起来也有些怪异
#24
谢谢楼上的,以上的代码只在整个应用程序关闭时才会执行....
为了能够响应关闭的按钮事件才这么写的..
还有就是,我用这个单元单独做了个DEMO,怎么跑都不会S机,一集成到软件中就S了
为了能够响应关闭的按钮事件才这么写的..
还有就是,我用这个单元单独做了个DEMO,怎么跑都不会S机,一集成到软件中就S了
#25
越来越怀疑是你的代码或者内存越界了,如果单独跑没问题的话……
多媒体方面真没接触过,唉……
封装过没有?
最后finally free没?
多媒体方面真没接触过,唉……
封装过没有?
最后finally free没?
#26
-_-
看起来像一直在为它准备数据块,好像是越界了
可是我封装成DLL,然后再调用,还是会S机,郁闷得不行了...
看起来像一直在为它准备数据块,好像是越界了
可是我封装成DLL,然后再调用,还是会S机,郁闷得不行了...
#27
我也遇到了同样的问题,期待高人的出现。。。
#28
在网上找了很久。。。最有可能的估计就是内存使用不当引起的。如使用了未初始化的内存、内存溢出了
#29
这样的问题要如何查?因为代码太多,不知道如何下手。请高手指点迷津。。。
#30
我也遇到类似的问题,期待高人解决。
#31
你的程序是频繁的创建内存和释放内存,应该是这样的,造成了没有内存释放
#1
先顶一下,明天睡醒后看看
#2
补充一点,在定时器中调用 MaxValue 这个值,一直在调用
#3
用MemProof检查下有没有内存泄漏
#4
怎么检查?
我看了下任务管理器中,这个程序的内存使用一直在往上涨...要晕了,后面改了下程序
//处理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;
好像效果差不多,只是涨得很慢,上涨的值也不多
我看了下任务管理器中,这个程序的内存使用一直在往上涨...要晕了,后面改了下程序
//处理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;
好像效果差不多,只是涨得很慢,上涨的值也不多
#5
MemProof教程,可以定为到内存泄漏的具体代码行
http://blog.csdn.net/hero_yin/archive/2006/09/19/1246569.aspx
简单点就用fastmm4,调试模式下退出会有泄漏提示,但只有泄漏的指针类型,无法定位到代码
http://blog.csdn.net/hero_yin/archive/2006/09/19/1246569.aspx
简单点就用fastmm4,调试模式下退出会有泄漏提示,但只有泄漏的指针类型,无法定位到代码
#6
检测不到内存泄漏,直接死机了,各位有什么好的办法?
#7
GlobalAlloc主要是为了与16位系统兼容吧
推荐用CreateFileMapping
推荐用CreateFileMapping
#8
内存检测的原理是,对所有分配内存的操作计数,new一个就加1,free一个就减1,在程序 退出后看计数器有没有归零,没有则存在泄漏
所以你必须在运行一段时间后 正常退出,才能检测到泄漏....
#9
还有,如果是在"有的机器"上会死机的话,最好重装个最新的声卡驱动,也可能是硬件驱动的问题
#10
CreateFileMapping 不是内存映射么?
哪位帮我看下 ONWAVEIN 函数,问题在这里...
哪位帮我看下 ONWAVEIN 函数,问题在这里...
#11
TO :skylkj
是在配置低一些的机器上就会S机,还有,计数器是在哪里看的?
是在配置低一些的机器上就会S机,还有,计数器是在哪里看的?
#12
我只是说内存泄漏检测的原理...计数器是memproof自己内置的,它就是通过这个检测是否有泄漏.所以你的程序必须正常退出.
运行期总不能分配个内存,memproof就报一下吧,它认为你程序退出就应该回收所有资源,所以只有到退出的时候,才去统计是否存在泄漏.你运行期间直接死机,肯定检测不到...
所以你先运行一小会,尽量把各种功能都执行到,然后正常退出程序.memproof就会给出统计结果了. 或者你用aqtime,更强大,但用起来也更复杂
#13
HEAP[SoGuaKK.exe]:
Invalid Address specified to RtlGetUserInfoHeap( 00060000, 17199300 )
Exception 80000003 BREAKPOINT at 7C921230
那些信息,看不懂,不过在调试信息中出现很多这种情况,程序是不是有问题?
Invalid Address specified to RtlGetUserInfoHeap( 00060000, 17199300 )
Exception 80000003 BREAKPOINT at 7C921230
那些信息,看不懂,不过在调试信息中出现很多这种情况,程序是不是有问题?
#14
程序上看不出什么问题,
对是对些硬件的操作,是不是API本身有问题.
对是对些硬件的操作,是不是API本身有问题.
#15
我也不太清楚了,如果说在函数中一直准备内存,但是现在也有进行释放.可还是死机
#16
帮顶的.....................
#17
高人呢?
大家都很忙??
大家都很忙??
#18
要疯了,怎么还没高人帮忙?????
顶起来..
顶起来..
#19
这里暂时没高人,就一堆菜鸟而已
看样子似乎是代码越界了
看样子似乎是代码越界了
#20
CSDN人才济济,竟然没人帮忙解决问题.....伤心中...
#21
顶起来...
我靠,顶自己的贴还内容太短.....
我靠,顶自己的贴还内容太短.....
#22
帮你顶下贴子,关注你的问题。
#23
destructor TSoundCap.Destroy;
begin
inherited;
CloseCapture;
end;
为什么这么写
if stop = false then
Exit;
stop := false;
while not stop do
Application.ProcessMessages;
stop := false;
这里看起来也有些怪异
begin
inherited;
CloseCapture;
end;
为什么这么写
if stop = false then
Exit;
stop := false;
while not stop do
Application.ProcessMessages;
stop := false;
这里看起来也有些怪异
#24
谢谢楼上的,以上的代码只在整个应用程序关闭时才会执行....
为了能够响应关闭的按钮事件才这么写的..
还有就是,我用这个单元单独做了个DEMO,怎么跑都不会S机,一集成到软件中就S了
为了能够响应关闭的按钮事件才这么写的..
还有就是,我用这个单元单独做了个DEMO,怎么跑都不会S机,一集成到软件中就S了
#25
越来越怀疑是你的代码或者内存越界了,如果单独跑没问题的话……
多媒体方面真没接触过,唉……
封装过没有?
最后finally free没?
多媒体方面真没接触过,唉……
封装过没有?
最后finally free没?
#26
-_-
看起来像一直在为它准备数据块,好像是越界了
可是我封装成DLL,然后再调用,还是会S机,郁闷得不行了...
看起来像一直在为它准备数据块,好像是越界了
可是我封装成DLL,然后再调用,还是会S机,郁闷得不行了...
#27
我也遇到了同样的问题,期待高人的出现。。。
#28
在网上找了很久。。。最有可能的估计就是内存使用不当引起的。如使用了未初始化的内存、内存溢出了
#29
这样的问题要如何查?因为代码太多,不知道如何下手。请高手指点迷津。。。
#30
我也遇到类似的问题,期待高人解决。
#31
你的程序是频繁的创建内存和释放内存,应该是这样的,造成了没有内存释放