802 lines
36 KiB
HTML
802 lines
36 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
|
||
|
<head>
|
||
|
<title>SoundManager 2: Basic API Demo, Examples</title>
|
||
|
<meta name="robots" content="noindex" />
|
||
|
<meta name="author" content="Scott Schiller" />
|
||
|
<meta name="language" content="en-us" />
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||
|
<meta name="keywords" content="javascript sound library api" />
|
||
|
<meta name="description" content="API demo and code examples for SoundManager 2, Javascript Sound method calls and functions etc." />
|
||
|
<link rel="stylesheet" href="../index.css" media="screen" />
|
||
|
<!-- soundManager.useFlashBlock: related CSS -->
|
||
|
<link rel="stylesheet" type="text/css" href="../flashblock/flashblock.css" />
|
||
|
<style type="text/css">
|
||
|
|
||
|
h1 {
|
||
|
padding-top:0.2em;
|
||
|
padding-bottom:0.1em;
|
||
|
border-bottom:4px solid #000;
|
||
|
letter-spacing:-0.03em;
|
||
|
}
|
||
|
|
||
|
h2 {
|
||
|
margin-top:1em;
|
||
|
padding-bottom:0.1em;
|
||
|
border-bottom:2px solid #000;
|
||
|
}
|
||
|
|
||
|
pre,
|
||
|
code,
|
||
|
.code,
|
||
|
dt,
|
||
|
#soundmanager-debug {
|
||
|
color:#336699;
|
||
|
line-height:1.5em;
|
||
|
}
|
||
|
|
||
|
p {
|
||
|
line-height:1.5em;
|
||
|
margin-bottom:1em;
|
||
|
}
|
||
|
|
||
|
#soundmanager-debug {
|
||
|
position:fixed;
|
||
|
_position:absolute; /* IE <7 */
|
||
|
bottom:1em;
|
||
|
right:1em;
|
||
|
width:38em;
|
||
|
height:30em;
|
||
|
overflow:auto;
|
||
|
padding:0px;
|
||
|
margin:1em;
|
||
|
font-family:monaco,"VT-100","lucida console",courier,system;
|
||
|
opacity:0.9;
|
||
|
color:#333;
|
||
|
border:1px solid #ccddee;
|
||
|
border-radius:3px;
|
||
|
background:#f3f9ff;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
#soundmanager-debug code {
|
||
|
font-size:1.1em;
|
||
|
*font-size:1em;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
#soundmanager-debug div {
|
||
|
font-size:x-small;
|
||
|
padding:0.2em;
|
||
|
margin:0px;
|
||
|
}
|
||
|
|
||
|
#sm2-container.swf_unblocked {
|
||
|
/* if initially blocked (and then unblocked), stay relative so JS <-> Flash doesn't break. */
|
||
|
position: relative;
|
||
|
}
|
||
|
|
||
|
#sm2-container.high_performance.swf_unblocked {
|
||
|
/* ...unless high performance, in which case stay in corner (unless old IE) */
|
||
|
_position: relative;
|
||
|
position: fixed;
|
||
|
}
|
||
|
|
||
|
</style>
|
||
|
<script type="text/javascript" src="../../script/soundmanager2.js"></script>
|
||
|
<script type="text/javascript">
|
||
|
|
||
|
// flash version URL switch (for this demo page)
|
||
|
var winLoc = window.location.toString();
|
||
|
|
||
|
soundManager.setup({
|
||
|
preferFlash: (winLoc.match(/usehtml5audio=1/i) ? false : true)
|
||
|
});
|
||
|
|
||
|
if (winLoc.match(/flash9/i)) {
|
||
|
|
||
|
soundManager.setup({
|
||
|
flashVersion: 9
|
||
|
});
|
||
|
|
||
|
if (winLoc.match(/highperformance/i)) {
|
||
|
soundManager.setup({
|
||
|
useHighPerformance: true
|
||
|
});
|
||
|
|
||
|
}
|
||
|
|
||
|
} else if (winLoc.match(/flash8/i)) {
|
||
|
|
||
|
soundManager.setup({
|
||
|
flashVersion: 8
|
||
|
});
|
||
|
|
||
|
}
|
||
|
|
||
|
soundManager.setup({
|
||
|
useFlashBlock: true,
|
||
|
url: '../../swf/', // path to SoundManager2 SWF files (note trailing slash)
|
||
|
debugMode: true,
|
||
|
consoleOnly: false
|
||
|
});
|
||
|
|
||
|
soundManager.onready(function(oStatus) {
|
||
|
if (!oStatus.success) {
|
||
|
return false;
|
||
|
}
|
||
|
// soundManager is initialised, ready to use. Create a sound for this demo page.
|
||
|
|
||
|
if (soundManager.flashVersion > 8) {
|
||
|
t = window.setInterval(checkRAM,500);
|
||
|
document.getElementById('flash-ram-use').style.display = 'inline';
|
||
|
checkRAM();
|
||
|
}
|
||
|
|
||
|
soundManager.createSound({
|
||
|
id: 'aDrumSound',
|
||
|
url: '../mpc/audio/AMB_SN13.mp3'
|
||
|
});
|
||
|
|
||
|
soundManager.createSound({
|
||
|
id: 'aCymbalSound',
|
||
|
url: '../mpc/audio/SPLASH_1.mp3',
|
||
|
autoLoad: true
|
||
|
});
|
||
|
|
||
|
soundManager.createSound({
|
||
|
id: 'chinaCymbal',
|
||
|
url: '../mpc/audio/CHINA_1.mp3',
|
||
|
autoLoad: true
|
||
|
});
|
||
|
|
||
|
soundManager.createSound({
|
||
|
id: 's440hz',
|
||
|
url: '../_mp3/440hz.mp3',
|
||
|
autoLoad: true,
|
||
|
volume:50
|
||
|
});
|
||
|
|
||
|
});
|
||
|
|
||
|
function checkRAM() {
|
||
|
if (soundManager.supported()) {
|
||
|
var ram = (soundManager.getMemoryUse()/1024/1024).toFixed(2);
|
||
|
if (!isNaN(ram)) {
|
||
|
document.getElementById('flash-ram-use').innerHTML = ram+' MB';
|
||
|
} else {
|
||
|
document.getElementById('flash-ram-use').style.display = 'none';
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var t = null;
|
||
|
|
||
|
function doEval(sHTML) {
|
||
|
var html = sHTML.replace(/\<(span|code)\>/gi,'');
|
||
|
html = html.replace(/\<[\/](span|code)\>/gi,'');
|
||
|
html = html.replace(/>/gi,'>');
|
||
|
eval(html);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
function getRandomMP3URL() {
|
||
|
return 'http://freshly-ground.com/data/audio/mpc/20060826%20-%20Armstrong.mp3?rnd='+parseInt(Math.random()*1048576);
|
||
|
}
|
||
|
|
||
|
</script>
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
|
||
|
<div id="flash9" style="padding-left:1em;margin-right:38em">
|
||
|
|
||
|
<h1><a href="http://www.schillmania.com/projects/soundmanager2/" style="color:#000;text-decoration:none">SoundManager 2</a> / API Demo and Code Examples</h1>
|
||
|
|
||
|
<p class="note">You can run the API demos with <a href="#sm2-usehtml5audio=1" onclick="window.location.replace(this.href);window.location.reload()">HTML5</a> enabled, <a href="#flash8" onclick="window.location.replace(this.href);window.location.reload()">Flash 8</a> (API default), <a href="#flash9" onclick="window.location.replace(this.href);window.location.reload()">Flash 9</a> (normal) or <a href="#flash9-highperformance" onclick="window.location.replace(this.href);window.location.reload()">Flash 9 + highPerformance + fastPolling</a> modes (higher JS callback frequency).</p>
|
||
|
|
||
|
<p>Wondering where to start? This page has inline executable code examples using the SoundManager 2 API.</p>
|
||
|
|
||
|
<p>If you're wondering <em>"How to include SM2 in my page?"</em>, the <a href="../template/" title="SoundManager 2 bare-bones template" onclick="if (!document.domain && !this.href.match(/index/i)) this.href=this.href+'index.html'">basic template</a> will get you started.</p>
|
||
|
|
||
|
<div id="sm2-container">
|
||
|
<!-- flash is appended here -->
|
||
|
</div>
|
||
|
|
||
|
<h2>Adding "onready" listeners</h2>
|
||
|
|
||
|
<p>Before you can create and play sounds, you need to wait for the "onready" event to fire.</p>
|
||
|
|
||
|
<p>You can register listeners by passing a function to <code>onready()</code>, and it will be called when SoundManager has finished starting up:</p>
|
||
|
|
||
|
<pre class="block"><code>soundManager.onready(function() {<span>
|
||
|
<span>// ready to go! createSound() and play() etc. can now be called</span>
|
||
|
</span>});
|
||
|
</code></pre>
|
||
|
|
||
|
<p>You may also listen for a startup timeout, a form of failure (eg., Flash was required, but was blocked from loading etc.):</p>
|
||
|
|
||
|
<pre class="block"><code>soundManager.ontimeout(function() {<span>
|
||
|
<span>// uh-oh, SM2 failed to start - error, unsupported or other issue</span>
|
||
|
</span>});
|
||
|
</code></pre>
|
||
|
|
||
|
<p>SoundManager processes the <code>onready</code> or <code>ontimeout</code> queue in the order items were added. If you call <code>onready()</code> after SM2 has loaded, your callback will be fired immediately.</p>
|
||
|
|
||
|
<p>These methods can also be passed as <code>onready</code> and <code>ontimeout</code> parameters to <code>soundManager.setup()</code>.</p>
|
||
|
|
||
|
<h2>A note about initialization</h2>
|
||
|
|
||
|
<p class="compact">Keep in mind SoundManager's core methods (createSound, etc.) will not be available until soundManager.onready() fires. The initialization time for SM2 can vary across browsers/platforms, and should effectively be assumed to be "asynchronous." Because of this, it is recommended you write your code to handle soundManager.onready() being called either before or after window.onload().</p>
|
||
|
<p class="compact">If you wish to have SM2 always wait for window.onload() before calling soundManager.onready/ontimeout(), you can pass <code>waitForWindowLoad: true</code> to <code>soundManager.setup()</code>.</p>
|
||
|
|
||
|
<h2>Debug Output, disabling and minified versions</h2>
|
||
|
<p class="compact">SoundManager 2 has debug mode enabled by default and will write to agents supporting <em>console.log</em>-style debugging, and/or a custom <div> element in the absence of a console.</p>
|
||
|
<p>To disable debug output, pass <code>debugMode: false</code> to <code>soundManager.setup()</code>.</p>
|
||
|
<p>Alternately, you may use the no-debug, minified version of the SM2 javascript library (which has internal debug code removed, and will silently return false.)</p>
|
||
|
|
||
|
<h2 id="create">Demo 1: Create + play a sound by ID</h2>
|
||
|
|
||
|
<pre class="block"><code>soundManager.createSound({
|
||
|
id:'<span>mySound1</span>',
|
||
|
url:'<span>../mpc/audio/CHINA_1.mp3</span>'
|
||
|
});
|
||
|
soundManager.play('<span>mySound1</span>');</code></pre>
|
||
|
<button onclick="soundManager._writeDebug('Demo 1',1);soundManager.createSound({id:'mySound1',url:'../mpc/audio/CHINA_1.mp3'});soundManager.play('mySound1')">Do this</button>
|
||
|
<p>Creates, then plays a sound. This object literal method allows for other parameters to be used (see demo 2)</p>
|
||
|
|
||
|
<h3>Variant: Create + play sound by object (best method)</h3>
|
||
|
|
||
|
<pre class="block"><code>var soundObject = soundManager.createSound({
|
||
|
id:'<span>mySound2</span>',
|
||
|
url:'<span>../mpc/audio/CHINA_1.mp3</span>'
|
||
|
});
|
||
|
soundObject.play();</code></pre>
|
||
|
<button onclick="soundManager._writeDebug('Demo 1b variant',1);var aSoundObject = soundManager.createSound({id:'mySound2',url:'../mpc/audio/CHINA_1.mp3'});aSoundObject.play()">Do this</button>
|
||
|
<p>Creates, then plays a sound. This object literal method allows for other parameters to be used (see demo 2)</p>
|
||
|
|
||
|
<h2>Demo 2: Create with onfinish event handler + play with volume argument</h2>
|
||
|
<pre id="demo2" class="block"><code>var demo2Sound = soundManager.createSound({
|
||
|
id:'<span>mySound4</span>',
|
||
|
url:'<span>../mpc/audio/CHINA_1.mp3</span>',
|
||
|
onfinish:function() {
|
||
|
soundManager._writeDebug(this.id+'<span> finished playing</span>');
|
||
|
}
|
||
|
});
|
||
|
demo2Sound.play({volume:50});
|
||
|
</code></pre>
|
||
|
<button onclick="return doEval(document.getElementById('demo2').innerHTML)">Do this</button>
|
||
|
<p>(creates, then plays a new sound - a function is called when the sound finishes playing)</p>
|
||
|
|
||
|
<h2>Demo 3: Play a pre-existing sound by ID</h2>
|
||
|
<pre>soundManager.play('<span>aDrumSound</span>');</pre>
|
||
|
<button onclick="soundManager._writeDebug('Demo 3',1);soundManager.play('aDrumSound')">Do this</button>
|
||
|
<p>This plays an existing sound which was created by soundManager.onready() (for reference, view source of this page.)</p>
|
||
|
|
||
|
<h2>Demo 4a: Play a sequence of sounds via "onfinish", with multiShot (Flash 9-only)</h2>
|
||
|
<pre>soundManager.play('<span>aDrumSound</span>',{multiShotEvents:true,onfinish:function(){soundManager.play('<span>aCymbalSound</span>');}})</pre>
|
||
|
<p>Differently formatted:</p>
|
||
|
<pre class="block"><code>soundManager.play('<span>aDrumSound</span>',{
|
||
|
multiShotEvents: true, <span>// allow onfinish() to fire for each "shot" (default: only fire onfinish() for last shot.)</span>
|
||
|
onfinish:function() {
|
||
|
soundManager.play('<span>aCymbalSound</span>');
|
||
|
}
|
||
|
});</code></pre>
|
||
|
<button onclick="soundManager._writeDebug('Demo 4a',1);soundManager.play('aDrumSound',{multiShotEvents:true,onfinish:function(){soundManager.play('aCymbalSound');}})">Do this</button>
|
||
|
<p>This will play an existing sound (created in-page), and uses the "onfinish" handler to make a call to play a second, pre-existing sound.</p>
|
||
|
<p>Also note that the button can be clicked multiple times, and the sound will be "layered" as multiShot is enabled for both of these sounds when using Flash 9. An onfinish event will also fire as each sound finishes.</p>
|
||
|
<p><strong>Bug/behaviour note:</strong> Whenever "play" is called on a SMSound object, any parameters passed in will apply to all currently-playing instances of the sound if multiShot is allowed. For example, the onfinish handler from demo 4a will apply to demo 3 if 4a is started while 3 is still playing.</p>
|
||
|
<p class="note">* Multishot is Flash 9+ only.</p>
|
||
|
|
||
|
<h2>Demo 4b: Create and play a sequence of new sounds via "onfinish"</h2>
|
||
|
<pre class="block"><code>soundManager.createSound({
|
||
|
id:'<span>aBassDrum</span>',
|
||
|
url:'<span>../mpc/audio/AMB_BD_1.mp3</span>',
|
||
|
multiShot:false,
|
||
|
onfinish:function() {
|
||
|
soundManager.play('<span>aRimSound</span>','<span>AMB_RIM1.mp3</span>');
|
||
|
}
|
||
|
});
|
||
|
soundManager.play('<span>aRimSound</span>');</code></pre>
|
||
|
<button onclick="soundManager._writeDebug('Demo 4b',1);soundManager.createSound({id:'aBassDrum',url:'../mpc/audio/AMB_BD_1.mp3',multiShot:false,onfinish:function(){soundManager.play('aRimSound','../mpc/audio/AMB_RIM1.mp3');}});soundManager.play('aBassDrum')">Do this</button>
|
||
|
<p>This will crate and play a new sound, using the "onfinish" handler to create and play a second, new sound.</p>
|
||
|
<p>It is recommended to create sound objects first, to simplify troubleshooting.</p>
|
||
|
|
||
|
<h2 id="looping-conventional">Demo 4c: Looping a sound (conventional, onfinish()-based)</h2>
|
||
|
<pre id="demo4c" class="block"><code>var s = soundManager.createSound({
|
||
|
id:'<span>hhCymbal</span>',
|
||
|
url:'<span>../mpc/audio/AMB_HHOP.mp3</span>'
|
||
|
});
|
||
|
|
||
|
function loopSound(sound) {
|
||
|
sound.play({
|
||
|
onfinish: function() {
|
||
|
loopSound(sound);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
loopSound(s);
|
||
|
</code></pre>
|
||
|
|
||
|
<button onclick="return doEval(document.getElementById('demo4c').innerHTML);return false">Do this</button> | <button onclick="soundManager.stop('hhCymbal')">make it stop!</button>
|
||
|
<p>Note that there are issues with seamlessly-looping sounds, it is "close, but not perfect" with Flash 8/9 at this point.</p>
|
||
|
|
||
|
<h2 id="looping">Demo 4d: Looping a sound ("loops" parameter method, Flash-only)</h2>
|
||
|
<pre id="demo4d" class="block"><code>var s = soundManager.createSound({
|
||
|
id:'<span>hhCymbal</span>',
|
||
|
url:'<span>../mpc/audio/AMB_HHOP.mp3</span>'
|
||
|
});
|
||
|
|
||
|
s.play({
|
||
|
loops: 3
|
||
|
});
|
||
|
</code></pre>
|
||
|
|
||
|
<button onclick="return doEval(document.getElementById('demo4d').innerHTML);return false">Do this</button> | <button onclick="soundManager.stop('hhCymbal')">make it stop!</button>
|
||
|
<p>Looping is possible as shown above using Flash 9. <b>With flash 8, the sound must be preloaded before looping can begin</b> - eg. <code>autoLoad: true, onload: function() { this.play{loops:3} }</code>. For tighter looping, see See <a href="http://www.flickr.com/photos/schill/4499319436/" title="Seamless looping MP3 sounds in Flash">Seamless Looping MP3 in Flash</a> for further details.</p>
|
||
|
|
||
|
<p><b>HTML5 support note:</b> Native HTML5 looping is infinite when enabled, and does not support arbitrary loop counts. For now, consider using your own function with <code>onfinish()</code> -> <code>play()</code> if you want to loop a sound a certain number of times. Refer to the above <code>onfinish()</code> example for a basic idea.</p>
|
||
|
|
||
|
<h2 id="onposition">Demo 4e: Sound timing notifications using onPosition()</h2>
|
||
|
<pre id="demo4e" class="block"><code>var s = soundManager.getSoundById('<span>aCymbalSound</span>'); <span><span>// existing sound object</span></span>
|
||
|
|
||
|
<span><span>// register some listeners (only do this once, they will work for subsequent plays)</span></span>
|
||
|
|
||
|
if (typeof addedListeners === '<span>undefined</span>') {
|
||
|
addedListeners = true;
|
||
|
|
||
|
s.onPosition(<span>500</span>, function(eventPosition) { <span><span>// fire at 0.5 seconds</span></span>
|
||
|
soundManager._writeDebug(<span>'Sound '+this.id+' has reached position '+eventPosition</span>);
|
||
|
});
|
||
|
|
||
|
s.onPosition(<span>1000</span>, function(eventPosition) { <span><span>// fire at 1 second</span></span>
|
||
|
soundManager._writeDebug(<span>'Sound '+this.id+' has reached position '+eventPosition</span>);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
s.play({
|
||
|
whileplaying:function() {
|
||
|
<span><span>// demo only: show sound position while playing, for context</span></span>
|
||
|
soundManager._writeDebug('position = ' + this.position);
|
||
|
}
|
||
|
});
|
||
|
</code></pre>
|
||
|
|
||
|
<button onclick="return doEval(document.getElementById('demo4e').innerHTML);return false">Do this</button>
|
||
|
<p>onPosition() allows you to add an event listener for a given time (in miliseconds, watching the position property); the event fires when that time has been reached while a sound is playing.</p>
|
||
|
<p>Note that for multiShot cases, the listeners will only fire for the original (first) shot because its position is the only one that is tracked within Flash.</p>
|
||
|
|
||
|
<h2 id="onposition-2">Demo 4f: Sound timing with onPosition() and clearOnPosition()</h2>
|
||
|
<pre id="demo4f" class="block"><code>var s = soundManager.getSoundById('<span>aCymbalSound</span>'); <span><span>// existing sound object</span></span>
|
||
|
|
||
|
<span><span>// clear listeners from prior demo, if they were assigned...</span></span>
|
||
|
|
||
|
if (typeof addedListeners !== '<span>undefined</span>') {
|
||
|
|
||
|
soundManager._writeDebug(<span>'Removing previous demo listeners...'</span>);
|
||
|
s.clearOnPosition(<span>500</span>);<span><span> // remove 500 msec listener</span></span>
|
||
|
s.clearOnPosition(<span>1000</span>);<span><span> // remove 1000 msec listener</span></span>
|
||
|
|
||
|
}
|
||
|
|
||
|
s.onPosition(<span>750</span>, function(eventPosition) { <span><span>// fire at 0.75 seconds</span></span>
|
||
|
|
||
|
soundManager._writeDebug(<span>'Sound '+this.id+' has reached position '+eventPosition</span>);
|
||
|
<span><span>// and now, remove the listener using the eventPosition specified in this callback</span></span>
|
||
|
<span><span>// so next time the sound plays, this listener will not fire</span></span>
|
||
|
this.clearOnPosition(eventPosition);
|
||
|
|
||
|
});
|
||
|
|
||
|
s.play({
|
||
|
whileplaying: function() {
|
||
|
<span><span>// demo only: show sound position while playing, for context</span></span>
|
||
|
soundManager._writeDebug(<span>'position = ' + this.position</span>);
|
||
|
},
|
||
|
onfinish: function() {
|
||
|
<span><span>// when the sound finishes, play it once more to show that the listener does not fire.</span></span>
|
||
|
soundManager._writeDebug(<span>'Playing once more, onPosition() should not fire'</span>);
|
||
|
this.play({
|
||
|
onfinish: function() {
|
||
|
soundManager._writeDebug(<span>'"' + this.id + '" finished.'</span>);
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
</code></pre>
|
||
|
|
||
|
<button onclick="return doEval(document.getElementById('demo4f').innerHTML);return false">Do this</button>
|
||
|
<p>When onPosition() is used, a listener is added and a callback is fired when the sound reaches the desired position. To remove the listener, clearOnPosition() is called using the same position value.</p>
|
||
|
|
||
|
<h2 id="from-to">Demo 4g: Sound splicing / sampling with from: and to: parameters</h2>
|
||
|
<pre id="demo4g" class="block"><code>var spliceDemo = soundManager.createSound({
|
||
|
id: '<span>spliceSound</span>',
|
||
|
url: '<span>../mpc/audio/AMB_HHOP.mp3</span>'
|
||
|
});
|
||
|
|
||
|
spliceDemo.stop(); <span><span>// optional: stop before re-starting sound (covers overlapping play attempts)</span></span>
|
||
|
|
||
|
spliceDemo.play({
|
||
|
from: <span>500</span>, <span><span>// start playing at 500 msec</span></span>
|
||
|
to: <span>1200</span>, <span><span>// end at 1200 msec</span></span>
|
||
|
onstop: function() {
|
||
|
soundManager._writeDebug(<span>'sound stopped at position ' + this.position</span>);
|
||
|
<span><span>// note that the "to" target may be over-shot by 200+ msec, depending on polling and other factors.</span></span>
|
||
|
}
|
||
|
});
|
||
|
</code></pre>
|
||
|
|
||
|
<button onclick="return doEval(document.getElementById('demo4g').innerHTML);return false">Do this</button> | <button onclick="soundManager.stop('spliceSound');soundManager.play('spliceSound','../mpc/audio/AMB_HHOP.mp3');return false">Play full sound</button>
|
||
|
<p>By specifying "from" and "to" parameters to methods like play() and createSound(), you may play a sample (or segment) of audio from a larger file. An audio "sprite" of one file with many sounds is one way to think of this. Given timing accuracy of the "to" target may vary a lot, it is safest to have perhaps 500-msec gaps of silence between distinct sounds to ensure that no accidental overlaps occur.</p>
|
||
|
<p>To tighten the accuracy of the "to" timing, <a href="?flash9-highperformance#from-to" onclick="window.location.replace(this.href);window.location.reload()">try using soundManager.useHighPerformance</a>.</p>
|
||
|
<p>If HTML5 audio is being used, the sound should begin playing once a "canplay" event fires (after a connection has established), and the sound will then seek to the correct start position. When using flash, the whole audio file will be loaded before playback can begin.</p>
|
||
|
<p>Given limitations, Flash 9's multiShot (chorusing) mode does not apply here. If you wish to trigger a sound numerous times, call stop() before play() to reset the sound each time, or make multiple sound objects that reuse the same sprite.</p>
|
||
|
|
||
|
<h2 id="fitter-happier">Demo 4g: "Fitter, Happier" example using from: and to: parameters</h2>
|
||
|
|
||
|
<p>
|
||
|
<img src="../_image/fitter-happier-waveform.png" alt="Fitter, Happier waveform showing sound samples" />
|
||
|
</p>
|
||
|
|
||
|
<p>Portions of a sound can be played by specifying <b>from</b> and <b>to</b> when calling <code>play()</code>. This can be useful for performance, i.e., having an "audio sprite" that loads in a single HTTP request.</p>
|
||
|
|
||
|
<pre id="demo4h" class="block"><code>var fhDemo = soundManager.createSound({
|
||
|
id: '<span>fitterHappier</span>',
|
||
|
url: '<span>http://freshly-ground.com/data/audio/sm2/fitter-happier-64kbps.mp3</span>'
|
||
|
});
|
||
|
|
||
|
function playFromTo(nFrom, nTo) {
|
||
|
fhDemo.stop(); <span><span>// optional: stop before re-starting sound (covers overlapping play attempts)</span></span>
|
||
|
fhDemo.play({
|
||
|
from: nFrom,
|
||
|
to: nTo,
|
||
|
onstop: function() {
|
||
|
soundManager._writeDebug(<span>'sound stopped at position ' + this.position</span>);
|
||
|
<span><span>// note that the "to" target may be over-shot by 200+ msec, depending on polling and other factors.</span></span>
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function fitterHappier() {
|
||
|
playFromTo(<span>128, 2100</span>);
|
||
|
}
|
||
|
|
||
|
function moreProductive() {
|
||
|
playFromTo(<span>2500, 3850</span>);
|
||
|
}
|
||
|
|
||
|
function comfortable() {
|
||
|
playFromTo(<span>4275, 5200</span>);
|
||
|
}
|
||
|
|
||
|
function notDrinkingTooMuch() {
|
||
|
playFromTo(<span>5500, 7250</span>);
|
||
|
}
|
||
|
|
||
|
function regularExerciseAtTheGymThreeDaysAWeek() {
|
||
|
playFromTo(<span>7500, 11500</span>);
|
||
|
}
|
||
|
|
||
|
function atEase() {
|
||
|
<span><span>// interesting edge case: flash may cut off sound near end.
|
||
|
// workarounds: use play({position:x}), or specify "to" time > duration eg. 99999.</span></span>
|
||
|
playFromTo(<span>11600, 99999</span>);
|
||
|
}
|
||
|
|
||
|
<span><span>// demo-specific hack: assign to the window object, so demo buttons work</span></span>
|
||
|
window.fitterHappier = fitterHappier;
|
||
|
window.moreProductive = moreProductive;
|
||
|
window.comfortable = comfortable;
|
||
|
window.notDrinkingTooMuch = notDrinkingTooMuch;
|
||
|
window.regularExerciseAtTheGymThreeDaysAWeek = regularExerciseAtTheGymThreeDaysAWeek;
|
||
|
window.atEase = atEase;
|
||
|
</code></pre>
|
||
|
|
||
|
<script>
|
||
|
// do this work up front
|
||
|
soundManager.onready(function() {
|
||
|
doEval(document.getElementById('demo4h').innerHTML);
|
||
|
});
|
||
|
</script>
|
||
|
|
||
|
<button onclick="fitterHappier();return false">fitterHappier()</button> | <button onclick="moreProductive();return false">moreProductive()</button> | <button onclick="comfortable();return false">comfortable()</button> | <button onclick="notDrinkingTooMuch();return false">notDrinkingTooMuch()</button> | <button onclick="regularExerciseAtTheGymThreeDaysAWeek();return false">regularExerciseAtTheGymThreeDaysAWeek()</button> | <button onclick="atEase();return false">atEase()</button>
|
||
|
|
||
|
<h2>Demo 5a: Set sound parameters, then play</h2>
|
||
|
<pre class="block"><code>var sound = soundManager.getSoundById('<span>chinaCymbal</span>'); <span><span>// predefined/preloaded sound</span></span>
|
||
|
sound.setPosition(<span>500</span>); <span><span>// 500 msec into sound</span></span>
|
||
|
sound.setPan(<span>-75</span>); <span><span>// 75% left pan</span></span>
|
||
|
sound.play();
|
||
|
</code></pre>
|
||
|
<button onclick="soundManager._writeDebug('Demo 5',1);var sound=soundManager.getSoundById('chinaCymbal');sound.setPosition(500);sound.setPan(-75);sound.play()">Do this</button> | <button onclick="soundManager._writeDebug('Demo 5: sound from position:0',1);var sound=soundManager.getSoundById('chinaCymbal');sound.setPosition(0);sound.setPan(-75);sound.play()">Play from position:0</button>
|
||
|
<p>This will set the position of an existing, pre-loaded sound, then play it.</p>
|
||
|
|
||
|
<h3>Variant: play()</h3>
|
||
|
<pre class="block"><code>var sound = soundManager.getSoundById('<span>chinaCymbal</span>');
|
||
|
sound.play({position:<span>500</span>,pan:<span>-75</span>});
|
||
|
</code></pre>
|
||
|
<button onclick="soundManager._writeDebug('Demo 5 variant',1);var sound=soundManager.getSoundById('chinaCymbal');sound.play({position:500,pan:-75})">Do this</button> | <button onclick="soundManager._writeDebug('Demo 5: variant: sound from position:0',1);var sound = soundManager.getSoundById('chinaCymbal');sound.play({position:0,pan:-75})">Play from position:0</button>
|
||
|
<p>Note that if planning to layer sounds with multiShot (Flash 9 only), this variant method will give best results as each new "channel" is started with parameters.</p>
|
||
|
|
||
|
<h2>Demo 5b: Global sound muting</h2>
|
||
|
<p>If not passed a sound ID, soundManager.mute() will mute all existing and newly-created sounds. soundManager.unmute() can also be passed a sound ID, and performs the inverse either on a single sound or all sounds.</p>
|
||
|
<p>In this demo, all sounds are globally muted and unmuted a few times. Different parameters are used to help audibly separate the sounds.</p>
|
||
|
<pre id="demo5b-1" class="block"><code>soundManager.mute(); <span><span>// mute all sounds</span></span>
|
||
|
|
||
|
soundManager.createSound({
|
||
|
id: '<span>880hz</span>',
|
||
|
url: '<span>../_mp3/880hz.mp3</span>',
|
||
|
autoLoad:true,
|
||
|
onload: function() {
|
||
|
<span><span>// soundManager.mute(); // mute all sounds</span></span>
|
||
|
<span><span>// play (muted) cymbal sound..</span></span>
|
||
|
this.play({
|
||
|
volume:75, <span><span>// volume for when un-muted</span></span>
|
||
|
pan:-75, <span><span>// mostly on left channel</span></span>
|
||
|
<span><span>// .. and clean-up afterwards</span></span>
|
||
|
onfinish:function() {
|
||
|
this.destruct();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
this.setVolume(25); <span><span>// new volume for when un-muted..</span></span>
|
||
|
|
||
|
soundManager.play('<span>s440hz</span>',{
|
||
|
pan:<span>75</span>,
|
||
|
onfinish:function() {
|
||
|
document.getElementById('<span>btn-d5b</span>').disabled = false;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
<span><span>// once playing, toggle all sounds some more</span></span>
|
||
|
setTimeout(soundManager.unmute,500);
|
||
|
setTimeout(soundManager.mute,1000);
|
||
|
setTimeout(soundManager.unmute,1500);
|
||
|
setTimeout(soundManager.mute,2000);
|
||
|
setTimeout(soundManager.unmute,2500);
|
||
|
}
|
||
|
});</code></pre>
|
||
|
<button id="btn-d5b" onclick="this.disabled=true;return doEval(document.getElementById('demo5b-1').innerHTML)">Do this</button>
|
||
|
<script type="text/javascript">document.getElementById('btn-d5b').disabled = false;</script>
|
||
|
|
||
|
<h2>Demo 5c: Per-object sound muting</h2>
|
||
|
<pre id="demo5c-1" class="block"><code>soundManager.createSound({
|
||
|
id: '<span>880hz</span>',
|
||
|
url: '<span>../_mp3/880hz.mp3</span>',
|
||
|
autoLoad:true,
|
||
|
onload: function() {
|
||
|
soundManager.mute('<span>880hz</span>'); <span><span>// mute this - alternately, this.mute() would work here</span></span>
|
||
|
soundManager.play('<span>s440hz</span>',{ <span><span>// play another sound to demo muting</span></span>
|
||
|
onfinish: function() {
|
||
|
document.getElementById('<span>btn-d5c</span>').disabled = false;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
<span><span>// play 880hz (muted)..</span></span>
|
||
|
this.play({
|
||
|
volume:75,
|
||
|
<span><span>// .. and clean-up afterwards</span></span>
|
||
|
onfinish:function() {
|
||
|
this.destruct();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
this.setVolume(50); <span><span>// still muted, however..</span></span>
|
||
|
|
||
|
<span><span>// mute/unmute china cymbal some more</span></span>
|
||
|
<span><span>// mute sound calls: soundManager.mute('<span>880hz</span>'), or soundManager.getSoundById('<span>880hz</span>').mute();</span></span>
|
||
|
setTimeout(this.unmute,250);
|
||
|
setTimeout(this.mute,500);
|
||
|
setTimeout(this.unmute,750);
|
||
|
setTimeout(this.mute,1000);
|
||
|
setTimeout(this.unmute,1250);
|
||
|
}
|
||
|
});</code></pre>
|
||
|
<button id="btn-d5c" onclick="this.disabled=true;return doEval(document.getElementById('demo5c-1').innerHTML)">Do this</button>
|
||
|
<script type="text/javascript">document.getElementById('btn-d5c').disabled = false;</script>
|
||
|
|
||
|
<h2>Demo 6: Create, play, unload and destroy a sound</h2>
|
||
|
<pre id="demo6" class="block"><code>var foo = soundManager.createSound({
|
||
|
id: '<span>fooSound</span>',
|
||
|
url: '<span>../mpc/audio/AMB_BD_1.mp3</span>'
|
||
|
});
|
||
|
|
||
|
<span><span>// soundManager.play('<span>fooSound</span>');
|
||
|
|
||
|
// (Some time later on...)
|
||
|
// soundManager.unload('<span>fooSound</span>'); - release the loaded MP3
|
||
|
// soundManager.destroySound('<span>fooSound</span>'); - destroy the sound, freeing up memory etc. Also calls unload().
|
||
|
|
||
|
// Alternate (demo) approach, call methods directly on sound object itself:</span></span>
|
||
|
foo.play({
|
||
|
onfinish:function() {
|
||
|
<span><span>// once sound has loaded and played, unload and destroy it.</span></span>
|
||
|
this.destruct(); <span><span>// will also try to unload before destroying.</span></span>
|
||
|
}
|
||
|
});</code></pre>
|
||
|
<button onclick="return doEval(document.getElementById('demo6').innerHTML)">Do this</button>
|
||
|
|
||
|
|
||
|
<h2>Demo 7: Create, manually pre-load and finally play a sound</h2>
|
||
|
<pre id="demo7" class="block"><code>var preload = soundManager.createSound({
|
||
|
id: '<span>preloadSound</span>',
|
||
|
url: '<span>../mpc/audio/AMB_HHOP.mp3</span>'
|
||
|
});
|
||
|
|
||
|
preload.load(); <span><span>// load the sound ahead of time</span></span>
|
||
|
setTimeout(preload.play,1500); <span><span>// and start playing it 1.5 seconds from now</span></span>
|
||
|
</code></pre>
|
||
|
<button onclick="return doEval(document.getElementById('demo7').innerHTML)">Do this</button>
|
||
|
|
||
|
<h2>Demo 8: Create and play an invalid sound (404)</h2>
|
||
|
<pre id="demo8" class="block"><code>var bad = soundManager.createSound({
|
||
|
id:'<span>badSound</span>',
|
||
|
url:'<span>badurl.mp3</span>',
|
||
|
onload: function(bSuccess) {
|
||
|
soundManager._writeDebug('<span>sound </span>'+(bSuccess?'<span>loaded!</span>':'<span>did NOT load.</span>'));
|
||
|
}
|
||
|
});
|
||
|
bad.play();
|
||
|
</code></pre>
|
||
|
<button onclick="return doEval(document.getElementById('demo8').innerHTML)">Do this</button>
|
||
|
|
||
|
<h2>Demo 9: Create and destroy a sound at once (unusual crash testcase)</h2>
|
||
|
<pre id="demo9" class="block"><code>var s = soundManager.createSound({
|
||
|
id:'<span>testcase</span>',
|
||
|
url:'<span>../mpc/audio/AMB_HHOP.mp3</span>'
|
||
|
});
|
||
|
s.play();
|
||
|
s.destruct();
|
||
|
</code></pre>
|
||
|
<button onclick="return doEval(document.getElementById('demo9').innerHTML)">Do this</button>
|
||
|
|
||
|
<h2>Demo 10: Sound timing (position accuracy testcase)</h2>
|
||
|
<p>The Flash 9 version seems to resume the sound 1 msec earlier than it should, perhaps related to the timing/delay issue most noticeable on Windows.</p>
|
||
|
<pre id="demo10" class="block"><code>var count = 0;
|
||
|
var pos = -1;
|
||
|
var s = soundManager.createSound({
|
||
|
id: '<span>s</span>',
|
||
|
url: '<span>../mpc/audio/CHINA_1.mp3</span>',
|
||
|
whileplaying: function() {
|
||
|
if (count == 0) {
|
||
|
if (this.position > 1000) {
|
||
|
this.pause();
|
||
|
pos = this.position;
|
||
|
count++;
|
||
|
this.resume();
|
||
|
}
|
||
|
} else if (count == 1) {
|
||
|
soundManager._writeDebug('<span>old position: </span>' + pos);
|
||
|
soundManager._writeDebug('<span>new position: </span>' + this.position);
|
||
|
<span><span>// See that this.position is less than pos!</span></span>
|
||
|
count++;
|
||
|
}
|
||
|
},
|
||
|
onfinish: function() {
|
||
|
this.destruct();
|
||
|
}
|
||
|
});
|
||
|
s.play();</code></pre>
|
||
|
<button onclick="return doEval(document.getElementById('demo10').innerHTML)">Do this</button>
|
||
|
|
||
|
<h2>Demo 11: Inline whileplaying() event assignment</h2>
|
||
|
<p class="in">Note that when using the Flash 9 version of SM2 with Flash 9 and 10 plugins, flash/OS-related delay conditions may result in the <code>position</code> property being less than the <code>duration</code> property, even by the end of the sound.</p>
|
||
|
<pre id="demo11" class="block"><code>var foo = soundManager.createSound({
|
||
|
id: '<span>bar</span>',
|
||
|
url: '<span>../mpc/audio/CRASH_1.mp3</span>'
|
||
|
});
|
||
|
foo.options.whileplaying = function() {
|
||
|
soundManager._writeDebug('<span>whileplaying(): </span>'+this.position+'<span> / </span>'+this.duration);
|
||
|
}
|
||
|
foo.play();
|
||
|
|
||
|
<span><span>// note: assign .options before calling .play(), as that "bakes" the options into a play instance object.
|
||
|
// the below "late" event handler assignment will have no effect on the already-playing instance.</span></span>
|
||
|
foo.options.onfinish = function() { soundManager._writeDebug(this.id+'<span> stopped.</span>'); }
|
||
|
</code></pre>
|
||
|
<button onclick="return doEval(document.getElementById('demo11').innerHTML)">Do this</button>
|
||
|
|
||
|
<h2>Demo 12: 48 KHz MP3 sampling rate playback issue workaround</h2>
|
||
|
<p>To work around a known "chipmunk" <a href="http://bugs.adobe.com/jira/browse/FP-862">sampling rate issue with 48 KHz MP3s</a> in Flash, one can apparently load a sound using Flash 9 with stream = false, and then call play() once the sound has fully-loaded. Exactly why this works is not known.</p>
|
||
|
<pre id="demo12" class="block"><code>var fortyeight = soundManager.createSound({
|
||
|
id: '<span>s-48khz</span>',
|
||
|
url: '<span>http://freshly-ground.com/data/audio/48khz-test.mp3</span>'
|
||
|
});
|
||
|
|
||
|
if (!fortyeight.loaded) {
|
||
|
<span><span>// first time loading/playing</span></span>
|
||
|
fortyeight.load({
|
||
|
stream: false,
|
||
|
onload: function() {
|
||
|
<span><span>// sound has fully-loaded</span></span>
|
||
|
this.play();
|
||
|
}
|
||
|
});
|
||
|
} else {
|
||
|
<span><span>// sound has already loaded</span></span>
|
||
|
fortyeight.play();
|
||
|
}
|
||
|
</code></pre>
|
||
|
<button onclick="return doEval(document.getElementById('demo12').innerHTML)">Do this</button> <button onclick="soundManager.stop('s-48khz')">Make it stop!</button>
|
||
|
|
||
|
<h2>Demo 13: autoLoad:true + play() testcase</h2>
|
||
|
<p>Bug testcase (Flash 8 version-specific): creating a sound with autoLoad:true and immediately calling play() does not work.</p>
|
||
|
<pre id="demo13" class="block"><code>var autoLoadTest = soundManager.createSound({
|
||
|
id: '<span>autoLoadTest</span>',
|
||
|
url: getRandomMP3URL(),
|
||
|
onload: function() {
|
||
|
soundManager._writeDebug(this.id+'<span> loaded.</span>');
|
||
|
},
|
||
|
onplay: function() {
|
||
|
soundManager._writeDebug('<span>Starting sound: </span>'+this.id);
|
||
|
},
|
||
|
autoPlay: false,
|
||
|
autoLoad: true,
|
||
|
stream: true
|
||
|
});
|
||
|
<span><span>// autoLoadTest.play(); // sound will not start</span></span>
|
||
|
setTimeout(autoLoadTest.play,1000); <span><span>// may work with a delay?</span></span>
|
||
|
</code></pre>
|
||
|
<p>Under Flash 8, this case does not work as expected. Even with the delay, the sound does not begin playing as soon as expected - sometimes it fires after the sound loads, in fact. For this reason, avoid using <code class="in">autoLoad:true</code> if you intend to play the sound shortly after creating it when using Flash 8.</p>
|
||
|
<button onclick="return doEval(document.getElementById('demo13').innerHTML)">Do this</button> <button onclick="soundManager.stop('autoLoadTest')">Make it stop!</button>
|
||
|
|
||
|
<h2>Demo 14: autoPlay + onfinish() testcase</h2>
|
||
|
<p>Bug testcase (Flash 8 version-specific): onfinish() does not fire with autoPlay:true</p>
|
||
|
<pre id="demo14" class="block"><code>var sound = soundManager.createSound({
|
||
|
id: '<span>demo14</span>',
|
||
|
url: '<span>../mpc/audio/AMB_SN13.mp3</span>',
|
||
|
onfinish: function() {
|
||
|
soundManager._writeDebug(this.id+'<span> finished (now destroying)</span>');
|
||
|
<span><span>// destroy this sound</span></span>
|
||
|
this.destruct();
|
||
|
},
|
||
|
autoPlay: true,
|
||
|
multiShot: false
|
||
|
});
|
||
|
</code></pre>
|
||
|
<button onclick="return doEval(document.getElementById('demo14').innerHTML)">Do this</button>
|
||
|
|
||
|
<h2>Demo 15: onstop() -> unload() testcase</h2>
|
||
|
<p>Bug testcase: unload() from onstop() does not work</p>
|
||
|
<pre id="demo15" class="block"><code>var sound16 = soundManager.createSound({
|
||
|
id: '<span>demo15</span>',
|
||
|
url: getRandomMP3URL(),
|
||
|
onstop: function() {
|
||
|
soundManager.unload(this.id);
|
||
|
},
|
||
|
onload: function() {
|
||
|
soundManager._writeDebug('<span>loaded</span>');
|
||
|
}
|
||
|
});
|
||
|
sound15.play();
|
||
|
setTimeout(sound15.stop,1500);
|
||
|
</code></pre>
|
||
|
<button onclick="return doEval(document.getElementById('demo15').innerHTML)">Do this</button>
|
||
|
|
||
|
<h2>Demo 16: Buffering event handler/property example (Flash 9 only)</h2>
|
||
|
<p>Reporting the isBuffering property of a SMSound object</p>
|
||
|
<pre id="demo16" class="block"><code>if (soundManager.flashVersion != 8) {
|
||
|
var sound16 = soundManager.createSound({
|
||
|
id: '<span>demo16</span>',
|
||
|
url: getRandomMP3URL(),
|
||
|
onbufferchange: function() {
|
||
|
soundManager._writeDebug('<span>Buffering </span>'+(this.isBuffering?'<span>started</span>':'<span>stopped</span>')+'<span>.</span>');
|
||
|
},
|
||
|
onload: function() {
|
||
|
soundManager._writeDebug(this.id+'<span> loaded.</span>');
|
||
|
}
|
||
|
});
|
||
|
sound16.play();
|
||
|
}
|
||
|
</code></pre>
|
||
|
<button onclick="return doEval(document.getElementById('demo16').innerHTML)">Do this</button> <button onclick="soundManager.stop('demo16')">Make it stop!</button>
|
||
|
|
||
|
|
||
|
<span id="flash-ram-use" title="Flash plugin RAM use (across this browser)" style="position:fixed;_position:absolute;top:0.5em;right:0.5em;background:#666;color:#fff;font-weight:bold;padding:0.3em 0.4em;cursor:pointer;cursor:hand;display:none" onclick="this.style.display='none';window.clearTimeout(t)">N/A</span>
|
||
|
|
||
|
</div>
|
||
|
|
||
|
</body>
|
||
|
</html>
|