9 Sound
Sound support in NeuroTask Scripting is based on the battle-tested JavaScript library SoundManager2, which provides a great cross-browser sound player. It supports older (i.e., really, really old) browsers using a Flash plugin and for recent browsers it uses native HTML5 sound play back whenever available. Like with video in the next chapter, NeuroTask Scripting aims to hide details that may daunt beginners. For advanced users, however, most of the more complex stuff can still be reached through a range of options.
Sound is not attached to a Block as that does not seem to make much sense. A sound continues until the end or until interrupted.
Playing a sound file is done as follows:
play('cow.mp3');
await('soundended');
This will play the entire sound file, halting execution until the end of the sound has been reached. Then this script will finish. If you do not add the await() statement, the script will continue while still playing the sound. In this case, it would show the end screen.
9.1 Preloading sounds
Consider the following script:
1 var main = new Box('lightgrey'),
2 a = main.addblock("center","top",50,25),
3 b = main.addblock("center","center",50,50,"lightgrey","Loading...");
4
5 image.preload('cow.png');
6 image.await('preloading_completed');
7
8 sound.preload('cow.mp3','mooh');
9 sound.await('preloading_completed');
10
11 a.text("Click the cow!");
12 b.clear();
13 b.setimage("cow.png",25);
14 b.await('click');
15 b.clear();
16 await(2000);
17 b.setimage("cow.png",50);
18
19 sound.play('mooh');
20 await('soundended');
21
22 a.clear();
23 b.text("Mooh said the cow!");
This will show the text ‘Loading…’ in the center for a while, which is cleared, after which it says ‘Click the cow!’ near the top. As soon as you click the cow image in the center (with the left mouse button), a mooh sound is heard. When it has ended, the text ‘Mooh said the cow!’ appears.
In the script, you see preload() statements. What these do is exactly that: they are preloading both the cow image and the mooh sound. The await() statements ensure that after line 9, both the image and the sound are available. Execution of the script continues only after both the image and sound file are completely loaded. If preloading was not done, it is likely that when encountering
13 b.setimage("cow.png",25);
the script would start loading the image, which in some cases might lead to noticeable delays. The same applies to the sound; a large sound file might take a second or so to download. Preloading ensures that, once it has been completed and all files are available, the script will run smoothly. This is essential in many experiments.
The sound.preload() statement allows giving the sound file, ‘cow.mp3’, a name or ID. Here we use ‘mooh’. This is sometimes handy for long file names, but it remains fully optional; there is no obligation to use the ID.
9.2 Advanced options
Options are taken straight from SoundManager2 and are given as a second argument to play(). They are:
1 autoLoad: false, // enable automatic loading (otherwise .load() will call
2 // with .play())
3 autoPlay: false, // enable playing of file ASAP (much faster if "stream" is
4 // true)
5 from: null, // position to start playback within a sound (msec)
6 loops: 1, // number of times to play the sound
7 multiShot: true, // let sounds "restart" or "chorus" when played multiple
8 // times.
9 multiShotEvents: false, // allow events (onfinish()) to fire for each shot, if
10 // supported.
11 onid3: null, // callback function for "ID3 data is added/available"
12 onload: null, // callback function for "load finished"
13 onstop: null, // callback for "user stop"
14 onfinish: null, // callback function for "sound finished playing"
15 onpause: null, // callback for "pause"
16 onplay: null, // callback for "play" start
17 onresume: null, // callback for "resume" (pause toggle)
18 position: null, // offset (milliseconds) to seek to within downloaded sound.
19 pan: 0, // "pan" settings, left-to-right, -100 to 100
20 stream: true, // allows playing before entire file has loaded (recommended)
21 to: null, // position to end playback within a sound (msec)
22 type: null, // MIME-like hint for canPlay() tests, eg. 'audio/mp3'
23 usePolicyFile: false, // enable crossdomain.xml request for remote domains
24 // (ID3/waveform access)
25 volume: 100, // self-explanatory. 0-100, the latter being the max.
26 whileloading: null, // callback function for updating progress (X of Y bytes
27 // received)
28 whileplaying: null, // callback during play (position update)
So, you could do sound.play("mooh",{volume:25}) to play at 25% volume level. It is possible to play only a fragment with to and from in the options shown above. You could for example have an mp3 file with many sounds, each lasting say exactly 1000 ms, and then play just a segment with from and to.