Skip to content

Commit

Permalink
added audio sprites
Browse files Browse the repository at this point in the history
  • Loading branch information
rserota committed Jun 1, 2018
1 parent 4776539 commit 94eaabf
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 7 deletions.
30 changes: 29 additions & 1 deletion README.md
Expand Up @@ -32,6 +32,7 @@ Wad is a Javascript library for manipulating audio using the new HTML5 Web Audio
<li><a href='#pitch-detection'>Pitch Detection</a></li>
</ul>
</li>
<li><a href='#audio-sprites'>Audio Sprites</a></li>
<li><a href='#external-fx'>External FX</a></li>
<li><a href='#presets'>Presets</a></li>
<li><a href='#midi-input'>MIDI Input</a></li>
Expand Down Expand Up @@ -117,7 +118,7 @@ var saw = new Wad({
},
reverb : {
wet : 1, // Volume of the reverberations.
impulse : 'http://www.myServer.com/path/to/impulse.wav' // A URL for an impulse response file, if you do not want to use the default impulse response.
impulse : 'https://www.myServer.com/path/to/impulse.wav' // A URL for an impulse response file, if you do not want to use the default impulse response.
},
delay : {
delayTime : .5, // Time in seconds between each delayed playback.
Expand Down Expand Up @@ -378,6 +379,33 @@ logPitch();
tuner.stopUpdatingPitch(); // Stop calculating the pitch if you don't need to know it anymore.
```

<h3 id='audio-sprites'>Audio Sprites</h3>

If your project contains many short audio clips, you may be able to achieve better performance by loading them as a single, longer audio clip, and play sections from that longer clip as needed.

```javascript
var helloWorld = new Wad({
source: 'https://www.myserver.com/audio/hello-world.wav',

// add a key for each sprite
sprite: {
hello : [0, .4], // the start and end time, in seconds
world : [.4,1]
}
});

// for each key on the sprite object in the constructor above, the wad that is created will have a key of the same name, with a play() method.
helloWorld.hello.play();
helloWorld.world.play();

// you can still play the entire clip normally, if you want.
helloWorld.play();

// if you hear clicks or pops from starting and stopping playback in the middle of the clip, you can try adding some attack and release to the envelope.
helloWorld.hello.play({env:{attack: .1, release:.02}})

```

<h3 id='exfx'>External FX</h3>

Sometimes you might want to incorporate external libraries into Wad, for example FX or visualizers. You can override the constructExternalFx and setUpExternalFxOnPlay methods to add those nodes to the wad chain. In the following example the values are hardcoded, but they could easily have been passed as arguments to play.
Expand Down
34 changes: 33 additions & 1 deletion build/wad.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion build/wad.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion build/wad.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "web-audio-daw",
"version": "4.0.1",
"version": "4.1.1",
"description": "Web Audio DAW. It's like jQuery for your ears.",
"main": "build/wad.js",
"scripts": {
Expand Down
19 changes: 19 additions & 0 deletions src/wad.js
Expand Up @@ -291,6 +291,7 @@ Check out http://www.voxengo.com/impulses/ for free impulse responses. **/
this.loop = arg.loop || false;
this.tuna = arg.tuna || null;
this.rate = arg.rate || 1;
this.sprite = arg.sprite || null;
constructEnv(this, arg);
constructFilter(this, arg);
constructVibrato(this, arg);
Expand Down Expand Up @@ -319,6 +320,23 @@ Check out http://www.voxengo.com/impulses/ for free impulse responses. **/
/** If the source is not a pre-defined value, assume it is a URL for an audio file, and grab it now. **/
else if ( !( this.source in { 'sine' : 0, 'sawtooth' : 0, 'square' : 0, 'triangle' : 0 } ) ) {
requestAudioFile(this, arg.callback);

if ( this.sprite ) {
var thatWad = this;
for ( var sprite in this.sprite ) {
this[sprite] = {
sprite: this.sprite[sprite],
play: async function(arg){
arg = arg || {}
arg.env = arg.env || {}
arg.env.hold = this.sprite[1] - this.sprite[0]
arg.offset = this.sprite[0]

return thatWad.play(arg)
}
}
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
else { arg.callback && arg.callback(this) }
Expand Down Expand Up @@ -680,6 +698,7 @@ then finally play the sound by calling playEnv() **/
if ( this.source === 'noise' || this.loop || arg.loop ) {
this.soundSource.loop = true;
}

}

if ( this.soundSource.playbackRate ) {
Expand Down
Binary file added test/es5/hello-man.wav
Binary file not shown.
22 changes: 22 additions & 0 deletions test/es5/index.html
Expand Up @@ -9,8 +9,18 @@
<button id="ignition">PLAY CLIP</button>
<button id="ignition-faster">PLAY CLIP FASTER</button>
<button id="ignition-slower">PLAY CLIP SLOWER</button>
<button id="sprite-a">SPRITE A</button>
<button id="sprite-b">SPRITE B</button>
<button id="sprite-ab">SPRITE AB</button>
<script>
var ignition = new Wad({source:'./ignition.mp3'})
var helloMan = new Wad({
source: './hello-man.wav',
sprite: {
hello: [0, .4],
man : [.4,1]
}
})
document.getElementById('ignition').addEventListener('click', async function(){
await ignition.play()
await ignition.play()
Expand All @@ -31,6 +41,18 @@
rate: 0.5,
})
})
document.getElementById('sprite-a').addEventListener('click', async function(){
await helloMan.hello.play({env:{release:.02}})
await helloMan.hello.play({rate: 1.1, volume:1.2, env:{release:.02}})
})
document.getElementById('sprite-b').addEventListener('click', async function(){
await helloMan.man.play({env:{attack: .1, release:.02}})
await helloMan.man.play({env:{attack: .1, release:.02}})
})
document.getElementById('sprite-ab').addEventListener('click', async function(){
await helloMan.play({env:{attack: .1, release:.02}})
await helloMan.play({env:{attack: .1, release:.02}})
})
</script>
<hr>

Expand Down
22 changes: 21 additions & 1 deletion test/es6/build/test.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion test/es6/build/test.js.map

Large diffs are not rendered by default.

Binary file added test/es6/hello-man.wav
Binary file not shown.
3 changes: 3 additions & 0 deletions test/es6/index.html
Expand Up @@ -8,6 +8,9 @@
<button id="ignition">PLAY CLIP</button>
<button id="ignition-faster">PLAY CLIP FASTER</button>
<button id="ignition-slower">PLAY CLIP SLOWER</button>
<button id="sprite-a">SPRITE A</button>
<button id="sprite-b">SPRITE B</button>
<button id="sprite-ab">SPRITE AB</button>

<hr>

Expand Down
20 changes: 20 additions & 0 deletions test/es6/src/index.js
Expand Up @@ -22,6 +22,26 @@ document.getElementById('ignition-slower').addEventListener('click', async funct
})
})

var helloMan = new Wad({
source: './hello-man.wav',
sprite: {
hello: [0, .4],
man : [.4,1]
}
})
document.getElementById('sprite-a').addEventListener('click', async function(){
await helloMan.hello.play({env:{release:.02}})
await helloMan.hello.play({rate: 1.1, volume:1.2, env:{release:.02}})
})
document.getElementById('sprite-b').addEventListener('click', async function(){
await helloMan.man.play({env:{attack: .1, release:.02}})
await helloMan.man.play({env:{attack: .1, release:.02}})
})
document.getElementById('sprite-ab').addEventListener('click', async function(){
await helloMan.play({env:{attack: .1, release:.02}})
await helloMan.play({env:{attack: .1, release:.02}})
})

var sine = new Wad({source:'sine', env: {attack: .07, hold: 1.5, release: .3}})
document.getElementById('sine').addEventListener('click', async function(){
await sine.play()
Expand Down

0 comments on commit 94eaabf

Please sign in to comment.