source: 2014/24/EemeliK/Zombieland/Jypeli/Sound/SoundEffect.cs @ 5974

Revision 5974, 4.8 KB checked in by empaheik, 5 years ago (diff)
Line 
1using System;
2using System.Diagnostics;
3using Microsoft.Xna.Framework.Audio;
4
5using XnaSoundEffect = Microsoft.Xna.Framework.Audio.SoundEffect;
6using System.Collections.Generic;
7
8namespace Jypeli
9{
10    /// <summary>
11    /// Ääniefekti. Yhdestä efektistä voi luoda <c>CreateSound</c>-metodilla monta ääntä (<c>Sound</c>),
12    /// jotka voivat soida yhtäaikaa. Ääntä ei tarvitse kuitenkaan luoda itse, jos vain kutsuu
13    /// <c>Play</c>-metodia.
14    /// </summary>
15    public class SoundEffect
16    {
17        List<Sound> Instances = new List<Sound>();
18
19        private string assetName;
20        XnaSoundEffect xnaEffect;
21        Timer posTimer;
22
23        /// <summary>
24        /// Ääniefektin kesto sekunteina.
25        /// </summary>
26        public TimeSpan Duration { get { DoLoad(); return xnaEffect.Duration; } }
27
28        /// <summary>
29        /// Paikka äänessä sekunteina (missä kohtaa toistoa ollaan). Ei voi asettaa.
30        /// </summary>
31        public DoubleMeter Position { get; set; }
32
33        /// <summary>
34        /// Toistetaanko ääntä parhaillaan.
35        /// </summary>
36        public bool IsPlaying { get; private set; }
37
38        private void DoLoad()
39        {
40            if (xnaEffect == null)
41            {
42                Debug.Assert(assetName != null);
43                xnaEffect = Game.Instance.Content.Load<XnaSoundEffect>(assetName);
44            }
45
46            Position.MaxValue = xnaEffect.Duration.TotalSeconds;
47        }
48
49        internal SoundEffect(string assetName)
50        {
51            this.assetName = assetName;
52            this.xnaEffect = null;
53            InitPosition();
54        }
55
56        internal SoundEffect( XnaSoundEffect effect )
57        {
58            this.Position = new DoubleMeter(0, 0, 0);
59            this.assetName = null;
60            xnaEffect = effect;
61            InitPosition();
62        }
63
64        private void InitPosition()
65        {
66            Position = new DoubleMeter(0, 0, 0);
67            posTimer = new Timer();
68            posTimer.Interval = 0.01;
69            posTimer.Timeout += new Action(IncrementPosition);
70            Position.UpperLimit += EffectPlayed;
71        }
72
73        private void IncrementPosition()
74        {
75            Position.Value += posTimer.Interval;
76        }
77
78        private void EffectPlayed()
79        {
80            posTimer.Stop();
81            Position.Reset();
82            Instances.Clear();
83            IsPlaying = false;
84        }
85
86        /// <summary>
87        /// Luo Sound-tyyppisen olion. Oliolla on ominaisuuksia kuten voimakkuus ja korkeus
88        /// joita voidaan muuttaa soiton aikana.
89        /// </summary>
90        /// <returns></returns>
91        public Sound CreateSound()
92        {
93            DoLoad();
94            return new Sound( xnaEffect.CreateInstance() );
95        }
96
97        /// <summary>
98        /// Soittaa äänen.
99        /// </summary>
100        /// <returns></returns>
101        public bool Play()
102        {
103            DoLoad();
104            Sound sound = CreateSound();
105            if (sound == null) return false;
106
107            StartPlaying( sound );
108            return true;
109        }
110
111        /// <summary>
112        /// Soittaa äänen.
113        /// </summary>
114        /// <param name="volume">Äänenvoimakkuus 0.0 - 1.0</param>
115        /// <param name="pitch">Äänen taajuusmuutos. -1.0 = oktaavi alaspäin, 1.0 = oktaavi ylöspäin, 0.0 = normaali.</param>
116        /// <param name="pan">Balanssi eli kummasta kaiuttimesta ääni kuuluu enemmän. -1.0 = kokonaan vasemmasta, 1.0 = kokonaan oikeasta, 0.0 = yhtä paljon kummastakin </param>
117        /// <returns></returns>
118        public bool Play( double volume, double pitch, double pan )
119        {
120            DoLoad();
121            Sound sound = CreateSound();
122            if (sound == null) return false;
123
124            sound.Volume = volume;
125            sound.Pitch = pitch;
126            sound.Pan = pan;
127
128            StartPlaying( sound );
129            return true;
130        }
131
132        private void StartPlaying( Sound sound )
133        {
134            sound.Play();
135            Instances.Add( sound );
136            Position.Reset();
137            posTimer.Start();
138            IsPlaying = true;
139        }
140
141        /// <summary>
142        /// Pysäyttää äänen toistamisen.
143        /// </summary>
144        public void Stop()
145        {
146            foreach (var sound in Instances)
147            {
148                sound.Stop();
149            }
150
151            EffectPlayed();
152        }
153
154        /// <summary>
155        /// Äänenvoimakkuuden taso 0.0 - 1.0
156        /// </summary>
157        public static double MasterVolume
158        {
159            set { XnaSoundEffect.MasterVolume = (float)value; }
160            get { return XnaSoundEffect.MasterVolume; }
161        }
162    }
163}
Note: See TracBrowser for help on using the repository browser.