diff --git a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs index d093224b3c..34253d5603 100644 --- a/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs +++ b/OpenSim/Region/CoreModules/World/Sound/SoundModule.cs @@ -48,6 +48,18 @@ namespace OpenSim.Region.CoreModules.World.Sound private Scene m_scene; + public enum SoundFlags: byte + { + NONE = 0, + LOOP = 1 << 0, + SYNC_MASTER = 1<<1, + SYNC_SLAVE = 1<<2, + SYNC_PENDING = 1<<3, + QUEUE = 1<<4, + STOP = 1<<5, + SYNC_MASK = SYNC_MASTER | SYNC_SLAVE | SYNC_PENDING + } + public bool Enabled { get; private set; } public float MaxDistance { get; private set; } @@ -124,26 +136,19 @@ namespace OpenSim.Region.CoreModules.World.Sound if (radius == 0) radius = MaxDistance; + if (part.SoundQueueing) + flags |= (byte)SoundFlags.QUEUE; + m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) { - double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); - if (dis > MaxDistance) // Max audio distance - return; - if (grp.IsAttachment) { if (grp.HasPrivateAttachmentPoint && sp.ControllingClient.AgentId != grp.OwnerID) return; - - if (sp.ControllingClient.AgentId == grp.OwnerID) - dis = 0; } - - // Scale by distance - double thisSpGain = gain * ((radius - dis) / radius); - +// no radius ? sp.ControllingClient.SendPlayAttachedSound(soundID, objectID, - ownerID, (float)thisSpGain, flags); + ownerID, (float)gain, flags); }); } @@ -161,9 +166,9 @@ namespace OpenSim.Region.CoreModules.World.Sound { SceneObjectGroup grp = part.ParentGroup; - if (grp.IsAttachment && grp.AttachmentPoint > 30) + if (grp.IsAttachment && grp.HasPrivateAttachmentPoint) { - objectID = ownerID; +// objectID = ownerID; parentID = ownerID; } } @@ -174,16 +179,12 @@ namespace OpenSim.Region.CoreModules.World.Sound m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) { double dis = Util.GetDistanceTo(sp.AbsolutePosition, position); - - if (dis > MaxDistance) // Max audio distance + if (dis > radius) // Max audio distance return; - // Scale by distance - double thisSpGain = gain * ((radius - dis) / radius); - sp.ControllingClient.SendTriggeredSound(soundId, ownerID, objectID, parentID, handle, position, - (float)thisSpGain); + (float)gain); }); } @@ -199,39 +200,12 @@ namespace OpenSim.Region.CoreModules.World.Sound private static void StopSound(SceneObjectPart m_host) { m_host.AdjustSoundGain(0); - // Xantor 20080528: Clear prim data of sound instead - if (m_host.ParentGroup.LoopSoundSlavePrims.Contains(m_host)) - { - if (m_host.ParentGroup.LoopSoundMasterPrim == m_host) - { - foreach (SceneObjectPart part in m_host.ParentGroup.LoopSoundSlavePrims) - { - part.Sound = UUID.Zero; - part.SoundFlags = 1 << 5; - part.SoundRadius = 0; - part.ScheduleFullUpdate(); - part.SendFullUpdateToAllClients(); - } - m_host.ParentGroup.LoopSoundMasterPrim = null; - m_host.ParentGroup.LoopSoundSlavePrims.Clear(); - } - else - { - m_host.Sound = UUID.Zero; - m_host.SoundFlags = 1 << 5; - m_host.SoundRadius = 0; - m_host.ScheduleFullUpdate(); - m_host.SendFullUpdateToAllClients(); - } - } - else - { - m_host.Sound = UUID.Zero; - m_host.SoundFlags = 1 << 5; - m_host.SoundRadius = 0; - m_host.ScheduleFullUpdate(); - m_host.SendFullUpdateToAllClients(); - } + m_host.Sound = UUID.Zero; + m_host.SoundFlags = (byte)SoundFlags.STOP; + m_host.SoundRadius = 0; + m_host.SoundGain = 0; + m_host.ScheduleFullUpdate(); + m_host.SendFullUpdateToAllClients(); } public virtual void PreloadSound(UUID objectID, UUID soundID, float radius) @@ -248,7 +222,7 @@ namespace OpenSim.Region.CoreModules.World.Sound m_scene.ForEachRootScenePresence(delegate(ScenePresence sp) { - if (!(Util.GetDistanceTo(sp.AbsolutePosition, part.AbsolutePosition) >= MaxDistance)) + if (Util.GetDistanceTo(sp.AbsolutePosition, part.AbsolutePosition) < radius) sp.ControllingClient.SendPreLoadSound(objectID, objectID, soundID); }); } @@ -262,21 +236,31 @@ namespace OpenSim.Region.CoreModules.World.Sound // 20080530 Updated to remove code duplication // 20080530 Stop sound if there is one, otherwise volume only changes don't work public void LoopSound(UUID objectID, UUID soundID, - double volume, double radius, bool isMaster) + double volume, double radius, bool isMaster, bool isSlave) { SceneObjectPart m_host; if (!m_scene.TryGetSceneObjectPart(objectID, out m_host)) return; - if (isMaster) - m_host.ParentGroup.LoopSoundMasterPrim = m_host; +// if (isMaster) +// m_host.ParentGroup.LoopSoundMasterPrim = m_host; - if (m_host.Sound != UUID.Zero) - StopSound(m_host); + // sl does not stop previus sound, volume changes don't work (wiki) +// if (m_host.Sound != UUID.Zero) +// StopSound(m_host); + + byte iflags = 1; // looping + if (isMaster) + iflags |= (byte)SoundFlags.SYNC_MASTER; + // TODO check viewer seems to accept both + if (isSlave) + iflags |= (byte)SoundFlags.SYNC_SLAVE; + if (m_host.SoundQueueing) + iflags |= (byte)SoundFlags.QUEUE; m_host.Sound = soundID; m_host.SoundGain = volume; - m_host.SoundFlags = 1; // looping + m_host.SoundFlags = iflags; m_host.SoundRadius = radius; m_host.ScheduleFullUpdate(); @@ -301,42 +285,19 @@ namespace OpenSim.Region.CoreModules.World.Sound Vector3 position = part.AbsolutePosition; // region local ulong regionHandle = m_scene.RegionInfo.RegionHandle; - if (useMaster) - { - if (isMaster) - { - if (triggered) - TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius); - else - PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius); - part.ParentGroup.PlaySoundMasterPrim = part; - if (triggered) - TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius); - else - PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius); - foreach (SceneObjectPart prim in part.ParentGroup.PlaySoundSlavePrims) - { - position = prim.AbsolutePosition; // region local - if (triggered) - TriggerSound(soundID, part.OwnerID, prim.UUID, parentID, volume, position, regionHandle, radius); - else - PlayAttachedSound(soundID, part.OwnerID, prim.UUID, volume, position, flags, radius); - } - part.ParentGroup.PlaySoundSlavePrims.Clear(); - part.ParentGroup.PlaySoundMasterPrim = null; - } - else - { - part.ParentGroup.PlaySoundSlavePrims.Add(part); - } - } + if(triggered) + TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius); else { - if (triggered) - TriggerSound(soundID, part.OwnerID, part.UUID, parentID, volume, position, regionHandle, radius); - else - PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, flags, radius); - } + byte bflags = 0; + + if (isMaster) + bflags |= (byte)SoundFlags.SYNC_MASTER; + // TODO check viewer seems to accept both + if (useMaster) + bflags |= (byte)SoundFlags.SYNC_SLAVE; + PlayAttachedSound(soundID, part.OwnerID, part.UUID, volume, position, bflags, radius); + } } public void TriggerSoundLimited(UUID objectID, UUID sound, diff --git a/OpenSim/Region/Framework/Interfaces/ISoundModule.cs b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs index 8372ddddf8..f7c6513cd1 100644 --- a/OpenSim/Region/Framework/Interfaces/ISoundModule.cs +++ b/OpenSim/Region/Framework/Interfaces/ISoundModule.cs @@ -95,7 +95,7 @@ namespace OpenSim.Region.Framework.Interfaces /// Sound radius /// Set object to sync master if true void LoopSound(UUID objectID, UUID soundID, double gain, - double radius, bool isMaster); + double radius, bool isMaster, bool isSlave); /// /// Trigger or play an attached sound in this part's inventory. diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 9527fa524c..ba97c47b90 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -908,14 +908,14 @@ namespace OpenSim.Region.Framework.Scenes } } } - + // PlaySoundMasterPrim no longer in use to remove private SceneObjectPart m_PlaySoundMasterPrim = null; public SceneObjectPart PlaySoundMasterPrim { get { return m_PlaySoundMasterPrim; } set { m_PlaySoundMasterPrim = value; } } - + // PlaySoundSlavePrims no longer in use to remove private List m_PlaySoundSlavePrims = new List(); public List PlaySoundSlavePrims { @@ -923,6 +923,7 @@ namespace OpenSim.Region.Framework.Scenes set { m_PlaySoundSlavePrims = value; } } + // LoopSoundMasterPrim no longer in use to remove private SceneObjectPart m_LoopSoundMasterPrim = null; public SceneObjectPart LoopSoundMasterPrim { @@ -930,6 +931,7 @@ namespace OpenSim.Region.Framework.Scenes set { m_LoopSoundMasterPrim = value; } } + // m_LoopSoundSlavePrims no longer in use to remove private List m_LoopSoundSlavePrims = new List(); public List LoopSoundSlavePrims { diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 4cb65d47b6..c65f9334e6 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -2844,7 +2844,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_SoundModule.SendSound( m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), - volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None, + volume, false, 0, 0, false, false); } } @@ -2855,7 +2855,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_SoundModule != null) { m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), - volume, 20, false); + volume, 20, false,false); } } @@ -2865,16 +2865,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (m_SoundModule != null) { m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), - volume, 20, true); + volume, 20, true, false); } } public void llLoopSoundSlave(string sound, double volume) { m_host.AddScriptLPS(1); - lock (m_host.ParentGroup.LoopSoundSlavePrims) + if (m_SoundModule != null) { - m_host.ParentGroup.LoopSoundSlavePrims.Add(m_host); + m_SoundModule.LoopSound(m_host.UUID, ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound), + volume, 20, false, true); } }