@@ -23,27 +23,32 @@ function( Client, Preferences, Memory )
2323 var _sounds = [ ] ;
2424
2525
26+ /**
27+ * Re-usable sounds
28+ */
29+ var _cache = [ ] ;
30+
31+
2632 /**
2733 * @Constructor
2834 */
29- var Sound = { } ;
35+ var SoundManager = { } ;
3036
3137
3238 /**
3339 * @var {float} sound volume
3440 *
3541 */
36- Sound . volume = Preferences . Sound . volume ;
42+ SoundManager . volume = Preferences . Sound . volume ;
3743
3844
3945 /**
4046 * Play a wav sound
4147 *
4248 * @param {string } filename
4349 * @param {optional|number } vol (volume)
44- * @param {optional|boolean } auto-repeat
4550 */
46- Sound . play = function play ( filename , vol , repeat ) {
51+ SoundManager . play = function play ( filename , vol ) {
4752 var volume ;
4853
4954 // Sound volume * Global volume
@@ -59,30 +64,39 @@ function( Client, Preferences, Memory )
5964 return ;
6065 }
6166
67+ // Re-usable sound
68+ var sound = getSoundFromCache ( filename ) ;
69+ if ( sound ) {
70+ sound . volume = Math . min ( volume , 1.0 ) ;
71+ sound . _volume = volume ;
72+ sound . tick = Date . now ( ) ;
73+ sound . play ( ) ;
74+ _sounds . push ( sound ) ;
75+ return ;
76+ }
77+
6278 // Get the sound from client.
6379 Client . loadFile ( 'data/wav/' + filename , function ( url ) {
64- var sound = document . createElement ( 'audio' ) ;
80+ var i , count = _sounds . length ;
81+ var sound , tick = Date . now ( ) ;
82+
83+ // Wait a delay to replay a sound
84+ for ( i = 0 ; i < count ; ++ i ) {
85+ if ( _sounds [ i ] . src === url && _sounds [ i ] . tick > tick - 100 ) {
86+ return ;
87+ }
88+ }
6589
6690 // Initialiaze the sound and play it
91+ sound = document . createElement ( 'audio' ) ;
6792 sound . filename = filename ;
6893 sound . src = url ;
94+ sound . tick = tick ;
6995 sound . volume = Math . min ( volume , 1.0 ) ;
7096 sound . _volume = volume ;
71- sound . play ( ) ;
7297
73- // Once the sound finish, remove it from memory
74- sound . addEventListener ( 'ended' , function Remove ( ) {
75- var pos = _sounds . indexOf ( this ) ;
76- if ( pos !== - 1 ) {
77- if ( repeat ) {
78- sound . currentTime = 0 ;
79- sound . play ( ) ;
80- }
81- else {
82- _sounds . splice ( pos , 1 ) ;
83- }
84- }
85- } , false ) ;
98+ sound . addEventListener ( 'ended' , onSoundEnded , false ) ;
99+ sound . play ( ) ;
86100
87101 // Add it to the list
88102 _sounds . push ( sound ) ;
@@ -95,7 +109,7 @@ function( Client, Preferences, Memory )
95109 *
96110 * @param {optional|string } filename to stop
97111 */
98- Sound . stop = function stop ( filename )
112+ SoundManager . stop = function stop ( filename )
99113 {
100114 var i , count , list ;
101115
@@ -130,7 +144,7 @@ function( Client, Preferences, Memory )
130144 *
131145 * @param {number } volume
132146 */
133- Sound . setVolume = function setVolume ( volume )
147+ SoundManager . setVolume = function setVolume ( volume )
134148 {
135149 var i , count = _sounds . length ;
136150 this . volume = Math . min ( volume , 1.0 ) ;
@@ -144,9 +158,62 @@ function( Client, Preferences, Memory )
144158 } ;
145159
146160
161+ /**
162+ * Move sound to cache.
163+ * ff we have a request to play the same sound again, get it back
164+ * Will avoid to re-create sound object at each request (re-usable object)
165+ */
166+ function onSoundEnded ( )
167+ {
168+ var pos = _sounds . indexOf ( this ) ;
169+
170+ if ( pos !== - 1 ) {
171+ _sounds . splice ( pos , 1 ) ;
172+ }
173+
174+ this . tick = Date . now ( ) ;
175+ _cache . push ( this ) ;
176+ }
177+
178+
179+ /**
180+ * Remove sound from cache and return it
181+ * Check at the same time to remove sound not used since some times.
182+ *
183+ * @param {string } filename
184+ * @param {Audio } sound element
185+ */
186+ function getSoundFromCache ( filename )
187+ {
188+ var i , tick = Date . now ( ) , count = _cache . length ;
189+ var out = null ;
190+
191+ for ( i = 0 ; i < count ; i ++ ) {
192+ if ( ! out && _cache [ i ] . filename === filename ) {
193+ out = _cache [ i ] ;
194+ out . tick = tick ;
195+ _cache . splice ( i , 1 ) ;
196+ i -- ;
197+ count -- ;
198+ continue ;
199+ }
200+
201+ // remove
202+ if ( _cache [ i ] . tick + 60000 < tick ) {
203+ _cache . splice ( i , 1 ) ;
204+ i -- ;
205+ count -- ;
206+ continue ;
207+ }
208+ }
209+
210+ return out ;
211+ }
212+
213+
147214 /**
148215 * Export
149216 */
150- return Sound ;
217+ return SoundManager ;
151218
152219} ) ;
0 commit comments