Bonjour,
Toujours avec mon vieux Laz 1.4/FPC 2.6.2 (la migration est pour bientôt), je suis sur un petit projet d'affichage de la forme d'onde du son d'un fichier audio .wav (44100 Hz, stereo), inspiré de CustLoop de la librairie Bass.
Tout se passe parfaitement bien sauf à la clôture où la console m'agresse violemment alors que j'ai bien pris soin de faire un free des objets created auparavant :
Bien sûr, avec des messages aussi cabalistiques pas moyen d'en savoir plus, et je répète bien que j'ai mis
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 WARNING: TLCLComponent.Destroy with LCLRefCount>0. Hint: Maybe the component is processing an event? [TGtk2WidgetSet.Destroy] WARNING: There are 3 unreleased DCs, a detailed dump follows: [TGtk2WidgetSet.Destroy] DCs: B651C470 B651C300 B651C190 [TGtk2WidgetSet.Destroy] WARNING: There are 18 unreleased GDIObjects, a detailed dump follows: [TGtk2WidgetSet.Destroy] GDIOs: B66B7880 B66B7820 B66B77C0 B66B7760 B66B7700 B66B76A0 B66B7640 [TGtk2WidgetSet.Destroy] gdiBitmap: 9 [TGtk2WidgetSet.Destroy] gdiBrush: 5 [TGtk2WidgetSet.Destroy] gdiPen: 4
tout comme dans la procédure de chargement du fichier
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction); begin BufferG.Free; BufferL.Free; BufferR.Free; end;
Ce sont les seuls objets que je crée, alors que se passe-t-il avec ce message d'erreur hermétique ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 //creating music stream chan1 := BASS_StreamCreateFile(FALSE,pchar(filename),0,0,0 {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF}); ... //getting peak levels chan2 := BASS_StreamCreateFile(FALSE,pchar(filename),0,0,BASS_STREAM_DECODE {$IFDEF UNICODE} or BASS_UNICODE {$ENDIF}); ... // affichage, puis BASS_StreamFree(chan1); BASS_StreamFree(chan2);
PS : en remplaçant le TPaintBox par un TImage, le message d'erreur évolue un peu, sans pour autant gagner en clarté hein, faut pas rêver :
Et si je regarde par exemple cet extrait du log (en utilisant heaptrc) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 WARNING: TLCLComponent.Destroy with LCLRefCount>0. Hint: Maybe the component is processing an event? [TGtk2WidgetSet.Destroy] WARNING: There are 2 unreleased DCs, a detailed dump follows: [TGtk2WidgetSet.Destroy] DCs: B635C3E0 B635C220 [TGtk2WidgetSet.Destroy] WARNING: There are 16 unreleased GDIObjects, a detailed dump follows: [TGtk2WidgetSet.Destroy] GDIOs: B7727D10 B7727C60 B7727B00 B7727A50 B77278F0 B7727840 B7727790 [TGtk2WidgetSet.Destroy] gdiBitmap: 8 [TGtk2WidgetSet.Destroy] gdiBrush: 4 [TGtk2WidgetSet.Destroy] gdiPen: 4 Heap dump by heaptrc unit 1021 memory blocks allocated : 1865593/1868032 970 memory blocks freed : 1860789/1863096 51 unfreed memory blocks : 4804 True heap size : 3473408 True free heap : 3464416 Should be : 3465208
on voit qu'il n'y a que deux endroits où je peux intervenir, les deux dernières lignes.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 Call trace for block $B66FD820 size 16 $080721A8 $081B43FB $08120E05 TCANVAS__CREATE, line 1492 of ./include/canvas.inc $081182DF TBITMAPCANVAS__CREATE, line 23 of ./include/bitmapcanvas.inc $08115A05 TRASTERIMAGE__CREATECANVAS, line 308 of ./include/rasterimage.inc $081159CB TRASTERIMAGE__GETCANVAS, line 300 of ./include/rasterimage.inc $08097B4E TFORM1__DRAWSPECTRUM, line 239 of Unit1.pas $080978CB TFORM1__LOADFILE, line 152 of Unit1.pas
La toute dernière se contente d'appeler la procédure de dessin DRAWSPECTRUM qu'on voit en avant-dernière ligne, et sa ligne 239 contient BufferL.Canvas.Brush.Style := bsSolid; et c'est tout.
C'est ça qui me cause une fuite mémoire ?
Il y en a sans doute d'autres, en rapport avec BufferR et BufferG (G comme général, il contiendra L et R) mais le log est assez indigeste.
Faut m'expliquer, là, parce que je rappelle que je free mes buffers dans le FormClose
Merci pour les pistes et les idées, et bon week-end,
Partager