Reputation: 149
I'm extremely new to programming and have still to master a lot of the basics. But I've managed to make an entire Program with help from here and there. However, I think I've got a Memory Leak with regards to my resources, again I'm new and almost certain this is a clumsy way to go about doing this...
I currently have background music in my application which uses a .wav file stored in My.Resources. I've implemented multiple measures to enable, disable and mute the audio successfully, but I've hit a snag when I introduced multiple audio tracks. The idea is to give the end-user an option between 4 background songs (stored as 4 .wav resources) in the 'settings' area of my program. When I build & test the solution it runs great, everything as expected. Then when I change the audio to a different track in the settings area, it works also. The snag happens when I change the song multiple times, I get a OutOfMemory error.
I think I understand what's happening; the resource is being added to the memory each time the user selects it, But I have no idea on how to remove -say- song1 from the memory if -say- song2 is selected. Here's my code which handles the selection & playing of the audio.
(The program uses radio buttons refereed to as '%chkbox' and requires the user to hit 'savebtn' before this code is ran.) Using Visual Basics 2012 .net 4.5
'Save and start songs.
If DjErhain_Mistychkbox.Checked = True Then
My.Settings.AudioDJErhain_UWBeats_Maniac = 0
My.Settings.Save()
My.Settings.AudioDjErhain_Misty = 1
My.Settings.Save()
My.Settings.AudioMachinimaSound_Exigence = 0
My.Settings.Save()
My.Settings.AudioSimplex_Memories_master = 0
My.Settings.Save()
My.Computer.Audio.Play(My.Resources.DjErhain_Misty, AudioPlayMode.BackgroundLoop)
ElseIf DJErhain_UWBeats_Maniacckbox.Checked = True Then
My.Settings.AudioDjErhain_Misty = 0
My.Settings.Save()
My.Settings.AudioDJErhain_UWBeats_Maniac = 1
My.Settings.Save()
My.Settings.AudioMachinimaSound_Exigence = 0
My.Settings.Save()
My.Settings.AudioSimplex_Memories_master = 0
My.Settings.Save()
My.Computer.Audio.Play(My.Resources.DJErhain_UWBeats_Maniac, AudioPlayMode.BackgroundLoop)
ElseIf MachinimaSound_Exigencechckbox.Checked = True Then
My.Settings.AudioMachinimaSound_Exigence = 1
My.Settings.Save()
My.Settings.AudioDJErhain_UWBeats_Maniac = 0
My.Settings.Save()
My.Settings.AudioDjErhain_Misty = 0
My.Settings.Save()
My.Settings.AudioSimplex_Memories_master = 0
My.Settings.Save()
My.Computer.Audio.Play(My.Resources.MachinimaSound_Exigence, AudioPlayMode.BackgroundLoop)
ElseIf Simplex_Memories_masterchckbox.Checked = True Then
My.Settings.AudioSimplex_Memories_master = 1
My.Settings.Save()
My.Settings.AudioDJErhain_UWBeats_Maniac = 0
My.Settings.Save()
My.Settings.AudioDjErhain_Misty = 0
My.Settings.Save()
My.Settings.AudioMachinimaSound_Exigence = 0
My.Settings.Save()
My.Computer.Audio.Play(My.Resources.Simplex_Memories_master, AudioPlayMode.BackgroundLoop)
Else
End If
Upvotes: 2
Views: 770
Reputation: 941545
Yes, this is likely to go wrong, the .wav format is not very compact. When you put it in a resource then using the resource is going to create an UnmanagedMemoryStream. It should be disposed when you don't use it anymore, the garbage collector won't run often enough to keep you out of trouble.
Add a new Module to your project and paste this code:
Imports System.IO
Module PlayerUtilities
Private CurrentStream As WeakReference(Of Stream)
Public Sub PlayResource(wave As Stream)
My.Computer.Audio.Play(wave, AudioPlayMode.BackgroundLoop)
Dim oldwave As Stream = Nothing
If CurrentStream IsNot Nothing AndAlso CurrentStream.TryGetTarget(oldwave) Then
oldwave.Dispose()
End If
CurrentStream = New WeakReference(Of Stream)(wave)
End Sub
End Module
And replace your calls to My.Computer.Audio.Play() with PlayResource(). The Dispose() call in this method on the previous audio stream will keep you out of trouble.
Upvotes: 1