Repos on GitHub

* online demonstration of VA99 *

Hey! You!
What!?
You, you must master to how to play sound in browser!
But, do not worry. I teach to you to VA99!
I don't get a word of what you is saying ...
I was baffled!
First, you should load to js file.
Teach with the simplest way.
*BEEP*
<script src="https://cdn.jsdelivr.net/npm/va99/dist/va99.min.js" type="text/javascript"></script>
If you know more better way, you shall use that.
Do you know npm? If it is so, get package from npm.
https://www.npmjs.com/package/va99
Next, you should load audio files.
But beware. Take a long time to load file. So you may use await or then.
I ran below codes this time.
*BEEP*
(async function () { VA.V = 0.4; // Set master volume to 0.4 (default is 0.2) window.kick = await VA.L("audio/kick.m4a"); window.unidentified = await VA.L("audio/unidentified.m4a"); window.dandd = await VA.L("audio/dandd.m4a"); window.cntr2 = await VA.L("audio/cntr2.m4a"); })();
It is ready!
You push below buttons!
Well, push!
Let's!
Please!
Do it!
// to play SE 1
// to play SE 2
// to play BGM 1
// to play BGM 2
// to stop BGM
I heard these sounds
Yes.
These buttons has function to execute own label as js-code.
So, you can play SE and BGM only these code!
This is basic and essence.
You, you became to master of playing sound in browsers!
Congratulations!
What!?
Leftover is miscellaneous specifications!
Read below if you interest!
λ λ λ ...

API References

*BEEP*
You can open js-console in your browser at this page, and run codes that you want.

VA.L()

L is for Load.
It start to load from url of audio file, and return instance of audioBuffer later.
This is async function.
You can enhance this function by monkey patch if you need.

VA.P()

P is for Play or Prepare.
It play a sound from audioBuffer, and return instance of sourceNode.

VA.P(audioBuffer, dontStartAutomatically=false, dontReduceVolumeByExcessPlay=false)

audioBuffer: If it is null or undefined, do nothing, return undefined.

dontStartAutomatically: If it is set, only prepare and return sourceNode, does't play this sound.
In this situation, you should execute sourceNode.start() later by yourself.

dontReduceVolumeByExcessPlay: If it was set, does not use safety mechanism.
It may cause the audio catastrophe by playing SE per frame.

Returned sourceNode contains gainNode as G and stereoPannerNode as P.
(iOS started to support stereoPannerNode from 2021/04)
You can tweak these freely.
// play SE normally
// prepare SE and tweak parameters and play
// play SE with prevent excess playing (default)
// play SE without prevent excess playing (mash buttons for comparison)
// can set volume over 1.0 but may cause distortion

VA.BGM()

Play a BGM from audioBuffer.

VA.BGM(audioBuffer, isOneshot=0, fadeSec=1, pitch=1, volume=1, pan=0)

audioBuffer: If this is null or undefined, do only stop previous BGM with fade-out. Play nothing.
If already playing previous BGM, first, finish previous BGM with fade-out, and then, it start to play new BGM.
If not playing previous BGM, it play new BGM immediately.

If audioBuffer is not instance of AudioBuffer, and it is loadable value by VA.L(), VA99 try to load audioBuffer ahead.
So, you can play BGM after loading by below code.
VA.BGM("path/to/music.m4a", ... andMoreOptions)
But audioBuffer is not cached in this case. If you want to not load each time, you will use VA.L() explicitly please.

isOneshot: If you set this, BGM is not looping.

fadeSec: is applied to time of fade-out previous BGM.
If not playing previous BGM, play new BGM immediately notwithstanding this.

pitch, volume, and pan: These are apply to new BGM.
// play BGM normally
// stop BGM with fade-out
// play BGM oneshot
// play BGM with parameters
// stop previous BGM immediately
// can set volume over 1.0 but may cause distortion
// stop previous BGM with long fade-out
// play BGM from URL (but audioBuffer is not cached)
VA.BGM() returns arguments for resume BGM, if stopping.

var r r = VA.BGM(cntr2, true, 1, 0.5) // play BGM and returns [] // wait a minute r = VA.BGM() // stop BGM and returns arguments for resume BGM // wait a minute r = VA.BGM(... r) // resume previous BGM and returns []

VA.D()

D is for Dispose.
Stop and dispose spent sourceNode safely.
This interface is rarely used.
Because, it is called automatically by internal usually.
// play endless SE
// stop endless SE safely

VA.V

V is for master Volume.
It is a property, not a function.
This is the master volume of VA99.
All playing SE and BGM are affected immediately by this changes.
Default value is 0.2.
WARNING: Megavolume will cause down of audio quality!
You don't over to 0.5 for audio quality, if possible.

// This will cause down of audio quality
// 0.5 is upper limit within safety range
// default

VA.A

A is for AudioContext.
It is a property, not a function.
You can access to instance of AudioContext in VA99 internal.
But you should beware unlocking AudioContext (See FAQ).

VA.I()

I is for Interpolate.
Interpolate extra node between masterGainNode and ac.destination, or remove it.
It can keep only one extra node.
It is rarely used.
// interpolate extra node between masterGainNode and ac.destination
// remove interpolated node

VA.VER

It is a property, not a function.
You get a version string of this library.
It is rarely used.

FAQ

Occasionally, doesn't play sound
Perhaps, you don't execute unlock AudioContext.
VA99 provide and activate handler to unlock AudioContext automatically, but this is only run by `user-action`.
More specifically, `user-action` mean click or touch to page screen of browser.
That means, you should not be play BGM at the first (probably title) scene in html5 games.
Which type of audio file is best?
Conclusion: m4a is better.

mp3 is may include useless silent time at head. Pretty noticeable in some situations.
m4a is may include useless silent time at tail. But doesn't noticeable.
ogg is not include useless silent time, good. But some environments has lack of decoder.
Does support IE?
No.
VA99 support only Chromium family, WebKit mobile famliy and Firefox.
These of our time will update automatically itself, be maintained recency.
The dark age was already done.
I see it is written in a little strange js
Yes.
It is optimized for google-closure-compiler.
There is no problem in practice.
VA99 is tiny sure, but audio files remains in too big.
As a result, whole product not become tiny
Exactly!
We need to prepare AudioBuffer by very little resources.
Infact, I had the answer for this problem, but work in progress.

To be continued ...

table of contents