Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
SoundEffectInstance.Windows.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 #if SILICONSTUDIO_PLATFORM_WINDOWS
4 
5 using System;
6 
7 using SiliconStudio.Core.Mathematics;
8 using SiliconStudio.Paradox.Audio.Wave;
9 
10 using SharpDX.XAudio2;
11 using SharpDX.X3DAudio;
12 
13 namespace SiliconStudio.Paradox.Audio
14 {
15  public partial class SoundEffectInstance
16  {
17  #region Implementation of the ILocalizable Interface
18 
19  internal void Apply3DImpl(AudioListener listener, AudioEmitter emitter)
20  {
21  //////////////////////////////////////////////////////////////
22  // 1. First let's calculate the parameters to set to the voice
23  var inputChannels = soundEffect.WaveFormat.Channels;
24  var outputChannels = MasterVoice.VoiceDetails.InputChannelCount;
25 
26  if (inputChannels != 1 || outputChannels != 2)
27  throw new AudioSystemInternalException("Error in Apply3DImpl only mono sounds are supposed to be localizable");
28 
29  var list = new Listener
30  {
31  Position = listener.Position.ToSharpDX(),
32  Velocity = listener.Velocity.ToSharpDX(),
33  OrientFront = listener.Forward.ToSharpDX(),
34  OrientTop = listener.Up.ToSharpDX()
35  };
36  var emit = new Emitter
37  {
38  Position = emitter.Position.ToSharpDX(),
39  Velocity = emitter.Velocity.ToSharpDX(),
40  DopplerScaler = emitter.DopplerScale,
41  CurveDistanceScaler = emitter.DistanceScale,
42  ChannelRadius = 0f, // Multi-channels localizable sound are considered as source of multiple sounds coming from the same location.
43  ChannelCount = inputChannels
44  };
45 
46  var dspSettings = new DspSettings(inputChannels, outputChannels);
47 
48  AudioEngine.X3DAudio.Calculate(list, emit, CalculateFlags.Matrix | CalculateFlags.LpfDirect, dspSettings);
49 
50  /////////////////////////////////////////////////////////////
51  // 2. Now let's set the voice parameters to simulate a 3D voice.
52 
53  // 2.1 The Doppler effect due to the difference of speed between the emitter and listener
54  ComputeDopplerFactor(listener, emitter);
55  UpdatePitch();
56 
57  // 2.2 The channel attenuations due to the source localization.
58  localizationChannelVolumes = new[] { dspSettings.MatrixCoefficients[0], dspSettings.MatrixCoefficients[1] }; // only mono sound can be localized so matrix should be 2*1
59  UpdateStereoVolumes();
60  }
61 
62  internal override void UpdateLooping()
63  {
64  // Nothing to do here for windows version.
65  // All the work is done in LoadBuffer.
66  }
67 
68  internal override void PauseImpl()
69  {
70  SourceVoice.Stop();
71  }
72 
73  internal override void ExitLoopImpl()
74  {
75  SourceVoice.ExitLoop();
76  }
77 
78  internal override void PlayImpl()
79  {
80  SourceVoice.Start();
81  }
82 
83  internal override void StopImpl()
84  {
85  SourceVoice.Stop();
86  SourceVoice.FlushSourceBuffers();
87  }
88 
89  private void UpdateStereoVolumes()
90  {
91  var sourceChannelCount = WaveFormat.Channels;
92 
93  // then update the volume of each channel
94  Single[] matrix;
95  if (sourceChannelCount == 1)
96  { // panChannelVolumes and localizationChannelVolumes are both in [0,1] so multiplication too, no clamp is needed
97  matrix = new[] { panChannelVolumes[0] * localizationChannelVolumes[0], panChannelVolumes[1] * localizationChannelVolumes[1] };
98  }
99  else if (sourceChannelCount == 2)
100  {
101  matrix = new[] { panChannelVolumes[0], 0, 0, panChannelVolumes[1] }; // no localization on stereo sounds.
102  }
103  else
104  {
105  throw new AudioSystemInternalException("The sound is not supposed to contain more than 2 channels");
106  }
107 
108  SourceVoice.SetOutputMatrix(sourceChannelCount, MasterVoice.VoiceDetails.InputChannelCount, matrix);
109  }
110 
111  private void UpdatePitch()
112  {
113  SourceVoice.SetFrequencyRatio(MathUtil.Clamp((float)Math.Pow(2, Pitch) * dopplerPitchFactor, 0.5f, 2f)); // conversion octave to frequencyRatio
114  }
115 
116  #endregion
117 
118  #region Implementation of the IDisposable Interface
119 
120  internal void PlatformSpecificDisposeImpl()
121  {
122  if(SourceVoice == null)
123  return;
124 
125  SourceVoice.DestroyVoice();
126  SourceVoice.Dispose();
127  }
128 
129  #endregion
130 
131  internal SourceVoice SourceVoice;
132 
133  internal void CreateVoice(WaveFormat format)
134  {
135  SourceVoice = new SourceVoice(AudioEngine.XAudio2, format.ToSharpDX(), VoiceFlags.None, 2f, true); // '2f' -> allow to modify pitch up to one octave, 'true' -> enable callback
136  SourceVoice.StreamEnd += Stop;
137  }
138 
139  internal override void LoadBuffer()
140  {
141  var buffer = new AudioBuffer(new SharpDX.DataPointer(soundEffect.WaveDataPtr, soundEffect.WaveDataSize));
142 
143  if (IsLooped)
144  buffer.LoopCount = AudioBuffer.LoopInfinite;
145 
146  SourceVoice.SubmitSourceBuffer(buffer, null);
147  }
148 
149  private void Reset3DImpl()
150  {
151  // nothing to do here.
152  }
153 
154  internal override void UpdateVolume()
155  {
156  SourceVoice.SetVolume(Volume);
157  }
158 
159  private void UpdatePan()
160  {
161  UpdateStereoVolumes();
162  }
163  }
164 }
165 
166 #endif
Gets a single texture view at the specified index in the mip hierarchy and in the array of textures T...
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Definition: DirectXTexP.h:175