mirror of
https://github.com/wassname/sound.js.git
synced 2026-07-29 11:27:46 +08:00
337 lines
12 KiB
Markdown
337 lines
12 KiB
Markdown
Sound.js
|
|
===============
|
|
|
|
"Sound.js" is micro-library that lets you load, play and generate sound effects and music for
|
|
games and interactive applications. It's very small: less than 800
|
|
lines of code and no dependencies. [Click here to try an interactive
|
|
demo.](https://cdn.rawgit.com/kittykatattack/sound.js/master/index.html)
|
|
|
|
At its heart it's composed of
|
|
just two, short, independent functions: `makeSound` and `soundEffect`. The `makeSound` function helps you
|
|
load and play sound files (mp3, wav, ogg, and webm). The `soundEffect`
|
|
function helps you generate a wide range of sound and music effects
|
|
from pure code.
|
|
These two functions are completely modular and free of dependencies, so
|
|
you can
|
|
copy and paste whichever parts of them you need into your own
|
|
projects. In fact, you can create all the sound an music for your
|
|
project in less than
|
|
150 lines of code by just using the `soundEffect` function on its own.
|
|
|
|
If you need it, there's also a `sounds` object with a helpful
|
|
`load` method that makes it easy to load and access sound files.
|
|
You'll find all the code in the `sound.js` file. Take a look at the
|
|
`index.html` file for a working example of all the features. All this
|
|
code is completely unlicensed and free for you to use however you
|
|
like.
|
|
|
|
Installation
|
|
-------------
|
|
|
|
Just link to the `sound.js` file with a `<script>` tag:
|
|
```
|
|
<script src="sound.js"></script>
|
|
```
|
|
Or just copy/paste whichever functions you need from the `sound.js`
|
|
file into your own project code.
|
|
|
|
Loading sound files
|
|
-------------------
|
|
|
|
The best way to load sound files is to use the `sounds` object's
|
|
`load` method. List the each sound file's path and name in the `sound.load`
|
|
method's array. Then assign a callback function to `sounds.whenLoaded`.
|
|
```
|
|
//Load the sounds
|
|
sounds.load([
|
|
"sounds/shoot.wav",
|
|
"sounds/music.wav",
|
|
"sounds/bounce.mp3"
|
|
]);
|
|
|
|
//Assign the callback function that should run
|
|
//when the sounds have loaded
|
|
sounds.whenLoaded = setup;
|
|
```
|
|
After the sounds have loaded, the `setup` function will run. Use the
|
|
`setup` function to initialize your sounds.
|
|
```
|
|
function setup() {
|
|
//Initialize sounds here
|
|
}
|
|
```
|
|
Of course, you can give this function any name you like, it doesn't
|
|
have to be called `setup`.
|
|
|
|
Initializing loaded sounds
|
|
--------------------------
|
|
|
|
After a sound file is loaded using the `sounds.load` method, you can access
|
|
it as a property of the `sounds` object like this:
|
|
```
|
|
sounds["sounds/music.wav"]
|
|
```
|
|
Create variable references to all the sounds you want to use so that
|
|
they're easier to work with:
|
|
```
|
|
var shoot = sounds["sounds/shoot.wav"],
|
|
music = sounds["sounds/music.wav"],
|
|
bounce = sounds["sounds/bounce.mp3"];
|
|
```
|
|
You now have three sound objects, `shoot`, `music`, and `bounce` that
|
|
you can play and control.
|
|
|
|
Playing and controlling loaded sounds
|
|
-------------------------------------
|
|
|
|
You can play, pause, loop and restart sounds as well as set their volume and speaker
|
|
pan settings. You can also fade sounds in or out. Here's how:
|
|
```
|
|
//Play the sound
|
|
music.play();
|
|
|
|
//Make the sound loop
|
|
music.loop = true;
|
|
|
|
//Set the volume
|
|
//1 is full volume, 2 is double volume, 0.5 is half volume, etc.
|
|
music.volume = 0.7;
|
|
|
|
//Pause the sound. To resume paused sounds call `play` again
|
|
music.pause();
|
|
|
|
//Play from a specific time (in seconds)
|
|
music.playFrom(10)
|
|
|
|
//Set the pan
|
|
//-1 is the full left speaker, 0 is the middle, 1 is the full right
|
|
//speaker
|
|
music.pan = -0.8;
|
|
|
|
//Fade a sound out, over 3 seconds
|
|
music.fadeOut(3);
|
|
|
|
//Fade a sound in, over 2 seconds
|
|
music.fadeIn(2)
|
|
|
|
//Fade a sound to a volume level of `0.3` over 1 second
|
|
music.fade(0.3, 1);
|
|
|
|
```
|
|
### Change the playback rate
|
|
Use `playbackRate` to change the speed at which the sound plays back.
|
|
A value of 0.5 will make the sound play at half speed. A value of 2
|
|
will make it play at double speed. 1 is normal speed.
|
|
```
|
|
music.playbackRate = 0.5;
|
|
```
|
|
Changing a sound's playback rate doesn't affect its pitch.
|
|
|
|
### Add echo
|
|
|
|
Use the `setEcho` method to set the sound's optional echo effect.
|
|
`setEcho` takes three arguments: `delay`, `feedback` and `filter`.
|
|
```
|
|
bounce.setEcho(0.2, 0.3, 1000);
|
|
```
|
|
`delay` and `feedback` are times, in seconds. `delay`determines how much
|
|
time will pass before the sound repeats. `feedback` determines the how
|
|
strong each repetition is - the higher the `feedback` value, the
|
|
longer the echo will last. `filter` is an optional value in Hertz that
|
|
filters out frequencies above that value. It changes the echo's tone
|
|
with each repetition for a more organic effect. Set `filter` to `0` to
|
|
disable it. If you ever need to switch off a sound's echo effect, set
|
|
the sound's
|
|
`echo` property to `false`
|
|
```
|
|
bounce.echo = false;
|
|
```
|
|
### Add reverb
|
|
|
|
Set a sound's reverb effect using `setReverb`. `setReverb` takes 3
|
|
arguments: `duration`, `decay`, and `reverse`.
|
|
```
|
|
music.setReverb(2, 2, false);
|
|
```
|
|
`duration` and `decay` are times, in seconds, that determine how
|
|
pronounced the reverb effect is. Give them large values to simulate a
|
|
large space, and small values to simulate a small space. The third
|
|
argument `reverse` is a Boolean (a true/false value) that determines whether the
|
|
reverb effect should be reversed. Set it to `false` for normal reverb, or
|
|
to `true` for a spooky reverse reverb. Set the sound's `reverb`
|
|
property to `false` if you need to disable the reverb effect later.
|
|
|
|
This is how work with sound files. But "Sound for Games" also lets you
|
|
generate your own
|
|
music and sound effects from scratch.
|
|
|
|
Generating sound effects and music
|
|
----------------------------------
|
|
|
|
Use the versatile `soundEffect` function to create an almost limitless
|
|
variety of sound effects using thirteen low-level parameters. Here's a model
|
|
for using it, including a description of what each parameter does.
|
|
```
|
|
soundEffect(
|
|
frequencyValue, //The sound's fequency pitch in Hertz
|
|
attack, //The time, in seconds, to fade the sound in
|
|
decay, //The time, in seconds, to fade the sound out
|
|
type, //waveform type: "sine", "triangle", "square", "sawtooth"
|
|
volumeValue, //The sound's maximum volume
|
|
panValue, //The speaker pan. left: -1, middle: 0, right: 1
|
|
wait, //The time, in seconds, to wait before playing the sound
|
|
pitchBendAmount, //The number of Hz to bend the sound's pitch down
|
|
reverse, //If `reverse` is true the pitch will bend up
|
|
randomValue, //A range, in Hz, within which to randomize the pitch
|
|
dissonance, //A value in Hz. Creates 2 dissonant frequencies above and below the target pitch
|
|
echo, //An array: [delayTimeInSeconds, feedbackTimeInSeconds, filterValueInHz]
|
|
reverb //An array: [durationInSeconds, decayRateInSeconds, reverse]
|
|
);
|
|
|
|
```
|
|
(Note: `reverb` for sound effects is currently **experimental** due to
|
|
browser quirks. In the future it might stabilize but, until then use
|
|
it at your peril!)
|
|
The strategy for using the `soundEffect` function is to tinker with
|
|
all these parameters and come up with your own custom library of sound
|
|
effects for games. Think of it as a big sound board with thirteen colourful
|
|
flashing dials you can play with. And think of yourself as a mad
|
|
scientist and that thirteen is your lucky number!
|
|
|
|
###Shoot sound
|
|
|
|
Here's an
|
|
example of how to use the `soundEffect` function to create a typical laser shoot sound.
|
|
```
|
|
function shootSound() {
|
|
soundEffect(
|
|
1046.5, //frequency
|
|
0, //attack
|
|
0.3, //decay
|
|
"sawtooth", //waveform
|
|
1, //Volume
|
|
-0.8, //pan
|
|
0, //wait before playing
|
|
1200, //pitch bend amount
|
|
false, //reverse bend
|
|
0, //random pitch range
|
|
25, //dissonance
|
|
[0.2, 0.2, 2000], //echo array: [delay, feedback, filter]
|
|
undefined //reverb array: [duration, decay, reverse?]
|
|
);
|
|
}
|
|
```
|
|
The "sawtooth" waveform setting gives the sound a biting harshness.
|
|
The `pitchBendAmount` is 1200, which means the sound's pitch drops
|
|
1200 Hz. from start to finish. That makes it sound like every laser
|
|
from every science fiction movie you've ever seen. The `dissonance` value of 25 means that
|
|
two extra overtones are added to the sound, 25 Hz above and below the
|
|
main frequency. Those extra overtones add an edgy complexity to the
|
|
tone.
|
|
|
|
Because the `soundEffect` function is wrapped in a custom `shootSound`
|
|
function, you can play the effect at any time in your application code
|
|
like this:
|
|
```
|
|
shootSound();
|
|
```
|
|
It will play immediately.
|
|
|
|
###Jump sound
|
|
|
|
Let's look at another example. Here's a `jumpSound` function that
|
|
produces a typical platform game character jumping sound.
|
|
```
|
|
function jumpSound() {
|
|
soundEffect(
|
|
523.25, //frequency
|
|
0.05, //attack
|
|
0.2, //decay
|
|
"sine", //waveform
|
|
3, //volume
|
|
0.8, //pan
|
|
0, //wait before playing
|
|
600, //pitch bend amount
|
|
true, //reverse
|
|
100, //random pitch range
|
|
0, //dissonance
|
|
undefined, //echo array: [delay, feedback, filter]
|
|
undefined //reverb array: [duration, decay, reverse?]
|
|
);
|
|
}
|
|
|
|
```
|
|
The `jumpSound` has an `attack` value of 0.05, which means there's a
|
|
very quick fade-in to the sound. It's so quick that you can't really hear it, but it
|
|
softens the start of sound a bit. The `reverse` value is `true` which means
|
|
that the pitch bends up instead down. (This makes sense because
|
|
jumping characters jump upwards.) The `randomValue` is 100. That means
|
|
the pitch will randomize within a range 100 Hz above and below the target frequency, so
|
|
that the sound's pitch is slightly different every time. This adds organic interest to
|
|
the sound and makes the game world feel alive.
|
|
|
|
###Explosion sound
|
|
|
|
You can create a radically different `explosionSound` effect just by
|
|
tweaking these same parameters.
|
|
```
|
|
function explosionSound() {
|
|
soundEffect(
|
|
16, //frequency
|
|
0, //attack
|
|
1, //decay
|
|
"sawtooth", //waveform
|
|
1, //volume
|
|
0, //pan
|
|
0, //wait before playing
|
|
0, //pitch bend amount
|
|
false, //reverse
|
|
0, //random pitch range
|
|
50, //dissonance
|
|
undefined, //echo array: [delay, feedback, filter]
|
|
undefined //reverb array: [duration, decay, reverse?]
|
|
);
|
|
}
|
|
```
|
|
This creates a low frequency rumble. The starting point for the
|
|
explosion sound is to set the `frequency` value extremely low: 16 Hz. It also
|
|
has a harsh "sawtooth" waveform. But what makes it really work is the
|
|
`dissonance` value of 50. This adds two overtones above and below the
|
|
target frequency; they interfere with each other and the main sound.
|
|
|
|
###Making music
|
|
|
|
But it's not just for sound effects! You can use the `soundEffect`
|
|
function to create musical notes, and play them at set intervals.
|
|
Here's a function called `bonusSound` which plays three notes (D, A
|
|
and high D) in a
|
|
rising pitch sequence. It's typical of the kind of musical motif you might
|
|
hear when a game character scores some bonus points, like picking up
|
|
stars or coins. (When you hear this sound you might have a flashback to 1985!)
|
|
```
|
|
function bonusSound() {
|
|
//D
|
|
soundEffect(587.33, 0, 0.2, "square", 1, 0, 0);
|
|
//A
|
|
soundEffect(880, 0, 0.2, "square", 1, 0, 0.1);
|
|
//High D
|
|
soundEffect(1174.66, 0, 0.3, "square", 1, 0, 0.2);
|
|
}
|
|
```
|
|
The key to making it work is the last argument: the `wait` value. The
|
|
first sound's `wait` value is 0, which means the sound will play
|
|
immediately. The second sound's `wait` value is 0.1, which means it
|
|
will play after a delay of 100 milliseconds. The last sound's `wait`
|
|
value is 0.2, which will make it play in 200 milliseconds. This
|
|
means that all three notes play in sequence with a 100 millisecond
|
|
gap between them.
|
|
|
|
With just a little more work you could use the `wait` parameter to build
|
|
a simple music sequencer, and build your own mini-library of musical sound effects
|
|
just for playing notes. If you need it, here's how to convert
|
|
frequencies in Hertz to real note values:
|
|
|
|
[Note values of frequencies in Hertz](http://www.phy.mtu.edu/~suits/notefreqs.html)
|
|
|
|
Have fun!
|