5 using System.Collections.Generic;
6 using System.Collections.Specialized;
8 using SiliconStudio.Core;
9 using SiliconStudio.Core.Collections;
11 using SiliconStudio.Paradox.EntityModel;
12 using SiliconStudio.Paradox.Audio;
13 using SiliconStudio.Paradox.Games;
15 namespace SiliconStudio.
Paradox.Engine
34 internal Dictionary<Entity, AssociatedData> MatchingEntitiesForDebug {
get {
return matchingEntities; } }
66 : base(new
PropertyKey[] { AudioEmitterComponent.Key, TransformationComponent.Key })
70 protected internal override void OnSystemAdd()
74 audioSystem = Services.GetServiceAs<AudioSystem>();
76 audioSystem.Listeners.CollectionChanged += OnListenerCollectionChanged;
85 ListenerControllerToSoundInstance =
new Dictionary<Tuple<AudioListenerComponent, AudioEmitterSoundController>,
SoundEffectInstance>()
89 protected internal override void OnSystemRemove()
91 base.OnSystemRemove();
94 foreach (var soundInstance
in matchingEntities.Values.SelectMany(x => x.AudioEmitterComponent.SoundEffectToController.Values))
95 soundInstance.DestroyAllSoundInstances();
97 audioSystem.Listeners.CollectionChanged -= OnListenerCollectionChanged;
102 base.OnEntityAdding(entity, data);
105 data.TransformationComponent.UpdateWorldMatrix();
106 data.AudioEmitter =
new AudioEmitter { Position = data.TransformationComponent.WorldMatrix.TranslationVector };
109 foreach (var listener
in audioSystem.Listeners.Keys)
111 foreach (var soundController
in data.AudioEmitterComponent.SoundEffectToController.Values)
112 data.ListenerControllerToSoundInstance[Tuple.Create(listener, soundController)] = soundController.CreateSoundInstance();
115 data.AudioEmitterComponent.ControllerCollectionChanged += OnSoundControllerListChanged;
122 foreach (var associatedData
in matchingEntities.Values)
124 var emitter = associatedData.AudioEmitter;
125 var worldMatrix = associatedData.TransformationComponent.WorldMatrix;
126 var newPosition = worldMatrix.TranslationVector;
128 if (!associatedData.AudioEmitterComponent.ShouldBeProcessed)
130 emitter.Position = newPosition;
135 emitter.DistanceScale = associatedData.AudioEmitterComponent.DistanceScale;
136 emitter.DopplerScale = associatedData.AudioEmitterComponent.DopplerScale;
137 emitter.Velocity = newPosition - emitter.Position;
138 emitter.Position = newPosition;
141 var performedAtLeastOneApply =
false;
142 foreach (var controller
in associatedData.AudioEmitterComponent.SoundEffectToController.Values)
144 foreach (var listenerComponent
in audioSystem.Listeners.Keys)
146 var currentTupple = Tuple.Create(listenerComponent, controller);
147 var instance = associatedData.ListenerControllerToSoundInstance[currentTupple];
148 var listener = audioSystem.Listeners[listenerComponent];
150 if (listener == null)
157 if (instance.PlayState ==
SoundPlayState.Playing || controller.ShouldBePlayed)
159 instance.Apply3D(listener, emitter);
160 performedAtLeastOneApply =
true;
164 if (controller.ShouldBePlayed)
166 instance.Volume = controller.Volume;
168 instance.IsLooped = controller.IsLooped && !controller.ShouldExitLoop;
169 instance.Play(
false);
172 controller.ShouldBePlayed =
false;
173 controller.ShouldExitLoop =
false;
176 associatedData.AudioEmitterComponent.ShouldBeProcessed = performedAtLeastOneApply;
182 base.OnEntityRemoved(entity, data);
185 foreach (var soundController
in data.AudioEmitterComponent.SoundEffectToController.Values)
186 soundController.DestroyAllSoundInstances();
188 data.AudioEmitterComponent.ControllerCollectionChanged -= OnSoundControllerListChanged;
199 foreach (var associatedData
in matchingEntities.Values)
201 var listenerControllerToSoundInstance = associatedData.ListenerControllerToSoundInstance;
202 var soundControllers = associatedData.AudioEmitterComponent.SoundEffectToController.Values;
204 foreach (var soundController
in soundControllers)
208 if (args.
Action == NotifyCollectionChangedAction.Add)
210 listenerControllerToSoundInstance[currentTupple] = soundController.CreateSoundInstance();
212 else if (args.
Action == NotifyCollectionChangedAction.Remove)
214 soundController.DestroySoundInstance(listenerControllerToSoundInstance[currentTupple]);
215 listenerControllerToSoundInstance.Remove(currentTupple);
221 private void OnSoundControllerListChanged(
object o, AudioEmitterComponent.ControllerCollectionChangedEventArgs args)
223 AssociatedData associatedData;
224 if (!matchingEntities.TryGetValue(args.Entity, out associatedData))
231 foreach (var listener
in listeners)
233 var currentTuple = Tuple.Create(listener, args.Controller);
235 if (args.
Action == NotifyCollectionChangedAction.Add)
237 associatedData.ListenerControllerToSoundInstance[currentTuple] = args.Controller.CreateSoundInstance();
239 else if(args.
Action == NotifyCollectionChangedAction.Remove )
241 args.Controller.DestroySoundInstance(associatedData.ListenerControllerToSoundInstance[currentTuple]);
242 associatedData.ListenerControllerToSoundInstance.Remove(currentTuple);
override AssociatedData GenerateAssociatedData(Entity entity)
Game entity. It usually aggregates multiple EntityComponent
Data associated to each Entity instances of the system having an AudioEmitterComponent and an Transfo...
override void OnEntityRemoved(Entity entity, AssociatedData data)
Component representing an audio listener.
TransformationComponent TransformationComponent
The Engine.TransformationComponent associated to the entity
SoundPlayState
Current state (playing, paused, or stopped) of a sound implementing the IPlayableSound interface...
AudioEmitterProcessor()
Create a new instance of the processor.
override void Draw(GameTime time)
Entity processor, triggered on various EntitySystem events such as Entity and Component additions and...
AudioEmitterComponent AudioEmitterComponent
The Paradox.Engine.AudioEmitterComponent associated to the entity
override void OnEntityAdding(Entity entity, AssociatedData data)
Current timing used for variable-step (real time) or fixed-step (game time) games.
AudioEmitter AudioEmitter
The Paradox.Audio.AudioEmitter associated to the AudioEmitterComponent.
NotifyCollectionChangedAction Action
Gets the type of action performed. Allowed values are NotifyCollectionChangedAction.Add and NotifyCollectionChangedAction.Remove.
Represents a 3D audio emitter in the audio scene. This object, used in combination with an AudioListe...
bool CollectionChanged
Gets a value indicating whether [collection changed (not a replacement but real insertion/removal)].
object Key
Gets the added or removed key (if dictionary).
The Audio System. It creates an underlying instance of AudioEngine.
Component representing an audio emitter.
Dictionary< Tuple< AudioListenerComponent, AudioEmitterSoundController >, SoundEffectInstance > ListenerControllerToSoundInstance
A dictionary associating each activated listener of the AudioSystem and each sound controller of the ...
A class that represents a tag propety.
Instance of a SoundEffect sound which can be independently localized and played.
Processor in charge of updating the AudioEmitterComponents.