1//
2//   Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
3//   Foundation, Inc
4//
5// This program is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program; if not, write to the Free Software
17// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18//
19
20// Test case for Sound ActionScript class
21// compile this test case with Ming makeswf, and then
22// execute it like this gnash -1 -r 0 -v out.swf
23
24
25rcsid="Sound.as";
26#include "check.as"
27
28endOfTest = function()
29{
30#if OUTPUT_VERSION > 5
31    check_totals(112);
32#else
33    check_totals(94);
34#endif
35    play();
36};
37
38
39// test Sound class and interface availability
40
41check_equals(typeof(Sound), 'function');
42check_equals(typeof(Sound.prototype), 'object');
43check_equals(typeof(Sound.prototype.__proto__), 'object');
44check_equals(Sound.prototype.__proto__, Object.prototype);
45
46check_equals(typeof(Sound.prototype.attachSound), 'function');
47check_equals(typeof(Sound.prototype.getPan), 'function');
48check_equals(typeof(Sound.prototype.setPan), 'function');
49check_equals(typeof(Sound.prototype.start), 'function');
50check_equals(typeof(Sound.prototype.stop), 'function');
51check_equals(typeof(Sound.prototype.getTransform), 'function');
52check_equals(typeof(Sound.prototype.setTransform), 'function');
53check_equals(typeof(Sound.prototype.getVolume), 'function');
54check_equals(typeof(Sound.prototype.setVolume), 'function');
55
56#if OUTPUT_VERSION > 5
57 var functionSinceSWF6 = 'function';
58#else
59 var functionSinceSWF6 = 'undefined';
60#endif
61check_equals(typeof(Sound.prototype.getDuration), functionSinceSWF6);
62check_equals(typeof(Sound.prototype.setDuration), functionSinceSWF6);
63check_equals(typeof(Sound.prototype.loadSound), functionSinceSWF6);
64check_equals(typeof(Sound.prototype.getPosition), functionSinceSWF6);
65check_equals(typeof(Sound.prototype.setPosition), functionSinceSWF6);
66check_equals(typeof(Sound.prototype.getBytesLoaded), functionSinceSWF6);
67check_equals(typeof(Sound.prototype.getBytesTotal), functionSinceSWF6);
68
69// The ones below are undefined in SWF5..SWF8, chances are an ASSetPropFlags
70// to drop the onlyForSWF9 flag would expose them (TODO: test that)
71check_equals(typeof(Sound.prototype.areSoundInaccessible), 'undefined');
72check_equals(typeof(Sound.prototype.duration), 'undefined');
73check_equals(typeof(Sound.prototype.ID3), 'undefined');
74check_equals(typeof(Sound.prototype.checkPolicyFile), 'undefined');
75check_equals(typeof(Sound.prototype.position), 'undefined');
76check_equals(typeof(Sound.prototype.onID3), 'undefined');
77check_equals(typeof(Sound.prototype.onLoad), 'undefined');
78check_equals(typeof(Sound.prototype.onSoundComplete), 'undefined');
79
80
81//-----------------------------------------
82// Test Sound constructor
83//-----------------------------------------
84
85//
86// Use default constructor and check return of all inspectors
87//
88
89// It seems like if Sound ctor is passed nothing, undefined or null
90// it gets associated to some kind of global volume which is DIFFERENT
91// from the one associated with _root...
92//
93s1 = new Sound();
94s2 = new Sound();
95check(s1 instanceof Sound);
96check_equals(typeof(s1.getDuration()), 'undefined');
97xcheck_equals(typeof(s1.getPan()), 'number');
98xcheck_equals(s1.getPan(), 0);
99check_equals(typeof(s1.getPosition()), 'undefined');
100xcheck_equals(typeof(s1.getTransform()), 'object'); // TODO: check composition
101
102// Now, it seems s1 and s2 are both attached to something, and share
103// the volume !
104check_equals(typeof(s1.getVolume()), 'number');
105check_equals(s1.getVolume(), 100); // why, since we didn't specify an attached char ??
106s1.setVolume(95);
107check_equals(s1.getVolume(), 95);
108check_equals(s2.getVolume(), 95);
109
110check_equals(typeof(s1.getBytesLoaded()), 'undefined');
111check_equals(typeof(s1.getBytesTotal()), 'undefined');
112xcheck_equals(typeof(s1.checkPolicyFile), 'boolean');
113
114// The following are undefined in SWF5..SWF8, chances are
115// some ASSetPropFlag to drop SWF9-only flag would expose
116check_equals(typeof(s1.duration), 'undefined');
117check_equals(typeof(s1.ID3), 'undefined');
118check_equals(typeof(s1.position), 'undefined');
119
120#if OUTPUT_VERSION > 5
121
122// We hope that this is loaded in before the test finishes.
123
124#if 0
125
126click = new Sound();
127click.onLoad = function() {
128    note("onLoad");
129    // Is called after onID3
130    check_equals(typeof(click.id3), "object");
131};
132
133click.onID3 = function() {
134    note("onID3");
135    xcheck_equals(typeof(click.id3), "object");
136    xcheck_equals(click.id3.album, "Gnash");
137    xcheck_equals(click.id3.songname, "Clicky");
138    xcheck_equals(click.id3.artist, "Benjamin Wolsey");
139    xcheck_equals(click.id3.comment, "Gnash can read this.");
140    xcheck_equals(click.id3.year, "2011");
141    xcheck_equals(click.id3.genre, "42");
142};
143
144click.loadSound(MEDIA(click.mp3), false);
145
146#endif
147
148wav = new Sound();
149wav.onID3 = function() {
150    fail("Should not be called for wave sounds!");
151};
152wav.loadSound(MEDIA(brokenchord.wav), false);
153
154mp3 = new Sound();
155mp3.onID3 = function() {
156    fail("Should not be called where no tag is present.");
157};
158mp3.loadSound(MEDIA(stereo8.mp3), false);
159
160
161#endif
162
163
164//
165// Use constructor taking a movieclip and check return of all inspectors
166//
167
168s2 = new Sound(_root);
169check(s2 instanceof Sound);
170check_equals(typeof(s2.getDuration()), 'undefined');
171xcheck_equals(typeof(s2.getPan()), 'number');
172xcheck_equals(s2.getPan(), 0);
173check_equals(typeof(s2.getPosition()), 'undefined');
174xcheck_equals(typeof(s2.getTransform()), 'object'); // TODO: check composition
175check_equals(typeof(s2.getVolume()), 'number');
176check_equals(s2.getVolume(), 100);
177check_equals(typeof(s2.getBytesLoaded()), 'undefined');
178check_equals(typeof(s2.getBytesTotal()), 'undefined');
179xcheck_equals(typeof(s2.checkPolicyFile), 'boolean');
180
181// The following are undefined in SWF5..SWF8, chances are
182// some ASSetPropFlag to drop SWF9-only flag would expose
183check_equals(typeof(s2.duration), 'undefined');
184check_equals(typeof(s2.ID3), 'undefined');
185check_equals(typeof(s2.position), 'undefined');
186
187// this is still valid, altought getVolume would return undefined
188s3 = new Sound(33);
189check(s3 instanceof Sound);
190check_equals(typeof(s3.getVolume()), 'undefined');
191
192//-----------------------------------------
193// Test association of Sound to characters
194//-----------------------------------------
195
196
197s1a = new Sound();
198s1b = new Sound();
199check_equals(s1a.getVolume(), 95);
200check_equals(s1b.getVolume(), 95);
201s1b.setVolume(76);
202check_equals(s1a.getVolume(), 76);
203check_equals(s1b.getVolume(), 76);
204
205// Numbers are invalid controllable-characters
206s1c = new Sound(54);
207s1d = new Sound(54);
208check_equals(typeof(s1c.getVolume()), 'undefined');
209check_equals(typeof(s1d.getVolume()), 'undefined');
210s1c.setVolume(54);
211check_equals(typeof(s1c.getVolume()), 'undefined');
212check_equals(typeof(s1d.getVolume()), 'undefined');
213
214s1e = new Sound(null);
215s1f = new Sound(undefined);
216check_equals(s1e.getVolume(), 76);
217check_equals(s1f.getVolume(), 76);
218
219// Objects are invalid controllable characters
220o = new Object;
221s1g = new Sound(o);
222s1h = new Sound(o);
223check_equals(typeof(s1g.getVolume()), 'undefined');
224check_equals(typeof(s1h.getVolume()), 'undefined');
225s1g.setVolume(54);
226check_equals(typeof(s1g.getVolume()), 'undefined');
227check_equals(typeof(s1h.getVolume()), 'undefined');
228
229s2 = new Sound(_root);
230s3 = new Sound(_root);
231
232check_equals(s2.getVolume(), 100);
233check_equals(s3.getVolume(), 100);
234s2.setVolume(80);
235check_equals(s2.getVolume(), 80);
236check_equals(s3.getVolume(), 80);
237
238
239// Check association to unloaded characters, and rebinding
240MovieClip.prototype.createEmptyMovieClip = ASnative(901, 0);
241createEmptyMovieClip('c1', 1);
242s2 = new Sound(c1);
243s3 = new Sound(c1);
244check_equals(s2.getVolume(), 100);
245check_equals(s3.getVolume(), 100);
246c1.removeMovieClip(); // unload, no unload handler
247check_equals(typeof(s2.getVolume()), 'undefined');
248check_equals(typeof(s3.getVolume()), 'undefined');
249createEmptyMovieClip('c1', 2); // rebind ref to _level0.c1
250check_equals(s2.getVolume(), 100);
251check_equals(s3.getVolume(), 100);
252s2.setVolume(80);
253check_equals(s2.getVolume(), 80);
254check_equals(s3.getVolume(), 80);
255c1.removeMovieClip(); // unload, no unload handler
256check_equals(typeof(s2.getVolume()), 'undefined');
257check_equals(typeof(s3.getVolume()), 'undefined');
258createEmptyMovieClip('c1', 3); // rebind ref to _level0.c1
259check_equals(s2.getVolume(), 100); // old volume isn't remembered
260check_equals(s3.getVolume(), 100);
261s2.setVolume(80);
262check_equals(s2.getVolume(), 80);
263check_equals(s3.getVolume(), 80);
264c1.onUnload = function() {}; // give c1 an unload handler
265c1.removeMovieClip(); // there's an unload handler now
266#if OUTPUT_VERSION < 6
267 // No matter onUnload, SWF5 looses association
268 xcheck_equals(typeof(s2.getVolume()), 'undefined');
269 xcheck_equals(typeof(s3.getVolume()), 'undefined');
270#else
271 // in SWF6 up, presence of an onUnload handler
272 // prevents loosing the association
273 check_equals(s2.getVolume(), 80);
274 check_equals(s3.getVolume(), 80);
275#endif
276
277// TODO: test association with other kind of characters:
278//       - TextField
279//       - Video
280//       - ...
281
282//-----------------------------------------
283// Test loadSound  (SWF6+ only)
284//-----------------------------------------
285
286#if OUTPUT_VERSION > 5
287
288s = new Sound();
289s.onSoundComplete = function()
290{
291    clearInterval(intval);
292
293    trace("onSoundComplete called");
294    pass("onSoundComplete called");
295
296    xcheck_equals(s.position, 209);
297
298    // fixing this might fix google dict
299    // See https://savannah.gnu.org/bugs/index.php?31314
300    check(s.onLoadCalled);
301    check_equals(typeof(s.onLoadArg), 'boolean');
302    check_equals(s.onLoadArg, true);
303
304    // Test for #33760:
305    // Try to load an mp3 sound (without any tags) that is longer than the
306    // (at the time of writing) hard-coded single minute of buffer time.
307    longsilence = new Sound();
308    longsilence.onLoad = function(success) {
309        // Test for #33760, continued: Having this test here is a hack, but the
310        // delay in calling this function will ensure the sound has started.
311        pass("mp3 over one minute long loaded");
312
313        endOfTest();
314    };
315
316    longsilence.loadSound(MEDIA(silence.mp3), true);
317
318    stop();
319
320    // TODO: test non-streaming sound
321    // TODO: test loadSound on unexistent sound
322
323};
324
325s.onLoad = function(arg)
326{
327    trace("onLoad called");
328    xcheck_equals(s.duration, 209);
329    check_equals(s.position, 0);
330    s.onLoadCalled = true;
331    s.onLoadArg = arg;
332};
333
334stop();
335
336check_equals(typeof(s.getBytesLoaded()), "undefined");
337check_equals(typeof(s.getBytesTotal()), "undefined");
338check_equals(typeof(s.duration), "undefined");
339check_equals(typeof(s.getPosition()), "undefined");
340check_equals(typeof(s.getDuration()), "undefined");
341
342// streaming sound doesn't need .start() to play...
343s.loadSound(MEDIA(sound1.mp3), true);
344
345check_equals(typeof(s.getBytesTotal()), "number");
346check_equals(typeof(s.getBytesLoaded()), "number");
347check_equals(typeof(s.getPosition()), "number");
348check_equals(typeof(s.duration), "number");
349check_equals(typeof(s.getDuration()), "number");
350
351//s.loadSound(MEDIA(brokenchord.wav), true);
352
353onSoundCompleteFailed = function()
354{
355    clearInterval(intval);
356    fail("no onSoundComplete arrived after 3 seconds");
357    endOfTest();
358};
359
360note("Waiting 3 seconds for onSoundComplete to be called");
361intval = setInterval(onSoundCompleteFailed, 3000);
362
363#else // OUTPUT_VERSION < 6
364
365endOfTest();
366
367#endif // OUTPUT_VERSION < 6
368
369//-----------------------------------------
370// END OF TEST
371//-----------------------------------------
372
373