From 4ebb37fbb4934073dfd6329dcaef461c87c4b7dc Mon Sep 17 00:00:00 2001 From: Latif Khalifa Date: Thu, 3 Jun 2010 05:31:38 +0000 Subject: [PATCH] Protect against nullref in StopSound(). Override EndCallback to free memory. git-svn-id: https://radegast.googlecode.com/svn/trunk@672 f7a694da-4d33-11de-9ad6-1127a62b9fcd --- Radegast/Core/Media/BufferSound.cs | 59 ++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/Radegast/Core/Media/BufferSound.cs b/Radegast/Core/Media/BufferSound.cs index 0b4519c..088fe56 100644 --- a/Radegast/Core/Media/BufferSound.cs +++ b/Radegast/Core/Media/BufferSound.cs @@ -56,8 +56,8 @@ namespace Radegast.Media /// Creates a new sound object /// /// Sound system - public BufferSound( UUID objectId, UUID soundId, bool loop, bool global, Vector3 worldpos, float vol ) - :base() + public BufferSound(UUID objectId, UUID soundId, bool loop, bool global, Vector3 worldpos, float vol) + : base() { InitBuffer(objectId, soundId, loop, global, worldpos, vol); } @@ -72,7 +72,7 @@ namespace Radegast.Media { // Do not let this get garbage-collected. lock (allBuffers) - allBuffers[objectId] =this; + allBuffers[objectId] = this; ContainerId = objectId; Id = soundId; @@ -109,7 +109,7 @@ namespace Radegast.Media new AssetManager.AssetReceivedCallback(Assets_OnSoundReceived)); } - public static void Kill( UUID id ) + public static void Kill(UUID id) { if (allBuffers.ContainsKey(id)) { @@ -150,11 +150,11 @@ namespace Radegast.Media private void AdjustVolume() { //TODO This is disabled until we find why FMOD objects to the handle -// Volume = volumeSetting * AllObjectVolume; + // Volume = volumeSetting * AllObjectVolume; } // A simpler constructor used by PreFetchSound. - public BufferSound( UUID soundId ) + public BufferSound(UUID soundId) : base() { lock (allBuffers) @@ -194,7 +194,7 @@ namespace Radegast.Media return; } -// Logger.Log("Opening sound " + Id.ToString(), Helpers.LogLevel.Debug); + // Logger.Log("Opening sound " + Id.ToString(), Helpers.LogLevel.Debug); // Decode the Ogg Vorbis buffer. AssetSound s = asset as AssetSound; @@ -204,6 +204,7 @@ namespace Radegast.Media // Describe the data to FMOD extraInfo.length = (uint)data.Length; extraInfo.nonblockcallback = loadCallback; + extraInfo.cbsize = Marshal.SizeOf(extraInfo); invoke(new SoundDelegate(delegate { @@ -216,7 +217,7 @@ namespace Radegast.Media // Register for callbacks. RegisterSound(sound); - })); + })); } else { @@ -242,7 +243,7 @@ namespace Radegast.Media { uint soundlen = 0; FMODExec(sound.getLength(ref soundlen, TIMEUNIT.PCM)); - FMODExec( sound.setLoopPoints( 0, TIMEUNIT.PCM, soundlen-1, TIMEUNIT.PCM )); + FMODExec(sound.setLoopPoints(0, TIMEUNIT.PCM, soundlen - 1, TIMEUNIT.PCM)); FMODExec(sound.setLoopCount(-1)); } @@ -254,7 +255,11 @@ namespace Radegast.Media sound.getRaw().ToString("X"), Id), Helpers.LogLevel.Debug); - FMODExec(channel.setVolume(volumeSetting * AllObjectVolume )); + + lock (allChannels) + allChannels[channel.getRaw()] = this; + + FMODExec(channel.setVolume(volumeSetting * AllObjectVolume)); // Take note of when the sound is finished playing. FMODExec(channel.setCallback(endCallback)); @@ -280,24 +285,12 @@ namespace Radegast.Media } /// - /// Callback handler for reaching the end of a sound. + /// Handles stop sound even from FMOD /// - /// - /// - /// - /// - /// - private RESULT EndCallback( - IntPtr channelraw, - CHANNEL_CALLBACKTYPE type, - IntPtr commanddata1, - IntPtr commanddata2) + /// RESULT.OK + protected override RESULT EndCallbackHandler() { - // Ignore other callback types. - if (type != CHANNEL_CALLBACKTYPE.END) return RESULT.OK; - StopSound(); - return RESULT.OK; } @@ -307,24 +300,28 @@ namespace Radegast.Media invoke(new SoundDelegate(delegate { - Logger.Log( String.Format("Removing channel {0} sound {1} ID {2}", - channel.getRaw().ToString("X"), - sound.getRaw().ToString("X"), - Id.ToString()), - Helpers.LogLevel.Debug); + string chanStr = "none"; + string soundStr = "none"; // Release the buffer to avoid a big memory leak. if (channel != null) { + chanStr = channel.getRaw().ToString("X"); channel.stop(); channel = null; } if (sound != null) { + soundStr = sound.getRaw().ToString("X"); sound.release(); sound = null; } - channel = null; + + Logger.Log(String.Format("Removing channel {0} sound {1} ID {2}", + chanStr, + soundStr, + Id.ToString()), + Helpers.LogLevel.Debug); lock (allBuffers) allBuffers.Remove(ContainerId); -- 2.11.0